forked from freeeve/pgn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
position.go
320 lines (307 loc) · 5.45 KB
/
position.go
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
package pgn
import "fmt"
type Rank byte
const (
NoRank Rank = '0'
Rank1 Rank = '1'
Rank2 Rank = '2'
Rank3 Rank = '3'
Rank4 Rank = '4'
Rank5 Rank = '5'
Rank6 Rank = '6'
Rank7 Rank = '7'
Rank8 Rank = '8'
)
type File byte
const (
NoFile File = ' '
FileA File = 'a'
FileB File = 'b'
FileC File = 'c'
FileD File = 'd'
FileE File = 'e'
FileF File = 'f'
FileG File = 'g'
FileH File = 'h'
)
type Position uint64
const NoPosition Position = 0
const (
A1 Position = 1 << iota
B1 Position = 1 << iota
C1 Position = 1 << iota
D1 Position = 1 << iota
E1 Position = 1 << iota
F1 Position = 1 << iota
G1 Position = 1 << iota
H1 Position = 1 << iota
A2 Position = 1 << iota
B2 Position = 1 << iota
C2 Position = 1 << iota
D2 Position = 1 << iota
E2 Position = 1 << iota
F2 Position = 1 << iota
G2 Position = 1 << iota
H2 Position = 1 << iota
A3 Position = 1 << iota
B3 Position = 1 << iota
C3 Position = 1 << iota
D3 Position = 1 << iota
E3 Position = 1 << iota
F3 Position = 1 << iota
G3 Position = 1 << iota
H3 Position = 1 << iota
A4 Position = 1 << iota
B4 Position = 1 << iota
C4 Position = 1 << iota
D4 Position = 1 << iota
E4 Position = 1 << iota
F4 Position = 1 << iota
G4 Position = 1 << iota
H4 Position = 1 << iota
A5 Position = 1 << iota
B5 Position = 1 << iota
C5 Position = 1 << iota
D5 Position = 1 << iota
E5 Position = 1 << iota
F5 Position = 1 << iota
G5 Position = 1 << iota
H5 Position = 1 << iota
A6 Position = 1 << iota
B6 Position = 1 << iota
C6 Position = 1 << iota
D6 Position = 1 << iota
E6 Position = 1 << iota
F6 Position = 1 << iota
G6 Position = 1 << iota
H6 Position = 1 << iota
A7 Position = 1 << iota
B7 Position = 1 << iota
C7 Position = 1 << iota
D7 Position = 1 << iota
E7 Position = 1 << iota
F7 Position = 1 << iota
G7 Position = 1 << iota
H7 Position = 1 << iota
A8 Position = 1 << iota
B8 Position = 1 << iota
C8 Position = 1 << iota
D8 Position = 1 << iota
E8 Position = 1 << iota
F8 Position = 1 << iota
G8 Position = 1 << iota
H8 Position = 1 << iota
)
func ParsePosition(pstr string) (Position, error) {
switch pstr[0] {
case 'A', 'a':
switch pstr[1] {
case '1':
return A1, nil
case '2':
return A2, nil
case '3':
return A3, nil
case '4':
return A4, nil
case '5':
return A5, nil
case '6':
return A6, nil
case '7':
return A7, nil
case '8':
return A8, nil
}
case 'B', 'b':
switch pstr[1] {
case '1':
return B1, nil
case '2':
return B2, nil
case '3':
return B3, nil
case '4':
return B4, nil
case '5':
return B5, nil
case '6':
return B6, nil
case '7':
return B7, nil
case '8':
return B8, nil
}
case 'C', 'c':
switch pstr[1] {
case '1':
return C1, nil
case '2':
return C2, nil
case '3':
return C3, nil
case '4':
return C4, nil
case '5':
return C5, nil
case '6':
return C6, nil
case '7':
return C7, nil
case '8':
return C8, nil
}
case 'D', 'd':
switch pstr[1] {
case '1':
return D1, nil
case '2':
return D2, nil
case '3':
return D3, nil
case '4':
return D4, nil
case '5':
return D5, nil
case '6':
return D6, nil
case '7':
return D7, nil
case '8':
return D8, nil
}
case 'E', 'e':
switch pstr[1] {
case '1':
return E1, nil
case '2':
return E2, nil
case '3':
return E3, nil
case '4':
return E4, nil
case '5':
return E5, nil
case '6':
return E6, nil
case '7':
return E7, nil
case '8':
return E8, nil
}
case 'F', 'f':
switch pstr[1] {
case '1':
return F1, nil
case '2':
return F2, nil
case '3':
return F3, nil
case '4':
return F4, nil
case '5':
return F5, nil
case '6':
return F6, nil
case '7':
return F7, nil
case '8':
return F8, nil
}
case 'G', 'g':
switch pstr[1] {
case '1':
return G1, nil
case '2':
return G2, nil
case '3':
return G3, nil
case '4':
return G4, nil
case '5':
return G5, nil
case '6':
return G6, nil
case '7':
return G7, nil
case '8':
return G8, nil
}
case 'H', 'h':
switch pstr[1] {
case '1':
return H1, nil
case '2':
return H2, nil
case '3':
return H3, nil
case '4':
return H4, nil
case '5':
return H5, nil
case '6':
return H6, nil
case '7':
return H7, nil
case '8':
return H8, nil
}
}
return NoPosition, fmt.Errorf("pgn: invalid position string: %s", pstr)
}
func (p Position) String() string {
if NoPosition == p {
return "-"
}
return fmt.Sprintf("%c%c", p.GetFile(), p.GetRank())
}
func (p Position) GetRank() Rank {
if uint64(p) <= uint64(NoPosition) {
return NoRank
} else if uint64(p) <= uint64(H1) {
return Rank1
} else if uint64(p) <= uint64(H2) {
return Rank2
} else if uint64(p) <= uint64(H3) {
return Rank3
} else if uint64(p) <= uint64(H4) {
return Rank4
} else if uint64(p) <= uint64(H5) {
return Rank5
} else if uint64(p) <= uint64(H6) {
return Rank6
} else if uint64(p) <= uint64(H7) {
return Rank7
} else {
return Rank8
}
}
func (p Position) GetFile() File {
switch uint64(p) % 255 {
case 1 << 7:
return FileH
case 1 << 6:
return FileG
case 1 << 5:
return FileF
case 1 << 4:
return FileE
case 1 << 3:
return FileD
case 1 << 2:
return FileC
case 1 << 1:
return FileB
case 1 << 0:
return FileA
}
return NoFile
}
func PositionFromFileRank(f File, r Rank) (p Position) {
pos, err := ParsePosition(fmt.Sprintf("%c%c", f, r))
if err != nil {
//fmt.Println(err)
return NoPosition
}
return pos
}