From 9a6d4112cf0a22e3f8a6967d962507ec316081b9 Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Wed, 4 Feb 2026 14:21:37 +0200 Subject: [PATCH] feat: finish game; store reports --- internal/controller/controller.go | 3 +++ internal/controller/generate_turn.go | 16 +++++++++------- internal/controller/report.go | 1 - internal/controller/vote.go | 12 ++++++++++++ internal/model/game/game.go | 5 +++++ internal/repo/game.go | 16 ++++++++++++++-- 6 files changed, 43 insertions(+), 10 deletions(-) diff --git a/internal/controller/controller.go b/internal/controller/controller.go index 5350139..ce98853 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -32,6 +32,9 @@ type Repo interface { // SaveBombing stores all prodused bombings for turn t SaveBombings(t uint, b []*game.Bombing) error + + // SaveReport stores latest report for a race + SaveReport(t uint, rep *report.Report) error } type Controller struct { diff --git a/internal/controller/generate_turn.go b/internal/controller/generate_turn.go index 1e34b34..9d9e3f5 100644 --- a/internal/controller/generate_turn.go +++ b/internal/controller/generate_turn.go @@ -50,6 +50,7 @@ func MakeTurn(c *Controller, r Repo) error { // 16. Происходит голосование. winners := c.Cache.TurnCalculateVotes() + c.Cache.TurnAcceptWinners(winners) /*** Last steps ***/ @@ -107,15 +108,16 @@ func MakeTurn(c *Controller, r Repo) error { c.Cache.DeleteKilledShipGroups() // Store game state for the new turn and 'current' state as well - r.SaveTurn(c.Cache.g.Turn, c.Cache.g) - - // TODO: Store individual reports - for ri := range c.Cache.g.Race { - _ = ri - // c.Cache.GenerateReport(ri) + if err := r.SaveTurn(c.Cache.g.Turn, c.Cache.g); err != nil { + return err + } + + for rep := range c.Cache.Report(c.Cache.g.Turn, battleReport, bombingReport) { + if err := r.SaveReport(c.Cache.g.Turn, rep); err != nil { + return err + } } - _ = winners // [ ] monitor memory consumption at this point? return nil } diff --git a/internal/controller/report.go b/internal/controller/report.go index 25e2967..7df8d17 100644 --- a/internal/controller/report.go +++ b/internal/controller/report.go @@ -248,7 +248,6 @@ func (c *Cache) ReportLocalShipClass(ri int, report *mr.Report) { slices.SortFunc(report.LocalShipClass, func(a, b mr.ShipClass) int { return cmp.Compare(a.Name, b.Name) }) } -// FIXME: add ships bombed/wiped planets without battles func (c *Cache) ReportOtherShipClass(ri int, rep *mr.Report) { c.validateRaceIndex(ri) r := &c.g.Race[ri] diff --git a/internal/controller/vote.go b/internal/controller/vote.go index e484701..a6ef1be 100644 --- a/internal/controller/vote.go +++ b/internal/controller/vote.go @@ -30,6 +30,18 @@ func (n VoteNode) String() string { return fmt.Sprintf("%s%d%s", lh, n.ID, rh) } +func (c *Cache) TurnAcceptWinners(v []int) { + if c.g.Finished() { + panic("game is already has its winner(s)") + } + if len(v) == 0 { + return + } + for _, ri := range v { + c.g.Winner = append(c.g.Winner, c.g.Race[ri].ID) + } +} + func (c *Cache) TurnCalculateVotes() []int { raceVotes := c.votesByRace() calc := GroupVotes(raceVotes, VotingGraph(c.g.Race, c.RaceIndex)) diff --git a/internal/model/game/game.go b/internal/model/game/game.go index 6282ccc..fb7c242 100644 --- a/internal/model/game/game.go +++ b/internal/model/game/game.go @@ -47,6 +47,11 @@ type Game struct { Votes float64 `json:"votes"` ShipGroups []ShipGroup `json:"shipGroup,omitempty"` Fleets []Fleet `json:"fleet,omitempty"` + Winner []uuid.UUID `json:"winner,omitempty"` +} + +func (g Game) Finished() bool { + return len(g.Winner) > 0 } type GameMeta struct { diff --git a/internal/repo/game.go b/internal/repo/game.go index 21170ee..3babd12 100644 --- a/internal/repo/game.go +++ b/internal/repo/game.go @@ -22,6 +22,18 @@ const ( metaPath = "meta.json" ) +func (r *repo) SaveReport(t uint, rep *report.Report) error { + return saveReport(r.s, t, rep) +} + +func saveReport(s Storage, t uint, v *report.Report) error { + path := fmt.Sprintf("%s/report/%s.json", turnDir(t), v.RaceID.String()) + if err := s.Write(path, v); err != nil { + return NewStorageError(err) + } + return nil +} + func (r *repo) SaveTurn(t uint, g *game.Game) error { return saveTurn(r.s, t, g) } @@ -127,13 +139,13 @@ func (r *repo) SaveBattle(t uint, b *report.BattleReport, m *game.BattleMeta) er } func saveBattle(s Storage, t uint, b *report.BattleReport) error { - path := fmt.Sprintf("%s/battle/%s.json", turnDir(t), b.ID) + path := fmt.Sprintf("%s/battle/%s.json", turnDir(t), b.ID.String()) exist, err := s.Exists(path) if err != nil { return NewStorageError(err) } if exist { - return NewStateError(fmt.Sprintf("battle %s for turn %d already has been saved", b.ID, t)) + return NewStateError(fmt.Sprintf("battle %v for turn %d already has been saved", b.ID, t)) } if err := s.Write(path, b); err != nil { return NewStorageError(err)