diff --git a/cpp/board b/cpp/board new file mode 100755 index 0000000..be3d593 Binary files /dev/null and b/cpp/board differ diff --git a/cpp/board.cpp b/cpp/board.cpp new file mode 100644 index 0000000..a5758b6 --- /dev/null +++ b/cpp/board.cpp @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include + +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 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 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; +} diff --git a/cpp/main.cpp b/cpp/main.cpp new file mode 100644 index 0000000..bf59c81 --- /dev/null +++ b/cpp/main.cpp @@ -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; +} diff --git a/cpp/stickfosh.cpp b/cpp/stickfosh.cpp new file mode 100644 index 0000000..e69de29 diff --git a/cpp/tests/fen b/cpp/tests/fen new file mode 100755 index 0000000..bafed67 Binary files /dev/null and b/cpp/tests/fen differ diff --git a/cpp/tests/fen.cpp b/cpp/tests/fen.cpp new file mode 100644 index 0000000..857e917 --- /dev/null +++ b/cpp/tests/fen.cpp @@ -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()); +}