From 6c3c936dbd62ca70570e416d976597ac0d33a7f5 Mon Sep 17 00:00:00 2001 From: Kistaro Windrider Date: Sat, 15 Apr 2023 16:06:55 -0700 Subject: [PATCH] Debug Actions: Another set of permanent actions. These are only reachable in debug mode. --- cardsim/player.go | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/cardsim/player.go b/cardsim/player.go index 9384698..1fea13b 100644 --- a/cardsim/player.go +++ b/cardsim/player.go @@ -13,6 +13,7 @@ var ( ErrInvalidChoice = errors.New("invalid choice specified") ErrNotUrgent = errors.New("action not urgent when urgent card is available") ErrNoActions = errors.New("no actions remaining") + ErrNotDebugging = errors.New("this is a debug-only feature and you're not in debug mode") WarningStalemate = errors.New("no actions can be taken") ) @@ -104,6 +105,10 @@ type Player[C StatsCollection] struct { // card is in the hand. PermanentActions []Card[C] + // DebugActions are PermanentActions only available when the player is in + // debug mode. + DebugActions []Card[C] + // InfoPanels lists informational views available to the player. The Prompt // is the InfoPanel shown before the main action menu. InfoPanels []InfoPanel[C] @@ -381,10 +386,31 @@ func (p *Player[C]) EnactCard(cardIdx, choiceIdx int) (Message, error) { // result of enacting the permanent action. If enacting the card causes a // serious error, the State becomes GameCrashed. func (p *Player[C]) EnactPermanentActionUnchecked(actionIdx, choiceIdx int) (Message, error) { - if actionIdx < 0 || actionIdx >= len(p.PermanentActions) { - return nil, fmt.Errorf("%w: no action #%d when %d permanent actions exist", ErrInvalidCard, actionIdx, len(p.PermanentActions)) + return p.enactActionUnchecked(p.PermanentActions, actionIdx, choiceIdx) +} + +// EnactDebugActionUnchecked executes a debug action and decrements the +// ActionsRemaining, even though most debug actions will want to refund that +// action point. (Consistency with other actions is important.) It does not +// check for Urgent cards or for already being out of actions. If no such action +// or card option exists, or the option is not enabled, this returns nil and +// ErrInvalidCard or ErrInvalidChoice without changing anything. If the player +// is not in debug mode (DebugLevel >= 1), this returns ErrNotDebugging. +// Otherwise, this returns the result of enacting the debug action. If enacting +// the action causes a serious error, the State becomes GameCrashed. +func (p *Player[C]) EnactDebugActionUnchecked(actionIdx, choiceIdx int) (Message, error) { + if p.DebugLevel < 1 { + return nil, ErrNotDebugging } - card := p.PermanentActions[actionIdx] + return p.enactActionUnchecked(p.DebugActions, actionIdx, choiceIdx) +} + +// enactActionUnchecked implements EnactPermanentActionUnchecked and EnactDebugActionUnchecked. +func (p *Player[C]) enactActionUnchecked(actionSource []Card[C], actionIdx, choiceIdx int) (Message, error) { + if actionIdx < 0 || actionIdx >= len(actionSource) { + return nil, fmt.Errorf("%w: no action #%d when %d actions exist", ErrInvalidCard, actionIdx, len(actionSource)) + } + card := actionSource[actionIdx] var errs ErrorCollector options, err := card.Options(p) if IsSeriousError(err) { @@ -393,12 +419,12 @@ func (p *Player[C]) EnactPermanentActionUnchecked(actionIdx, choiceIdx int) (Mes } errs.Add(err) if choiceIdx < 0 || choiceIdx > len(options) { - errs.Add(fmt.Errorf("%w: no option #%d on permanent action #%d with %d options", ErrInvalidChoice, choiceIdx, actionIdx, len(options))) + errs.Add(fmt.Errorf("%w: no option #%d on action #%d with %d options", ErrInvalidChoice, choiceIdx, actionIdx, len(options))) return nil, errs.Emit() } chosen := options[choiceIdx] if !chosen.Enabled(p) { - errs.Add(fmt.Errorf("%w: option #%d on permanent action #%d is not enabled", ErrInvalidChoice, choiceIdx, actionIdx)) + errs.Add(fmt.Errorf("%w: option #%d on action #%d is not enabled", ErrInvalidChoice, choiceIdx, actionIdx)) return nil, errs.Emit() }