#include "ChessGame.h" #include #include using namespace chessy; ChessGame::ChessGame(void) { board.resetBoard(); } ChessGame::ChessGame(const std::string& fenString) { loadFromFen(fenString); } bool ChessGame::isValidMove(const Move& move) const { return false; } std::vector ChessGame::getValidMoves(void) const { std::vector ret; return ret; } void ChessGame::move(Move move) { board.move(move); if (turn == BLACK_SIDE) { moveCount++; } turn = turn == WHITE_SIDE ? BLACK_SIDE : WHITE_SIDE; } void ChessGame::loadFromFen(const std::string& fenString) { using namespace std; stringstream tokenizer (fenString); string board; string turn; string castling; string enPassant; string halfmoves; string moveCount; tokenizer >> board; tokenizer >> turn; tokenizer >> castling; tokenizer >> enPassant; tokenizer >> halfmoves; tokenizer >> moveCount; this->board.setBoard(board); this->enPassant = Index {enPassant}; if (turn == "w"s) this->turn = WHITE_SIDE; else if (turn == "b"s) this->turn = BLACK_SIDE; else throw runtime_error("invalid turn "s + turn); canCastleQueenSide[WHITE_SIDE] = false; canCastleKingSide[WHITE_SIDE] = false; canCastleQueenSide[BLACK_SIDE] = false; canCastleKingSide[BLACK_SIDE] = false; if (castling != "-") for (auto character : castling) { switch (character) { case 'k': canCastleKingSide[WHITE_SIDE] = true; break; case 'q': canCastleQueenSide[WHITE_SIDE] = true; break; case 'K': canCastleKingSide[BLACK_SIDE] = true; break; case 'Q': canCastleQueenSide[BLACK_SIDE] = true; break; default: throw runtime_error("invalid castling right: "s + character); } } if (enPassant == "-"s) { this->enPassant = -1; } else { if (enPassant.size() != 2 || (enPassant[1] != '3' && enPassant[1] != '6')) throw runtime_error("invalid en passant string: "s + enPassant); this->enPassant = Index{ enPassant }; } try { reversibleHalfMoves = stoi(halfmoves); } catch(...) { throw runtime_error("invalid number of halfmoves: "s + halfmoves); } try { this->moveCount = stoi(moveCount); } catch(...) { throw runtime_error("invalid number of moves: "s + halfmoves); } } std::string ChessGame::generateFen(void) const { using namespace std; string board = this->board.getFenBoard(); string turn = this->turn == WHITE_SIDE ? "w"s : "b"s; string castlingRights = (canCastleKingSide[BLACK_SIDE] ? "K"s : ""s) + (canCastleQueenSide[BLACK_SIDE] ? "Q"s : ""s) + (canCastleKingSide[WHITE_SIDE] ? "k"s : ""s) + (canCastleQueenSide[WHITE_SIDE] ? "q"s : ""s); if (castlingRights.empty()) castlingRights = "-"s; string enPassant; if (this->enPassant == -1) { enPassant = "-"s; } else { enPassant = this->enPassant.getName(); } string halfmoves = to_string(reversibleHalfMoves); string mCount = to_string(moveCount); return board + " " + turn + " " + castlingRights + " " + enPassant + " " + halfmoves + " " + mCount; } UndoInfo ChessGame::doMove(const MoveInfo& mi) { UndoInfo ui; ui.before = board; board.move(mi.move); turn = otherSide(turn); moveCount++; if(mi.movedPiece != PAWN && board.getAtPosition(mi.move.destination) != EMPTY) { reversibleHalfMoves++; ui.decrementReversibleHalfMoves = true; } return ui; } void ChessGame::undoMove(const UndoInfo& ui) { board = ui.before; turn = otherSide(turn); moveCount--; if (ui.decrementReversibleHalfMoves) reversibleHalfMoves--; }