cpp board can go back and forth from FEN
Some checks failed
pre-release / Pre Release (push) Waiting to run
tagged-release / Tagged Release (push) Has been cancelled

This commit is contained in:
Karma Riuk 2025-02-02 14:50:44 +01:00
parent 947114877b
commit 4792daf127
6 changed files with 163 additions and 0 deletions

BIN
cpp/board Executable file

Binary file not shown.

110
cpp/board.cpp Normal file
View File

@ -0,0 +1,110 @@
#include <cctype>
#include <ios>
#include <iostream>
#include <map>
#include <string>
enum Piece {
None = 0,
King = 1,
Pawn = 2,
Knigt = 3,
Bishop = 4,
Rook = 5,
Queen = 6,
};
enum Colour {
White = 8,
Black = 16,
};
enum CastleRights {
KingSide = 1,
QueenSide = 2,
};
class Board {
public: // make this private after debugging
int squares[64] = {Piece::None};
Colour turn;
int castle_rights;
public:
static Board* setup_fen_position(std::string fen);
std::string to_fen();
};
Board* Board::setup_fen_position(std::string fen) {
Board* board = new Board();
std::map<char, Piece> c2p{
{'k', Piece::King},
{'p', Piece::Pawn},
{'n', Piece::Knigt},
{'b', Piece::Bishop},
{'r', Piece::Rook},
{'q', Piece::Queen},
};
std::string fen_board = fen.substr(0, fen.find(' '));
int rank = 7, file = 0;
for (char symbol : fen_board) {
if (symbol == '/') {
file = 0;
rank--;
continue;
}
if (std::isdigit(symbol))
file += symbol - '0';
else {
Colour colour =
std::isupper(symbol) ? Colour::White : Colour::Black;
Piece piece = c2p[std::tolower(symbol)];
board->squares[rank * 8 + file] = colour | piece;
file++;
}
}
return board;
}
std::string Board::to_fen() {
std::map<int, char> p2c{
{Piece::King, 'k'},
{Piece::Pawn, 'p'},
{Piece::Knigt, 'n'},
{Piece::Bishop, 'b'},
{Piece::Rook, 'r'},
{Piece::Queen, 'q'},
};
std::string ret;
for (int rank = 7; rank >= 0; rank--) {
int empty_cell_counter = 0;
for (int file = 0; file < 8; file++) {
if (this->squares[rank * 8 + file] == Piece::None) {
empty_cell_counter++;
continue;
}
int full_piece = this->squares[rank * 8 + file];
char piece = p2c[full_piece & 0b111];
Colour colour = (full_piece & 0b11000) == Colour::White
? Colour::White
: Colour::Black;
if (empty_cell_counter > 0) {
ret += std::to_string(empty_cell_counter);
empty_cell_counter = 0;
}
ret += colour == Colour::White ? std::toupper(piece) : piece;
}
if (empty_cell_counter > 0)
ret += std::to_string(empty_cell_counter);
if (rank > 0)
ret += "/";
}
return ret;
}

16
cpp/main.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "board.cpp"
int main(int argc, char* argv[]) {
std::string pos =
"rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8";
Board* b = Board::setup_fen_position(pos);
std::string fen = b->to_fen();
std::cout << pos << std::endl;
std::cout << fen << std::endl;
std::cout << (fen.substr(0, fen.find(" ")) == pos.substr(0, pos.find(" ")))
<< std::endl;
return 0;
}

0
cpp/stickfosh.cpp Normal file
View File

BIN
cpp/tests/fen Executable file

Binary file not shown.

37
cpp/tests/fen.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "../board.cpp"
#define IS_TRUE(x) \
{ \
if (!(x)) \
std::cout << __FUNCTION__ << " failed on line " << __LINE__ \
<< std::endl; \
}
#define ASSERT_EQUALS(expected, actual) \
{ \
if (expected != actual) \
std::cout << "Expected: " << std::endl \
<< '\t' << expected << std::endl \
<< "Got: " << std::endl \
<< '\t' << actual << std::endl; \
}
int main() {
std::string pos = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR";
ASSERT_EQUALS(pos, Board::setup_fen_position(pos)->to_fen());
pos = "r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1";
ASSERT_EQUALS(pos, Board::setup_fen_position(pos)->to_fen());
pos = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR";
ASSERT_EQUALS(pos, Board::setup_fen_position(pos)->to_fen());
pos = "4k2r/6r1/8/8/8/8/3R4/R3K3";
ASSERT_EQUALS(pos, Board::setup_fen_position(pos)->to_fen());
pos = "8/8/8/4p1K1/2k1P3/8/8/8";
ASSERT_EQUALS(pos, Board::setup_fen_position(pos)->to_fen());
pos = "8/5k2/3p4/1p1Pp2p/pP2Pp1P/P4P1K/8/8";
ASSERT_EQUALS(pos, Board::setup_fen_position(pos)->to_fen());
}