games - main_test.go
1 package main
2
3 import (
4 "testing"
5 )
6
7 func TestXOSwitch(t *testing.T) {
8 if p := X.Switch(); p != O {
9 t.Errorf("test 1: from X expecting O, got %s", p)
10 }
11
12 if p := O.Switch(); p != X {
13 t.Errorf("test 2: from O expecting X, got %s", p)
14 }
15 }
16
17 func TestPositionRotateClockwise(t *testing.T) {
18 for n, test := range [...][2]Position{
19 {0, 2},
20 {1, 5},
21 {2, 8},
22 {3, 1},
23 {4, 4},
24 {5, 7},
25 {6, 0},
26 {7, 3},
27 {8, 6},
28 } {
29 if q := test[0].RotateClockwise(); q != test[1] {
30 t.Errorf("test %d: from position %d, expecting clockwise rotation to equal %d, got %d", n+1, test[0], test[1], q)
31 }
32 }
33 }
34
35 func TestPositionFlop(t *testing.T) {
36 for n, test := range [...][2]Position{
37 {0, 2},
38 {1, 1},
39 {2, 0},
40 {3, 5},
41 {4, 4},
42 {5, 3},
43 {6, 8},
44 {7, 7},
45 {8, 6},
46 } {
47 if q := test[0].Flop(); q != test[1] {
48 t.Errorf("test %d: from position %d, expecting flop to equal %d, got %d", n+1, test[0], test[1], q)
49 }
50 }
51 }
52
53 func TestBoardGetSet(t *testing.T) {
54 for n, test := range [...][9]XO{
55 {None, X, O, None, X, O, None, X, O},
56 {X, O, None, X, O, None, X, O, None},
57 {O, None, X, O, None, X, O, None, X},
58 {None, None, None, None, None, None, None, None, None},
59 {X, X, X, X, X, X, X, X, X},
60 {O, O, O, O, O, O, O, O, O},
61 } {
62 var b Board
63
64 for i, p := range test {
65 b = b.Set(Position(i), p)
66 }
67
68 for i, p := range test {
69 if q := b.Get(Position(i)); q != p {
70 t.Errorf("test %d.%d: expecting value %s, got %s", n, i, p, q)
71 }
72 }
73 }
74 }
75
76 func TestBoardSwitch(t *testing.T) {
77 for n, test := range [...][2]Board{
78 {
79 emptyBoard.Set(0, X).Set(4, X).Set(1, O),
80 emptyBoard.Set(0, O).Set(4, O).Set(1, X),
81 },
82 {
83 emptyBoard.Set(0, O).Set(4, O).Set(1, X),
84 emptyBoard.Set(0, X).Set(4, X).Set(1, O),
85 },
86 {
87 emptyBoard.Set(0, X).Set(1, O).Set(2, X).Set(3, O).Set(4, X).Set(5, O).Set(6, X).Set(7, O).Set(8, X),
88 emptyBoard.Set(0, O).Set(1, X).Set(2, O).Set(3, X).Set(4, O).Set(5, X).Set(6, O).Set(7, X).Set(8, O),
89 },
90 {
91 emptyBoard.Set(0, O).Set(1, X).Set(2, O).Set(3, X).Set(4, O).Set(5, X).Set(6, O).Set(7, X).Set(8, O),
92 emptyBoard.Set(0, X).Set(1, O).Set(2, X).Set(3, O).Set(4, X).Set(5, O).Set(6, X).Set(7, O).Set(8, X),
93 },
94 } {
95 if s := test[0].Switch(); s != test[1] {
96 t.Errorf("test %d: from board:\n%s\nexpecting switched board:\n%s\n...but got:\n%s", n+1, test[0], test[1], s)
97 }
98 }
99 }
100
101 func TestBoardTransform(t *testing.T) {
102 for n, test := range [...][9]Board{
103 {
104 emptyBoard.Set(0, X).Set(2, O).Set(4, X),
105 emptyBoard.Set(2, X).Set(8, O).Set(4, X),
106 emptyBoard.Set(8, X).Set(6, O).Set(4, X),
107 emptyBoard.Set(6, X).Set(0, O).Set(4, X),
108 emptyBoard.Set(2, X).Set(0, O).Set(4, X),
109 emptyBoard.Set(8, X).Set(2, O).Set(4, X),
110 emptyBoard.Set(6, X).Set(8, O).Set(4, X),
111 emptyBoard.Set(0, X).Set(6, O).Set(4, X),
112 },
113 {
114 emptyBoard.Set(1, X).Set(5, O).Set(4, O),
115 emptyBoard.Set(5, X).Set(7, O).Set(4, O),
116 emptyBoard.Set(7, X).Set(3, O).Set(4, O),
117 emptyBoard.Set(3, X).Set(1, O).Set(4, O),
118 emptyBoard.Set(1, X).Set(3, O).Set(4, O),
119 emptyBoard.Set(5, X).Set(1, O).Set(4, O),
120 emptyBoard.Set(7, X).Set(5, O).Set(4, O),
121 emptyBoard.Set(3, X).Set(7, O).Set(4, O),
122 },
123 } {
124 for i := uint8(0); i < 8; i++ {
125 if c := test[0].Transform(i&4 != 0, i&3); c != test[i] {
126 t.Errorf("test %d.%d: expecting output:\n%s\n...got:\n%s", n+1, i+1, test[i], c)
127 }
128 }
129 }
130 }
131
132 func TestBoardHasWin(t *testing.T) {
133 for n, test := range [...]struct {
134 Board
135 Wins bool
136 }{
137 {
138 emptyBoard.Set(0, X).Set(1, X).Set(2, X),
139 true,
140 },
141 {
142 emptyBoard.Set(3, X).Set(4, X).Set(5, X),
143 true,
144 },
145 {
146 emptyBoard.Set(6, X).Set(7, X).Set(8, X),
147 true,
148 },
149 {
150 emptyBoard.Set(0, X).Set(3, X).Set(6, X),
151 true,
152 },
153 {
154 emptyBoard.Set(1, X).Set(4, X).Set(7, X),
155 true,
156 },
157 {
158 emptyBoard.Set(2, X).Set(5, X).Set(8, X),
159 true,
160 },
161 {
162 emptyBoard.Set(0, X).Set(4, X).Set(8, X),
163 true,
164 },
165 {
166 emptyBoard.Set(2, X).Set(4, X).Set(6, X),
167 true,
168 },
169 {
170 emptyBoard.Set(0, O).Set(1, O).Set(2, O),
171 false,
172 },
173 {
174 emptyBoard.Set(3, O).Set(4, O).Set(5, O),
175 false,
176 },
177 {
178 emptyBoard.Set(6, O).Set(7, O).Set(8, O),
179 false,
180 },
181 {
182 emptyBoard.Set(0, O).Set(3, O).Set(6, O),
183 false,
184 },
185 {
186 emptyBoard.Set(1, O).Set(4, O).Set(7, O),
187 false,
188 },
189 {
190 emptyBoard.Set(2, O).Set(5, O).Set(8, O),
191 false,
192 },
193 {
194 emptyBoard.Set(0, O).Set(4, O).Set(8, O),
195 false,
196 },
197 {
198 emptyBoard.Set(2, O).Set(4, O).Set(6, O),
199 false,
200 },
201 {
202 emptyBoard,
203 false,
204 },
205 {
206 emptyBoard.Set(0, X),
207 false,
208 },
209 {
210 emptyBoard.Set(1, X),
211 false,
212 },
213 {
214 emptyBoard.Set(2, X),
215 false,
216 },
217 {
218 emptyBoard.Set(3, X),
219 false,
220 },
221 {
222 emptyBoard.Set(4, X),
223 false,
224 },
225 {
226 emptyBoard.Set(5, X),
227 false,
228 },
229 {
230 emptyBoard.Set(6, X),
231 false,
232 },
233 {
234 emptyBoard.Set(7, X),
235 false,
236 },
237 {
238 emptyBoard.Set(8, X),
239 false,
240 },
241 {
242 emptyBoard.Set(0, X).Set(1, X),
243 false,
244 },
245 {
246 emptyBoard.Set(0, X).Set(2, X),
247 false,
248 },
249 {
250 emptyBoard.Set(1, X).Set(2, X),
251 false,
252 },
253 } {
254 if test.HasWin() != test.Wins {
255 t.Errorf("test %d: board.HasWin() should return %v when it doesn't:\n%s", n, test.Wins, test.Board)
256 }
257 }
258 }
259
260 func TestBoardHasPossibleWin(t *testing.T) {
261 for n, test := range [...]struct {
262 Board
263 Possible bool
264 }{
265 {
266 emptyBoard.Set(0, X).Set(1, X),
267 true,
268 },
269 {
270 emptyBoard.Set(0, X).Set(2, X),
271 true,
272 },
273 {
274 emptyBoard.Set(1, X).Set(2, X),
275 true,
276 },
277 {
278 emptyBoard.Set(3, X).Set(4, X),
279 true,
280 },
281 {
282 emptyBoard.Set(3, X).Set(5, X),
283 true,
284 },
285 {
286 emptyBoard.Set(4, X).Set(5, X),
287 true,
288 },
289 {
290 emptyBoard.Set(6, X).Set(7, X),
291 true,
292 },
293 {
294 emptyBoard.Set(6, X).Set(8, X),
295 true,
296 },
297 {
298 emptyBoard.Set(7, X).Set(8, X),
299 true,
300 },
301 {
302 emptyBoard.Set(0, X).Set(3, X),
303 true,
304 },
305 {
306 emptyBoard.Set(0, X).Set(6, X),
307 true,
308 },
309 {
310 emptyBoard.Set(3, X).Set(6, X),
311 true,
312 },
313 {
314 emptyBoard.Set(1, X).Set(4, X),
315 true,
316 },
317 {
318 emptyBoard.Set(1, X).Set(7, X),
319 true,
320 },
321 {
322 emptyBoard.Set(4, X).Set(7, X),
323 true,
324 },
325 {
326 emptyBoard.Set(2, X).Set(5, X),
327 true,
328 },
329 {
330 emptyBoard.Set(2, X).Set(8, X),
331 true,
332 },
333 {
334 emptyBoard.Set(5, X).Set(8, X),
335 true,
336 },
337 {
338 emptyBoard.Set(0, X).Set(4, X),
339 true,
340 },
341 {
342 emptyBoard.Set(0, X).Set(8, X),
343 true,
344 },
345 {
346 emptyBoard.Set(4, X).Set(8, X),
347 true,
348 },
349 {
350 emptyBoard.Set(2, X).Set(4, X),
351 true,
352 },
353 {
354 emptyBoard.Set(2, X).Set(6, X),
355 true,
356 },
357 {
358 emptyBoard.Set(4, X).Set(6, X),
359 true,
360 },
361 {
362 emptyBoard.Set(0, O).Set(1, O),
363 false,
364 },
365 {
366 emptyBoard.Set(3, O).Set(5, O),
367 false,
368 },
369 {
370 emptyBoard.Set(7, O).Set(8, O),
371 false,
372 },
373 {
374 emptyBoard.Set(3, O).Set(6, O),
375 false,
376 },
377 {
378 emptyBoard.Set(1, O).Set(7, O),
379 false,
380 },
381 {
382 emptyBoard.Set(2, O).Set(5, O),
383 false,
384 },
385 {
386 emptyBoard.Set(0, X),
387 false,
388 },
389 {
390 emptyBoard.Set(0, X).Set(5, X),
391 false,
392 },
393 {
394 emptyBoard.Set(1, X).Set(0, 6),
395 false,
396 },
397 } {
398 if test.HasPossibleWin() != test.Possible {
399 t.Errorf("test %d: board.HasPossibleWin should return %v when it doesn't:\n%s", n, test.Possible, test.Board)
400 }
401 }
402 }
403
404 func TestResultSwitch(t *testing.T) {
405 for n, test := range [...]struct {
406 In, Out Result
407 }{
408 {FilledX, FilledX},
409 {FilledO, FilledO},
410 {WillWin, WillLose},
411 {WillLose, WillWin},
412 {Draw, Draw},
413 {CanWin, CanLose},
414 {CanLose, CanWin},
415 } {
416 if out := test.In.Switch(); out != test.Out {
417 t.Errorf("test %d: for input %q, expecting output %q, got %q", n+1, test.In, test.Out, out)
418 }
419 }
420 }
421
422 func TestResultsGetSet(t *testing.T) {
423 var rs Results
424 for _, p := range Positions {
425 for r := WillLose; r <= FilledO; r++ {
426 rs = rs.Set(p, r)
427
428 if g := rs.Get(p); g != r {
429 t.Errorf("test %d.%d: expecting to get %s, got %s", p+1, r+1, r, g)
430 }
431 }
432 }
433 }
434
435 func TestResultsEncode(t *testing.T) {
436 for n, test := range [...]Results{
437 Results(0).Set(0, WillLose).Set(1, Draw).Set(2, CanWin).Set(3, WillWin).Set(4, FilledX).Set(5, FilledO).Set(6, WillLose).Set(7, Draw).Set(8, CanWin),
438 Results(0).Set(0, Draw).Set(1, CanWin).Set(2, WillWin).Set(3, FilledX).Set(4, FilledO).Set(5, WillLose).Set(6, Draw).Set(7, CanWin).Set(8, WillWin),
439 Results(0).Set(0, CanWin).Set(1, WillWin).Set(2, FilledX).Set(3, FilledO).Set(4, WillLose).Set(5, Draw).Set(6, CanWin).Set(7, WillWin).Set(8, FilledX),
440 Results(0).Set(0, WillWin).Set(1, FilledX).Set(2, FilledO).Set(3, WillLose).Set(4, Draw).Set(5, CanWin).Set(6, WillWin).Set(7, FilledX).Set(8, FilledO),
441 Results(0).Set(0, FilledX).Set(1, FilledO).Set(2, WillLose).Set(3, Draw).Set(4, CanWin).Set(5, WillWin).Set(6, FilledX).Set(7, FilledO).Set(8, WillLose),
442 Results(0).Set(0, FilledO).Set(1, WillLose).Set(2, Draw).Set(3, CanWin).Set(4, WillWin).Set(5, FilledX).Set(6, FilledO).Set(7, WillLose).Set(8, Draw),
443 Results(0).Set(0, FilledX).Set(1, FilledO).Set(2, FilledX).Set(3, WillLose).Set(4, FilledO).Set(5, WillLose).Set(6, WillLose).Set(7, CanLose).Set(8, WillLose).SetState(CanLose),
444 } {
445 re := test.Encode()
446
447 e := Results(re[2]) | (Results(re[1]) << 8) | (Results(re[0]) << 16)
448
449 for _, p := range Positions {
450 r := Result(e % 6)
451 e /= 6
452
453 if r > 0 {
454 r++
455 }
456
457 if g := test.Get(p); g != r && g != CanLose && r != Draw {
458 t.Errorf("test %d.%d: expecting result %s, got %s", n+1, p+1, g, r)
459 }
460 }
461 }
462 }
463
464 func TestBrainMove(t *testing.T) {
465 for n, test := range [...]struct {
466 Board
467 Result
468 }{
469 {
470 emptyBoard,
471 CanWin,
472 },
473 {
474 emptyBoard.Set(0, X).Set(1, X).Set(8, O).Set(3, O),
475 WillWin,
476 },
477 {
478 emptyBoard.Set(0, O).Set(2, O).Set(8, X).Set(3, X),
479 CanLose,
480 },
481 {
482 emptyBoard.Set(0, O).Set(1, O).Set(4, O).Set(3, X).Set(8, X),
483 WillLose,
484 },
485 } {
486 b := make(Brain)
487
488 if r := b.move(test.Board); r != test.Result {
489 t.Errorf("test %d: for board:\n%s, expected result %s, got %s", n+1, test.Board, test.Result, r)
490 }
491 }
492 }
493
494 func TestBrainGetResults(t *testing.T) {
495 brain := NewBrain()
496
497 for n, test := range [...]struct {
498 Board
499 Results
500 }{
501 {
502 emptyBoard,
503 Results(0).Set(0, CanWin).Set(1, CanWin).Set(2, CanWin).Set(3, CanWin).Set(4, CanWin).Set(5, CanWin).Set(6, CanWin).Set(7, CanWin).Set(8, CanWin).SetState(CanWin),
504 },
505 {
506 emptyBoard.Set(1, X).Set(6, O).Set(7, O).Set(8, X),
507 Results(0).Set(0, FilledX).Set(1, FilledO).Set(2, FilledO).Set(3, WillWin).Set(4, CanWin).Set(5, WillWin).Set(6, WillWin).Set(7, FilledX).Set(8, WillWin).SetState(WillWin),
508 },
509 {
510 emptyBoard.Set(0, O).Set(1, X).Set(2, O).Set(4, X).Set(7, O),
511 Results(0).Set(0, FilledO).Set(1, FilledX).Set(2, FilledO).Set(3, CanWin).Set(4, FilledX).Set(5, CanWin).Set(6, CanLose).Set(7, FilledO).Set(8, CanLose).SetState(CanWin),
512 },
513 {
514 emptyBoard.Set(0, X).Set(1, O).Set(2, X).Set(4, O),
515 Results(0).Set(0, FilledX).Set(1, FilledO).Set(2, FilledX).Set(3, WillLose).Set(4, FilledO).Set(5, WillLose).Set(6, WillLose).Set(7, CanLose).Set(8, WillLose).SetState(CanLose),
516 },
517 } {
518 if r, ok := brain.getResults(test.Board); !ok {
519 t.Errorf("test %d: for board:\n%s\n...got no result when expecting one", n+1, test.Board)
520 } else if r != test.Results {
521 t.Errorf("test %d: for board:\n%s\n...expecting Results:\n%s, got:\n%s", n+1, test.Board, test.Results, r)
522 }
523 }
524 }
525