cpp board can go back and forth from FEN
This commit is contained in:
parent
947114877b
commit
4792daf127
110
cpp/board.cpp
Normal file
110
cpp/board.cpp
Normal 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
16
cpp/main.cpp
Normal 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
0
cpp/stickfosh.cpp
Normal file
BIN
cpp/tests/fen
Executable file
BIN
cpp/tests/fen
Executable file
Binary file not shown.
37
cpp/tests/fen.cpp
Normal file
37
cpp/tests/fen.cpp
Normal 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());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user