1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
package game
import (
"fmt"
"log"
)
type PlayerNotificationType int
const (
DeclaredActionNotification PlayerNotificationType = iota
ResolvedActionNotification
PriorityNotification
TargetSelectionPrompt
DeclareTriggeredActionsPrompt
)
func (n PlayerNotificationType) String() string {
switch n {
case DeclaredActionNotification:
return "DeclaredActionNotification"
case ResolvedActionNotification:
return "ResolvedActionNotification"
case PriorityNotification:
return "PriorityNotification"
case TargetSelectionPrompt:
return "TargetSelectionPrompt"
case DeclareTriggeredActionsPrompt:
return "DeclareTriggeredActionsPrompt"
default:
log.Panicf("Unhandled notification %d", n)
return ""
}
}
func (n PlayerNotification) IsPriorityNotification() bool {
return n.Notification == PriorityNotification
}
type PlayerNotification struct {
Notification PlayerNotificationType
Context interface{}
Error error
}
func (n *PlayerNotification) String() string {
if n.Error != nil {
return fmt.Sprintf("error %v: %v", n.Notification, n.Error)
}
return fmt.Sprintf("%v: %v", n.Notification, n.Context)
}
type TargetSelectionCtx struct {
Action Action
Prompt string
}
func newPriorityNotification() PlayerNotification {
return PlayerNotification{PriorityNotification, nil, nil}
}
func newDeclaredActionNotification(a Action, err error) PlayerNotification {
return PlayerNotification{DeclaredActionNotification, a, err}
}
func newResolvedActionNotification(a Action, err error) PlayerNotification {
return PlayerNotification{ResolvedActionNotification, a, err}
}
func newTargetSelectionPrompt(a Action, desc string) PlayerNotification {
return PlayerNotification{TargetSelectionPrompt, TargetSelectionCtx{a, desc}, nil}
}
func newUpkeepPrompt(p *Player) PlayerNotification {
a := newUpkeepAction(p)
return newTargetSelectionPrompt(a, "Select units to disband")
}
func newBuyPrompt(p *Player) PlayerNotification {
a := newBuyAction(p)
prompt := newTargetSelectionPrompt(a, "Select a card to buy")
return prompt
}
func newHandCardSelectionPrompt(p *Player, min, max int) PlayerNotification {
a := newHandCardSelection(p, min, max)
desc := fmt.Sprintf("Select between %d and %d hand cards", min, max)
return newTargetSelectionPrompt(a, desc)
}
func newDeclareTriggeredActionsPrompt(triggeredActions []*TriggeredAction) PlayerNotification {
return PlayerNotification{DeclareTriggeredActionsPrompt, triggeredActions, nil}
}
type PlayerControl interface {
Player() *Player
RecvAction() Action
SendNotification(PlayerNotification)
}
type ChanPlayerControl struct {
player *Player
actions chan Action
notifications chan PlayerNotification
}
func (c *ChanPlayerControl) Player() *Player { return c.player }
func (c *ChanPlayerControl) SendAction(a Action) { c.actions <- a }
func (c *ChanPlayerControl) RecvAction() Action { return <-c.actions }
func (c *ChanPlayerControl) SendNotification(n PlayerNotification) { c.notifications <- n }
func (c *ChanPlayerControl) RecvNotification() *PlayerNotification {
select {
case n := <-c.notifications:
return &n
default:
return nil
}
}
func NewChanPlayerControl(p *Player) *ChanPlayerControl {
a := make(chan Action)
n := make(chan PlayerNotification)
return &ChanPlayerControl{p, a, n}
}
func prompt(ctrl PlayerControl, notification PlayerNotification) Action {
ctrl.SendNotification(notification)
return ctrl.RecvAction()
}
func promptBuy(ctrl PlayerControl) Action {
return prompt(ctrl, newBuyPrompt(ctrl.Player()))
}
func promptAction(ctrl PlayerControl) Action {
return prompt(ctrl, newPriorityNotification())
}
|