static boolean is_not_pawn_make_to_base_line(numecoup n) { square const sq_departure = move_generation_stack[n].departure; square const sq_arrival = move_generation_stack[n].arrival; boolean result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); result = !(is_pawn(get_walk_of_piece_on_square(sq_departure)) && ((trait[nbply]==White && sq_arrival<=square_h1) || (trait[nbply]==Black && sq_arrival>=square_a8))); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
char get_chesspiece(char p) { if (is_king(p)) return KING; if (is_queen(p)) return QUEEN; if (is_rook(p)) return ROOK; if (is_bishop(p)) return BISHOP; if (is_knight(p)) return KNIGHT; if (is_pawn(p)) return PAWN; return ERROR; }
void print_chesspiece(char p, FILE * f) { char output, black; output = '?'; if (is_black(p)) black = 1; else black = 0; if (is_king(p)) output = 'K'; if (is_queen(p)) output = 'Q'; if (is_rook(p)) output = 'R'; if (is_bishop(p)) output = 'B'; if (is_knight(p)) output = 'N'; if (is_pawn(p)) output = 'P'; if (black) output += 'a' - 'A'; if (is_free(p)) output = ' '; fprintf(f, "%c", output); }
// Decodes a string in long algebraic notation and returns a move. If the // notation is not recognized the move is returned as (Move)0. //------------------------------------------------------------------------------ Move new_move_from_string(Position *self, char *e2e4) { bool queen_side_castle = !strcmp(e2e4, "0-0-0"); bool king_side_castle = !strcmp(e2e4, "0-0") && !queen_side_castle; if (king_side_castle || queen_side_castle) { bool king_side_ok = false, queen_side_ok = false; can_castle(self, self->color, &king_side_ok, &queen_side_ok); if (king_side_castle && king_side_ok) { int from = self->king[self->color]; int to = G1 + self->color * A8; return validate(self, new_castle(self, from, to)); } if (queen_side_castle && queen_side_ok) { int from = self->king[self->color]; int to = C1 + self->color * A8; return validate(self, new_castle(self, from, to)); } return (Move)0; } char notation[strlen(e2e4)]; char *src = e2e4, *dst = notation; // Strip all optional characters. while (*src) { if (strchr("KkQqRrBbNn12345678acdefgh", *src)) { *dst++ = *src; } src++; } *dst = '\0'; if (strlen(notation) >= 4 && strlen(notation) <= 5) { // Validate optional piece character to make sure the actual piece it // represents is there. Piece piece = pawn(self->color); switch (notation[0]) { case 'K': piece = king(self->color); break; case 'Q': piece = queen(self->color); break; case 'R': piece = rook(self->color); break; case 'B': piece = bishop(self->color); break; case 'N': piece = knight(self->color); } int sq; if (is_pawn(piece)) { sq = square(notation[1] - '1', notation[0] - 'a'); } else { sq = square(notation[2] - '1', notation[1] - 'a'); } if (sq >= A1 && sq <= H8) { if (self->pieces[sq] == piece) { return validate(self, new_move_from_notation(self, is_pawn(piece) ? notation : notation + 1)); } } } return (Move)0; }
// ------------------------------------------------------------------- // Piece movement: // - this function must be passed a *VALID* move (e.g. one that has // been verified by can_move()) // - promotion piece will be automatically cast to correct colour // ------------------------------------------------------------------- game_status ChessBoard::do_move(int from, int to, piece_type promotion) { // Disable castling if rook is captured or moved for (int *sq=&to;sq;sq=sq==&to?&from:(int *)NULL) switch (*sq) { case a1: w_castle_q=false; break; case a8: b_castle_q=false; break; case h1: w_castle_k=false; break; case h8: b_castle_k=false; } // Reset castled flags b_castled=w_castled=false; // Mark en-passant square, if any if (square[from]==w_Pawn && to==from+2*Rank) en_passant=from+Rank; else if (square[from]==b_Pawn && to==from-2*Rank) en_passant=from-Rank; else en_passant=No_square; // Perform actual rearrangement of board pieces bool increment_fifty=true; if (w_castle_k && from==e1 && to==g1) { square[g1]=w_King; // White castles kingside square[f1]=w_Rook; square[e1]=square[h1]=Empty; w_castled=true; } else if (w_castle_q && from==e1 && to==c1) { square[c1]=w_King; // White castles queenside square[d1]=w_Rook; square[e1]=square[a1]=Empty; w_castled=true; } else if (b_castle_k && from==e8 && to==g8) { square[g8]=b_King; // Black castles kingside square[f8]=b_Rook; square[e8]=square[h8]=Empty; b_castled=true; } else if (b_castle_q && from==e8 && to==c8) { square[c8]=b_King; // Black castles queenside square[d8]=b_Rook; square[e8]=square[a8]=Empty; b_castled=true; } else if (square[from]==w_Pawn && square[to]==Empty && to!=from+Rank) { square[to]=w_Pawn; // White captures en-passant square[from]=square[to-Rank]=Empty; increment_fifty=false; } else if (square[from]==b_Pawn && square[to]==Empty && to!=from-Rank) { square[to]=b_Pawn; // Black captures en-passant square[from]=square[to+Rank]=Empty; increment_fifty=false; } else { // Normal move if (square[to]!=Empty || is_pawn(square[from])) increment_fifty=false; promotion=make_colour(promotion, w_turn); square[to]=(promotion!=Empty)?promotion:square[from]; square[from]=Empty; } // Disable castling if king was moved if (square[e1]!=w_King) w_castle_q=w_castle_k=false; if (square[e8]!=b_King) b_castle_q=b_castle_k=false; // Update king position if (square[to]==w_King) w_king_pos=to; else if (square[to]==b_King) b_king_pos=to; // Adjust 50-move rule counter fifty=increment_fifty?fifty+1:0; // Set check flag if (w_turn) { w_check=is_attacked(!w_turn, w_king_pos); b_check=is_attacked(w_turn, b_king_pos); } else { b_check=is_attacked(!w_turn, b_king_pos); w_check=is_attacked(w_turn, w_king_pos); } // Change active player w_turn=!w_turn; // Check for checkmate/stalemate move_list moves; for (int i=a1;i<=h8;i++) { if (is_colour(square[i], w_turn)) { switch (make_neutral(square[i])) { case King: moves=mobility_king(i); break; case Pawn: moves=mobility_pawn(i); break; case Knight: moves=mobility_knight(i); break; case Bishop: moves=mobility_bishop(i); break; case Rook: moves=mobility_rook(i); break; case Queen: moves=mobility_queen(i); break; } if (!moves.empty()) break; } } // Update log of board configurations boardlog.append(*this); // Set game status if (triple_occurrence()) { status=TripleOccurrence; in_progress=false; } else if (moves.empty() && is_in_check(w_turn)) { status=Checkmate; in_progress=false; } else if (moves.empty()) { status=Stalemate; in_progress=false; } else if (fifty>=99) { status=FiftyMoves; in_progress=false; } else if (is_in_check(w_turn)) status=Check; else status=Normal; return status; }