indicate round and game end with errors

Fixes #8.
This commit is contained in:
Branden J Brown 2024-01-29 11:37:17 -06:00
parent f7be9beabc
commit 6077316a0d
1 changed files with 30 additions and 11 deletions

View File

@ -113,8 +113,8 @@ func (g *Match) Opponent() *Player {
} }
// Apply uses an item by index for the current player. // Apply uses an item by index for the current player.
// This may cause the current game to end, but does not start the next game // If this causes the current game to end (a beer discharges the last shell),
// if so. // returns ErrGameEnded but does not start the next game.
// Returns ErrWrongTurn if id does not correspond to the current player. // Returns ErrWrongTurn if id does not correspond to the current player.
func (g *Match) Apply(id player.ID, item int) error { func (g *Match) Apply(id player.ID, item int) error {
cur := g.CurrentPlayer() cur := g.CurrentPlayer()
@ -127,6 +127,9 @@ func (g *Match) Apply(id player.ID, item int) error {
if cur.items[item].Apply(g) { if cur.items[item].Apply(g) {
cur.items[item] = ItemNone cur.items[item] = ItemNone
} }
if g.Empty() {
return ErrGameEnded
}
return nil return nil
} }
@ -175,7 +178,9 @@ func (g *Match) MatchWinner() *Player {
} }
// Shoot fires the shotgun, at the opponent if self is false and at the current // Shoot fires the shotgun, at the opponent if self is false and at the current
// player if self is true. Afterward, the round or game may be over. // player if self is true. Advances the turn if appropriate.
// Returns ErrRoundEnded if this causes the round to end.
// Returns ErrGameEnded if this causes the game but not the round to end.
// Returns ErrWrongTurn if id does not correspond to the current player. // Returns ErrWrongTurn if id does not correspond to the current player.
func (g *Match) Shoot(id player.ID, self bool) error { func (g *Match) Shoot(id player.ID, self bool) error {
cur := g.CurrentPlayer() cur := g.CurrentPlayer()
@ -189,27 +194,37 @@ func (g *Match) Shoot(id player.ID, self bool) error {
live := g.popShell() live := g.popShell()
if live { if live {
target.hp -= g.damage target.hp -= g.damage
g.NextTurn() if target.hp <= 0 {
} else if !self { // If the target is the challenger, the match is over as well.
if target == &g.players[1] {
g.round = 3
}
return ErrRoundEnded
}
}
if g.Empty() {
return ErrGameEnded
}
if !self || live {
g.NextTurn() g.NextTurn()
} }
return nil return nil
} }
// Concede sets the player with the given ID to zero health and ends the match. // Concede sets the player with the given ID to zero health and ends the match.
// The returned bool indicates whether the match has ended. (It will be false // The returned error is ErrRoundEnded if id corresponds to either player and
// if id does not correspond to either player.) // ErrWrongTurn otherwise.
func (g *Match) Concede(id player.ID) bool { func (g *Match) Concede(id player.ID) error {
switch id { switch id {
case g.players[0].id: case g.players[0].id:
g.players[0].hp = 0 g.players[0].hp = 0
case g.players[1].id: case g.players[1].id:
g.players[1].hp = 0 g.players[1].hp = 0
default: default:
return false return ErrWrongTurn
} }
g.round = 3 g.round = 3
return true return ErrRoundEnded
} }
// DTO returns the current match state as viewed by the given player. // DTO returns the current match state as viewed by the given player.
@ -239,4 +254,8 @@ func (g *Match) ShellCounts() serve.ShellCounts {
return counts return counts
} }
var ErrWrongTurn = errors.New("not your turn") var (
ErrWrongTurn = errors.New("not your turn")
ErrGameEnded = errors.New("the shotgun is empty")
ErrRoundEnded = errors.New("someone h*ckin died")
)