cards.gno
5.09 Kb · 146 lines
1// Package cards holds the static definition of the 12 action cards, each with
2// a front and a back side (24 actions), as printed in the 1982 game.
3package cards
4
5// Code identifies the action printed on one side of a card.
6type Code string
7
8const (
9 Advance Code = "advance"
10 BackUp Code = "back_up"
11 Run Code = "run"
12 SpinAround Code = "spin_around"
13 Sprint Code = "sprint"
14 Turn Code = "turn"
15 LeapDrop Code = "leap_drop"
16 CockAimShoot Code = "cock_aim_shoot"
17 GetUpDown Code = "get_up_down"
18 Throw Code = "throw"
19 Shoot Code = "shoot"
20 Strength Code = "strength"
21 Load Code = "load"
22 HeadOutBack Code = "head_out_back"
23 DrawAndCock Code = "draw_and_cock"
24 Jab Code = "jab"
25 Duck Code = "duck"
26 Swing Code = "swing"
27 Block Code = "block"
28 Belt Code = "belt"
29 Guard Code = "guard"
30)
31
32// Kind is the card category (rule 5.2).
33type Kind int
34
35const (
36 KindFoot Kind = iota
37 KindHand
38 KindAttack
39 KindDefense
40 KindStrength
41)
42
43// Choice is what the player must decide when selecting a side.
44type Choice int
45
46const (
47 ChoiceNone Choice = iota
48 ChoiceMoveAhead
49 ChoiceMoveBack
50 ChoiceTurnAhead
51 ChoiceTurnBack
52 ChoiceTargetRanged
53 ChoiceTargetMelee
54 ChoiceTargetDefend
55 // ChoiceGun picks one of the character's holstered guns (Draw & Cock).
56 ChoiceGun
57)
58
59// NeedsRel reports whether the choice is a relative direction (move or turn).
60func (c Choice) NeedsRel() bool { return c.IsAheadRel() || c.IsBackRel() }
61
62// IsAheadRel reports whether the choice is one of the three forward directions.
63func (c Choice) IsAheadRel() bool { return c == ChoiceMoveAhead || c == ChoiceTurnAhead }
64
65// IsBackRel reports whether the choice is one of the three backward directions.
66func (c Choice) IsBackRel() bool { return c == ChoiceMoveBack || c == ChoiceTurnBack }
67
68// NeedsGun reports whether the choice is a gun slot.
69func (c Choice) NeedsGun() bool { return c == ChoiceGun }
70
71// Side is one face of a card.
72type Side struct {
73 Code Code
74 Name string
75 Kind Kind
76 Cost int // time points: the sequences the action takes
77 Choice Choice
78}
79
80// Card is one physical card; its two sides cannot both be played in a turn.
81type Card struct {
82 Number int
83 Front Side
84 Back Side
85}
86
87// Side selectors as used in the plan string.
88const (
89 FrontSide byte = 'f'
90 BackSide byte = 'b'
91)
92
93// Cards is the deck, indexed by Number-1.
94var Cards = [12]Card{
95 {1, Side{Advance, "Advance", KindFoot, 2, ChoiceMoveAhead}, Side{BackUp, "Back Up", KindFoot, 3, ChoiceMoveBack}},
96 {2, Side{Run, "Run", KindFoot, 1, ChoiceMoveAhead}, Side{SpinAround, "Spin Around", KindFoot, 2, ChoiceTurnBack}},
97 {3, Side{Sprint, "Sprint", KindFoot, 1, ChoiceNone}, Side{Turn, "Turn", KindFoot, 1, ChoiceTurnAhead}},
98 {4, Side{Sprint, "Sprint", KindFoot, 1, ChoiceNone}, Side{LeapDrop, "Leap/Drop", KindFoot, 1, ChoiceNone}},
99 {5, Side{CockAimShoot, "Cock/Aim/Shoot", KindHand, 2, ChoiceTargetRanged}, Side{GetUpDown, "Get Up/Down", KindFoot, 3, ChoiceNone}},
100 {6, Side{CockAimShoot, "Cock/Aim/Shoot", KindHand, 2, ChoiceTargetRanged}, Side{Throw, "Throw", KindHand, 2, ChoiceTargetRanged}},
101 {7, Side{Shoot, "Shoot", KindHand, 1, ChoiceTargetRanged}, Side{Strength, "Strength", KindStrength, 2, ChoiceNone}},
102 {8, Side{Load, "Load", KindHand, 3, ChoiceNone}, Side{HeadOutBack, "Head Out/Back", KindFoot, 2, ChoiceNone}},
103 {9, Side{DrawAndCock, "Draw & Cock", KindHand, 3, ChoiceGun}, Side{HeadOutBack, "Head Out/Back", KindFoot, 2, ChoiceNone}},
104 {10, Side{Jab, "Jab", KindAttack, 2, ChoiceTargetMelee}, Side{Duck, "Duck", KindDefense, 1, ChoiceTargetDefend}},
105 {11, Side{Swing, "Swing", KindAttack, 3, ChoiceTargetMelee}, Side{Block, "Block", KindDefense, 2, ChoiceTargetDefend}},
106 {12, Side{Belt, "Belt", KindAttack, 3, ChoiceTargetMelee}, Side{Guard, "Guard", KindDefense, 2, ChoiceTargetDefend}},
107}
108
109// Lookup returns the side of card number (1-12) selected by 'f' or 'b'.
110func Lookup(number int, side byte) (Side, bool) {
111 if number < 1 || number > len(Cards) {
112 return Side{}, false
113 }
114 switch side {
115 case FrontSide:
116 return Cards[number-1].Front, true
117 case BackSide:
118 return Cards[number-1].Back, true
119 }
120 return Side{}, false
121}
122
123// Enabled reports whether the action is implemented by the engine: the foot
124// actions, Draw & Cock, Cock/Aim/Shoot, Shoot, Load, Throw and Strength;
125// brawling comes later.
126func Enabled(c Code) bool {
127 switch c {
128 case Advance, BackUp, Run, SpinAround, Sprint, Turn, LeapDrop, GetUpDown, DrawAndCock, CockAimShoot, Shoot, Load, Throw, Strength:
129 return true
130 }
131 return false
132}
133
134// IsShooting reports whether the action is played with a gun in hand: it
135// takes a shoot option (cock, uncock, aim, shoot, nothing) and names the
136// target (rules 11.3, 11.31).
137func IsShooting(c Code) bool { return c == CockAimShoot || c == Shoot }
138
139// TakesTarget reports whether the action may name a target, a hex or a
140// character: the gun actions and Throw (11.31, 17.11).
141func TakesTarget(c Code) bool { return IsShooting(c) || c == Throw }
142
143// IsMove reports whether the action moves the character to another hex.
144func IsMove(c Code) bool {
145 return c == Advance || c == Run || c == BackUp || c == Sprint
146}