package game import ( "log" ) type Stack struct { gameState *LocalState Actions []Action } func NewStack(s *LocalState) *Stack { return &Stack{s, []Action{}} } func (s *Stack) IsEmpty() bool { return len(s.Actions) == 0 } func (s *Stack) push(a Action) { s.Actions = append(s.Actions, a) } func (s *Stack) remove(a Action) { for i, o := range s.Actions { if o != a { continue } s.Actions = append(s.Actions[:i], s.Actions[i+1:]...) return } } func (s *Stack) pop() { l := len(s.Actions) if l == 0 { log.Panicf("Can not pop from empty stack") } a := s.Actions[l-1] s.Actions = s.Actions[:l-1] err := s.gameState.ValidateAction(a) if err == nil { s.gameState.ResolveAction(a) } resolvedActionEvent := newResolvedActionEvent(a, err) s.gameState.fireEvent(resolvedActionEvent) s.gameState.broadcastNotification(newResolvedActionNotification(a, err)) // Some action may be reused like full actions of permanents. // Reset their target selection to allow possible reuse. if t := a.Targets(); err == nil && t != nil { t.ClearSelections() } } func (s *Stack) resolve() []*Player { for !s.IsEmpty() { for { passing, w := s.gameState.allPassing(false) if len(w) > 0 { return w } if passing { break } } s.pop() w := s.gameState.stateBasedActions() if len(w) > 0 { return w } } return nil }