version 1.4.30b
[polyglot.git] / line.c
diff --git a/line.c b/line.c
new file mode 100644 (file)
index 0000000..de8c5bb
--- /dev/null
+++ b/line.c
@@ -0,0 +1,205 @@
+\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