package game import ( "slices" "github.com/google/uuid" e "github.com/iliadenisov/galaxy/internal/error" ) type Race struct { ID uuid.UUID `json:"id"` Name string `json:"name"` Extinct bool `json:"extinct"` Vote uuid.UUID `json:"vote"` Relations []RaceRelation `json:"relations"` Tech TechSet `json:"tech"` Sciences []Science `json:"science,omitempty"` ShipTypes []ShipType `json:"shipType,omitempty"` } type Relation string const ( RelationWar Relation = "War" RelationPeace Relation = "Peace" ) type RaceRelation struct { RaceID uuid.UUID `json:"raceId"` Relation Relation `json:"relation"` } func (r Race) TechLevel(t Tech) float64 { return r.Tech.Value(t) } // TODO: refactor to separate method with *Race as parameter func (r *Race) SetTechLevel(t Tech, v float64) { r.Tech = r.Tech.Set(t, v) } func (r Race) FlightDistance() float64 { return r.TechLevel(TechDrive) * 40 } func (r Race) VisibilityDistance() float64 { return r.TechLevel(TechDrive) * 30 } 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) 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) GiveVotes(race, recipient string) error { ri, err := g.raceIndex(race) if err != nil { return err } rec, err := g.raceIndex(recipient) if err != nil { return err } g.Race[ri].Vote = g.Race[rec].ID return nil } func (g Game) relationInternal(ri, other int) (RaceRelation, error) { if ri == other { return RaceRelation{ RaceID: g.Race[ri].ID, Relation: RelationPeace, }, nil } 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 } 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 }