diff --git a/game/game.go b/game/game.go index e48b9c3..426c460 100644 --- a/game/game.go +++ b/game/game.go @@ -4,6 +4,7 @@ import ( "errors" "git.sunturtle.xyz/studio/shotgun/player" + "git.sunturtle.xyz/studio/shotgun/serve" ) type Game struct { @@ -105,7 +106,7 @@ func (g *Game) PopShell() bool { // Peek returns the current turn's shell if it is revealed for the player with // the given ID, or nil otherwise. func (g *Game) Peek(id player.ID) *bool { - if id != g.CurrentPlayer().ID || !g.Reveal { + if len(g.Shells) == 0 || id != g.CurrentPlayer().ID || !g.Reveal { return nil } return &g.Shells[0] @@ -150,4 +151,20 @@ func (g *Game) Shoot(id player.ID, self bool) error { return nil } +// DTO returns the current game state as viewed by the given player. +func (g *Game) DTO(id player.ID) serve.Game { + return serve.Game{ + Players: [2]serve.Player{ + g.PP[0].DTO(), + g.PP[1].DTO(), + }, + Round: g.Round, + Group: g.Group, + Turn: g.Turn, + Damage: g.Damage, + Shell: g.Peek(id), + Previous: g.Prev, + } +} + var ErrWrongTurn = errors.New("not your turn") diff --git a/game/player.go b/game/player.go index 46eeada..2f35f1d 100644 --- a/game/player.go +++ b/game/player.go @@ -4,6 +4,7 @@ import ( "slices" "git.sunturtle.xyz/studio/shotgun/player" + "git.sunturtle.xyz/studio/shotgun/serve" ) type Player struct { @@ -29,6 +30,22 @@ func (p *Player) StartGroup(rng *RNG, items int) { p.Cuffs = Uncuffed // TODO(zeph): or is this startround? } +func (p *Player) DTO() serve.Player { + r := serve.Player{ + HP: p.HP, + Items: make([]string, 0, 8), + Cuffs: p.Cuffs != Uncuffed, + } + for _, i := range p.Items { + s := i.String() + if s == "" { + continue + } + r.Items = append(r.Items, s) + } + return r +} + type CuffState uint8 const ( diff --git a/serve/dto.go b/serve/dto.go new file mode 100644 index 0000000..e199278 --- /dev/null +++ b/serve/dto.go @@ -0,0 +1,32 @@ +package serve + +// Game is the JSON DTO for a game. +type Game struct { + // Players is the players in the game. + // The dealer is always the first player. + Players [2]Player `json:"players"` + // Round is the current round. + Round uint `json:"round"` + // Group is the current shell group. + Group uint `json:"group"` + // Turn is the current turn. + Turn uint `json:"turn"` + // Damage is the damage a live shell will deal this turn. + Damage int8 `json:"damage"` + // Shell gives whether the current shell is live if it is revealed. + // Undefined if this game state is not for the current player or if the + // current player hasn't revealed it. + Shell *bool `json:"shell,omitempty"` + // Previous gives whether the previously discharged shell was live. + Previous *bool `json:"previous"` +} + +// Player is the JSON DTO for a player. +type Player struct { + // HP is the player's current health. + HP int8 `json:"hp"` + // Items is the player's items. + Items []string `json:"items,omitempty"` + // Cuffs is whether the player is currently wearing cuffs. + Cuffs bool `json:"cuffs,omitempty"` +}