summaryrefslogtreecommitdiff
path: root/src/Board.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Board.cpp')
-rw-r--r--src/Board.cpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/Board.cpp b/src/Board.cpp
new file mode 100644
index 0000000..afd32e3
--- /dev/null
+++ b/src/Board.cpp
@@ -0,0 +1,196 @@
+#include "Board.hpp"
+
+namespace chessarbiter {
+
+bool Board::IsEmpty(std::string coord) {
+ for (Piece &p : pieces) {
+ if (p.coord == coord) {
+ return (false);
+ }
+ }
+ return (true);
+}
+
+bool Board::AddPiece(char p, std::string coord) {
+ if (IsEmpty(coord)) {
+ Piece piece(p, coord);
+ pieces.push_back(piece);
+ return (true);
+ }
+ return (false);
+}
+
+bool Board::RemovePiece(std::string coord) {
+ for (char i = 0; i < pieces.size(); i++) {
+ if (pieces[i].coord == coord) {
+ pieces.erase(pieces.begin() + i);
+ return (true);
+ }
+ }
+ return false;
+}
+
+Piece Board::GetPieceAt(std::string coord) {
+ for (Piece &p : pieces) {
+ if (p.coord == coord)
+ return p;
+ }
+ throw NoPieceFound();
+}
+
+std::vector<Piece> Board::GetPlayerPieces(bool isBlack) {
+ std::vector<Piece> pp;
+ for (Piece &p : pieces) {
+ if (p.isBlack == isBlack) {
+ pp.push_back(p);
+ }
+ }
+ return (pp);
+}
+
+short Board::CountPiece(char c) {
+ char count = 0;
+ for (Piece &p : pieces) {
+ if (p.piece == c) {
+ count++;
+ }
+ }
+ return (count);
+}
+
+void Board::Clear() { pieces.clear(); }
+
+std::string Board::GetKingLocation(bool isBlack) {
+ for (Piece &p : pieces) {
+ if (p.isBlack == isBlack) {
+ if (p.piece == 'k' || p.piece == 'K') {
+ return (p.coord);
+ }
+ }
+ }
+ throw NoPieceFound();
+}
+
+void Board::Move(std::string move) {
+ std::string src(move.substr(0, 2));
+ std::string dst(move.substr(2, 2));
+ if (!IsEmpty(src)) {
+ if (!IsEmpty(dst)) {
+ RemovePiece(dst);
+ }
+ for (Piece &p : pieces) {
+ if (p.coord == src) {
+ p.coord = dst;
+ }
+ }
+ }
+}
+
+std::string Board::Serialize() {
+ std::string s;
+ for (short i = 0; i < 8; i++) {
+ for (short j = 0; j < 8; j++) {
+ try {
+ Piece p = GetPieceAt((char)('a' + j) + std::string() + (char)('8' - i));
+ s += p.piece;
+ } catch (...) {
+ s += " ";
+ }
+ }
+ }
+ return (s);
+}
+
+bool Board::IsMovePossible(std::string move) {
+ std::string src(move.substr(0, 2));
+ std::string dst(move.substr(2, 2));
+ if (src == dst) {
+ return (false);
+ }
+ Piece srcp = GetPieceAt(src);
+
+ // Check move is possible
+ std::vector<std::string> srcm = srcp.GetMoves();
+ if (find(srcm.begin(), srcm.end(), dst) == srcm.end()) {
+ return (false);
+ }
+
+ // Check colors on dst square
+ if (!IsEmpty(dst)) {
+ Piece dstp = GetPieceAt(dst);
+ if (srcp.isBlack == dstp.isBlack)
+ return (false);
+ }
+
+ // Check if no piece in between
+ if (src[0] == dst[0] || src[1] == dst[1]) { // Rook like moves
+ if (src[0] == dst[0]) { // Vertical
+ char side = 1;
+ if (src[1] > dst[1]) {
+ side = -1;
+ }
+ char r = src[1] + 1 * side;
+ while (r != dst[1]) {
+ if (!IsEmpty(src[0] + std::string() + r)) {
+ return (false);
+ }
+ r += 1 * side;
+ }
+ } else { // Horizontal
+ char side = 1;
+ if (src[0] > dst[0]) {
+ side = -1;
+ }
+ char f = src[0] + 1 * side;
+ while (f != dst[0]) {
+ if (!IsEmpty(f + std::string() + src[1])) {
+ return (false);
+ }
+ f += 1 * side;
+ }
+ }
+ } else if ((src[0] - dst[0] == src[1] - dst[1]) ||
+ (dst[0] - src[0] == src[1] - dst[1])) { // Bishop like moves
+ // That code if for diagonal 1 (bottom left to up right)
+ // Using the d2 variable allow to reuse the same code for the 2 diagonals
+ char d2 = 1; // d2 stand for diagonal 2 (bottom right to up left)
+ if ((dst[0] - src[0] == src[1] - dst[1])) { // If move is for diagonal 2
+ d2 = -1;
+ }
+
+ // Move direction check
+ char side = 1;
+ if (src[0] > dst[0]) {
+ side = -1;
+ }
+
+ // Setup variables
+ char f = src[0] + 1 * side;
+ char r = src[1] + d2 * side;
+
+ // Perform empty square checks
+ while (f != dst[0], r != dst[1]) {
+ if (!IsEmpty(f + std::string() + r)) {
+ return (false);
+ }
+ f += 1 * side;
+ r += d2 * side;
+ }
+ }
+ return (true);
+}
+
+std::vector<std::string> Board::ListPossibleMoves(bool isBlack) {
+ std::vector<std::string> moves;
+ for (Piece &p : pieces) {
+ if (p.isBlack == isBlack) {
+ for (std::string &m : p.GetMoves()) {
+ if (IsMovePossible(p.coord + m)) {
+ moves.push_back(p.coord + m);
+ }
+ }
+ }
+ }
+ return (moves);
+}
+} // namespace chessarbiter \ No newline at end of file