version 1.4b27
[polyglot.git] / line.cpp
1 \r
2 // line.cpp\r
3 \r
4 // includes\r
5 \r
6 #include <cstring>\r
7 \r
8 #include "board.h"\r
9 #include "line.h"\r
10 #include "move.h"\r
11 #include "move_do.h"\r
12 #include "move_legal.h"\r
13 #include "san.h"\r
14 #include "util.h"\r
15 \r
16 // constants\r
17 \r
18 static const bool Strict = false; // false\r
19 static const bool UseDebug = false; // false\r
20 \r
21 static const int StringSize = 1024;\r
22 \r
23 // functions\r
24 \r
25 // line_is_ok()\r
26 \r
27 bool line_is_ok(const move_t line[]) {\r
28 \r
29    int move;\r
30 \r
31    if (line == NULL) return false;\r
32 \r
33    while ((move = *line++) != MoveNone) {\r
34       if (!move_is_ok(move)) return false;\r
35    }\r
36 \r
37    return true;\r
38 }\r
39 \r
40 // line_clear()\r
41 \r
42 void line_clear(move_t line[]) {\r
43 \r
44    ASSERT(line!=NULL);\r
45 \r
46    *line = MoveNone;\r
47 }\r
48 \r
49 // line_copy()\r
50 \r
51 void line_copy(move_t dst[], const move_t src[]) {\r
52 \r
53    ASSERT(dst!=NULL);\r
54    ASSERT(src!=NULL);\r
55 \r
56    ASSERT(dst!=src);\r
57 \r
58    while ((*dst++ = *src++) != MoveNone)\r
59       ;\r
60 }\r
61 \r
62 // line_from_can()\r
63 \r
64 bool line_from_can (move_t line[], const board_t * board, const char string[], int size) {\r
65 \r
66    int pos;\r
67    char new_string[StringSize], *p;\r
68    int move;\r
69    board_t new_board[1];\r
70 \r
71    ASSERT(line!=NULL);\r
72    ASSERT(board_is_ok(board));\r
73    ASSERT(string!=NULL);\r
74    ASSERT(size>=LineSize);\r
75 \r
76    // init\r
77 \r
78    pos = 0;\r
79    board_copy(new_board,board);\r
80 \r
81    // loop\r
82 \r
83    strcpy(new_string,string); // HACK\r
84 \r
85    for (p = strtok(new_string," "); p != NULL; p = strtok(NULL," ")) {\r
86 \r
87       move = move_from_can(p,new_board);\r
88 \r
89       ASSERT(move!=MoveNone);\r
90       ASSERT(move_is_legal(move,new_board));\r
91 \r
92       if (move == MoveNone || !move_is_legal(move,new_board)) break; // HACK: ignore illegal moves\r
93 \r
94       if (pos >= size) return false;\r
95       line[pos++] = move;\r
96 \r
97       move_do(new_board,move);\r
98    }\r
99 \r
100    if (pos >= size) return false;\r
101    line[pos] = MoveNone;\r
102 \r
103    return true;\r
104 }\r
105 \r
106 // line_to_can()\r
107 \r
108 bool line_to_can(const move_t line[], const board_t * board, char string[], int size) {\r
109 \r
110    board_t new_board[1];\r
111    int pos;\r
112    int move;\r
113 \r
114    ASSERT(line_is_ok(line));\r
115    ASSERT(board_is_ok(board));\r
116    ASSERT(string!=NULL);\r
117    ASSERT(size>=StringSize);\r
118 \r
119    // init\r
120 \r
121    if (size < StringSize) return false;\r
122 \r
123    board_copy(new_board,board);\r
124    pos = 0;\r
125 \r
126    // loop\r
127 \r
128    while ((move = *line++) != MoveNone) {\r
129 \r
130       if (pos != 0) {\r
131          if (pos >= size) return false;\r
132          string[pos++] = ' ';\r
133       }\r
134 \r
135       if (!move_to_can(move,new_board,&string[pos],size-pos)) return false;\r
136       pos += strlen(&string[pos]);\r
137 \r
138       move_do(new_board,move);\r
139    }\r
140 \r
141    if (pos >= size) return false;\r
142    string[pos] = '\0';\r
143 \r
144    return true;\r
145 }\r
146 \r
147 // line_to_san()\r
148 \r
149 bool line_to_san(const move_t line[], const board_t * board, char string[], int size) {\r
150 \r
151    board_t new_board[1];\r
152    int pos;\r
153    int move;\r
154    char move_string[256];\r
155 \r
156    ASSERT(line_is_ok(line));\r
157    ASSERT(board_is_ok(board));\r
158    ASSERT(string!=NULL);\r
159    ASSERT(size>=StringSize);\r
160 \r
161    // init\r
162 \r
163    if (size < StringSize) return false;\r
164 \r
165    board_copy(new_board,board);\r
166    pos = 0;\r
167 \r
168    // loop\r
169 \r
170    while ((move = *line++) != MoveNone) {\r
171 \r
172       if (pos != 0) {\r
173          if (pos >= size) return false;\r
174          string[pos++] = ' ';\r
175       }\r
176 \r
177       if (!move_is_legal(move,new_board)\r
178        || !move_to_san(move,new_board,&string[pos],size-pos)) {\r
179 \r
180          if (Strict || UseDebug) {\r
181 \r
182             move_to_can(move,new_board,move_string,256);\r
183             my_log("POLYGLOT ILLEGAL MOVE IN LINE %s\n",move_string);\r
184 \r
185             board_disp(new_board);\r
186          }\r
187 \r
188          if (Strict) my_fatal("line_to_san(): illegal move\n");\r
189 \r
190          break;\r
191       }\r
192 \r
193       pos += strlen(&string[pos]);\r
194 \r
195       move_do(new_board,move);\r
196    }\r
197 \r
198    if (pos >= size) return false;\r
199    string[pos] = '\0';\r
200 \r
201    return true;\r
202 }\r
203 \r
204 // end of line.cpp\r
205 \r