implement model for adrenaline

This commit is contained in:
Branden J Brown 2024-04-07 20:40:01 -05:00
parent 9395b2192e
commit 93716a7f0f
2 changed files with 22 additions and 9 deletions

View File

@ -36,6 +36,9 @@ type Match struct {
// reveal indicates whether the current player has revealed the shell that
// will fire next.
reveal bool
// adrenaline indicates whether the current player has adrenaline in
// effect, requiring them to use an opponent's item.
adrenaline bool
// prev is a pointer to the element of shellArray which was fired last this
// game, or nil if none has been.
prev *bool
@ -117,17 +120,22 @@ func (g *Match) Opponent() *playerState {
// Apply uses an item by index for the current player.
// If this causes the current game to end (a beer discharges the last shell),
// 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
// (with appropriate exception for adrenaline).
func (g *Match) Apply(id player.ID, item int) error {
cur := g.CurrentPlayer()
if cur.id != id {
p := g.CurrentPlayer()
if g.adrenaline {
p = g.Opponent()
}
if p.id != id {
return ErrWrongTurn
}
if item < 0 || item >= len(cur.items) {
if item < 0 || item >= len(p.items) {
return errors.New("item index out of bounds")
}
if cur.items[item].apply(g) {
cur.items[item] = itemNone
if p.items[item].apply(g) {
p.items[item] = itemNone
g.adrenaline = false
}
if g.Empty() {
return ErrGameEnded
@ -183,10 +191,11 @@ func (g *Match) MatchWinner() *playerState {
// 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
// or if adrenaline is in effect.
func (g *Match) Shoot(id player.ID, self bool) error {
cur := g.CurrentPlayer()
if cur.id != id {
if cur.id != id || g.adrenaline {
return ErrWrongTurn
}
target := g.Opponent()

View File

@ -62,8 +62,12 @@ func (i item) apply(g *Match) bool {
g.damage = 2
return true
case itemAdrenaline:
if g.adrenaline {
// Adrenaline forbids using adrenaline.
return false
}
g.action = actAdrenaline
// TODO(zeph): implement
g.adrenaline = true
return true
case itemPhone:
g.action = actPhone