From 016654da2f09f99ee959a2590be33afd419dae2a Mon Sep 17 00:00:00 2001 From: "A.M. Rowsell" Date: Wed, 6 Aug 2025 09:27:13 -0400 Subject: [PATCH] dev: added Pawn movement checks, working through legal move logic --- Piece.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- Piece.hpp | 24 ++++++++++++++++- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/Piece.cpp b/Piece.cpp index e13db3d..79c09e6 100644 --- a/Piece.cpp +++ b/Piece.cpp @@ -58,7 +58,7 @@ std::vector Rook::getLegalMoves(const Square &from, const Board &board) co if (!target) { moveList.push_back({from, targetSquare}); - } else if (target->getColour() != this->colour) { + } else if (target->getColour() != this->getColour()) { moveList.push_back({from, targetSquare}); break; @@ -94,6 +94,84 @@ std::vector Bishop::getLegalMoves(const Square &from, const Board &board) std::vector Pawn::getLegalMoves(const Square &from, const Board &board) const { std::vector moveList; + const int directions[2][4][2] = { + { // black + {-1, 0}, // Up + {-2, 0}, // 2up first move + {-1, 1}, // attack to right + {-1, -1} // attack to left + }, + { // white + {1, 0}, // down + {2, 0}, // 2down first move + {1, 1}, // attack to right + {1, -1} // attack to left + } + }; + + if (this->getColour() == PIECE_BLACK) { + // go through black options + for (auto &dir : directions[0]) { + int r = from.rank + dir[0]; + int f = from.file + dir[1]; + if (r >= 0 && r < 8 && f >= 0 && f < 8) { // no need for a while loop as we only have finite moves in limited directions + const auto& target = board.boardGrid[r][f]; + auto ra = static_cast (r); + auto fi = static_cast (f); + Square targetSquare = {ra, fi}; + + if (dir[0] == -2 && !this->checkIfMoved()) { + // then 2 is potentially legal + if (!target && !(board.boardGrid[r + 1][f])) // check both squares for pieces of any colour + moveList.push_back({from, targetSquare}); + else + break; + } else if (abs(dir[1]) == 1) { // attempted capture (diagonal) + if (target && target->getColour() != this->getColour()) { + // legal capture + moveList.push_back({from, targetSquare}); + } else { + break; + } + } else { // normal one square forward + if (!target) + moveList.push_back({from, targetSquare}); + } + // now check if we are on 8th rank, for promotion + } + } + } else if (this->getColour() == PIECE_WHITE) { + for (auto &dir : directions[1]) { + // go through white options + int r = from.rank + dir[0]; + int f = from.file + dir[1]; + if (r >= 0 && r < 8 && f >= 0 && f < 8) { // no need for a while loop as we only have finite moves in limited directions + const auto& target = board.boardGrid[r][f]; + auto ra = static_cast (r); + auto fi = static_cast (f); + Square targetSquare = {ra, fi}; + + if (dir[0] == 2 && !this->checkIfMoved()) { + // then 2 is potentially legal + if (!target && !(boardGrid[r - 1][f])) + moveList.push_back({from, targetSquare}); + else + break; + } else if (abs(dir[1]) == 1) { // attempted capture (diagonal) + if (target && target->getColour() != this->getColour()) { // can only move there if it's a capture + // legal capture + moveList.push_back({from, targetSquare}); + } else { + break; + } + } else { // normal one square forward + if (!target) + moveList.push_back({from, targetSquare}); + } + // now check if we are on 8th rank, for promotion + } + } + } return moveList; } \ No newline at end of file diff --git a/Piece.hpp b/Piece.hpp index fe093a7..7e3e9dc 100644 --- a/Piece.hpp +++ b/Piece.hpp @@ -48,12 +48,13 @@ struct Move { }; class Piece { -friend class Board; + friend class Board; protected: PieceColour colour; bool hasMoved = false; public: + Piece(PieceColour pColour) : colour(pColour) { } virtual ~Piece(); @@ -62,17 +63,34 @@ public: PieceColour getColour() const { return colour; } + + bool checkIfMoved() const { + return hasMoved; + } }; class King : public Piece { + friend class Board; public: King(PieceColour colour) : Piece(colour) { } virtual std::vector getLegalMoves(const Square &from, const Board &board) const override; + + bool checkForCheck() const { + return inCheck; + } + + bool checkForCastle() const { + return canCastle; + } +protected: + bool canCastle = true; + bool inCheck = false; }; class Rook : public Piece { + friend class Board; public: Rook(PieceColour colour) : Piece(colour) { @@ -81,6 +99,7 @@ public: }; class Queen : public Piece { + friend class Board; public: Queen(PieceColour colour) : Piece(colour) { @@ -89,6 +108,7 @@ public: }; class Knight : public Piece { + friend class Board; public: Knight(PieceColour colour) : Piece(colour) { @@ -97,6 +117,7 @@ public: }; class Bishop : public Piece { + friend class Board; public: Bishop(PieceColour colour) : Piece(colour) { @@ -105,6 +126,7 @@ public: }; class Pawn : public Piece { + friend class Board; public: Pawn(PieceColour colour) : Piece(colour) {