diff options
Diffstat (limited to 'go')
| -rw-r--r-- | go/game/action.go | 34 | ||||
| -rw-r--r-- | go/game/playerControl.go | 7 | ||||
| -rw-r--r-- | go/game/state.go | 45 | ||||
| -rw-r--r-- | go/game/trigger.go | 6 |
4 files changed, 81 insertions, 11 deletions
diff --git a/go/game/action.go b/go/game/action.go index 4f433845..a8b27314 100644 --- a/go/game/action.go +++ b/go/game/action.go @@ -2,6 +2,7 @@ package game import ( "fmt" + "log" ) type ( @@ -12,6 +13,7 @@ type ( type Action interface { Source() interface{} + Controller() *Player Targets() *Targets Target() *Target // Shortcut for to select the first target @@ -25,6 +27,7 @@ type Action interface { type PassPriority struct{ player *Player } func (a *PassPriority) Source() interface{} { return a.player } +func (a *PassPriority) Controller() *Player { return a.player } func (*PassPriority) Targets() *Targets { return nil } func (*PassPriority) Target() *Target { return nil } func (*PassPriority) NeedsActionCostChoice() bool { return false } @@ -40,6 +43,7 @@ type TargetSelection struct { } func (sel *TargetSelection) Source() interface{} { return sel.player } +func (sel *TargetSelection) Controller() *Player { return sel.player } func (sel *TargetSelection) Targets() *Targets { return sel.targets } func (sel *TargetSelection) Target() *Target { return sel.targets.ts[0] } func (*TargetSelection) NeedsActionCostChoice() bool { return false } @@ -67,7 +71,20 @@ type ActionBase struct { costFunc ActionCostFunc } -func (a *ActionBase) Source() interface{} { return a.source } +func (a *ActionBase) Source() interface{} { return a.source } +func (a *ActionBase) Controller() *Player { + switch t := a.source.(type) { + case *Player: + return t + case Permanent: + return t.Controller() + default: + log.Panicf("Unhandled source type %v", t) + return nil + } + + return nil +} func (a *ActionBase) resolve(s *State) { a.resolveFunc(s) } func (a *ActionBase) PayCosts(s *State) bool { return a.costFunc(s) } func (a *ActionBase) Targets() *Targets { return a.targets } @@ -102,6 +119,21 @@ func (a *TriggeredAction) String() string { return fmt.Sprintf("%v ! %v", a.event, a.source) } +// Wrapper action to pass all triggered actions through the PlayerControl +type DeclareTriggeredActionsAction struct { + actions []*TriggeredAction +} + +func (sel *DeclareTriggeredActionsAction) Source() interface{} { return nil } +func (sel *DeclareTriggeredActionsAction) Controller() *Player { return nil } +func (sel *DeclareTriggeredActionsAction) Targets() *Targets { return nil } +func (sel *DeclareTriggeredActionsAction) Target() *Target { return nil } +func (*DeclareTriggeredActionsAction) NeedsActionCostChoice() bool { return false } +func (sel *DeclareTriggeredActionsAction) CheckTargets(s *State) error { return nil } +func (*DeclareTriggeredActionsAction) PayCosts(*State) bool { return true } +func (*DeclareTriggeredActionsAction) resolve(*State) {} +func (*DeclareTriggeredActionsAction) String() string { return "declared triggered actions" } + type PileDropAction struct { ActionBase pile []Permanent diff --git a/go/game/playerControl.go b/go/game/playerControl.go index eea6a19b..94c8be7e 100644 --- a/go/game/playerControl.go +++ b/go/game/playerControl.go @@ -12,6 +12,7 @@ const ( ResolvedActionNotification PriorityNotification TargetSelectionPrompt + DeclareTriggeredActionsPrompt ) func (n PlayerNotificationType) String() string { @@ -24,6 +25,8 @@ func (n PlayerNotificationType) String() string { return "PriorityNotification" case TargetSelectionPrompt: return "TargetSelectionPrompt" + case DeclareTriggeredActionsPrompt: + return "DeclareTriggeredActionsPrompt" default: log.Panicf("Unhandled notification %d", n) return "" @@ -86,6 +89,10 @@ func newHandCardSelectionPrompt(p *Player, min, max int) PlayerNotification { return newTargetSelectionPrompt(a, desc) } +func newDeclareTriggeredActionsPrompt(triggeredActions []*TriggeredAction) PlayerNotification { + return PlayerNotification{DeclareTriggeredActionsPrompt, triggeredActions, nil} +} + type PlayerControl interface { Player() *Player RecvAction() Action diff --git a/go/game/state.go b/go/game/state.go index 6bb3dbf0..36dc3e77 100644 --- a/go/game/state.go +++ b/go/game/state.go @@ -106,7 +106,7 @@ func (s *State) removeTriggers(triggers []Trigger) { } func (s *State) handleTriggers() { - var actions []Action + var actions []*TriggeredAction var triggersToRemove []Trigger for _, e := range s.events { @@ -126,9 +126,11 @@ func (s *State) handleTriggers() { s.removeTriggers(triggersToRemove) - orderedActions := s.orderTriggeredActions(actions) - for _, a := range orderedActions { - s.declareAction(a) + if len(actions) > 0 { + orderedActions := s.orderTriggeredActions(actions) + for _, a := range orderedActions { + s.declareAction(a) + } } } @@ -360,9 +362,38 @@ func (s *State) declareAction(a Action) { s.broadcastNotification(newDeclaredActionNotification(a, err)) } -func (s *State) orderTriggeredActions(actions []Action) []Action { - // TODO: implement ordering - return actions +func (s *State) orderTriggeredActions(triggeredActions []*TriggeredAction) []Action { + playerActions := make(map[*Player][]*TriggeredAction) + for _, action := range triggeredActions { + p := action.Controller() + if actions, found := playerActions[p]; found { + playerActions[p] = append(actions, action) + } else { + playerActions[p] = []*TriggeredAction{action} + } + } + + orderedActions := []Action{} + nPlayers := len(s.Players) + for i := 0; i < nPlayers; i++ { + p := s.Players[(i+s.ActivePlayer.Id-1)%nPlayers] + + actions := playerActions[p] + p.Ctrl.SendNotification(newDeclareTriggeredActionsPrompt(actions)) + + switch a := p.Ctrl.RecvAction().(type) { + case *DeclareTriggeredActionsAction: + pActions := make([]Action, 0, len(a.actions)) + for _, a := range a.actions { + pActions = append(pActions, a) + } + orderedActions = append(orderedActions, pActions...) + default: + log.Panicf("Unexpected action type %T after DeclareTriggerPrompt", a) + } + } + + return orderedActions } func (s *State) allPassing(skipFirst bool) bool { diff --git a/go/game/trigger.go b/go/game/trigger.go index 39901d71..8fe4ae89 100644 --- a/go/game/trigger.go +++ b/go/game/trigger.go @@ -61,7 +61,7 @@ func newEotEvent() Event { type Trigger interface { Card() *Card String() string - trigger(*State, Event) ([]Action, bool) + trigger(*State, Event) ([]*TriggeredAction, bool) } type triggerBase struct { @@ -80,11 +80,11 @@ func (t *triggerBase) String() string { return t.desc } -func (t *triggerBase) trigger(s *State, e Event) ([]Action, bool) { +func (t *triggerBase) trigger(s *State, e Event) ([]*TriggeredAction, bool) { triggered, remove := t.condition(s, e) if !triggered { return nil, remove } - return []Action{newTriggeredAction(e, t, t.resolveFunc, t.costFunc)}, remove + return []*TriggeredAction{newTriggeredAction(e, t, t.resolveFunc, t.costFunc)}, remove } |
