diff --git a/internal/model/game/game.go b/internal/model/game/game.go index e75e6ab..28a725e 100644 --- a/internal/model/game/game.go +++ b/internal/model/game/game.go @@ -76,59 +76,6 @@ func (g Game) raceIndex(name string) (int, error) { 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 diff --git a/internal/model/game/game_test.go b/internal/model/game/game_test.go index 836563e..cf60845 100644 --- a/internal/model/game/game_test.go +++ b/internal/model/game/game_test.go @@ -10,7 +10,8 @@ import ( var ( Race_0 = game.Race{ - ID: uuid.New(), + ID: Race_0_ID, + Vote: Race_0_ID, Name: "Race_0", Tech: map[game.Tech]float64{ game.TechDrive: 1.1, @@ -20,7 +21,8 @@ var ( }, } Race_1 = game.Race{ - ID: uuid.New(), + ID: Race_1_ID, + Vote: Race_1_ID, Name: "Race_1", Tech: map[game.Tech]float64{ game.TechDrive: 2.1, @@ -30,6 +32,7 @@ var ( }, } + Race_0_ID = uuid.New() Race_0_idx = 0 Race_0_Gunship = "R0_Gunship" Race_0_Freighter = "R0_Freighter" @@ -39,6 +42,7 @@ var ( Race_0_Freighter_idx = 1 Race_0_Cruiser_idx = 2 + Race_1_ID = uuid.New() Race_1_idx = 1 Race_1_Gunship = "R1_Gunship" Race_1_Freighter = "R1_Freighter" diff --git a/internal/model/game/race.go b/internal/model/game/race.go index 58b8729..6b8e50d 100644 --- a/internal/model/game/race.go +++ b/internal/model/game/race.go @@ -1,7 +1,10 @@ package game import ( + "slices" + "github.com/google/uuid" + e "github.com/iliadenisov/galaxy/internal/error" ) type Race struct { @@ -47,3 +50,69 @@ func (r Race) FlightDistance() float64 { 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 +} diff --git a/internal/model/game/race_test.go b/internal/model/game/race_test.go new file mode 100644 index 0000000..05559ea --- /dev/null +++ b/internal/model/game/race_test.go @@ -0,0 +1,22 @@ +package game_test + +import ( + "testing" + + e "github.com/iliadenisov/galaxy/internal/error" + "github.com/stretchr/testify/assert" +) + +func TestGiveVotes(t *testing.T) { + g := newGame() + + assert.Equal(t, g.Race[Race_0_idx].ID, g.Race[Race_0_idx].Vote) + assert.Equal(t, g.Race[Race_1_idx].ID, g.Race[Race_1_idx].Vote) + + assert.NoError(t, g.GiveVotes(Race_0.Name, Race_1.Name)) + assert.Equal(t, g.Race[Race_1_idx].ID, g.Race[Race_0_idx].Vote) + assert.Equal(t, g.Race[Race_1_idx].ID, g.Race[Race_1_idx].Vote) + + assert.ErrorContains(t, g.GiveVotes("UnknownRace", Race_1.Name), e.GenericErrorText(e.ErrInputUnknownRace)) + assert.ErrorContains(t, g.GiveVotes(Race_0.Name, "UnknownRace"), e.GenericErrorText(e.ErrInputUnknownRace)) +}