diff --git a/Board.cpp b/Board.cpp index 77cbd8e..933dfcc 100644 --- a/Board.cpp +++ b/Board.cpp @@ -30,12 +30,19 @@ */ Board::Board() { + boardGrid.resize(8); + for(int i = 0; i < 8; i++) + boardGrid[i].resize(8); +} + +Board::~Board() { +} + +void Board::setupInitialPosition() { // set up the board grid with smart pointers // initialize each square with a Piece playerTurn = PL_WHITE; - boardGrid.resize(8); for(int i = 0; i < 8; i++) { - boardGrid[i].resize(8); switch(i) { case 0: // white back rank @@ -57,7 +64,9 @@ Board::Board() { case 3: case 4: case 5: - continue; + for(int j = 0; j <= 8; j++) + boardGrid[i][j] = nullptr; + break; case 6: // black pawn rank for(int j = 0; j <= 8; j++) @@ -77,27 +86,105 @@ Board::Board() { break; } } -} - -Board::~Board() { -} - -void Board::setupInitialPosition() { return; } int setupFromFEN(std::string strFEN) { - std::string field1, field2, field3, field4, field5, field6; std::vector splitFEN = split(strFEN, ' '); - if(splitFEN.size() != 6) { // a valid FEN *must* contain 6 fields + if(splitFEN.size() != 6) // a valid FEN *must* contain 6 fields return -1; + std::vector splitField1 = split(splitFEN[0], '/'); + int rank = 0, file = 0; + int skip = 0; + bool wKingPlaced = false, bKingPlaced = false; + for(auto &ranks : splitField1) { + for(auto &sym : ranks) { + if(skip) { + boardGrid[rank][file] = nullptr; // remove reference + skip--; + file++; + continue; + } + switch(sym) { + case 'R': + // white rook + boardGrid[rank][file] = std::make_unique(PIECE_WHITE); + break; + case 'r': + // black rook + boardGrid[rank][file] = std::make_unique(PIECE_BLACK); + break; + case 'N': + // white knight + boardGrid[rank][file] = std::make_unique(PIECE_WHITE); + break; + case 'n': + // black knight + boardGrid[rank][file] = std::make_unique(PIECE_BLACK); + break; + case 'B': + // white bishop + boardGrid[rank][file] = std::make_unique(PIECE_WHITE); + break; + case 'b': + // black bishop + boardGrid[rank][file] = std::make_unique(PIECE_BLACK); + break; + case 'Q': + // white queen + boardGrid[rank][file] = std::make_unique(PIECE_WHITE); + break; + case 'q': + // black queen; + boardGrid[rank][file] = std::make_unique(PIECE_BLACK); + break; + case 'K': + // white king + if(wKingPlaced) { + // invalid FEN, more than 1 white king + return -1; + } else { + boardGrid[rank][file] = std::make_unique(PIECE_WHITE); + wKingPlaced = true; + } + break; + case 'k': + // black king + if(bKingPlaced) { + // invalid FEN, more than 1 black king + return -1; + } else { + boardGrid[rank][file] = std::make_unique(PIECE_BLACK); + bKingPlaced = true; + } + break; + case 'P': + // white pawn + boardGrid[rank][file] = std::make_unique(PIECE_WHITE); + break; + case 'p': + // black pawn + boardGrid[rank][file] = std::make_unique(PIECE_BLACK); + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + skip = atoi(sym); + break; + default: + // invalid character? + return -1; + } + file++; + } + rank++; } - field1 = splitFEN[0]; - field2 = splitFEN[1]; - field3 = splitFEN[2]; - field4 = splitFEN[3]; - field5 = splitFEN[4]; - field6 = splitFEN[5]; return 0; } diff --git a/Piece.cpp b/Piece.cpp index 251e5e9..95ab9f3 100644 --- a/Piece.cpp +++ b/Piece.cpp @@ -22,6 +22,28 @@ std::vector Piece::getLegalMoves(const Square &from, const Board &board) c std::vector moveList; return moveList; } +bool King::checkForCheck() const { + std::vector> kingVulnerable = { + {-1, 0}, // Up + {-1, -1}, // up-left + {-1, 1}, // up-right + {1, 0}, // Down + {1, -1}, // down-left + {1, 1}, // down-right + {0, -1}, // Left + {0, 1}, // Right + {-1, -2}, // 1 + {-1, 2}, // 2 + {-2, -1}, // 3 + {-2, 1}, // 4 + {1, -2}, // 5 + {1, 2}, // 6 + {2, -1}, // 7 + {2, 1} // 8 + }; + // locate our King + return inCheck; +} std::vector King::getLegalMoves(const Square &from, const Board &board) const { std::vector moveList; @@ -97,18 +119,20 @@ std::vector King::getLegalMoves(const Square &from, const Board &board) co if(target && (target->getColour() != this->getColour())) { // is it occupied & an enemy? if((target->getPieceType() == QUEEN || target->getPieceType() == BISHOP) && diagonal) { // we are being attacked diagonally on this square, so remove it - moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE; - } - else if(target->getPieceType() == KNIGHT && knight) { + moves.to.rank = INVALID_RANK; + moves.to.file = INVALID_FILE; + } else if(target->getPieceType() == KNIGHT && knight) { // we are being attacked by a knight, so remove it - moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE; - } - else if(target->getPieceType() == ROOK || target->getPieceType() == QUEEN && (!diagonal && !knight)) { + moves.to.rank = INVALID_RANK; + moves.to.file = INVALID_FILE; + } else if(target->getPieceType() == ROOK || target->getPieceType() == QUEEN && (!diagonal && !knight)) { // again, being attacked, remove it - moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE; + moves.to.rank = INVALID_RANK; + moves.to.file = INVALID_FILE; } if(target->getPieceType() == PAWN && (abs(r - startSquare.rank) == 1 && abs(f - startSquare.file) == 1)) { - moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE; + moves.to.rank = INVALID_RANK; + moves.to.file = INVALID_FILE; } } if(target && (target->getColour() == this->getColour())) { @@ -125,10 +149,10 @@ std::vector King::getLegalMoves(const Square &from, const Board &board) co } // will this actually work? moveList.erase( - std::remove_if(moveList.begin(), moveList.end(), - [&](const auto &x) { - return !x.to.isValid(); - })); + std::remove_if(moveList.begin(), moveList.end(), + [&](const auto & x) { + return !x.to.isValid(); + })); return moveList; } diff --git a/Piece.hpp b/Piece.hpp index 7f24412..b2cd0cb 100644 --- a/Piece.hpp +++ b/Piece.hpp @@ -92,6 +92,7 @@ class Piece { }; class King : public Piece { + private: friend class Board; public: @@ -102,18 +103,17 @@ class King : public Piece { } virtual std::vector getLegalMoves(const Square &from, const Board &board) const override; - bool checkForCheck() const { - return inCheck; - } + bool checkForCheck() const; bool checkForCastle(enum CastleSide side) const { - if(side == KINGSIDE) { + if(side == KINGSIDE) return canCastleKS; - } else if(side == QUEENSIDE) { + + else if(side == QUEENSIDE) return canCastleQS; - } else { + + else return false; - } } protected: bool canCastleQS = true; diff --git a/main.cpp b/main.cpp index 616443f..ee3b5e1 100644 --- a/main.cpp +++ b/main.cpp @@ -114,7 +114,7 @@ uint8_t initSystem(void) { SDI1R = 0b0100; // RB8 RPA0R = 0b0001; // U1TX SYSKEY = 0x12345678; // lock SYSKEY - ANSELBCLR = 0xFFFF; // port A all digital + ANSELBCLR = 0xFFFF; // port B all digital SL_TRIS = 0; // RA0 as output SL_LAT = 1; // set high /* Set up SPI1 */ diff --git a/strFuncs.cpp b/strFuncs.cpp index 9e09da6..a4a2da3 100644 --- a/strFuncs.cpp +++ b/strFuncs.cpp @@ -4,9 +4,8 @@ template void split(const std::string &s, char delim, Out result) { std::istringstream iss(s); std::string item; - while (std::getline(iss, item, delim)) { + while(std::getline(iss, item, delim)) *result++ = item; - } } std::vector split(const std::string &s, char delim) {