#include "board.hpp" #include #include #include #include #include #include char toChar(PieceType type) { switch (type) { case NONE: return '.'; case PAWN: return 'P'; case KNIGHT: return 'N'; case BISHOP: return 'B'; case ROOK: return 'R'; case QUEEN: return 'Q'; case KING: return 'K'; default: std::cout << "\n" << type << "\n"; assert(false && "Unknown piece" && type); return '?'; } } Piece createPiece(PieceType type, bool color, bool moved) { Piece piece; piece.type = type; piece.color = color; piece.moved = moved; return piece; } void printBoard(Board *b) { std::string line = " +-----------------+\n"; std::string whiteLetters = " a b c d e f g h\n"; std::string blackLetters = " h g f e d c b a\n"; std::cout << (b->turn ? whiteLetters : blackLetters); std::cout << line; if (b->turn) { for (int rank = 0; rank < 8; rank++) { std::printf("%d |", 8 - rank); for (int file = 0; file < 8; file++) { Piece piece = b->pieces[rank * 8 + file]; char symbol = toChar(piece.type); if (!piece.color) symbol = std::tolower(static_cast(symbol)); std::printf(" %c", symbol); } std::printf(" | %d\n", 8 - rank); } } else { for (int rank = 7; rank >= 0; rank--) { std::printf("%d |", 8 - rank); for (int file = 7; file >= 0; file--) { Piece piece = b->pieces[rank * 8 + file]; char symbol = toChar(piece.type); if (!piece.color) symbol = std::tolower(static_cast(symbol)); std::printf(" %c", symbol); } std::printf(" | %d\n", 8 - rank); } } std::cout << line; std::cout << (b->turn ? whiteLetters : blackLetters); std::println(); std::println("Turn: {}", b->turn ? "White" : "Black"); assert(b->castle != ""); std::println("Castling: {}", b->castle); std::println("Can enpassant: {}", b->canEnpassant ? "Yes" : "No"); std::println("Where enpassant: {}{}", (char)((int)b->enPassant.file + 'A'), 8 - (int)b->enPassant.rank); std::printf("Move clock: %d\n", b->MoveClock); std::printf("Half move clock: %d\n", b->halfMoveClock); } void PlayMove(Move move, Board *b) { // TODO: add all fide behavior Piece piece = b->pieces[PositionToIndex(move.From)]; Piece piece2 = b->pieces[PositionToIndex(move.To)]; if (piece2.type != NONE) { if (piece2.color == b->turn) { assert(false && "capturing friendly piece error"); } } piece.moved = true; if (piece.type == PAWN || piece2.type != NONE) { b->halfMoveClock = 0; } else { b->halfMoveClock++; } if (piece.type == PAWN && b->canEnpassant && move.To == b->enPassant) { Position capturedPawn = move.To; capturedPawn.rank += piece.color ? 1 : -1; b->pieces[PositionToIndex(capturedPawn)] = {false, NONE, false}; } b->canEnpassant = false; b->MoveClock++; if (piece.type == PAWN) { Position to = move.To; to.rank -= (piece.color ? -2 : 2); if (to == move.From) { b->canEnpassant = true; Position target = move.From; target.rank += piece.color ? -1 : 1; b->enPassant = target; }; } b->pieces[PositionToIndex(move.To)] = piece; b->pieces[PositionToIndex(move.From)] = {false, NONE, false}; }; int PositionToIndex(Position i) { return i.rank * 8 + i.file; }