1 package bei
2
3 import "fmt"
4
5 const (
6 CommandBEI = "bei"
7 CommandList = "list"
8 CommandSet = "set"
9 CommandDouble = "double"
10 CommandMove = "move"
11 CommandChoose = "choose"
12 )
13
14 const (
15 StateHome1 = 0
16 StateHome2 = 25
17 StateBar1 = 26
18 StateBar2 = 27
19 StateRoll1 = 28
20 StateRoll2 = 29
21 StateRoll3 = 30
22 StateTurn1 = 31
23 StateTurn2 = 32
24 StateCubeValue = 33
25 StateCubePlayer = 34
26 StatePoints1 = 35
27 StatePoints2 = 36
28 StateTotalPoints = 37
29 StateCrawford = 38
30 StateJacoby = 39
31 StateMurphy = 40
32 StateBeavers = 41
33 StateVariant = 42
34 StateEntered1 = 43
35 StateEntered2 = 44
36 )
37
38 const CellCount = 45
39
40 type BeaversType int
41
42 const (
43 BeaversNone BeaversType = iota
44 BeaversOnly
45 BeaversAndRaccoons
46 )
47
48 type State struct {
49 Board []int
50
51 Roll1 int
52 Roll2 int
53 Roll3 int
54
55 Turn1 int
56 Turn2 int
57
58 CubeValue int
59 CubePlayer int
60
61 Points1 int
62 Points2 int
63 TotalPoints int
64
65 Crawford bool
66 Jacoby bool
67 Murphy bool
68 Beavers BeaversType
69
70 Variant int
71 Entered1 bool
72 Entered2 bool
73 }
74
75 func EncodeState(s *State) []int {
76 var v []int
77 v = append(v, s.Board[0:28]...)
78 v = append(v, s.Roll1, s.Roll2, s.Roll3, s.Turn1, s.Turn2, s.CubeValue, s.CubePlayer, s.Points1, s.Points2, s.TotalPoints)
79 var crawford, jacoby, murphy, entered1, entered2 int
80 if s.Crawford {
81 crawford = 1
82 }
83 if s.Jacoby {
84 jacoby = 1
85 }
86 if s.Murphy {
87 murphy = 1
88 }
89 if s.Entered1 {
90 entered1 = 1
91 }
92 if s.Entered2 {
93 entered2 = 1
94 }
95 return append(v, crawford, jacoby, murphy, int(s.Beavers), int(s.Variant), entered1, entered2)
96 }
97
98 func DecodeState(state []int) (*State, error) {
99 if len(state) < CellCount {
100 return nil, fmt.Errorf("failed to parse state %d: expected at least %d cells, got %d", state, CellCount, len(state))
101 }
102 s := &State{
103 Board: state[0:28],
104 Roll1: state[StateRoll1],
105 Roll2: state[StateRoll2],
106 Roll3: state[StateRoll3],
107 Turn1: state[StateTurn1],
108 Turn2: state[StateTurn2],
109 CubeValue: state[StateCubeValue],
110 CubePlayer: state[StateCubePlayer],
111 Points1: state[StatePoints1],
112 Points2: state[StatePoints2],
113 TotalPoints: state[StateTotalPoints],
114 Crawford: state[StateCrawford] == 1,
115 Jacoby: state[StateJacoby] == 1,
116 Murphy: state[StateMurphy] == 1,
117 Beavers: BeaversType(state[StateBeavers]),
118 Variant: state[StateVariant],
119 Entered1: state[StateEntered1] == 1,
120 Entered2: state[StateEntered2] == 1,
121 }
122 switch {
123 case s.Roll1 < 0 || s.Roll1 > 6:
124 return nil, fmt.Errorf("failed to parse state %d: invalid dice roll 1: %d", state, s.Roll1)
125 case s.Roll2 < 0 || s.Roll2 > 6:
126 return nil, fmt.Errorf("failed to parse state %d: invalid dice roll 2: %d", state, s.Roll2)
127 case s.Roll3 < 0 || s.Roll3 > 6:
128 return nil, fmt.Errorf("failed to parse state %d: invalid dice roll 3: %d", state, s.Roll3)
129 case s.Beavers < BeaversNone || s.Beavers > BeaversAndRaccoons:
130 return nil, fmt.Errorf("failed to parse state %d: invalid beavers type: %d", state, s.Beavers)
131 default:
132 return s, nil
133 }
134 }
135
View as plain text