replay: replay_sample_moves(),
[pachi.git] / t-unit / test.c
blobf50dce9e3d0a56e5178aaeff1b336d6ec6336cd7
1 #define DEBUG
2 #include <ctype.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <assert.h>
8 #include "board.h"
9 #include "debug.h"
10 #include "tactics/selfatari.h"
11 #include "tactics/ladder.h"
12 #include "random.h"
14 static bool board_printed;
16 void
17 board_load(struct board *b, FILE *f, unsigned int size)
19 board_printed = false;
20 board_resize(b, size);
21 board_clear(b);
22 for (int y = size - 1; y >= 0; y--) {
23 char line[256];
24 if (!fgets(line, sizeof(line), f)) {
25 fprintf(stderr, "Premature EOF.\n");
26 exit(EXIT_FAILURE);
28 line[strlen(line) - 1] = 0; // chomp
29 if (strlen(line) != size * 2 - 1) {
30 fprintf(stderr, "Line not %d char long: %s\n", size * 2 - 1, line);
31 exit(EXIT_FAILURE);
33 for (unsigned int i = 0; i < size * 2; i++) {
34 enum stone s;
35 switch (line[i]) {
36 case '.': s = S_NONE; break;
37 case 'X': s = S_BLACK; break;
38 case 'O': s = S_WHITE; break;
39 default: fprintf(stderr, "Invalid stone '%c'\n", line[i]);
40 exit(EXIT_FAILURE);
42 i++;
43 if (line[i] != ' ' && i/2 < size - 1) {
44 fprintf(stderr, "No space after stone %i: '%c'\n", i/2 + 1, line[i]);
45 exit(EXIT_FAILURE);
47 if (s == S_NONE) continue;
48 struct move m = { .color = s, .coord = coord_xy(b, i/2 + 1, y + 1) };
49 if (board_play(b, &m) < 0) {
50 fprintf(stderr, "Failed to play %s %s\n",
51 stone2str(s), coord2sstr(m.coord, b));
52 board_print(b, stderr);
53 exit(EXIT_FAILURE);
57 if (DEBUGL(2))
58 board_print(b, stderr);
59 int suicides = b->captures[S_BLACK] || b->captures[S_WHITE];
60 assert(!suicides);
63 bool
64 test_sar(struct board *b, char *arg)
66 enum stone color = str2stone(arg);
67 arg += 2;
68 coord_t *cc = str2coord(arg, board_size(b));
69 coord_t c = *cc; coord_done(cc);
70 arg += strcspn(arg, " ") + 1;
71 int eres = atoi(arg);
72 if (DEBUGL(1))
73 printf("sar %s %s %d...\t", stone2str(color), coord2sstr(c, b), eres);
75 assert(board_at(b, c) == S_NONE);
76 int rres = is_bad_selfatari(b, color, c);
78 if (rres == eres) {
79 if (DEBUGL(1))
80 printf("OK\n");
81 } else {
82 if (debug_level <= 2) {
83 if (DEBUGL(0) && !board_printed) {
84 board_print(b, stderr);
85 board_printed = true;
87 printf("sar %s %s %d...\t", stone2str(color), coord2sstr(c, b), eres);
89 printf("FAILED (%d)\n", rres);
91 return rres == eres;
94 bool
95 test_ladder(struct board *b, char *arg)
97 enum stone color = str2stone(arg);
98 arg += 2;
99 coord_t *cc = str2coord(arg, board_size(b));
100 coord_t c = *cc; coord_done(cc);
101 arg += strcspn(arg, " ") + 1;
102 int eres = atoi(arg);
103 if (DEBUGL(1))
104 printf("ladder %s %s %d...\t", stone2str(color), coord2sstr(c, b), eres);
106 assert(board_at(b, c) == S_NONE);
107 group_t atari_neighbor = board_get_atari_neighbor(b, c, color);
108 assert(atari_neighbor);
109 int rres = is_ladder(b, c, atari_neighbor, true);
111 if (rres == eres) {
112 if (DEBUGL(1))
113 printf("OK\n");
114 } else {
115 if (debug_level <= 2) {
116 if (DEBUGL(0) && !board_printed) {
117 board_print(b, stderr);
118 board_printed = true;
120 printf("ladder %s %s %d...\t", stone2str(color), coord2sstr(c, b), eres);
122 printf("FAILED (%d)\n", rres);
125 return (rres == eres);
129 void
130 unittest(char *filename)
132 FILE *f = fopen(filename, "r");
133 if (!f) {
134 perror(filename);
135 exit(EXIT_FAILURE);
138 int total = 0;
139 int passed = 0;
140 int skipped = 0;
142 struct board *b = board_init(NULL);
143 char line[256];
145 while (fgets(line, sizeof(line), f)) {
146 line[strlen(line) - 1] = 0; // chomp
147 switch (line[0]) {
148 case '%': printf("\n%s\n", line); continue;
149 case '!': printf("%s...\tSKIPPED\n", line); skipped++; continue;
150 case 0: continue;
152 if (!strncmp(line, "boardsize ", 10)) {
153 board_load(b, f, atoi(line + 10));
154 continue;
157 total++;
158 if (!strncmp(line, "sar ", 4))
159 passed += test_sar(b, line + 4);
160 else if (!strncmp(line, "ladder ", 7))
161 passed += test_ladder(b, line + 7);
162 else {
163 fprintf(stderr, "Syntax error: %s\n", line);
164 exit(EXIT_FAILURE);
168 fclose(f);
170 printf("\n\n----------- [ %i/%i tests passed (%i%%) ] -----------\n\n", passed, total, passed * 100 / total);
171 if (total == passed)
172 printf("\nAll tests PASSED");
173 else {
174 printf("\nSome tests FAILED\n");
175 exit(EXIT_FAILURE);
177 if (skipped > 0)
178 printf(", %d test(s) SKIPPED", skipped);
179 printf("\n");