Add forgotten files 1.4.70b
[polyglot.git] / board.c
diff --git a/board.c b/board.c
index 8c51a88..4f1139f 100644 (file)
--- a/board.c
+++ b/board.c
-\r
-// board.c\r
-\r
-// includes\r
-\r
-#include <stdio.h>\r
-\r
-#include "attack.h"\r
-#include "board.h"\r
-#include "colour.h"\r
-#include "fen.h"\r
-#include "hash.h"\r
-#include "list.h"\r
-#include "move.h"\r
-#include "move_do.h"\r
-#include "move_gen.h"\r
-#include "move_legal.h"\r
-#include "piece.h"\r
-#include "util.h"\r
-\r
-// constants\r
-\r
-static const bool UseSlowDebug = FALSE;\r
-\r
-// functions\r
-\r
-// board_is_ok()\r
-\r
-bool board_is_ok(const board_t * board) {\r
-\r
-   int sq, piece;\r
-   int colour, pos;\r
-   int king, rook;\r
-\r
-   if (board == NULL) return FALSE;\r
-\r
-   // optional heavy DEBUG mode\r
-\r
-   if (!UseSlowDebug) return TRUE;\r
-\r
-   // squares\r
-\r
-   for (sq = 0; sq < SquareNb; sq++) {\r
-      piece = board->square[sq];\r
-      if (square_is_ok(sq)) {\r
-         pos = board->pos[sq];\r
-         if (piece == Empty) {\r
-            if (pos != -1) return FALSE;\r
-         } else {\r
-            if (pos < 0) return FALSE;\r
-            if (board->list[piece_colour(piece)][pos] != sq) return FALSE;\r
-         }\r
-      } else {\r
-         if (piece != Knight64) return FALSE;\r
-      }\r
-   }\r
-\r
-   // white piece list\r
-\r
-   colour = White;\r
-   pos = 0;\r
-\r
-   if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return FALSE;\r
-\r
-   sq = board->list[colour][pos];\r
-   if (sq == SquareNone) return FALSE;\r
-   if (board->pos[sq] != pos) return FALSE;\r
-   piece = board->square[sq];\r
-   if (!colour_equal(piece,colour) || !piece_is_king(piece)) return FALSE;\r
-\r
-   for (pos++; pos < board->list_size[colour]; pos++) {\r
-      sq = board->list[colour][pos];\r
-      if (sq == SquareNone) return FALSE;\r
-      if (board->pos[sq] != pos) return FALSE;\r
-      if (!colour_equal(board->square[sq],colour)) return FALSE;\r
-   }\r
-\r
-   sq = board->list[colour][pos];\r
-   if (sq != SquareNone) return FALSE;\r
-\r
-   // black piece list\r
-\r
-   colour = Black;\r
-   pos = 0;\r
-\r
-   if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return FALSE;\r
-\r
-   sq = board->list[colour][pos];\r
-   if (sq == SquareNone) return FALSE;\r
-   if (board->pos[sq] != pos) return FALSE;\r
-   piece = board->square[sq];\r
-   if (!colour_equal(piece,colour) || !piece_is_king(piece)) return FALSE;\r
-\r
-   for (pos++; pos < board->list_size[colour]; pos++) {\r
-      sq = board->list[colour][pos];\r
-      if (sq == SquareNone) return FALSE;\r
-      if (board->pos[sq] != pos) return FALSE;\r
-      if (!colour_equal(board->square[sq],colour)) return FALSE;\r
-   }\r
-\r
-   sq = board->list[colour][pos];\r
-   if (sq != SquareNone) return FALSE;\r
-\r
-   // TODO: material\r
-\r
-   if (board->number[WhiteKing12] != 1) return FALSE;\r
-   if (board->number[BlackKing12] != 1) return FALSE;\r
-\r
-   if (!colour_is_ok(board->turn)) return FALSE;\r
-\r
-   // castling status\r
-\r
-   if (board->castle[White][SideH] != SquareNone) {\r
-\r
-      king = board->list[White][0];\r
-      if ((king < A1) || (king > H1)) return FALSE;\r
-      if (board->square[king] != WhiteKing256) return FALSE;\r
-\r
-      rook = board->castle[White][SideH];\r
-      if ((rook < A1) || (rook > H1)) return FALSE;\r
-      if (board->square[rook] != WhiteRook256) return FALSE;\r
-\r
-      if (rook <= king) return FALSE;\r
-   }\r
-\r
-   if (board->castle[White][SideA] != SquareNone) {\r
-\r
-      king = board->list[White][0];\r
-      if ((king < A1) || (king > H1)) return FALSE;\r
-      if (board->square[king] != WhiteKing256) return FALSE;\r
-\r
-      rook = board->castle[White][SideA];\r
-      if ((rook < A1) || (rook > H1)) return FALSE;\r
-      if (board->square[rook] != WhiteRook256) return FALSE;\r
-\r
-      if (rook >= king) return FALSE;\r
-   }\r
-\r
-   if (board->castle[Black][SideH] != SquareNone) {\r
-\r
-      king = board->list[Black][0];\r
-      if ((king < A8) || (king > H8)) return FALSE;\r
-      if (board->square[king] != BlackKing256) return FALSE;\r
-\r
-      rook = board->castle[Black][SideH];\r
-      if ((rook < A8) || (rook > H8)) return FALSE;\r
-      if (board->square[rook] != BlackRook256) return FALSE;\r
-\r
-      if (rook <= king) return FALSE;\r
-   }\r
-\r
-   if (board->castle[Black][SideA] != SquareNone) {\r
-\r
-      king = board->list[Black][0];\r
-      if (king < A8 || king > H8) return FALSE;\r
-      if (board->square[king] != BlackKing256) return FALSE;\r
-\r
-      rook = board->castle[Black][SideA];\r
-      if (rook < A8 || rook > H8) return FALSE;\r
-      if (board->square[rook] != BlackRook256) return FALSE;\r
-\r
-      if (rook >= king) return FALSE;\r
-   }\r
-\r
-   return TRUE;\r
-}\r
-\r
-// board_clear()\r
-\r
-void board_clear(board_t * board) {\r
-\r
-   int file, rank, sq;\r
-   int colour, pos;\r
-   int piece;\r
-\r
-   ASSERT(board!=NULL);\r
-\r
-   // edge squares\r
-\r
-   for (sq = 0; sq < SquareNb; sq++) {\r
-      board->square[sq] = Knight64; // HACK: uncoloured knight\r
-      board->pos[sq] = -1;\r
-   }\r
-\r
-   // empty squares\r
-\r
-   for (rank = 0; rank < 8; rank++) {\r
-      for (file = 0; file < 8; file++) {\r
-         sq = square_make(file,rank);\r
-         board->square[sq] = Empty;\r
-      }\r
-   }\r
-\r
-   // piece lists\r
-\r
-   for (colour = 0; colour < 3; colour++) {\r
-      for (pos = 0; pos < 32; pos++) { // HACK\r
-         board->list[colour][pos] = SquareNone;\r
-      }\r
-      board->list_size[colour] = 0;\r
-   }\r
-\r
-   // material\r
-\r
-   for (piece = 0; piece < 12; piece++) {\r
-      board->number[piece] = 0;\r
-   }\r
-\r
-   // rest\r
-\r
-   board->turn = ColourNone;\r
-   board->castle[White][SideH] = SquareNone;\r
-   board->castle[White][SideA] = SquareNone;\r
-   board->castle[Black][SideH] = SquareNone;\r
-   board->castle[Black][SideA] = SquareNone;\r
-   board->ep_square = SquareNone;\r
-\r
-   board->ply_nb = 0;\r
-   board->move_nb = 0;\r
-\r
-   board->key = 0;\r
-}\r
-\r
-// board_start()\r
-\r
-void board_start(board_t * board) {\r
-\r
-   ASSERT(board!=NULL);\r
-\r
-   if (!board_from_fen(board,StartFen)) ASSERT(FALSE);\r
-}\r
-\r
-// board_copy()\r
-\r
-void board_copy(board_t * dst, const board_t * src) {\r
-\r
-   ASSERT(dst!=NULL);\r
-   ASSERT(board_is_ok(src));\r
-\r
-   *dst = *src;\r
-}\r
-\r
-// board_equal()\r
-\r
-bool board_equal(const board_t * board_1, const board_t * board_2) {\r
-\r
-   int sq_64, sq;\r
-\r
-   ASSERT(board_is_ok(board_1));\r
-   ASSERT(board_is_ok(board_2));\r
-\r
-   // fast comparison\r
-\r
-   if (board_1->key != board_2->key) return FALSE;\r
-\r
-   // slow comparison\r
-\r
-   for (sq_64 = 0; sq_64 < 64; sq_64++) {\r
-      sq = square_from_64(sq_64);\r
-      if (board_1->square[sq] != board_2->square[sq]) return FALSE;\r
-   }\r
-\r
-   if (board_1->turn != board_2->turn) return FALSE;\r
-   if (board_1->castle[White][SideH] != board_2->castle[White][SideH]) return FALSE;\r
-   if (board_1->castle[White][SideA] != board_2->castle[White][SideA]) return FALSE;\r
-   if (board_1->castle[Black][SideH] != board_2->castle[Black][SideH]) return FALSE;\r
-   if (board_1->castle[Black][SideA] != board_2->castle[Black][SideA]) return FALSE;\r
-   if (board_1->ep_square != board_2->ep_square) return FALSE;\r
-\r
-   return TRUE;\r
-}\r
-\r
-// board_init_list()\r
-\r
-void board_init_list(board_t * board) {\r
-\r
-   int sq_64, sq, piece;\r
-   int colour, pos;\r
-\r
-   ASSERT(board!=NULL);\r
-\r
-   // init\r
-\r
-   for (sq_64 = 0; sq_64 < 64; sq_64++) {\r
-      sq = square_from_64(sq_64);\r
-      board->pos[sq] = -1;\r
-   }\r
-\r
-   for (piece = 0; piece < 12; piece++) board->number[piece] = 0;\r
-\r
-   // white piece list\r
-\r
-   colour = White;\r
-   pos = 0;\r
-\r
-   for (sq_64 = 0; sq_64 < 64; sq_64++) {\r
-      sq = square_from_64(sq_64);\r
-      piece = board->square[sq];\r
-      ASSERT(pos>=0&&pos<=16);\r
-      if (colour_equal(piece,colour) && piece_is_king(piece)) {\r
-         board->pos[sq] = pos;\r
-         board->list[colour][pos] = sq;\r
-         pos++;\r
-         board->number[piece_to_12(piece)]++;\r
-      }\r
-   }\r
-   ASSERT(pos==1);\r
-\r
-   for (sq_64 = 0; sq_64 < 64; sq_64++) {\r
-      sq = square_from_64(sq_64);\r
-      piece = board->square[sq];\r
-      ASSERT(pos>=0&&pos<=16);\r
-      if (colour_equal(piece,colour) && !piece_is_king(piece)) {\r
-         board->pos[sq] = pos;\r
-         board->list[colour][pos] = sq;\r
-         pos++;\r
-         board->number[piece_to_12(piece)]++;\r
-      }\r
-   }\r
-\r
-   ASSERT(pos>=1&&pos<=16);\r
-   board->list[colour][pos] = SquareNone;\r
-   board->list_size[colour] = pos;\r
-\r
-   // black piece list\r
-\r
-   colour = Black;\r
-   pos = 0;\r
-\r
-   for (sq_64 = 0; sq_64 < 64; sq_64++) {\r
-      sq = square_from_64(sq_64);\r
-      piece = board->square[sq];\r
-      ASSERT(pos>=0&&pos<=16);\r
-      if (colour_equal(piece,colour) && piece_is_king(piece)) {\r
-         board->pos[sq] = pos;\r
-         board->list[colour][pos] = sq;\r
-         pos++;\r
-         board->number[piece_to_12(piece)]++;\r
-      }\r
-   }\r
-   ASSERT(pos==1);\r
-\r
-   for (sq_64 = 0; sq_64 < 64; sq_64++) {\r
-      sq = square_from_64(sq_64);\r
-      piece = board->square[sq];\r
-      ASSERT(pos>=1&&pos<=16);\r
-      if (colour_equal(piece,colour) && !piece_is_king(piece)) {\r
-         board->pos[sq] = pos;\r
-         board->list[colour][pos] = sq;\r
-         pos++;\r
-         board->number[piece_to_12(piece)]++;\r
-      }\r
-   }\r
-\r
-   ASSERT(pos>=1&&pos<=16);\r
-   board->list[colour][pos] = SquareNone;\r
-   board->list_size[colour] = pos;\r
-\r
-   // hash key\r
-\r
-   board->key = hash_key(board);\r
-}\r
-\r
-// board_flags()\r
-\r
-int board_flags(const board_t * board) {\r
-\r
-   int flags;\r
-\r
-   flags = 0;\r
-\r
-   if (board->castle[White][SideH] != SquareNone) flags |= 1 << 0;\r
-   if (board->castle[White][SideA] != SquareNone) flags |= 1 << 1;\r
-   if (board->castle[Black][SideH] != SquareNone) flags |= 1 << 2;\r
-   if (board->castle[Black][SideA] != SquareNone) flags |= 1 << 3;\r
-\r
-   return flags;\r
-}\r
-\r
-// board_can_play()\r
-\r
-bool board_can_play(const board_t * board) {\r
-\r
-   list_t list[1];\r
-   int i, move;\r
-\r
-   ASSERT(board_is_ok(board));\r
-\r
-   gen_moves(list,board);\r
-\r
-   for (i = 0; i < list_size(list); i++) {\r
-      move = list_move(list,i);\r
-      if (pseudo_is_legal(move,board)) return TRUE;\r
-   }\r
-\r
-   return FALSE; // no legal move\r
-}\r
-\r
-// board_mobility()\r
-\r
-int board_mobility(const board_t * board) {\r
-\r
-   list_t list[1];\r
-\r
-   ASSERT(board_is_ok(board));\r
-\r
-   gen_legal_moves(list,board);\r
-\r
-   return list_size(list);\r
-}\r
-\r
-// board_is_check()\r
-\r
-bool board_is_check(const board_t * board) {\r
-\r
-   ASSERT(board_is_ok(board));\r
-\r
-   return is_in_check(board,board->turn);\r
-}\r
-\r
-// board_is_mate()\r
-\r
-bool board_is_mate(const board_t * board) {\r
-\r
-   ASSERT(board_is_ok(board));\r
-\r
-   if (!board_is_check(board)) return FALSE;\r
-   if (board_can_play(board)) return FALSE;\r
-\r
-   return TRUE;\r
-}\r
-\r
-// board_is_stalemate()\r
-\r
-bool board_is_stalemate(const board_t * board) {\r
-\r
-   ASSERT(board_is_ok(board));\r
-\r
-   if (board_is_check(board)) return FALSE;\r
-   if (board_can_play(board)) return FALSE;\r
-\r
-   return TRUE;\r
-}\r
-\r
-// king_pos()\r
-\r
-int king_pos(const board_t * board, int colour) {\r
-\r
-   ASSERT(board_is_ok(board));\r
-   ASSERT(colour_is_ok(colour));\r
-\r
-   return board->list[colour][0];\r
-}\r
-\r
-// board_disp()\r
-\r
-void board_disp(const board_t * board) {\r
-\r
-   int file, rank, sq;\r
-   int piece, c;\r
-   char fen[256];\r
-   char row[9];\r
-   char line[256];\r
-\r
-   ASSERT(board!=NULL);\r
-\r
-   if (!board_to_fen(board,fen,256)) ASSERT(FALSE);\r
-   my_log("POLYGLOT FEN %s\n",fen);\r
-   my_log("POLYGLOT *** CURRENT BOARD ***\n");\r
-\r
-   for (rank = 7; rank >= 0; rank--) {\r
-\r
-      for (file = 0; file < 8; file++) {\r
-\r
-         sq = square_make(file,rank);\r
-         piece = board->square[sq];\r
-\r
-         c = (piece != Empty) ? piece_to_char(piece) : '-';\r
-         row[file]=c;\r
-      }\r
-      row[8]='\0';\r
-      snprintf(line,sizeof(line),"POLYGLOT %s\n",row);\r
-      line[sizeof(line)-1]='\0';\r
-      my_log(line);\r
-   }\r
-\r
-   my_log("POLYGLOT %s to play\n",(colour_is_black(board->turn))?"black":"white");\r
-   my_log("POLYGLOT\n");\r
-}\r
-\r
-// end of board.cpp\r
-\r
+
+// board.c
+
+// includes
+
+#include <stdio.h>
+
+#include "attack.h"
+#include "board.h"
+#include "colour.h"
+#include "fen.h"
+#include "hash.h"
+#include "list.h"
+#include "move.h"
+#include "move_do.h"
+#include "move_gen.h"
+#include "move_legal.h"
+#include "piece.h"
+#include "util.h"
+
+// constants
+
+static const bool UseSlowDebug = FALSE;
+
+// functions
+
+// board_is_ok()
+
+bool board_is_ok(const board_t * board) {
+
+   int sq, piece;
+   int colour, pos;
+   int king, rook;
+
+   if (board == NULL) return FALSE;
+
+   // optional heavy DEBUG mode
+
+   if (!UseSlowDebug) return TRUE;
+
+   // squares
+
+   for (sq = 0; sq < SquareNb; sq++) {
+      piece = board->square[sq];
+      if (square_is_ok(sq)) {
+         pos = board->pos[sq];
+         if (piece == Empty) {
+            if (pos != -1) return FALSE;
+         } else {
+            if (pos < 0) return FALSE;
+            if (board->list[piece_colour(piece)][pos] != sq) return FALSE;
+         }
+      } else {
+         if (piece != Knight64) return FALSE;
+      }
+   }
+
+   // white piece list
+
+   colour = White;
+   pos = 0;
+
+   if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return FALSE;
+
+   sq = board->list[colour][pos];
+   if (sq == SquareNone) return FALSE;
+   if (board->pos[sq] != pos) return FALSE;
+   piece = board->square[sq];
+   if (!colour_equal(piece,colour) || !piece_is_king(piece)) return FALSE;
+
+   for (pos++; pos < board->list_size[colour]; pos++) {
+      sq = board->list[colour][pos];
+      if (sq == SquareNone) return FALSE;
+      if (board->pos[sq] != pos) return FALSE;
+      if (!colour_equal(board->square[sq],colour)) return FALSE;
+   }
+
+   sq = board->list[colour][pos];
+   if (sq != SquareNone) return FALSE;
+
+   // black piece list
+
+   colour = Black;
+   pos = 0;
+
+   if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return FALSE;
+
+   sq = board->list[colour][pos];
+   if (sq == SquareNone) return FALSE;
+   if (board->pos[sq] != pos) return FALSE;
+   piece = board->square[sq];
+   if (!colour_equal(piece,colour) || !piece_is_king(piece)) return FALSE;
+
+   for (pos++; pos < board->list_size[colour]; pos++) {
+      sq = board->list[colour][pos];
+      if (sq == SquareNone) return FALSE;
+      if (board->pos[sq] != pos) return FALSE;
+      if (!colour_equal(board->square[sq],colour)) return FALSE;
+   }
+
+   sq = board->list[colour][pos];
+   if (sq != SquareNone) return FALSE;
+
+   // TODO: material
+
+   if (board->number[WhiteKing12] != 1) return FALSE;
+   if (board->number[BlackKing12] != 1) return FALSE;
+
+   if (!colour_is_ok(board->turn)) return FALSE;
+
+   // castling status
+
+   if (board->castle[White][SideH] != SquareNone) {
+
+      king = board->list[White][0];
+      if ((king < A1) || (king > H1)) return FALSE;
+      if (board->square[king] != WhiteKing256) return FALSE;
+
+      rook = board->castle[White][SideH];
+      if ((rook < A1) || (rook > H1)) return FALSE;
+      if (board->square[rook] != WhiteRook256) return FALSE;
+
+      if (rook <= king) return FALSE;
+   }
+
+   if (board->castle[White][SideA] != SquareNone) {
+
+      king = board->list[White][0];
+      if ((king < A1) || (king > H1)) return FALSE;
+      if (board->square[king] != WhiteKing256) return FALSE;
+
+      rook = board->castle[White][SideA];
+      if ((rook < A1) || (rook > H1)) return FALSE;
+      if (board->square[rook] != WhiteRook256) return FALSE;
+
+      if (rook >= king) return FALSE;
+   }
+
+   if (board->castle[Black][SideH] != SquareNone) {
+
+      king = board->list[Black][0];
+      if ((king < A8) || (king > H8)) return FALSE;
+      if (board->square[king] != BlackKing256) return FALSE;
+
+      rook = board->castle[Black][SideH];
+      if ((rook < A8) || (rook > H8)) return FALSE;
+      if (board->square[rook] != BlackRook256) return FALSE;
+
+      if (rook <= king) return FALSE;
+   }
+
+   if (board->castle[Black][SideA] != SquareNone) {
+
+      king = board->list[Black][0];
+      if (king < A8 || king > H8) return FALSE;
+      if (board->square[king] != BlackKing256) return FALSE;
+
+      rook = board->castle[Black][SideA];
+      if (rook < A8 || rook > H8) return FALSE;
+      if (board->square[rook] != BlackRook256) return FALSE;
+
+      if (rook >= king) return FALSE;
+   }
+
+   return TRUE;
+}
+
+// board_clear()
+
+void board_clear(board_t * board) {
+
+   int file, rank, sq;
+   int colour, pos;
+   int piece;
+
+   ASSERT(board!=NULL);
+
+   // edge squares
+
+   for (sq = 0; sq < SquareNb; sq++) {
+      board->square[sq] = Knight64; // HACK: uncoloured knight
+      board->pos[sq] = -1;
+   }
+
+   // empty squares
+
+   for (rank = 0; rank < 8; rank++) {
+      for (file = 0; file < 8; file++) {
+         sq = square_make(file,rank);
+         board->square[sq] = Empty;
+      }
+   }
+
+   // piece lists
+
+   for (colour = 0; colour < 3; colour++) {
+      for (pos = 0; pos < 32; pos++) { // HACK
+         board->list[colour][pos] = SquareNone;
+      }
+      board->list_size[colour] = 0;
+   }
+
+   // material
+
+   for (piece = 0; piece < 12; piece++) {
+      board->number[piece] = 0;
+   }
+
+   // rest
+
+   board->turn = ColourNone;
+   board->castle[White][SideH] = SquareNone;
+   board->castle[White][SideA] = SquareNone;
+   board->castle[Black][SideH] = SquareNone;
+   board->castle[Black][SideA] = SquareNone;
+   board->ep_square = SquareNone;
+
+   board->ply_nb = 0;
+   board->move_nb = 0;
+
+   board->key = 0;
+}
+
+// board_start()
+
+void board_start(board_t * board) {
+
+   ASSERT(board!=NULL);
+
+   if (!board_from_fen(board,StartFen)) ASSERT(FALSE);
+}
+
+// board_copy()
+
+void board_copy(board_t * dst, const board_t * src) {
+
+   ASSERT(dst!=NULL);
+   ASSERT(board_is_ok(src));
+
+   *dst = *src;
+}
+
+// board_equal()
+
+bool board_equal(const board_t * board_1, const board_t * board_2) {
+
+   int sq_64, sq;
+
+   ASSERT(board_is_ok(board_1));
+   ASSERT(board_is_ok(board_2));
+
+   // fast comparison
+
+   if (board_1->key != board_2->key) return FALSE;
+
+   // slow comparison
+
+   for (sq_64 = 0; sq_64 < 64; sq_64++) {
+      sq = square_from_64(sq_64);
+      if (board_1->square[sq] != board_2->square[sq]) return FALSE;
+   }
+
+   if (board_1->turn != board_2->turn) return FALSE;
+   if (board_1->castle[White][SideH] != board_2->castle[White][SideH]) return FALSE;
+   if (board_1->castle[White][SideA] != board_2->castle[White][SideA]) return FALSE;
+   if (board_1->castle[Black][SideH] != board_2->castle[Black][SideH]) return FALSE;
+   if (board_1->castle[Black][SideA] != board_2->castle[Black][SideA]) return FALSE;
+   if (board_1->ep_square != board_2->ep_square) return FALSE;
+
+   return TRUE;
+}
+
+// board_init_list()
+
+void board_init_list(board_t * board) {
+
+   int sq_64, sq, piece;
+   int colour, pos;
+
+   ASSERT(board!=NULL);
+
+   // init
+
+   for (sq_64 = 0; sq_64 < 64; sq_64++) {
+      sq = square_from_64(sq_64);
+      board->pos[sq] = -1;
+   }
+
+   for (piece = 0; piece < 12; piece++) board->number[piece] = 0;
+
+   // white piece list
+
+   colour = White;
+   pos = 0;
+
+   for (sq_64 = 0; sq_64 < 64; sq_64++) {
+      sq = square_from_64(sq_64);
+      piece = board->square[sq];
+      ASSERT(pos>=0&&pos<=16);
+      if (colour_equal(piece,colour) && piece_is_king(piece)) {
+         board->pos[sq] = pos;
+         board->list[colour][pos] = sq;
+         pos++;
+         board->number[piece_to_12(piece)]++;
+      }
+   }
+   ASSERT(pos==1);
+
+   for (sq_64 = 0; sq_64 < 64; sq_64++) {
+      sq = square_from_64(sq_64);
+      piece = board->square[sq];
+      ASSERT(pos>=0&&pos<=16);
+      if (colour_equal(piece,colour) && !piece_is_king(piece)) {
+         board->pos[sq] = pos;
+         board->list[colour][pos] = sq;
+         pos++;
+         board->number[piece_to_12(piece)]++;
+      }
+   }
+
+   ASSERT(pos>=1&&pos<=16);
+   board->list[colour][pos] = SquareNone;
+   board->list_size[colour] = pos;
+
+   // black piece list
+
+   colour = Black;
+   pos = 0;
+
+   for (sq_64 = 0; sq_64 < 64; sq_64++) {
+      sq = square_from_64(sq_64);
+      piece = board->square[sq];
+      ASSERT(pos>=0&&pos<=16);
+      if (colour_equal(piece,colour) && piece_is_king(piece)) {
+         board->pos[sq] = pos;
+         board->list[colour][pos] = sq;
+         pos++;
+         board->number[piece_to_12(piece)]++;
+      }
+   }
+   ASSERT(pos==1);
+
+   for (sq_64 = 0; sq_64 < 64; sq_64++) {
+      sq = square_from_64(sq_64);
+      piece = board->square[sq];
+      ASSERT(pos>=1&&pos<=16);
+      if (colour_equal(piece,colour) && !piece_is_king(piece)) {
+         board->pos[sq] = pos;
+         board->list[colour][pos] = sq;
+         pos++;
+         board->number[piece_to_12(piece)]++;
+      }
+   }
+
+   ASSERT(pos>=1&&pos<=16);
+   board->list[colour][pos] = SquareNone;
+   board->list_size[colour] = pos;
+
+   // hash key
+
+   board->key = hash_key(board);
+}
+
+// board_flags()
+
+int board_flags(const board_t * board) {
+
+   int flags;
+
+   flags = 0;
+
+   if (board->castle[White][SideH] != SquareNone) flags |= 1 << 0;
+   if (board->castle[White][SideA] != SquareNone) flags |= 1 << 1;
+   if (board->castle[Black][SideH] != SquareNone) flags |= 1 << 2;
+   if (board->castle[Black][SideA] != SquareNone) flags |= 1 << 3;
+
+   return flags;
+}
+
+// board_can_play()
+
+bool board_can_play(const board_t * board) {
+
+   list_t list[1];
+   int i, move;
+
+   ASSERT(board_is_ok(board));
+
+   gen_moves(list,board);
+
+   for (i = 0; i < list_size(list); i++) {
+      move = list_move(list,i);
+      if (pseudo_is_legal(move,board)) return TRUE;
+   }
+
+   return FALSE; // no legal move
+}
+
+// board_mobility()
+
+int board_mobility(const board_t * board) {
+
+   list_t list[1];
+
+   ASSERT(board_is_ok(board));
+
+   gen_legal_moves(list,board);
+
+   return list_size(list);
+}
+
+// board_is_check()
+
+bool board_is_check(const board_t * board) {
+
+   ASSERT(board_is_ok(board));
+
+   return is_in_check(board,board->turn);
+}
+
+// board_is_mate()
+
+bool board_is_mate(const board_t * board) {
+
+   ASSERT(board_is_ok(board));
+
+   if (!board_is_check(board)) return FALSE;
+   if (board_can_play(board)) return FALSE;
+
+   return TRUE;
+}
+
+// board_is_stalemate()
+
+bool board_is_stalemate(const board_t * board) {
+
+   ASSERT(board_is_ok(board));
+
+   if (board_is_check(board)) return FALSE;
+   if (board_can_play(board)) return FALSE;
+
+   return TRUE;
+}
+
+// king_pos()
+
+int king_pos(const board_t * board, int colour) {
+
+   ASSERT(board_is_ok(board));
+   ASSERT(colour_is_ok(colour));
+
+   return board->list[colour][0];
+}
+
+// board_disp()
+
+void board_disp(const board_t * board) {
+
+   int file, rank, sq;
+   int piece, c;
+   char fen[256];
+   char row[9];
+   char line[256];
+
+   ASSERT(board!=NULL);
+
+   if (!board_to_fen(board,fen,256)) ASSERT(FALSE);
+   my_log("POLYGLOT FEN %s\n",fen);
+   my_log("POLYGLOT *** CURRENT BOARD ***\n");
+
+   for (rank = 7; rank >= 0; rank--) {
+
+      for (file = 0; file < 8; file++) {
+
+         sq = square_make(file,rank);
+         piece = board->square[sq];
+
+         c = (piece != Empty) ? piece_to_char(piece) : '-';
+         row[file]=c;
+      }
+      row[8]='\0';
+      snprintf(line,sizeof(line),"POLYGLOT %s\n",row);
+      line[sizeof(line)-1]='\0';
+      my_log(line);
+   }
+
+   my_log("POLYGLOT %s to play\n",(colour_is_black(board->turn))?"black":"white");
+   my_log("POLYGLOT\n");
+}
+
+// end of board.cpp
+