aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/board.cpp17
-rw-r--r--src/board.hpp9
-rw-r--r--src/fen.cpp2
-rw-r--r--src/fen.hpp2
-rw-r--r--src/main.cpp146
-rw-r--r--src/moves.cpp16
-rw-r--r--src/moves.hpp8
-rw-r--r--src/repl.cpp109
-rw-r--r--src/repl.hpp12
10 files changed, 197 insertions, 128 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f5a42f..ec93cc0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,9 +16,9 @@ add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_include_directories(${PROJECT_NAME} PRIVATE src)
if (MSVC)
- target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
+ target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
else()
- target_compile_options(${PROJECT_NAME} PRIVATE
+ target_compile_options(${PROJECT_NAME} PRIVATE
-Wall
-Wextra
-Wpedantic
diff --git a/src/board.cpp b/src/board.cpp
index 172a9be..54df662 100644
--- a/src/board.cpp
+++ b/src/board.cpp
@@ -36,7 +36,7 @@ Piece createPiece(pieceType type, bool color, bool moved) {
piece.moved = moved;
return piece;
};
-void printBoard(board *b) {
+void printBoard(Board *b) {
std::string line = " +-----------------+\n";
std::string whiteLetters = " a b c d e f g h\n";
std::string blackLetters = " h g f e d c b a\n";
@@ -89,4 +89,17 @@ void printBoard(board *b) {
std::println("Castling: {}", b->castle);
}
-// void PlayMove(Move move, board *b) { return; }
+void PlayMove(Move move, Board *b) {
+ // TODO: add all fide behavior
+ Piece piece = b->pieces[PositionToIndex(move.From)];
+ Piece piece2 = b->pieces[PositionToIndex(move.To)];
+ if (piece2.type != NONE) {
+ if (piece2.color == b->turn) {
+ assert(false && "capturing friendly piece error");
+ }
+ }
+ b->pieces[PositionToIndex(move.To)] = piece;
+ b->pieces[PositionToIndex(move.From)] = {false, NONE, false};
+ return;
+}
+int PositionToIndex(Position i) { return i.rank * 8 + i.file; }
diff --git a/src/board.hpp b/src/board.hpp
index afdb938..9e80025 100644
--- a/src/board.hpp
+++ b/src/board.hpp
@@ -21,7 +21,7 @@ struct Piece {
bool moved;
};
-struct board {
+struct Board {
Piece pieces[64];
bool turn; // 1 white; 0 black
std::string castle;
@@ -42,8 +42,9 @@ struct Move {
bool operator==(const Move &) const = default;
};
-void printBoard(board *b);
+void printBoard(Board *b);
Piece createPiece(pieceType type, bool color, bool moved = false);
-void PlayMove(Move move, board *b); // TODO implement
-#endif /* SRC_BOARD_H_ */
+void PlayMove(Move move, Board *b);
+int PositionToIndex(Position i);
+#endif /* SRC_BOARD_H_ */
diff --git a/src/fen.cpp b/src/fen.cpp
index 9c3154c..9ddc795 100644
--- a/src/fen.cpp
+++ b/src/fen.cpp
@@ -8,7 +8,7 @@
bool WHITE = true;
bool BLACK = false;
-void setBoardFen(std::string fen, board *b) {
+void setBoardFen(std::string fen, Board *b) {
// example fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
int file = 0;
int rank = 0;
diff --git a/src/fen.hpp b/src/fen.hpp
index 19f88e2..1bd7f80 100644
--- a/src/fen.hpp
+++ b/src/fen.hpp
@@ -5,5 +5,5 @@
#include "board.hpp"
-void setBoardFen(std::string fen, board *b);
+void setBoardFen(std::string fen, Board *b);
#endif /* SRC_FEN_H_ */
diff --git a/src/main.cpp b/src/main.cpp
index 261c19d..4b9e965 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,50 +1,38 @@
#include "board.hpp"
#include "fen.hpp"
-#include "moves.hpp"
-#include <algorithm>
-#include <cctype>
-#include <cstdint>
+#include "repl.hpp"
#include <cstdio>
-#include <cstdlib>
+#include <iostream>
#include <print>
#include <string>
-#include <vector>
-#include <iostream>
+using namespace std;
-bool isValidChessRank(char rank) {
- if (rank >= '1' && rank <= '8') {
- return true;
- } else {
- return false;
- }
-}
-bool isValidChessFile(char rank) {
- if (rank >= 'A' && rank <= 'H') {
- return true;
- } else {
- return false;
- }
-}
-void setAllPiecesToEmpty(board *b) {
- Piece NonePiece = {
+enum Mode {
+ EXIT,
+ REPL,
+};
+
+void setAllPiecesToEmpty(Board *b) {
+ Piece EmptyPiece = {
false,
NONE,
false,
};
for (int i = 0; i < 64; i++) {
- b->pieces[i] = NonePiece;
+ b->pieces[i] = EmptyPiece;
};
-}
-void PrintMoves(const std::vector<Move> &moves) {
- std::cout << "Moves (" << moves.size() << "):\n";
+};
+Board initBoard(string startingFEN) {
+ Board b;
+ b.turn = true;
+ b.castle = "";
+ b.halfMoveClock = 0;
+ b.MoveClock = 0;
+ setBoardFen(startingFEN, &b);
+ return b;
+};
- for (const Move &move : moves) {
- std::cout << "(" << (int)move.From.file << ", " << (int)move.From.rank
- << ") -> (" << (int)move.To.file << ", " << (int)move.To.rank
- << ")\n";
- }
-}
int main(int argc, char **argv) {
std::string startingFen =
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
@@ -56,81 +44,25 @@ int main(int argc, char **argv) {
if (argc == 2) {
startingFen = argv[1];
}
- board b;
- b.turn = true;
- b.castle = "";
- b.halfMoveClock = 0;
- b.MoveClock = 0;
- setBoardFen(startingFen, &b);
- printBoard(&b);
- while (true) {
- std::cout << "> ";
- std::string command;
- std::cin >> command;
- std::cout << command << "\n";
-
- transform(command.begin(), command.end(), command.begin(), ::toupper);
- if (command == "EXIT") {
- std::println();
- std::cout << "Exiting...\n";
- return 0;
- }
+ println("ENTER which mode you want (REPL)");
+ Mode mode = EXIT;
+ string modeString;
+ cin >> modeString;
+ std::transform(modeString.begin(), modeString.end(), modeString.begin(),
+ ::toupper);
- if (command.length() != 4) {
- std::cout << "Unknown Command, use EXIT to exit";
- std::println();
- continue;
- }
- if (!isValidChessFile(command[0])) {
- std::cout << "ERROR: Expected valid file at first place";
- std::println();
- continue;
- }
-
- if (!isValidChessRank(command[1])) {
- std::cout << "ERROR: Expected valid rank at second place";
- std::println();
- continue;
- }
-
- if (!isValidChessFile(command[2])) {
- std::cout << "ERROR: Expected valid file at third place";
- std::println();
- continue;
- }
-
- if (!isValidChessRank(command[3])) {
- std::cout << "ERROR: Expected valid rank at four place";
- std::println();
- continue;
- }
-
- // we know its a valid chess pos
- int fromFile = command[0] - 'A';
- int fromRank = '8' - command[1];
- int toFile = command[2] - 'A';
- int toRank = '8' - command[3];
- std::cout << fromFile << "\n";
- std::cout << fromRank << "\n";
- std::cout << toFile << "\n";
- std::cout << toRank << "\n";
- Move move = {
- {static_cast<uint8_t>(fromRank), static_cast<uint8_t>(fromFile)},
- {static_cast<uint8_t>(toRank), static_cast<uint8_t>(toFile)}};
+ if (modeString == "REPL") {
+ mode = REPL;
+ }
+ // ADD support for other modes here
- auto moves = GetLegalMoves(&b);
- if (std::ranges::find(moves, move) != moves.end()) {
- std::cout << "Move is legal!\n";
- } else {
- std::cout << "Move is not legal!\n";
- PrintMoves(moves);
- continue;
- }
- std::println();
- // PlayMove(move, &b); // todo implement
- b.MoveClock++;
- b.turn = !b.turn;
- printBoard(&b);
+ Board b = initBoard(startingFen);
+ if (mode == REPL) {
+ int replExitCode = startREPL(&b);
+ return replExitCode;
+ }
+ if (mode == EXIT) {
+ return 0;
}
- return EXIT_SUCCESS;
+ return 0;
}
diff --git a/src/moves.cpp b/src/moves.cpp
index 5c8c07e..0059039 100644
--- a/src/moves.cpp
+++ b/src/moves.cpp
@@ -5,7 +5,7 @@
#include "board.hpp"
#include "moves.hpp"
-void GeneratePawnMoves(board *b, int from, std::vector<Move> &moves) {
+void GeneratePawnMoves(Board *b, int from, std::vector<Move> &moves) {
Piece pawn = b->pieces[from];
if (pawn.type != PAWN) {
assert(false && "Calling generate pawn moves on non pawn");
@@ -49,7 +49,7 @@ void GeneratePawnMoves(board *b, int from, std::vector<Move> &moves) {
// the end
}
-std::vector<Move> GetLegalMoves(board *b) {
+std::vector<Move> GetLegalMoves(Board *b) {
std::vector<Move> moves;
moves.reserve(50); // almost all position dont have that many moves
@@ -93,7 +93,7 @@ Position IndexToPosition(int i) {
return {rank, file};
}
-void GenerateSlidingMoves(board *b, int from,
+void GenerateSlidingMoves(Board *b, int from,
const std::array<int, 4> &directions,
std::vector<Move> &moves) {
for (uint i = 0; i < directions.size(); i++) {
@@ -128,7 +128,7 @@ void GenerateSlidingMoves(board *b, int from,
};
};
-void GenerateKingMoves(board *b, int from, std::vector<Move> &moves) {
+void GenerateKingMoves(Board *b, int from, std::vector<Move> &moves) {
if (b->pieces[from].type != KING) {
assert(false && "calling generate king moves on non king");
return;
@@ -146,9 +146,11 @@ void GenerateKingMoves(board *b, int from, std::vector<Move> &moves) {
if (std::abs((next % 8) - (from % 8)) > 1) {
continue;
};
- if (b->pieces[next].color == b->turn) {
- continue;
- };
+ if (b->pieces[next].type != NONE) {
+ if (b->pieces[next].color == b->turn) {
+ continue;
+ };
+ }
moves.push_back({IndexToPosition(from), IndexToPosition(next)});
}
diff --git a/src/moves.hpp b/src/moves.hpp
index 2cede49..ae26e29 100644
--- a/src/moves.hpp
+++ b/src/moves.hpp
@@ -4,12 +4,12 @@
#include "board.hpp"
#include <vector>
-std::vector<Move> GetLegalMoves(board *b);
+std::vector<Move> GetLegalMoves(Board *b);
Position IndexToPosition(int i);
-void GenerateSlidingMoves(board *b, int from,
+void GenerateSlidingMoves(Board *b, int from,
const std::array<int, 4> &directions,
std::vector<Move> &moves);
-void GenerateKingMoves(board *b, int from, std::vector<Move> &moves);
-void GeneratePawnMoves(board *b, int from, std::vector<Move> &moves);
+void GenerateKingMoves(Board *b, int from, std::vector<Move> &moves);
+void GeneratePawnMoves(Board *b, int from, std::vector<Move> &moves);
#endif /* SRC_MOVES_H_ */
diff --git a/src/repl.cpp b/src/repl.cpp
new file mode 100644
index 0000000..642419a
--- /dev/null
+++ b/src/repl.cpp
@@ -0,0 +1,109 @@
+#include "repl.hpp"
+#include "board.hpp"
+#include "moves.hpp"
+#include <algorithm>
+#include <cctype>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <print>
+#include <string>
+
+bool isValidChessRank(char rank) {
+ if (rank >= '1' && rank <= '8') {
+ return true;
+ } else {
+ return false;
+ }
+}
+bool isValidChessFile(char rank) {
+ if (rank >= 'A' && rank <= 'H') {
+ return true;
+ } else {
+ return false;
+ }
+}
+int startREPL(Board *b) {
+ printBoard(b);
+ while (true) {
+ std::cout << "> ";
+ std::string command;
+ std::cin >> command;
+
+ std::transform(command.begin(), command.end(), command.begin(), ::toupper);
+ if (command == "EXIT") {
+ std::println();
+ std::cout << "Exiting...\n";
+ return EXIT_SUCCESS;
+ }
+ if (command == "BOARD") {
+ printBoard(b);
+ continue;
+ }
+
+ if (command.length() != 4) {
+ std::cout << "Unknown Command, use EXIT to exit";
+ std::println();
+ continue;
+ }
+ if (!isValidChessFile(command[0])) {
+ std::cout << "ERROR: Expected valid file at first place";
+ std::println();
+ continue;
+ }
+
+ if (!isValidChessRank(command[1])) {
+ std::cout << "ERROR: Expected valid rank at second place";
+ std::println();
+ continue;
+ }
+
+ if (!isValidChessFile(command[2])) {
+ std::cout << "ERROR: Expected valid file at third place";
+ std::println();
+ continue;
+ }
+
+ if (!isValidChessRank(command[3])) {
+ std::cout << "ERROR: Expected valid rank at four place";
+ std::println();
+ continue;
+ }
+
+ // we know its a valid chess pos
+ int fromFile = command[0] - 'A';
+ int fromRank = '8' - command[1];
+ int toFile = command[2] - 'A';
+ int toRank = '8' - command[3];
+ std::cout << fromFile << "\n";
+ std::cout << fromRank << "\n";
+ std::cout << toFile << "\n";
+ std::cout << toRank << "\n";
+ Move move = {
+ {static_cast<uint8_t>(fromRank), static_cast<uint8_t>(fromFile)},
+ {static_cast<uint8_t>(toRank), static_cast<uint8_t>(toFile)}};
+
+ auto moves = GetLegalMoves(b);
+ if (!(std::ranges::find(moves, move) != moves.end())) {
+ std::cout << "Invalid move!";
+ std::println();
+ PrintMoves(moves);
+ continue;
+ }
+ std::println();
+ PlayMove(move, b);
+ b->MoveClock++;
+ b->turn = !b->turn;
+ printBoard(b);
+ }
+}
+
+void PrintMoves(const std::vector<Move> &moves) {
+ std::cout << "Moves (" << moves.size() << "):\n";
+
+ for (const Move &move : moves) {
+ std::cout << "(" << (int)move.From.file << ", " << (int)move.From.rank
+ << ") -> (" << (int)move.To.file << ", " << (int)move.To.rank
+ << ")\n";
+ }
+}
diff --git a/src/repl.hpp b/src/repl.hpp
new file mode 100644
index 0000000..5f457c4
--- /dev/null
+++ b/src/repl.hpp
@@ -0,0 +1,12 @@
+#ifndef SRC_REPL_H_
+#define SRC_REPL_H_
+
+#include "board.hpp"
+#include <vector>
+
+int startREPL(Board *b);
+void PrintMoves(const std::vector<Move> &moves);
+bool isValidChessRank(char rank);
+bool isValidChessFile(char rank);
+
+#endif /* SRC_REPL_H_ */