bool ChessMove::IsValidMoveRook(const ChessBoard& board) const{
    if (endX==startX){
        int deltaY = 1;
        if (startY > endY){deltaY = -1;}
        for (int i = startY+deltaY; GetCondition(i, startY, endY); i+=deltaY)
            if (board.GetPiece(startX, i)) return false;
        return true;
    } else if (endY==startY){
        int deltaX = 1;
        if (startX > endX){deltaX = -1;}
        for (int i = startX+deltaX; GetCondition(i, startX, endX); i+=deltaX)
            if (board.GetPiece(i, startY)) return false;
        return true;
    }
    return false;
}
bool ChessMove::IsValidMovePawn(const ChessBoard& board) const{
    ChessPiece* pawn = board.GetPiece(startX, startY);
    ChessColor color = pawn->GetColor();
    int delta = GetDelta(color);
    int startingRow = GetStartingRow(color);
    ChessPiece* occupyingPiece = board.GetPiece(endX, endY);
    if (occupyingPiece){
        return abs(startX-endX)==1 && startY+delta==endY;
    } else if (endX==startX){
        if (startingRow==startY){
            return endY==startingRow+delta || (!board.GetPiece(endX, startingRow+delta) && endY==startingRow+delta*2);
        } else {
            return endY==startY+delta;
        }
    }
    return false;
}
bool ChessMove::IsValidCastleMove(const ChessBoard& board) const{
    ChessPiece* king = board.GetPiece(startX, startY);
    if (king->GetMoveCount() != 0) return false;
    if (abs(startX-endX) != 2 || startY != endY) return false;
    int x = 7;
    int delta = 1;
    if (startX > endX){
        x = 0;
        delta = -1;
    }
    ChessPiece* rook = board.GetPiece(x, startY);
    if (rook && rook->GetMoveCount() != 0) return false;
    ChessColor opposingColor = SwitchColor(king->GetColor());
    for (int i = startX; GetCondition(i, startX, x); i += delta){
        if ((board.GetPiece(i, startY) && i != startX)
          || board.UnderAttack(opposingColor,i,startY)) return false;
    }
    return true;
}
bool ChessMove::IsValidMoveBishop(const ChessBoard & board) const{
    int i = -1, j = -1;
    int deltaX = 1, deltaY = 1;
    if (endX < startX && endY > startY){deltaX = -1;}
    else if (endX > startX && endY < startY){deltaY = -1;}
    else if (endX < startX && endY < startY){deltaX = -1; deltaY = -1;}
    for (i = startX+deltaX, j = startY+deltaY; GetConditionBishop(i,j); i+=deltaX, j+=deltaY)
        if (board.GetPiece(i, j)) return false;
    return i==endX && j==endY;
}
bool ChessMove::IsValidMove(const ChessBoard& board) const{
    if (endX < 0 || endX > 7 || endY < 0 || endY > 7)
        return false;
    ChessPiece* startPiece = board.GetPiece(startX, startY);
    ChessPiece* occupyingPiece = board.GetPiece(endX, endY);
    ChessColor color = startPiece->GetColor();
    if (occupyingPiece && occupyingPiece->GetColor() == color)
        return false;
    switch (startPiece->GetRank()){
    case PAWN:
        return IsValidMovePawn(board) || IsValidEnPassantMove(board, GetDelta(color), GetStartingRow(color));
    case ROOK:
        return IsValidMoveRook(board);
    case KNIGHT:
        return IsValidMoveKnight();
    case BISHOP:
        return IsValidMoveBishop(board);
    case QUEEN:
        return IsValidMoveBishop(board) || IsValidMoveRook(board);
    case KING:
        return IsValidMoveKing() || IsValidCastleMove(board);
    }
    return false;
}
Beispiel #6
0
void PawnMove::SelectPossibleMove(ChessBoard & board, QPoint & pos, const int player)
{
    auto get_end_y = [player, pos, board] (const int step) -> int {
        int k = (player == PLAYER_ONE) ? 1 : -1;
        int end_y = pos.y() + k * step;

        if(end_y < 0) end_y = 0;
        if(end_y >= ChessBoard::MAX_ROWS) end_y = ChessBoard::MAX_ROWS - 1;

        return end_y;
    };

    int col = pos.x();
    int row = pos.y();

    int row1 = get_end_y(1);

    if(board.IsFreeCell(row1, col))
        board.SetSelectedCell(row1, col, true);

    int capture_col = col - 1;
    if( capture_col >= 0 ) {
        if(board.IsNotFreeAndNotMine(row1, capture_col, player))
            board.SetSelectedCell(row1, capture_col, true);
    }
    capture_col = col + 1;
    if( capture_col < ChessBoard::MAX_ROWS ) {
        if(board.IsNotFreeAndNotMine(row1, capture_col, player))
            board.SetSelectedCell(row1, capture_col, true);
    }

    int row2 = get_end_y(2);
    if(board.IsFreeCell(row2, col)) {
        if(board.GetPiece(row, col) == PiecesManager::PIECE_WHITE_PAWN) {
            if( row == 1 ) {
                board.SetSelectedCell(row2, col, true);
            }
        }
        else if( row == 6 ) {
            board.SetSelectedCell(row2, col, true);
        }
    }
}
bool ChessMove::IsValidEnPassantMove(const ChessBoard& board, int delta, int startingRow) const{
    if (startY != startingRow+delta*3 || abs(startX-endX) != 1 || startY+delta != endY) return false;
    if (board.GetPiece(endX, endY)) return false;
    ChessPiece* potentialPawn = board.GetPiece(endX, startY);
    return potentialPawn && potentialPawn->GetRank()==PAWN && potentialPawn->GetMoveCount()==1;
}
bool ChessMove::PutsInCheck(const ChessBoard& board) const{
    ChessBoard boardCopy(board);
    ChessPiece* pieceCopy(board.GetPiece(startX,startY));
    return (boardCopy.DoMove(*this))->InCheck(pieceCopy->GetColor());
}