package game import ( "fmt" "log" ) type ActionPrototype interface { Specialize(...interface{}) Action String() string } type Action interface { Declare(s *State) Resolve(s *State) String() string } type FastAction interface { Action FastDeclare(s *State) } type ActionBase struct { Source interface{} Card *Card resolveFunc func(s *State) desc string } func (a *ActionBase) Declare(s *State) { if !s.Stack.IsEmpty() { log.Fatalf("Slow action can not be declared while other actions are on the stack") } s.Stack.Push(a) } func (a *ActionBase) Resolve(s *State) { a.resolveFunc(s) } func (a *ActionBase) String() string { if p, ok := a.Source.(Permanent); ok { return fmt.Sprintf("%s: %s %s", p.GetController().Name, p.GetTile().Position.String(), a.desc) } return fmt.Sprintf("%s %s", a.Source, a.desc) } type MoveActionPrototype struct { Unit *Unit } func NewMoveActionPrototype(u *Unit) *MoveActionPrototype { return &MoveActionPrototype{u} } func (proto *MoveActionPrototype) String() string { return fmt.Sprintf("move %d", proto.Unit.Movement) } func (proto *MoveActionPrototype) Specialize(args ...interface{}) Action { target := args[0].(*Tile) u := proto.Unit resolveFunc := func(s *State) { u.move(s, target) } desc := fmt.Sprintf("-> %s", target.Position.String()) return &ActionBase{u, u.GetCard(), resolveFunc, desc} } type AttackActionPrototype struct { Unit *Unit } func NewAttackActionPrototype(u *Unit) *AttackActionPrototype { return &AttackActionPrototype{u} } func (proto *AttackActionPrototype) String() string { return fmt.Sprintf("attack %s", proto.Unit.Attack.String()) } func (proto *AttackActionPrototype) Specialize(args ...interface{}) Action { target := args[0].(Permanent) u := proto.Unit resolveFunc := func(s *State) { s.Fight(u, target) } desc := fmt.Sprintf("x %s", target.GetTile().Position.String()) return &ActionBase{u, u.GetCard(), resolveFunc, desc} } type FullActionPrototype struct { Permanent Permanent } func (proto *FullActionPrototype) String() string { return "full_action" } func (proto *FullActionPrototype) Specialize(args ...interface{}) Action { p := proto.Permanent resolveFunc := args[0].(func(s *State)) desc := "full_action" return &ActionBase{p, p.GetCard(), resolveFunc, desc} } type FreeActionPrototype struct { Permanent Permanent } func (proto *FreeActionPrototype) String() string { return "free_action" } func (proto *FreeActionPrototype) Specialize(args ...interface{}) Action { p := proto.Permanent resolveFunc := args[0].(func(s *State)) desc := "free_action" return &FreeAction{ActionBase{p, p.GetCard(), resolveFunc, desc}} } type FreeAction struct { ActionBase } func (a *FreeAction) FastDeclare(s *State) { s.Stack.Push(a) } func (a *FreeAction) Resolve(s *State) { }