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; }
static void add_quiet_moves(list_t * list, const board_t * board) { int me; const sq_t * ptr; int from, to; int piece; ASSERT(list!=NULL); ASSERT(board!=NULL); me = board->turn; // piece moves for (ptr = &board->piece[me][0]; (from=*ptr) != SquareNone; ptr++) { piece = board->square[from]; switch (PIECE_TYPE(piece)) { case Knight64: to = from - 33; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 31; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 18; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 14; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 14; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 18; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 31; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 33; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); break; case Bishop64: for (to = from-17; board->square[to] == Empty; to -= 17) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from-15; board->square[to] == Empty; to -= 15) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+15; board->square[to] == Empty; to += 15) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+17; board->square[to] == Empty; to += 17) { LIST_ADD(list,MOVE_MAKE(from,to)); } break; case Rook64: for (to = from-16; board->square[to] == Empty; to -= 16) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from-1; board->square[to] == Empty; to -= 1) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+1; board->square[to] == Empty; to += 1) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+16; board->square[to] == Empty; to += 16) { LIST_ADD(list,MOVE_MAKE(from,to)); } break; case Queen64: for (to = from-17; board->square[to] == Empty; to -= 17) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from-16; board->square[to] == Empty; to -= 16) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from-15; board->square[to] == Empty; to -= 15) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from-1; board->square[to] == Empty; to -= 1) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+1; board->square[to] == Empty; to += 1) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+15; board->square[to] == Empty; to += 15) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+16; board->square[to] == Empty; to += 16) { LIST_ADD(list,MOVE_MAKE(from,to)); } for (to = from+17; board->square[to] == Empty; to += 17) { LIST_ADD(list,MOVE_MAKE(from,to)); } break; case King64: to = from - 17; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 16; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 15; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 1; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 1; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 15; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 16; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 17; if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to)); break; default: ASSERT(false); break; } } // pawn moves if (COLOUR_IS_WHITE(me)) { for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) { // non promotes if (SQUARE_RANK(from) != Rank7) { to = from + 16; if (board->square[to] == Empty) { ASSERT(!SQUARE_IS_PROMOTE(to)); LIST_ADD(list,MOVE_MAKE(from,to)); if (SQUARE_RANK(from) == Rank2) { to = from + 32; if (board->square[to] == Empty) { ASSERT(!SQUARE_IS_PROMOTE(to)); LIST_ADD(list,MOVE_MAKE(from,to)); } } } } } } else { // black for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) { // non promotes if (SQUARE_RANK(from) != Rank2) { to = from - 16; if (board->square[to] == Empty) { ASSERT(!SQUARE_IS_PROMOTE(to)); LIST_ADD(list,MOVE_MAKE(from,to)); if (SQUARE_RANK(from) == Rank7) { to = from - 32; if (board->square[to] == Empty) { ASSERT(!SQUARE_IS_PROMOTE(to)); LIST_ADD(list,MOVE_MAKE(from,to)); } } } } } } }
static void add_captures(list_t * list, const board_t * board) { int me, opp; int opp_flag; const sq_t * ptr; int from, to; int piece, capture; ASSERT(list!=NULL); ASSERT(board!=NULL); me = board->turn; opp = COLOUR_OPP(me); opp_flag = COLOUR_FLAG(opp); // piece captures for (ptr = &board->piece[me][0]; (from=*ptr) != SquareNone; ptr++) { piece = board->square[from]; switch (PIECE_TYPE(piece)) { case Knight64: to = from - 33; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 31; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 18; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 14; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 14; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 18; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 31; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 33; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); break; case Bishop64: for (to = from-17; (capture=board->square[to]) == Empty; to -= 17) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from-15; (capture=board->square[to]) == Empty; to -= 15) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+15; (capture=board->square[to]) == Empty; to += 15) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+17; (capture=board->square[to]) == Empty; to += 17) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); break; case Rook64: for (to = from-16; (capture=board->square[to]) == Empty; to -= 16) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from-1; (capture=board->square[to]) == Empty; to -= 1) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+1; (capture=board->square[to]) == Empty; to += 1) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+16; (capture=board->square[to]) == Empty; to += 16) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); break; case Queen64: for (to = from-17; (capture=board->square[to]) == Empty; to -= 17) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from-16; (capture=board->square[to]) == Empty; to -= 16) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from-15; (capture=board->square[to]) == Empty; to -= 15) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from-1; (capture=board->square[to]) == Empty; to -= 1) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+1; (capture=board->square[to]) == Empty; to += 1) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+15; (capture=board->square[to]) == Empty; to += 15) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+16; (capture=board->square[to]) == Empty; to += 16) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); for (to = from+17; (capture=board->square[to]) == Empty; to += 17) ; if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); break; case King64: to = from - 17; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 16; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 15; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from - 1; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 1; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 15; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 16; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); to = from + 17; if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to)); break; default: ASSERT(false); break; } } // pawn captures if (COLOUR_IS_WHITE(me)) { for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) { to = from + 15; if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to); to = from + 17; if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to); // promote if (SQUARE_RANK(from) == Rank7) { to = from + 16; if (board->square[to] == Empty) { add_promote(list,MOVE_MAKE(from,to)); } } } } else { // black for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) { to = from - 17; if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to); to = from - 15; if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to); // promote if (SQUARE_RANK(from) == Rank2) { to = from - 16; if (board->square[to] == Empty) { add_promote(list,MOVE_MAKE(from,to)); } } } } }
bool move_is_pseudo( int move, board_t *board ) { int me, opp; int from, to; int piece, capture; ASSERT(move_is_ok(move)); ASSERT(board != NULL); // init me = board->turn; opp = COLOUR_OPP(board->turn); // from from = MOVE_FROM(move); ASSERT(SQUARE_IS_OK(from)); piece = board->square[from]; if(INDEX_TO_COLOUR(piece) != me) return false; // to to = MOVE_TO(move); ASSERT(SQUARE_IS_OK(to)); capture = board->square[to]; if( INDEX_TO_COLOUR(capture) == me ) return false; // move switch(INDEX_TO_PIECE(piece)) { case RedKing: if(KING_IN_CITY(to) && KLegalDt[to - from + 256]) return true; if(EQUAL_FILE(from, to) && INDEX_TO_PIECE(capture) == BlackKing) { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; if(FileCapMin[row][board->file[col]] + col == to) return true; } return false; case BlackKing: if(KING_IN_CITY(to) && KLegalDt[to - from + 256]) return true; if(EQUAL_FILE(from, to) && INDEX_TO_PIECE(capture) ==RedKing) { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; if(FileCapMax[row][board->file[col]] + col == to) return true; } return false; case RedAdvisor: case BlackAdvisor: if(ADVISOR_IN_CITY(to) && ALegalDt[to - from + 256]) return true; return false; case RedBishop: case BlackBishop: if(BISHOP_IN_CITY(to) && BLegalDt[to - from + 256] && board->square[(to + from) >> 1] == PieceNone)// return true; return false; case RedKnight: case BlackKnight: if(NLegalDt[to - from + 256] && board->square[from + NLegalDt[to - from + 256]] == PieceNone)// return true; return false; case RedRook: case BlackRook: if(capture) { if(EQUAL_FILE(from, to)) { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; if(FileCapMax[row][board->file[col]] + col == to || FileCapMin[row][board->file[col]] + col == to) return true; } else if(EQUAL_RANK(from, to)) { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; if(RankCapMax[col][board->rank[row]] + (row << 4) == to || RankCapMin[col][board->rank[row]] + (row << 4) == to) return true; } } else { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; int to_row = SQUARE_RANK(to) - 3; int to_col = SQUARE_FILE(to) - 3; int rowbit = board->rank[row]; int colbit = board->file[col]; if(EQUAL_FILE(from, to)) { //if(FileNonCapMin[row][board->file[col]] + col <= to && to <= FileNonCapMax[row][board->file[col]] + col) if(PinNb[row][to_row][colbit] == 0) return true; } else if(EQUAL_RANK(from, to)) { //if(RankNonCapMin[col][board->rank[row]] + (row << 4) <= to && to <= RankNonCapMax[col][board->rank[row]] + (row << 4)) if(PinNb[col][to_col][rowbit] == 0) return true; } } return false; case RedCannon: case BlackCannon: if(capture) { if(EQUAL_RANK(from, to)) { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; if(CannonRankCapMax[col][board->rank[row]] + (row << 4) == to || CannonRankCapMin[col][board->rank[row]] + (row << 4) == to) return true; } else if(EQUAL_FILE(from, to)) { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; if(CannonFileCapMax[row][board->file[col]] + col == to || CannonFileCapMin[row][board->file[col]] + col == to) return true; } } else { int row=SQUARE_RANK(from) - 3; int col=SQUARE_FILE(from) - 3; int to_row = SQUARE_RANK(to) - 3; int to_col = SQUARE_FILE(to) - 3; int rowbit = board->rank[row]; int colbit = board->file[col]; if(EQUAL_RANK(from, to)) { //if(RankNonCapMin[col][board->rank[row]] + (row << 4) <= to && to <= RankNonCapMax[col][board->rank[row]] + (row << 4)) if(PinNb[col][to_col][rowbit] == 0) return true; } else if(EQUAL_FILE(from, to)) { //if(FileNonCapMin[row][board->file[col]] + col <= to&& to <= FileNonCapMax[row][board->file[col]] + col) if(PinNb[row][to_row][colbit] == 0) return true; } } return false; case BlackPawn: if((from + 16) == to) return true; if(SQUARE_COLOUR(from) == Red) { if((from - 1) == to || (from + 1) == to) return true; } return false; case RedPawn: if((from - 16) == to) return true; if(SQUARE_COLOUR(from) == Black) { if((from - 1) == to || (from + 1) == to) return true; } default: return false; } return false; }
static bool kpk_draw(int wp, int wk, int bk, int turn) { int wp_file, wp_rank; int wk_file; int bk_file, bk_rank; ASSERT(SQUARE_IS_OK(wp)); ASSERT(SQUARE_IS_OK(wk)); ASSERT(SQUARE_IS_OK(bk)); ASSERT(COLOUR_IS_OK(turn)); ASSERT(SQUARE_FILE(wp)<=FileD); wp_file = SQUARE_FILE(wp); wp_rank = SQUARE_RANK(wp); wk_file = SQUARE_FILE(wk); bk_file = SQUARE_FILE(bk); bk_rank = SQUARE_RANK(bk); if (false) { } else if (bk == wp+16) { if (wp_rank <= Rank6) { return true; } else { ASSERT(wp_rank==Rank7); if (COLOUR_IS_WHITE(turn)) { if (wk == wp-15 || wk == wp-17) return true; } else { if (wk != wp-15 && wk != wp-17) return true; } } } else if (bk == wp+32) { if (wp_rank <= Rank5) { return true; } else { ASSERT(wp_rank==Rank6); if (COLOUR_IS_WHITE(turn)) { if (wk != wp-1 && wk != wp+1) return true; } else { return true; } } } else if (wk == wp-1 || wk == wp+1) { if (bk == wk+32 && COLOUR_IS_WHITE(turn)) { // opposition return true; } } else if (wk == wp+15 || wk == wp+16 || wk == wp+17) { if (wp_rank <= Rank4) { if (bk == wk+32 && COLOUR_IS_WHITE(turn)) { // opposition return true; } } } // rook pawn if (wp_file == FileA) { if (DISTANCE(bk,A8) <= 1) return true; if (wk_file == FileA) { if (wp_rank == Rank2) wp_rank++; // HACK if (bk_file == FileC && bk_rank > wp_rank) return true; } } return false; }