mirror of
https://gitlab.com/manzerbredes/chessarbiter.git
synced 2025-04-18 03:31:59 +00:00
170 lines
3.3 KiB
C++
170 lines
3.3 KiB
C++
![]() |
#include "Fen.hpp"
|
||
|
|
||
|
namespace chessarbiter {
|
||
|
|
||
|
std::string FENParser::normalize_rank(std::string fen_rank) {
|
||
|
std::string normalized;
|
||
|
for (char &c : fen_rank) {
|
||
|
if (IS_DIGIT(c)) {
|
||
|
for (char i = 0; i < (c - '0'); i++) {
|
||
|
normalized += ' ';
|
||
|
}
|
||
|
} else {
|
||
|
normalized += c;
|
||
|
}
|
||
|
}
|
||
|
return (normalized);
|
||
|
}
|
||
|
|
||
|
char FENParser::NextToken(std::string fen, char loc) {
|
||
|
while (loc < fen.size() && IS_BLANK(fen[loc])) {
|
||
|
loc++;
|
||
|
}
|
||
|
return (loc);
|
||
|
}
|
||
|
|
||
|
char FENParser::NextRank(std::string fen, char loc) {
|
||
|
loc++;
|
||
|
while (loc < fen.size() && fen[loc] != '/' && fen[loc] != ' ') {
|
||
|
loc++;
|
||
|
}
|
||
|
return (loc);
|
||
|
}
|
||
|
|
||
|
std::string FENParser::Serialize(FEN fen) {
|
||
|
std::string s;
|
||
|
char skip = 0;
|
||
|
char rank = 0;
|
||
|
for (char &c : fen.board) {
|
||
|
rank++;
|
||
|
if (c == ' ') {
|
||
|
skip++;
|
||
|
} else {
|
||
|
if (skip > 0) {
|
||
|
s += std::to_string(skip);
|
||
|
skip = 0;
|
||
|
}
|
||
|
s += c;
|
||
|
}
|
||
|
if (rank == 8) {
|
||
|
if (skip != 0) {
|
||
|
s += std::to_string(skip);
|
||
|
skip = 0;
|
||
|
}
|
||
|
s += '/';
|
||
|
rank = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Remove last /
|
||
|
s = s.substr(0, s.size() - 1);
|
||
|
s += " ";
|
||
|
|
||
|
// Player
|
||
|
if (fen.player) {
|
||
|
s += "b ";
|
||
|
} else {
|
||
|
s += "w ";
|
||
|
}
|
||
|
|
||
|
// Castle
|
||
|
if (!(fen.white_castle_short || fen.white_castle_long ||
|
||
|
fen.black_castle_short || fen.black_castle_long)) {
|
||
|
s += "-";
|
||
|
} else {
|
||
|
if (fen.white_castle_short) {
|
||
|
s += "K";
|
||
|
}
|
||
|
if (fen.white_castle_long) {
|
||
|
s += "Q";
|
||
|
}
|
||
|
if (fen.black_castle_short) {
|
||
|
s += "k";
|
||
|
}
|
||
|
if (fen.black_castle_long) {
|
||
|
s += "q";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Remaining
|
||
|
s += " " + fen.en_passant + " " + std::to_string(fen.halfmove) + " " +
|
||
|
std::to_string(fen.move);
|
||
|
|
||
|
return (s);
|
||
|
}
|
||
|
|
||
|
FEN FENParser::Parse(std::string fen) {
|
||
|
FEN parsed;
|
||
|
|
||
|
// Parse board
|
||
|
char loc = 0;
|
||
|
for (char rank = 0; rank < 8; rank++) {
|
||
|
char newloc = NextRank(fen, loc);
|
||
|
parsed.board += normalize_rank(fen.substr(loc, newloc - loc));
|
||
|
loc = newloc + 1;
|
||
|
}
|
||
|
|
||
|
// Parse player to move
|
||
|
loc = NextToken(fen, loc);
|
||
|
parsed.player = fen[loc] == 'b';
|
||
|
|
||
|
// Parse castling
|
||
|
loc = NextToken(fen, loc + 1);
|
||
|
char length = 0;
|
||
|
char cur_loc = loc;
|
||
|
while (!IS_BLANK(fen[cur_loc])) {
|
||
|
length++;
|
||
|
cur_loc++;
|
||
|
}
|
||
|
parsed.white_castle_short = false;
|
||
|
parsed.white_castle_long = false;
|
||
|
parsed.black_castle_short = false;
|
||
|
parsed.black_castle_long = false;
|
||
|
std::string castle = fen.substr(loc, length);
|
||
|
for (char i = 0; i < length; i++) {
|
||
|
switch (fen[loc + i]) {
|
||
|
case 'K':
|
||
|
parsed.white_castle_short = true;
|
||
|
break;
|
||
|
case 'Q':
|
||
|
parsed.white_castle_long = true;
|
||
|
break;
|
||
|
case 'k':
|
||
|
parsed.black_castle_short = true;
|
||
|
break;
|
||
|
case 'q':
|
||
|
parsed.black_castle_long = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Parse en passant
|
||
|
loc = NextToken(fen, loc + length);
|
||
|
if (fen[loc] != '-') {
|
||
|
parsed.en_passant = fen.substr(loc, 2);
|
||
|
loc++;
|
||
|
}
|
||
|
loc++;
|
||
|
|
||
|
// Parse half move counter
|
||
|
loc = NextToken(fen, loc);
|
||
|
std::string halfmove;
|
||
|
while (!IS_BLANK(fen[loc])) {
|
||
|
halfmove += fen[loc];
|
||
|
loc++;
|
||
|
}
|
||
|
parsed.halfmove = stoi(halfmove);
|
||
|
|
||
|
// Parse move counter
|
||
|
loc = NextToken(fen, loc);
|
||
|
std::string move;
|
||
|
while (loc < fen.size() && !IS_BLANK(fen[loc])) {
|
||
|
move += fen[loc];
|
||
|
loc++;
|
||
|
}
|
||
|
parsed.move = stoi(move);
|
||
|
|
||
|
return (parsed);
|
||
|
}
|
||
|
|
||
|
} // namespace chessarbiter
|