Example #1
0
bool draw_krkr( const board_t *board)
{
	int rrook, brook;
	int rking, bking;

	if(board->piece[PIECE_TO_INDEX(RedRook)] != PieceNone)
		rrook = board->piece[PIECE_TO_INDEX(RedRook)];

	if(board->piece[PIECE_TO_INDEX(RedRook) + 1] != PieceNone)
		rrook = board->piece[PIECE_TO_INDEX(RedRook) + 1];

	if(board->piece[PIECE_TO_INDEX(BlackRook)] != PieceNone)
		brook = board->piece[PIECE_TO_INDEX(RedRook)];

	if(board->piece[PIECE_TO_INDEX(BlackRook) + 1] != PieceNone)
		brook = board->piece[PIECE_TO_INDEX(RedRook) + 1];

	rking = KING_POS(board, Red);
	bking = KING_POS(board, Black);

	if(EQUAL_FILE(rrook, rking) && EQUAL_RANK(brook, bking))
		return true;

    if(SQUARE_FILE(rking) != 0x7 && SQUARE_FILE(bking) != 0x7)
	{
		if(SQUARE_RANK(rking) < 0xa && SQUARE_RANK(bking) > 0x5)
			return true;

	} 

	return false;
}
Example #2
0
bool is_pinned(const board_t * board, int square, int colour) {

   int from, to;
   int inc;
   int sq, piece;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(square));
   ASSERT(COLOUR_IS_OK(colour));

   from = square;
   to = KING_POS(board,colour);

   inc = DELTA_INC_LINE(to-from);
   if (inc == IncNone) return false; // not a line

   sq = from;
   do sq += inc; while (board->square[sq] == Empty);

   if (sq != to) return false; // blocker

   sq = from;
   do sq -= inc; while ((piece=board->square[sq]) == Empty);

   return COLOUR_IS(piece,COLOUR_OPP(colour)) && SLIDER_ATTACK(piece,inc);
}
Example #3
0
static void note_quiet_moves(list_t * list, const board_t * board, bool in_pv, int ThreadId) {

   int size;
   int i, move;
   int move_piece;

   ASSERT(list_is_ok(list));
   ASSERT(board!=NULL);

   size = LIST_SIZE(list);

   if (size >= 2) {
      for (i = 0; i < size; i++) {
         move = LIST_MOVE(list,i);
         list->value[i] = quiet_move_value(move,board,ThreadId);
         if (TryQuietKingAttacks && in_pv) {
            move_piece = MOVE_PIECE(move,board);
            if (!(PIECE_IS_PAWN(move_piece) || PIECE_IS_KING(move_piece))) {
               if (narrow_piece_attack_king(board,move_piece,MOVE_TO(move),KING_POS(board,COLOUR_OPP(board->turn)))) {
                  if (see_move(move,board) >= 0) {
//                   if (1 == NumberThreadsInternal) print_board(board);
                     list->value[i] += 16;
                  }
               }
            }
         }
      }
   }
}
bool pseudo_is_legal(int move, board_t * board) {

    int me, opp;
    int from, to;
    int piece;
    bool legal;
    int king;
    undo_t undo[1];

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

    // init

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

    from = MOVE_FROM(move);
    to = MOVE_TO(move);

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

    // slow test for en-passant captures

    if (MOVE_IS_EN_PASSANT(move)) {

        move_do(board,move,undo);
        legal = !IS_IN_CHECK(board,me);
        move_undo(board,move,undo);

        return legal;
    }

    // king moves (including castle)

    if (PIECE_IS_KING(piece)) {

        legal = !is_attacked(board,to,opp);

        if (DEBUG) {
            ASSERT(board->square[from]==piece);
            board->square[from] = Empty;
            ASSERT(legal==!is_attacked(board,to,opp));
            board->square[from] = piece;
        }

        return legal;
    }

    // pins

    if (is_pinned(board,from,me)) {
        king = KING_POS(board,me);
        return DELTA_INC_LINE(king-to) == DELTA_INC_LINE(king-from); // does not discover the line
    }

    return true;
}
Example #5
0
static void find_pins(int list[], const board_t * board) {

    int me, opp;
    int king;
    const sq_t * ptr;
    int from;
    int piece;
    int delta;
    int inc;
    int sq;
    int capture;
    int pin;

    ASSERT(list!=NULL);
    ASSERT(board!=NULL);

    // init

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

    king = KING_POS(board,opp);

    for (ptr = &board->piece[me][1]; (from=*ptr) != SquareNone; ptr++) { // HACK: no king

        piece = board->square[from];

        delta = king - from;
        ASSERT(delta_is_ok(delta));

        if (PSEUDO_ATTACK(piece,delta)) {

            ASSERT(PIECE_IS_SLIDER(piece));

            inc = DELTA_INC_LINE(delta);
            ASSERT(inc!=IncNone);

            ASSERT(SLIDER_ATTACK(piece,inc));

            sq = from;
            do sq += inc;
            while ((capture=board->square[sq]) == Empty);

            ASSERT(sq!=king);

            if (COLOUR_IS(capture,me)) {
                pin = sq;
                do sq += inc;
                while (board->square[sq] == Empty);
                if (sq == king) *list++ = pin;
            }
        }
    }

    *list = SquareNone;
}
Example #6
0
static bool simple_stalemate(const board_t * board) {

   int me, opp;
   int king;
   int opp_flag;
   int from, to;
   int capture;
   const inc_t * inc_ptr;
   int inc;

   ASSERT(board!=NULL);

   ASSERT(board_is_legal(board));
   ASSERT(!board_is_check(board));

   // lone king?

   me = board->turn;
   if (board->piece_size[me] != 1 || board->pawn_size[me] != 0) return false; // no

   // king in a corner?

   king = KING_POS(board,me);
   if (king != A1 && king != H1 && king != A8 && king != H8) return false; // no

   // init

   opp = COLOUR_OPP(me);
   opp_flag = COLOUR_FLAG(opp);

   // king can move?

   from = king;

   for (inc_ptr = KingInc; (inc=*inc_ptr) != IncNone; inc_ptr++) {
      to = from + inc;
      capture = board->square[to];
      if (capture == Empty || FLAG_IS(capture,opp_flag)) {
         if (!is_attacked(board,to,opp)) return false; // legal king move
      }
   }

   // no legal move

   ASSERT(board_is_stalemate((board_t*)board));

   return true;
}
Example #7
0
bool move_is_check(int move, board_t * board) {

    undo_t undo[1];
    bool check;
    int me, opp, king;
    int from, to, piece;

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

    // slow test for complex moves

    if (MOVE_IS_SPECIAL(move)) {

        move_do(board,move,undo);
        check = IS_IN_CHECK(board,board->turn);
        move_undo(board,move,undo);

        return check;
    }

    // init

    me = board->turn;
    opp = COLOUR_OPP(me);
    king = KING_POS(board,opp);

    from = MOVE_FROM(move);
    to = MOVE_TO(move);
    piece = board->square[from];
    ASSERT(COLOUR_IS(piece,me));

    // direct check

    if (PIECE_ATTACK(board,piece,to,king)) return true;

    // indirect check

    if (is_pinned(board,from,opp)
            && DELTA_INC_LINE(king-to) != DELTA_INC_LINE(king-from)) {
        return true;
    }

    return false;
}
Example #8
0
static bool gen_evasions(list_t * list, const board_t * board, const attack_t * attack, bool legal, bool stop) {

   int me, opp;
   int opp_flag;
   int king;
   const inc_t * inc_ptr;
   int inc;
   int to;
   int piece;

   ASSERT(list!=NULL);
   ASSERT(board!=NULL);
   ASSERT(attack!=NULL);
   ASSERT(legal==true||legal==false);
   ASSERT(stop==true||stop==false);

   ASSERT(board_is_check(board));
   ASSERT(ATTACK_IN_CHECK(attack));

   // init

   LIST_CLEAR(list);

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

   opp_flag = COLOUR_FLAG(opp);

   king = KING_POS(board,me);

   for (inc_ptr = KingInc; (inc=*inc_ptr) != IncNone; inc_ptr++) {
      if (inc != -attack->di[0] && inc != -attack->di[1]) { // avoid escaping along a check line
         to = king + inc;
         piece = board->square[to];
         if (piece == Empty || FLAG_IS(piece,opp_flag)) {
            if (!legal || !is_attacked(board,to,opp)) {
               if (stop) return true;
               LIST_ADD(list,MOVE_MAKE(king,to));
            }
         }
      }
   }

   if (attack->dn >= 2) return false; // double check, we are done

   // single check

   ASSERT(attack->dn==1);

   // capture the checking piece

   if (add_pawn_captures(list,board,attack->ds[0],legal,stop) && stop) return true;
   if (add_piece_moves(list,board,attack->ds[0],legal,stop) && stop) return true;

   // interpose a piece

   inc = attack->di[0];

   if (inc != IncNone) { // line
      for (to = king+inc; to != attack->ds[0]; to += inc) {
         ASSERT(SQUARE_IS_OK(to));
         ASSERT(board->square[to]==Empty);
         if (add_pawn_moves(list,board,to,legal,stop) && stop) return true;
         if (add_piece_moves(list,board,to,legal,stop) && stop) return true;
      }
   }

   return false;
}
Example #9
0
static void add_quiet_checks(list_t * list, const board_t * board) {

    int me, opp;
    int king;
    const sq_t * ptr, * ptr_2;
    int from, to, sq;
    int piece;
    const inc_t * inc_ptr;
    int inc;
    int pawn;
    int rank;
    int pin[8+1];

    ASSERT(list!=NULL);
    ASSERT(board!=NULL);

    // init

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

    king = KING_POS(board,opp);

    find_pins(pin,board);

    // indirect checks

    for (ptr = pin; (from=*ptr) != SquareNone; ptr++) {

        piece = board->square[from];

        ASSERT(is_pinned(board,from,opp));

        if (PIECE_IS_PAWN(piece)) {

            inc = PAWN_MOVE_INC(me);
            rank = PAWN_RANK(from,me);

            if (rank != Rank7) { // promotes are generated with captures
                to = from + inc;
                if (board->square[to] == Empty) {
                    if (DELTA_INC_LINE(to-king) != DELTA_INC_LINE(from-king)) {
                        ASSERT(!SQUARE_IS_PROMOTE(to));
                        LIST_ADD(list,MOVE_MAKE(from,to));
                        if (rank == Rank2) {
                            to = from + (2*inc);
                            if (board->square[to] == Empty) {
                                ASSERT(DELTA_INC_LINE(to-king)!=DELTA_INC_LINE(from-king));
                                ASSERT(!SQUARE_IS_PROMOTE(to));
                                LIST_ADD(list,MOVE_MAKE(from,to));
                            }
                        }
                    }
                }
            }

        } else if (PIECE_IS_SLIDER(piece)) {

            for (inc_ptr = PIECE_INC(piece); (inc=*inc_ptr) != IncNone; inc_ptr++) {
                for (to = from+inc; board->square[to] == Empty; to += inc) {
                    ASSERT(DELTA_INC_LINE(to-king)!=DELTA_INC_LINE(from-king));
                    LIST_ADD(list,MOVE_MAKE(from,to));
                }
            }

        } else {

            for (inc_ptr = PIECE_INC(piece); (inc=*inc_ptr) != IncNone; inc_ptr++) {
                to = from + inc;
                if (board->square[to] == Empty) {
                    if (DELTA_INC_LINE(to-king) != DELTA_INC_LINE(from-king)) {
                        LIST_ADD(list,MOVE_MAKE(from,to));
                    }
                }
            }
        }
    }

    // piece direct checks

    for (ptr = &board->piece[me][1]; (from=*ptr) != SquareNone; ptr++) { // HACK: no king

        for (ptr_2 = pin; (sq=*ptr_2) != SquareNone; ptr_2++) {
            if (sq == from) goto next_piece;
        }

        ASSERT(!is_pinned(board,from,opp));

        piece = board->square[from];
        inc_ptr = PIECE_INC(piece);

        if (PIECE_IS_SLIDER(piece)) {

            for (; (inc=*inc_ptr) != IncNone; inc_ptr++) {
                for (to = from+inc; board->square[to] == Empty; to += inc) {
                    if (PIECE_ATTACK(board,piece,to,king)) {
                        LIST_ADD(list,MOVE_MAKE(from,to));
                    }
                }
            }

        } else {

            for (; (inc=*inc_ptr) != IncNone; inc_ptr++) {
                to = from + inc;
                if (board->square[to] == Empty) {
                    if (PSEUDO_ATTACK(piece,king-to)) {
                        LIST_ADD(list,MOVE_MAKE(from,to));
                    }
                }
            }
        }

next_piece:
        ;
    }

    // pawn direct checks

    inc = PAWN_MOVE_INC(me);
    pawn = PAWN_MAKE(me);

    to = king - (inc-1);
    ASSERT(PSEUDO_ATTACK(pawn,king-to));

    from = to - inc;
    if (board->square[from] == pawn) {
        if (board->square[to] == Empty) {
            ASSERT(!SQUARE_IS_PROMOTE(to));
            LIST_ADD(list,MOVE_MAKE(from,to));
        }
    } else {
        from = to - (2*inc);
        if (board->square[from] == pawn) {
            if (PAWN_RANK(from,me) == Rank2
                    && board->square[to] == Empty
                    && board->square[from+inc] == Empty) {
                ASSERT(!SQUARE_IS_PROMOTE(to));
                LIST_ADD(list,MOVE_MAKE(from,to));
            }
        }
    }

    to = king - (inc+1);
    ASSERT(PSEUDO_ATTACK(pawn,king-to));

    from = to - inc;
    if (board->square[from] == pawn) {
        if (board->square[to] == Empty) {
            ASSERT(!SQUARE_IS_PROMOTE(to));
            LIST_ADD(list,MOVE_MAKE(from,to));
        }
    } else {
        from = to - (2*inc);
        if (board->square[from] == pawn) {
            if (PAWN_RANK(from,me) == Rank2
                    && board->square[to] == Empty
                    && board->square[from+inc] == Empty) {
                ASSERT(!SQUARE_IS_PROMOTE(to));
                LIST_ADD(list,MOVE_MAKE(from,to));
            }
        }
    }
}
Example #10
0
       bool capture_is_good(int move, const board_t * board, bool in_pv) {
#else
static bool capture_is_good(int move, const board_t * board, bool in_pv) {
#endif

   int piece, capture;
   int see_value; // WHM 11/22/08

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

   ASSERT(move_is_tactical(move,board));

   // special cases

   if (MOVE_IS_EN_PASSANT(move)) return true;
   if (move_is_under_promote(move)) return false; // REMOVE ME?  Keep, looks good to me.  WHM;
// if (MOVE_IS_PROMOTE(move)) return true; // WHM; promote-to-queen, measures a little weaker
//                                                 too many garbage lines going nuts.
   
   // captures and queen promotes
   capture = board->square[MOVE_TO(move)];
   piece = board->square[MOVE_FROM(move)];

   if (capture != Empty) {

      // capture

      ASSERT(move_is_capture(move,board));

      if (MOVE_IS_PROMOTE(move)) return true; // capture a piece on Rank8 and promote to queen
      
      if (VALUE_PIECE(capture) >= VALUE_PIECE(piece)) return true;
   }


// return see_move(move,board) >= 0; WHM 11/22/08

// WHM 11/22/08 START

   see_value = see_move(move,board);
   if (see_value >= 0) return true;

   if (TryNodePVQueenPromotes) {
      if (in_pv && MOVE_IS_PROMOTE(move)) {
          ASSERT(!move_is_under_promote(move));
          return true; // WHM:
      }
   }
   
   if (TryKingAttackSacs || TryKingBoxSacs || TryPasserSacs) {
      if (in_pv  &&  see_value > -ValueBishop  &&  capture != Empty) {
         ASSERT(COLOUR_IS(capture,COLOUR_OPP(board->turn)));
         // king attack sacs.  
         if (TryKingAttackSacs) {
            if (narrow_piece_attack_king(board, piece, MOVE_TO(move), KING_POS(board,COLOUR_OPP(board->turn)))) {
               return true;
            }
         }
         // sacrifice attacks around the narrow/close king box can be examined more fully.  Rybka lessons.  
         if (TryKingBoxSacs) {
            if (DISTANCE(MOVE_TO(move),KING_POS(board,COLOUR_OPP(board->turn))) <= 1) {
               return true;
            }
         }
         // passer sacrifices...
         if (TryPasserSacs) {
            if (PIECE_IS_PAWN(capture) && PAWN_RANK(MOVE_TO(move),COLOUR_OPP(board->turn)) >= Rank6) {
               return true;
            }
         }
      }
   } // WHM 11/22/08 END
   
   
   return false;
}
Example #11
0
bool recog_draw(const board_t * board, int ThreadId) {

   material_info_t mat_info[1];

   ASSERT(board!=NULL);

   // material

   if (board->piece_nb > 4) return false;

   material_get_info(mat_info,board,ThreadId);

   if ((mat_info->flags & DrawNodeFlag) == 0) return false;

   // recognisers

   if (false) {

   } else if (mat_info->recog == MAT_KK) {

      // KK

      return true;

   } else if (mat_info->recog == MAT_KBK) {

      // KBK (white)

      return true;

   } else if (mat_info->recog == MAT_KKB) {

      // KBK (black)

      return true;

   } else if (mat_info->recog == MAT_KNK) {

      // KNK (white)

      return true;

   } else if (mat_info->recog == MAT_KKN) {

      // KNK (black)

      return true;

   } else if (mat_info->recog == MAT_KPK) {

      // KPK (white)

      int me, opp;
      int wp, wk, bk;

      me = White;
      opp = COLOUR_OPP(me);

      wp = board->pawn[me][0];
      wk = KING_POS(board,me);
      bk = KING_POS(board,opp);

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wk = SQUARE_FILE_MIRROR(wk);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kpk_draw(wp,wk,bk,board->turn)) {
         return true;
      }

   } else if (mat_info->recog == MAT_KKP) {

      // KPK (black)

      int me, opp;
      int wp, wk, bk;

      me = Black;
      opp = COLOUR_OPP(me);

      wp = SQUARE_RANK_MIRROR(board->pawn[me][0]);
      wk = SQUARE_RANK_MIRROR(KING_POS(board,me));
      bk = SQUARE_RANK_MIRROR(KING_POS(board,opp));

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wk = SQUARE_FILE_MIRROR(wk);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kpk_draw(wp,wk,bk,COLOUR_OPP(board->turn))) {
         return true;
      }

   } else if (mat_info->recog == MAT_KBKB) {

      // KBKB

      int wb, bb;

      wb = board->piece[White][1];
      bb = board->piece[Black][1];

      if (SQUARE_COLOUR(wb) == SQUARE_COLOUR(bb)) { // bishops on same colour
         return true;
      }

   } else if (mat_info->recog == MAT_KBPK) {

      // KBPK (white)

      int me, opp;
      int wp, wb, bk;

      me = White;
      opp = COLOUR_OPP(me);

      wp = board->pawn[me][0];
      wb = board->piece[me][1];
      bk = KING_POS(board,opp);

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wb = SQUARE_FILE_MIRROR(wb);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kbpk_draw(wp,wb,bk)) return true;

   } else if (mat_info->recog == MAT_KKBP) {

      // KBPK (black)

      int me, opp;
      int wp, wb, bk;

      me = Black;
      opp = COLOUR_OPP(me);

      wp = SQUARE_RANK_MIRROR(board->pawn[me][0]);
      wb = SQUARE_RANK_MIRROR(board->piece[me][1]);
      bk = SQUARE_RANK_MIRROR(KING_POS(board,opp));

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wb = SQUARE_FILE_MIRROR(wb);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kbpk_draw(wp,wb,bk)) return true;

   } else {

      ASSERT(false);
   }

   return false;
}
Example #12
0
void attack_set(attack_t * attack, const board_t * board) {

   int me, opp;
   const sq_t * ptr;
   int from, to;
   int inc;
   int pawn;
   int delta, piece;
   int sq;

   ASSERT(attack!=NULL);
   ASSERT(board!=NULL);

   // init

   attack->dn = 0;

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

   to = KING_POS(board,me);

   // pawn attacks

   inc = PAWN_MOVE_INC(opp);
   pawn = PAWN_MAKE(opp);

   from = to - (inc-1);
   if (board->square[from] == pawn) {
      attack->ds[attack->dn] = from;
      attack->di[attack->dn] = IncNone;
      attack->dn++;
   }

   from = to - (inc+1);
   if (board->square[from] == pawn) {
      attack->ds[attack->dn] = from;
      attack->di[attack->dn] = IncNone;
      attack->dn++;
   }

   // piece attacks

   for (ptr = &board->piece[opp][1]; (from=*ptr) != SquareNone; ptr++) { // HACK: no king

      piece = board->square[from];

      delta = to - from;
      ASSERT(delta_is_ok(delta));

      if (PSEUDO_ATTACK(piece,delta)) {

         inc = IncNone;

         if (PIECE_IS_SLIDER(piece)) {

            // check for blockers

            inc = DELTA_INC_LINE(delta);
            ASSERT(inc!=IncNone);

            sq = from;
            do sq += inc; while (board->square[sq] == Empty);

            if (sq != to) continue; // blocker => next attacker
         }

         attack->ds[attack->dn] = from;
         attack->di[attack->dn] = -inc; // HACK
         attack->dn++;
      }
   }

   attack->ds[attack->dn] = SquareNone;
   attack->di[attack->dn] = IncNone;

   // debug

   ASSERT(attack_is_ok(attack));
}
Example #13
0
bool egbb_probe(const board_t * board, int * value) {

   int i;
   int sq;
   int piece;
   int colour, me;
   const sq_t * ptr;
   int counter;
   int white_king, black_king;
   int piece_list[4], square_list[4];

   ASSERT(board!=NULL);
   ASSERT(value!=NULL);

   ASSERT(board_is_ok(board));
   ASSERT(!board_is_check(board));

   // init

   if (Egbb->init == 0) return false;
   if (Egbb->load == 0) return false;

   ASSERT(board->piece_nb<=Egbb->piece_nb);

   // init

   for (i = 0; i < 4; i++) {
      piece_list[i] = 0;
      square_list[i] = 0;
   }

   Egbb->read_nb++;

   // king

   white_king = SQUARE_TO_64(KING_POS(board,White));
   black_king = SQUARE_TO_64(KING_POS(board,Black));

   counter = 0;

   for (colour = 0; colour < ColourNb; colour++) {

      me = colour;

      // pieces

      for (ptr = &board->piece[me][1]; (sq=*ptr) != SquareNone; ptr++) { // HACK: no king

         piece = board->square[sq];

         // index

         ASSERT(counter>=0&&counter<4);

         piece_list[counter] = TbPiece[PIECE_TO_12(piece)];
         square_list[counter] = SQUARE_TO_64(sq);

         counter++;
      }

      // pawns

      for (ptr = &board->pawn[me][0]; (sq=*ptr) != SquareNone; ptr++) {

         piece = board->square[sq];

         // index

         ASSERT(counter>=0&&counter<4);

         piece_list[counter] = TbPiece[PIECE_TO_12(piece)];
         square_list[counter] = SQUARE_TO_64(sq);

         counter++;
      }
   }

   // probe

   *value = probe_egbb_ptr(board->turn,white_king,black_king,piece_list[0],square_list[0],piece_list[1],square_list[1],piece_list[2],square_list[2]);

   // score

   if (*value != ValueError) {
      Egbb->read_hit++;
      ASSERT(!value_is_mate(*value));
      return true;
   }

   return false;
}