Files
galaxy-game/internal/model/game/race.go
T
Ilia Denisov c9ed52b268 cmd: vote
2026-01-06 07:58:55 +02:00

119 lines
2.6 KiB
Go

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) {
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
}