--- /dev/null
+\r
+// line.c\r
+\r
+// includes\r
+\r
+#include <string.h>\r
+\r
+#include "board.h"\r
+#include "line.h"\r
+#include "move.h"\r
+#include "move_do.h"\r
+#include "move_legal.h"\r
+#include "san.h"\r
+#include "util.h"\r
+\r
+// constants\r
+\r
+static const bool Strict = FALSE; // FALSE\r
+static const bool UseDebug = FALSE; // FALSE\r
+\r
+static const int StringSize = 1024;\r
+\r
+// functions\r
+\r
+// line_is_ok()\r
+\r
+bool line_is_ok(const move_t line[]) {\r
+\r
+ int move;\r
+\r
+ if (line == NULL) return FALSE;\r
+\r
+ while ((move = *line++) != MoveNone) {\r
+ if (!move_is_ok(move)) return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+// line_clear()\r
+\r
+void line_clear(move_t line[]) {\r
+\r
+ ASSERT(line!=NULL);\r
+\r
+ *line = MoveNone;\r
+}\r
+\r
+// line_copy()\r
+\r
+void line_copy(move_t dst[], const move_t src[]) {\r
+\r
+ ASSERT(dst!=NULL);\r
+ ASSERT(src!=NULL);\r
+\r
+ ASSERT(dst!=src);\r
+\r
+ while ((*dst++ = *src++) != MoveNone)\r
+ ;\r
+}\r
+\r
+// line_from_can()\r
+\r
+bool line_from_can (move_t line[], const board_t * board, const char string[], int size) {\r
+\r
+ int pos;\r
+ char new_string[StringSize], *p;\r
+ int move;\r
+ board_t new_board[1];\r
+\r
+ ASSERT(line!=NULL);\r
+ ASSERT(board_is_ok(board));\r
+ ASSERT(string!=NULL);\r
+ ASSERT(size>=LineSize);\r
+\r
+ // init\r
+\r
+ pos = 0;\r
+ board_copy(new_board,board);\r
+\r
+ // loop\r
+\r
+ strcpy(new_string,string); // HACK\r
+\r
+ for (p = strtok(new_string," "); p != NULL; p = strtok(NULL," ")) {\r
+\r
+ move = move_from_can(p,new_board);\r
+\r
+ ASSERT(move!=MoveNone);\r
+ ASSERT(move_is_legal(move,new_board));\r
+\r
+ if (move == MoveNone || !move_is_legal(move,new_board)) break; // HACK: ignore illegal moves\r
+\r
+ if (pos >= size) return FALSE;\r
+ line[pos++] = move;\r
+\r
+ move_do(new_board,move);\r
+ }\r
+\r
+ if (pos >= size) return FALSE;\r
+ line[pos] = MoveNone;\r
+\r
+ return TRUE;\r
+}\r
+\r
+// line_to_can()\r
+\r
+bool line_to_can(const move_t line[], const board_t * board, char string[], int size) {\r
+\r
+ board_t new_board[1];\r
+ int pos;\r
+ int move;\r
+\r
+ ASSERT(line_is_ok(line));\r
+ ASSERT(board_is_ok(board));\r
+ ASSERT(string!=NULL);\r
+ ASSERT(size>=StringSize);\r
+\r
+ // init\r
+\r
+ if (size < StringSize) return FALSE;\r
+\r
+ board_copy(new_board,board);\r
+ pos = 0;\r
+\r
+ // loop\r
+\r
+ while ((move = *line++) != MoveNone) {\r
+\r
+ if (pos != 0) {\r
+ if (pos >= size) return FALSE;\r
+ string[pos++] = ' ';\r
+ }\r
+\r
+ if (!move_to_can(move,new_board,&string[pos],size-pos)) return FALSE;\r
+ pos += strlen(&string[pos]);\r
+\r
+ move_do(new_board,move);\r
+ }\r
+\r
+ if (pos >= size) return FALSE;\r
+ string[pos] = '\0';\r
+\r
+ return TRUE;\r
+}\r
+\r
+// line_to_san()\r
+\r
+bool line_to_san(const move_t line[], const board_t * board, char string[], int size) {\r
+\r
+ board_t new_board[1];\r
+ int pos;\r
+ int move;\r
+ char move_string[256];\r
+\r
+ ASSERT(line_is_ok(line));\r
+ ASSERT(board_is_ok(board));\r
+ ASSERT(string!=NULL);\r
+ ASSERT(size>=StringSize);\r
+\r
+ // init\r
+\r
+ if (size < StringSize) return FALSE;\r
+\r
+ board_copy(new_board,board);\r
+ pos = 0;\r
+\r
+ // loop\r
+\r
+ while ((move = *line++) != MoveNone) {\r
+\r
+ if (pos != 0) {\r
+ if (pos >= size) return FALSE;\r
+ string[pos++] = ' ';\r
+ }\r
+\r
+ if (!move_is_legal(move,new_board)\r
+ || !move_to_san(move,new_board,&string[pos],size-pos)) {\r
+\r
+ if (Strict || UseDebug) {\r
+\r
+ move_to_can(move,new_board,move_string,256);\r
+ my_log("POLYGLOT ILLEGAL MOVE IN LINE %s\n",move_string);\r
+\r
+ board_disp(new_board);\r
+ }\r
+\r
+ if (Strict) my_fatal("line_to_san(): illegal move\n");\r
+\r
+ break;\r
+ }\r
+\r
+ pos += strlen(&string[pos]);\r
+\r
+ move_do(new_board,move);\r
+ }\r
+\r
+ if (pos >= size) return FALSE;\r
+ string[pos] = '\0';\r
+\r
+ return TRUE;\r
+}\r
+\r
+// end of line.cpp\r
+\r