Пример #1
0
bool move_is_legal(int move, const board_t * board) {

   bool legal;

   ASSERT(move_is_ok(move));
   ASSERT(board_is_ok(board));

   legal = move_is_pseudo(move,board) && pseudo_is_legal(move,board);
   ASSERT(legal==move_is_legal_debug(move,board));

   return legal;
}
Пример #2
0
bool pseudo_is_legal(int move, const board_t * board) {

   board_t new_board[1];

   ASSERT(move_is_ok(move));
   ASSERT(board_is_ok(board));

   ASSERT(move_is_pseudo(move,board));

   board_copy(new_board,board);
   move_do(new_board,move);

   return !is_in_check(new_board,colour_opp(new_board->turn));
}
Пример #3
0
bool quiet_is_pseudo( int move, board_t *board )
{
	int to;

	ASSERT(move_is_ok(move));
	ASSERT(board != NULL);

	ASSERT(!board_is_check(board));

	to = MOVE_TO(move);
	ASSERT(SQUARE_IS_OK(to));

	if( board->square[to] != Empty )
		return false; // capture

	return move_is_pseudo(move, board );
}
Пример #4
0
void move_do(board_t * board, int move) {

   int me, opp;
   int from, to;
   int piece, pos, capture;
   int old_flags, new_flags;
   int sq, ep_square;
   int pawn;

   ASSERT(board_is_ok(board));
   ASSERT(move_is_ok(move));

   ASSERT(move_is_pseudo(move,board));

   // init

   me = board->turn;
   opp = colour_opp(me);

   from = move_from(move);
   to = move_to(move);

   piece = board->square[from];
   ASSERT(colour_equal(piece,me));

   pos = board->pos[from];
   ASSERT(pos>=0);

   // update turn

   board->turn = opp;
   board->key ^= random_64(RandomTurn);

   // update castling rights

   old_flags = board_flags(board);

   if (piece_is_king(piece)) {
      board->castle[me][SideH] = SquareNone;
      board->castle[me][SideA] = SquareNone;
   }

   if (board->castle[me][SideH] == from) board->castle[me][SideH] = SquareNone;
   if (board->castle[me][SideA] == from) board->castle[me][SideA] = SquareNone;

   if (board->castle[opp][SideH] == to) board->castle[opp][SideH] = SquareNone;
   if (board->castle[opp][SideA] == to) board->castle[opp][SideA] = SquareNone;

   new_flags = board_flags(board);

   board->key ^= hash_castle_key(new_flags^old_flags); // HACK

   // update en-passant square

   ep_square = sq = board->ep_square;
   if (sq != SquareNone) {
      board->key ^= random_64(RandomEnPassant+square_file(sq));
      board->ep_square = SquareNone;
   }

   if (piece_is_pawn(piece) && abs(to-from) == 32) {
      pawn = piece_make_pawn(opp);
      if (board->square[to-1] == pawn || board->square[to+1] == pawn) {
         board->ep_square = sq = (from + to) / 2;
         board->key ^= random_64(RandomEnPassant+square_file(sq));
      }
   }

   // update ply number (captures are handled later)

   board->ply_nb++;
   if (piece_is_pawn(piece)) board->ply_nb = 0; // conversion

   // update move number

   if (me == Black) board->move_nb++;

   // castle

   if (colour_equal(board->square[to],me)) {

      int rank;
      int king_from, king_to;
      int rook_from, rook_to;
      int rook;

      rank = colour_is_white(me) ? Rank1 : Rank8;

      king_from = from;
      rook_from = to;

      if (to > from) { // h side
         king_to = square_make(FileG,rank);
         rook_to = square_make(FileF,rank);
      } else { // a side
         king_to = square_make(FileC,rank);
         rook_to = square_make(FileD,rank);
      }

      // remove the rook

      pos = board->pos[rook_from];
      ASSERT(pos>=0);

      rook = Rook64 | me; // HACK

      square_clear(board,rook_from,rook);

      // move the king

      square_move(board,king_from,king_to,piece);

      // put the rook back

      square_set(board,rook_to,rook,pos);

      ASSERT(board->key==hash_key(board));

      return;
   }

   // remove the captured piece

   if (piece_is_pawn(piece) && to == ep_square) {

      // en-passant capture

      sq = square_ep_dual(to);
      capture = board->square[sq];
      ASSERT(capture==piece_make_pawn(opp));

      square_clear(board,sq,capture);

      board->ply_nb = 0; // conversion

   } else {

      capture = board->square[to];

      if (capture != Empty) {

         // normal capture

         ASSERT(colour_equal(capture,opp));
         ASSERT(!piece_is_king(capture));

         square_clear(board,to,capture);

         board->ply_nb = 0; // conversion
      }
   }

   // move the piece

   if (move_is_promote(move)) {

      // promote

      square_clear(board,from,piece);
      piece = move_promote_hack(move) | me; // HACK
      square_set(board,to,piece,pos);

   } else {

      // normal move

      square_move(board,from,to,piece);
   }

   ASSERT(board->key==hash_key(board));
}
Пример #5
0
int sort_next(sort_t * sort, int ThreadId) {

   int move;
   int gen;

   ASSERT(sort!=NULL);

   while (true) {

      while (sort->pos < LIST_SIZE(sort->list)) {

         // next move

         move = LIST_MOVE(sort->list,sort->pos);
         sort->value = HistoryMax; // default score, HistoryMax instead of 16384
         sort->pos++;

         ASSERT(move!=MoveNone);

         // test

         if (false) {

         } else if (sort->test == TEST_NONE) {

            // no-op

         } else if (sort->test == TEST_TRANS_KILLER) {

            if (!move_is_pseudo(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_GOOD_CAPTURE) {

            ASSERT(move_is_tactical(move,sort->board));

            if (move == sort->trans_killer) continue;

            if (!capture_is_good(move,sort->board,sort->in_pv)) {
               LIST_ADD(sort->bad,move);
               continue;
            }

            if (!pseudo_is_legal(move,sort->board)) continue;
            
         } else if (sort->test == TEST_BAD_CAPTURE) {

            ASSERT(move_is_tactical(move,sort->board));
            ASSERT(!capture_is_good(move,sort->board,sort->in_pv));

            ASSERT(move!=sort->trans_killer);
            if (!pseudo_is_legal(move,sort->board)) continue;

            sort->value = HistoryBadCap; // WHM(31)

         } else if (sort->test == TEST_KILLER) {

            if (move == sort->trans_killer) continue;
            if (!quiet_is_pseudo(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

            ASSERT(!move_is_tactical(move,sort->board));

            sort->value = HistoryKiller; // WHM(31)

         } else if (sort->test == TEST_QUIET) {

            ASSERT(!move_is_tactical(move,sort->board));

            if (move == sort->trans_killer) continue;
            if (move == sort->killer_1) continue;
            if (move == sort->killer_2) continue;
            if (move == sort->killer_3) continue;
            if (move == sort->killer_4) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

            sort->value = history_prob(move,sort->board,ThreadId);

         } else {

            ASSERT(false);

            return MoveNone;
         }

         ASSERT(pseudo_is_legal(move,sort->board));

         return move;
      }

      // next stage

      gen = Code[sort->gen++];

      if (false) {

      } else if (gen == GEN_TRANS) {

         LIST_CLEAR(sort->list);
         if (sort->trans_killer != MoveNone) LIST_ADD(sort->list,sort->trans_killer);

         sort->test = TEST_TRANS_KILLER;

      } else if (gen == GEN_GOOD_CAPTURE) {

         gen_captures(sort->list,sort->board);
         note_mvv_lva(sort->list,sort->board);
         list_sort(sort->list);

         LIST_CLEAR(sort->bad);

         sort->test = TEST_GOOD_CAPTURE;

      } else if (gen == GEN_BAD_CAPTURE) {

         list_copy(sort->list,sort->bad);

         sort->test = TEST_BAD_CAPTURE;

      } else if (gen == GEN_KILLER) {

         LIST_CLEAR(sort->list);
         if (sort->killer_1 != MoveNone) LIST_ADD(sort->list,sort->killer_1);
         if (sort->killer_2 != MoveNone) LIST_ADD(sort->list,sort->killer_2);
         if (sort->killer_3 != MoveNone) LIST_ADD(sort->list,sort->killer_3);
         if (sort->killer_4 != MoveNone) LIST_ADD(sort->list,sort->killer_4);
         
         sort->test = TEST_KILLER;

      } else if (gen == GEN_QUIET) {

         gen_quiet_moves(sort->list,sort->board);
         note_quiet_moves(sort->list,sort->board,sort->in_pv,ThreadId);
         list_sort(sort->list);

         sort->test = TEST_QUIET;

      } else {

         ASSERT(gen==GEN_END);

         return MoveNone;
      }

      sort->pos = 0;
   }
}
Пример #6
0
int sort_next_qs(sort_t * sort) {

   int move;
   int gen;

   ASSERT(sort!=NULL);

   while (true) {

      while (sort->pos < LIST_SIZE(sort->list)) {

         // next move

         move = LIST_MOVE(sort->list,sort->pos);
         sort->pos++;

         ASSERT(move!=MoveNone);

         // test

         if (false) {

         } else if (sort->test == TEST_LEGAL) {

            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_TRANS_KILLER) {

            if (!move_is_pseudo(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

            // check

            if (!MOVE_IS_TACTICAL(move,sort->board)
             && (!move_is_check(move,sort->board) || sort->depth < 0)) continue;

         } else if (sort->test == TEST_CAPTURE_QS) {

            ASSERT(MOVE_IS_TACTICAL(move,sort->board));
            ASSERT(sort->value==NodePV||sort->value==NodeCut||sort->value==NodeAll);

            if (move == sort->trans_killer) continue;
            if (sort->value != NodePV && !capture_is_good(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_CHECK_QS) {

            ASSERT(!MOVE_IS_TACTICAL(move,sort->board));
            ASSERT(move_is_check(move,sort->board));

            if (move == sort->trans_killer) continue;
            if (see_move(move,sort->board,0) < 0) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else {

            ASSERT(false);

            return MoveNone;
         }

         ASSERT(pseudo_is_legal(move,sort->board));

         return move;
      }

      // next stage

      gen = Code[sort->gen++];

      if (false) {

      } else if (gen == GEN_EVASION_QS) {

         gen_pseudo_evasions(sort->list,sort->board,sort->attack);
         note_moves_simple(sort->list,sort->board,sort->trans_killer);
         list_sort(sort->list);

         sort->test = TEST_LEGAL;

      } else if (gen == GEN_TRANS) {

         LIST_CLEAR(sort->list);
         if (sort->trans_killer != MoveNone) LIST_ADD(sort->list,sort->trans_killer);

         sort->test = TEST_TRANS_KILLER;

      } else if (gen == GEN_CAPTURE_QS) {

         gen_captures(sort->list,sort->board);
         note_mvv_lva(sort->list,sort->board);
         list_sort(sort->list);

         sort->test = TEST_CAPTURE_QS;

      } else if (gen == GEN_CHECK_QS) {

         gen_quiet_checks(sort->list,sort->board);

         sort->test = TEST_CHECK_QS;

      } else {

         ASSERT(gen==GEN_END);

         return MoveNone;
      }

      sort->pos = 0;
   }
}
Пример #7
0
int sort_next(sort_t * sort) {

   int move;
   int gen;

   ASSERT(sort!=NULL);

   while (true) {

      while (sort->pos < LIST_SIZE(sort->list)) {

         // next move

         move = LIST_MOVE(sort->list,sort->pos);
         sort->value = 65536; // default score
         sort->pos++;

         ASSERT(move!=MoveNone);

         // test

         if (false) {

         } else if (sort->test == TEST_NONE) {

            // Evasion (no-op)

         } else if (sort->test == TEST_TRANS_KILLER) {

            if (!move_is_pseudo(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_CAPTURE) {

            ASSERT(MOVE_IS_TACTICAL(move,sort->board));

            if (move == sort->trans_killer) continue;

            if (!capture_is_good(move,sort->board)) {
               LIST_ADD(sort->bad,move);
               continue;
            }

            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_KILLER) {

            if (move == sort->trans_killer) continue;
            if (!quiet_is_pseudo(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

            ASSERT(!MOVE_IS_TACTICAL(move,sort->board));

            sort->value = 32768;

         } else if (sort->test == TEST_QUIET) {

            ASSERT(!MOVE_IS_TACTICAL(move,sort->board));

            if (move == sort->trans_killer) continue;
            if (move == sort->killer_1) continue;
            if (move == sort->killer_2) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

            sort->value = history_prob(move,sort->board);

         } else if (sort->test == TEST_BAD) {

            ASSERT(MOVE_IS_TACTICAL(move,sort->board));
            ASSERT(!capture_is_good(move,sort->board));

            ASSERT(move!=sort->trans_killer);
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else {

            ASSERT(false);

            return MoveNone;
         }

         ASSERT(pseudo_is_legal(move,sort->board));

         return move;
      }

      // next stage

      gen = Code[sort->gen++];

      if (false) {

      } else if (gen == GEN_TRANS) {

         LIST_CLEAR(sort->list);
         if (sort->trans_killer != MoveNone) LIST_ADD(sort->list,sort->trans_killer);

         sort->test = TEST_TRANS_KILLER;

      } else if (gen == GEN_CAPTURE) {

         gen_captures(sort->list,sort->board);
         note_mvv_lva(sort->list,sort->board);
         list_sort(sort->list);

         LIST_CLEAR(sort->bad);

         sort->test = TEST_CAPTURE;

      } else if (gen == GEN_KILLER) {

         LIST_CLEAR(sort->list);
         if (sort->killer_1 != MoveNone) LIST_ADD(sort->list,sort->killer_1);
         if (sort->killer_2 != MoveNone) LIST_ADD(sort->list,sort->killer_2);

         sort->test = TEST_KILLER;

      } else if (gen == GEN_QUIET) {

         gen_quiet_moves(sort->list,sort->board);
         note_quiet_moves(sort->list,sort->board);
         list_sort(sort->list);

         sort->test = TEST_QUIET;

      } else if (gen == GEN_BAD) {

         list_copy(sort->list,sort->bad);

         sort->test = TEST_BAD;

      } else {

         ASSERT(gen==GEN_END);

         return MoveNone;
      }

      sort->pos = 0;
   }
}