diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-09-05 18:28:47 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-09-05 18:28:47 +0200 |
| commit | 034e176110cc0a27cd20bdfe8522fd0dc73d2346 (patch) | |
| tree | e0198741c94fb3af7777056c031e74100f4f9bb5 | |
| parent | 611c8cd048ca216c16da6744ce2052d9dc000c83 (diff) | |
| download | muhqs-game-034e176110cc0a27cd20bdfe8522fd0dc73d2346.tar.gz muhqs-game-034e176110cc0a27cd20bdfe8522fd0dc73d2346.zip | |
implement more prompts and exp1/backup!
| -rw-r--r-- | go/game/action.go | 14 | ||||
| -rw-r--r-- | go/game/cardImplementations.go | 21 | ||||
| -rw-r--r-- | go/game/player.go | 48 | ||||
| -rw-r--r-- | go/game/playerControl.go | 12 |
4 files changed, 82 insertions, 13 deletions
diff --git a/go/game/action.go b/go/game/action.go index 0cc0bd0a..ab38f238 100644 --- a/go/game/action.go +++ b/go/game/action.go @@ -93,6 +93,20 @@ func newHandCardSelection(p *Player, min, max int) Action { return a } +func newAlliedUnitSelection(p *Player, min, max int) Action { + a := &TargetSelection{player: p} + targetDesc := TargetDesc{"unit you control", fmt.Sprintf("%d-%d", min, max)} + a.targets = newTargets(newTarget(p.gameState, targetDesc, a)) + return a +} + +func newTileSelection(p *Player, constraint TargetConstraintFunc, min, max int) Action { + a := &TargetSelection{player: p} + desc := TargetDesc{"tile", fmt.Sprintf("%d-%d", min, max)} + a.targets = newTargets(newConstraintTarget(p.gameState, desc, constraint, a)) + return a +} + type FreeDiscardAction struct { TargetSelection } diff --git a/go/game/cardImplementations.go b/go/game/cardImplementations.go index ea07ccf4..f7f765d5 100644 --- a/go/game/cardImplementations.go +++ b/go/game/cardImplementations.go @@ -728,6 +728,26 @@ func (*unholyCannonballImpl) onPlay(a *PlayAction) { } } +// ====== Exp1 Set ====== + +type backupImpl struct{ cardImplementationBase } + +func (*backupImpl) onPlay(a *PlayAction) { + p := a.Controller() + units := p.PromptAlliedUnitSelection(0, 1) + if len(units) == 0 { + return + } + constraint := conjunction( + rangeTargetConstraint(units[0].Tile(), 1), + availableTileConstraint(a, NewCard("base/recruit")), + ) + tiles := p.PromptTilesSelection(constraint, 0, 2) + for _, tile := range tiles { + p.gameState.addNewUnit(NewCard("base/recruit"), tile.Position, p) + } +} + type illusionistImpl struct{ cardImplementationBase } func (*illusionistImpl) fullActions(u *Unit) []*FullAction { @@ -879,6 +899,7 @@ func init() { "kraken/tides_change!": &tidesChangeImpl{}, "kraken/unholy_cannonball": &unholyCannonballImpl{}, + "exp1/backup!": &backupImpl{}, "exp1/illusion": &illusionImpl{}, "exp1/illusionist": &illusionistImpl{}, "exp1/patrician": &patricianImpl{}, diff --git a/go/game/player.go b/go/game/player.go index a8372040..b3cdfe0f 100644 --- a/go/game/player.go +++ b/go/game/player.go @@ -224,37 +224,59 @@ func (p *Player) discardStep() { } cards := p.PromptHandCardSelection(0, p.Hand.Size()) - for _, c := range cards { - p.DiscardCard(c) - } + p.discardCards(cards) } -func (p *Player) PromptHandCardSelection(min, max int) []*Card { - p.Ctrl.SendNotification(newHandCardSelectionPrompt(p, min, max)) +func (p *Player) Prompt(n PlayerNotification) Action { + p.Ctrl.SendNotification(n) _a, err := p.Ctrl.RecvAction() if err != nil { // FIXME } switch a := _a.(type) { - case *TargetSelection: - err := a.CheckTargets(p.gameState) - if err != nil { - log.Panicf("Invalid hand card selection: %v", err) - } - - return utils.InterfaceSliceToTypedSlice[*Card](a.Target().sel) case *PassPriority: return nil case *ConcedeAction: p.concede() return nil default: - log.Panicf("Unexpected response type %T for hand card selection", a) + return a + } +} + +func PromptSelection[T any](p *Player, n PlayerNotification) []T { + _a := p.Prompt(n) + if _a == nil { + return nil + } + + switch a := _a.(type) { + case *TargetSelection: + err := a.CheckTargets(p.gameState) + if err != nil { + log.Panicf("Invalid selection: %v", err) + } + + return utils.InterfaceSliceToTypedSlice[T](a.Target().sel) + default: + log.Panicf("Unexpected response type %T for selection", a) } return nil } +func (p *Player) PromptHandCardSelection(min, max int) []*Card { + return PromptSelection[*Card](p, newHandCardSelectionPrompt(p, min, max)) +} + +func (p *Player) PromptAlliedUnitSelection(min, max int) []*Unit { + return PromptSelection[*Unit](p, newAlliedUnitSelectionPrompt(p, min, max)) +} + +func (p *Player) PromptTilesSelection(c TargetConstraintFunc, min, max int) []*Tile { + return PromptSelection[*Tile](p, newTileSelectionPrompt(p, c, min, max)) +} + func (p *Player) Draw() { toDraw := p.DrawPerTurn - p.Hand.Size() if toDraw < 1 { diff --git a/go/game/playerControl.go b/go/game/playerControl.go index 5f446106..676d15ce 100644 --- a/go/game/playerControl.go +++ b/go/game/playerControl.go @@ -109,6 +109,18 @@ func newHandCardSelectionPrompt(p *Player, min, max int) PlayerNotification { return newTargetSelectionPrompt(a, desc) } +func newAlliedUnitSelectionPrompt(p *Player, min, max int) PlayerNotification { + a := newAlliedUnitSelection(p, min, max) + desc := fmt.Sprintf("Select between %d and %d allied units", min, max) + return newTargetSelectionPrompt(a, desc) +} + +func newTileSelectionPrompt(p *Player, c TargetConstraintFunc, min, max int) PlayerNotification { + a := newTileSelection(p, c, min, max) + desc := fmt.Sprintf("Select between %d and %d tiles", min, max) + return newTargetSelectionPrompt(a, desc) +} + func newDeclareTriggeredActionsPrompt(triggeredActions []*TriggeredAction) PlayerNotification { return PlayerNotification{DeclareTriggeredActionsPrompt, triggeredActions, nil} } |
