chore: refactor structure

This commit is contained in:
Ilia Denisov
2025-11-21 21:40:15 +03:00
parent 126f381b04
commit 269de2184c
72 changed files with 512 additions and 393 deletions
+111
View File
@@ -0,0 +1,111 @@
package game
import (
"encoding/json"
"slices"
"strings"
"github.com/google/uuid"
e "github.com/iliadenisov/galaxy/internal/error"
)
type Game struct {
ID uuid.UUID `json:"id"`
Age uint `json:"turn"` // Game's turn number
Map Map `json:"map"`
Race []Race `json:"races"`
ShipGroups []ShipGroup `json:"shipGroup,omitempty"`
Fleets []Fleet `json:"fleet,omitempty"`
}
func (g Game) Votes(raceID uuid.UUID) float64 {
// XXX: calculate [Race]Population once when loading Game from Storage?
var pop float64
for i := range g.Map.Planet {
if g.Map.Planet[i].Owner == raceID {
pop += g.Map.Planet[i].Population
}
}
return pop / 1000.
}
func (g Game) raceIndex(name string) (int, error) {
i := slices.IndexFunc(g.Race, func(r Race) bool { return r.Name == name })
if i < 0 {
return i, e.NewRaceUnknownError(name)
}
return i, nil
}
func (g Game) UpdateRelation(race, opponent string, rel Relation) error {
ri, err := g.raceIndex(race)
if err != nil {
return err
}
var other int
if race == opponent {
other = ri
} else if other, err = g.raceIndex(opponent); err != nil {
return err
}
if err != nil {
return err
}
return g.updateRelationInternal(ri, other, rel)
}
func (g Game) updateRelationInternal(ri, other int, rel Relation) error {
for o := range g.Race[ri].Relations {
switch {
case ri == other:
g.Race[ri].Relations[o].Relation = rel
case g.Race[ri].Relations[o].RaceID == g.Race[other].ID:
g.Race[ri].Relations[o].Relation = rel
return nil
}
}
if ri != other {
return e.NewGameStateError("UpdateRelation: opponent not found")
}
return nil
}
func (g Game) Relation(hostRace, opponentRace string) (RaceRelation, error) {
ri, err := g.raceIndex(hostRace)
if err != nil {
return RaceRelation{}, err
}
other, err := g.raceIndex(opponentRace)
if err != nil {
return RaceRelation{}, err
}
return g.relationInternal(ri, other)
}
func (g Game) relationInternal(ri, other int) (RaceRelation, error) {
rel := slices.IndexFunc(g.Race[ri].Relations, func(r RaceRelation) bool { return r.RaceID == g.Race[other].ID })
if rel < 0 {
return RaceRelation{}, e.NewGameStateError("Relation: opponent not found")
}
return g.Race[ri].Relations[rel], nil
}
// -----------------------------------------------------------------------------
// validateTypeName always return v without leading and trailing spaces
func validateTypeName(v string) (string, bool) {
s := strings.TrimSpace(v)
if len(s) > 0 {
return s, true
}
// TODO: special symbols
return s, false
}
func (g Game) MarshalBinary() (data []byte, err error) {
return json.Marshal(&g)
}
func (g *Game) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, g)
}