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