diff options
| author | Loic Guegan <manzerbredes@mailbox.org> | 2022-01-29 11:52:47 +0100 |
|---|---|---|
| committer | Loic Guegan <manzerbredes@mailbox.org> | 2022-01-29 11:52:47 +0100 |
| commit | e9d328acf4ee45bd8771d422fa4db40298e6e16a (patch) | |
| tree | 68a86c53539fe57b434c49555feafac9081f75e0 /tests/chessarbiter.cpp | |
Init project
Diffstat (limited to 'tests/chessarbiter.cpp')
| -rw-r--r-- | tests/chessarbiter.cpp | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/tests/chessarbiter.cpp b/tests/chessarbiter.cpp new file mode 100644 index 0000000..7c2bffe --- /dev/null +++ b/tests/chessarbiter.cpp @@ -0,0 +1,302 @@ +#include "ChessArbiter.hpp" +#include <catch_amalgamated.hpp> + +using namespace chessarbiter; + +TEST_CASE("Setup/GetBoard", "[chessarbiter/Setup/GetBoard]") { + ChessArbiter a; + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetBoard() == "rnbqkbnr" + "pppppppp" + " " + " " + " " + " " + "PPPPPPPP" + "RNBQKBNR"); + + a.Setup("RnbqkbnR/pppppppp/8/8/8/8/PPPPPPPP/rNBQKBNr w KQkq - 0 1"); + CHECK(a.GetBoard() == "RnbqkbnR" + "pppppppp" + " " + " " + " " + " " + "PPPPPPPP" + "rNBQKBNr"); +} + +TEST_CASE("GetMaterialScore", "[chessarbiter/GetMaterialScore]") { + ChessArbiter a; + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 0); + + // White better + a.Setup("1nbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 5); + a.Setup("r1bqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 3); + a.Setup("rnbqkbnr/1ppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 1); + a.Setup("rnb1kbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 9); + a.Setup("rnbqk1nr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 3); + a.Setup("rnbq1bnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 0); + + // Black better + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/1NBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == -5); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKB1R w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == -3); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPP1/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == -1); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNB1KBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == -9); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RN1QKBNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == -3); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQ1BNR w KQkq - 0 1"); + CHECK(a.GetMaterialScore() == 0); +} + +TEST_CASE("GetCaptures", "[board/GetCaptures]") { + ChessArbiter a; + + // White captures + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == ""); + a.Setup("rnbqkbnr/8/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == "pppppppp"); + a.Setup("1nbqkbn1/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == "rr"); + a.Setup("r1bqkb1r/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == "nn"); + a.Setup("rnbqk1nr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == "b"); + a.Setup("rnb1kbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == "q"); + a.Setup("rnbq1bnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == "k"); // :D + + // Black captures + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/8/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(true) == "PPPPPPPP"); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/1NBQKBN1 w KQkq - 0 1"); + CHECK(a.GetCaptures(true) == "RR"); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/R1BQKB1R w KQkq - 0 1"); + CHECK(a.GetCaptures(true) == "NN"); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNbQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(true) == "B"); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNB1KBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(true) == "Q"); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQ1BNR w KQkq - 0 1"); + CHECK(a.GetCaptures(true) == "K"); // :D + + // Just because we know the order of the implementation + a.Setup("11bqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.GetCaptures(false) == "rn"); + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKB11 w KQkq - 0 1"); + CHECK(a.GetCaptures(true) == "RN"); +} + +TEST_CASE("IsAttacked", "[chessarbiter/IsAttacked]") { + ChessArbiter a; + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + + // White third rank attacked by white + CHECK(a.IsAttacked("a3", false)); + CHECK(a.IsAttacked("b3", false)); + CHECK(a.IsAttacked("c3", false)); + CHECK(a.IsAttacked("d3", false)); + CHECK(a.IsAttacked("e3", false)); + CHECK(a.IsAttacked("f3", false)); + CHECK(a.IsAttacked("g3", false)); + CHECK(a.IsAttacked("h3", false)); + // White third rank attacked by black + CHECK_FALSE(a.IsAttacked("a3", true)); + CHECK_FALSE(a.IsAttacked("b3", true)); + CHECK_FALSE(a.IsAttacked("c3", true)); + CHECK_FALSE(a.IsAttacked("d3", true)); + CHECK_FALSE(a.IsAttacked("e3", true)); + CHECK_FALSE(a.IsAttacked("f3", true)); + CHECK_FALSE(a.IsAttacked("g3", true)); + CHECK_FALSE(a.IsAttacked("h3", true)); + + // Black sixth rank attacked by black + CHECK(a.IsAttacked("a6", true)); + CHECK(a.IsAttacked("b6", true)); + CHECK(a.IsAttacked("c6", true)); + CHECK(a.IsAttacked("d6", true)); + CHECK(a.IsAttacked("e6", true)); + CHECK(a.IsAttacked("f6", true)); + CHECK(a.IsAttacked("g6", true)); + CHECK(a.IsAttacked("h6", true)); + // Black sixth rank attacked by white + CHECK_FALSE(a.IsAttacked("a6", false)); + CHECK_FALSE(a.IsAttacked("b6", false)); + CHECK_FALSE(a.IsAttacked("c6", false)); + CHECK_FALSE(a.IsAttacked("d6", false)); + CHECK_FALSE(a.IsAttacked("e6", false)); + CHECK_FALSE(a.IsAttacked("f6", false)); + CHECK_FALSE(a.IsAttacked("g6", false)); + CHECK_FALSE(a.IsAttacked("h6", false)); + + // Remove a pawn for black + a.Setup("rnbqkbnr/1ppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.IsAttacked("a3", false)); + CHECK(a.IsAttacked("a3", true)); + CHECK_FALSE(a.IsAttacked("a4", false)); + CHECK(a.IsAttacked("a4", true)); + + // Remove another pawn for black + a.Setup("rnbqkbnr/pppp1ppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.IsAttacked("a3", true)); + CHECK(a.IsAttacked("h4", true)); + CHECK(a.IsAttacked("a3", false)); + CHECK_FALSE(a.IsAttacked("h4", false)); + + // Add a crazy black knight + a.Setup("rnbqkbnr/pppppppp/8/8/8/4n3/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.IsAttacked("d1", true)); + CHECK_FALSE(a.IsAttacked("e1", true)); + CHECK(a.IsAttacked("f1", true)); + CHECK_FALSE(a.IsAttacked("f2", true)); + CHECK_FALSE(a.IsAttacked("d1", false)); // White can't attack is own pieces +} + +TEST_CASE("ListLegalMoves", "[chessarbiter/ListLegalMoves]") { + ChessArbiter a; + + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + std::vector<std::string> moves = a.ListLegalMoves(false); + REQUIRE(moves.size() == 20); + CHECK(std::find(moves.begin(), moves.end(), "e2e4") != moves.end()); + CHECK(std::find(moves.begin(), moves.end(), "e2e3") != moves.end()); + CHECK(std::find(moves.begin(), moves.end(), "b1c3") != moves.end()); + CHECK_FALSE(std::find(moves.begin(), moves.end(), "d1d3") != moves.end()); + + // White Short Castle possible + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQK11R w KQkq - 0 1"); + moves = a.ListLegalMoves(false); + REQUIRE(moves.size() == 22); + CHECK(std::find(moves.begin(), moves.end(), "O-O") != moves.end()); + + // White Short Castle impossible + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQK11R w Qkq - 0 1"); + moves = a.ListLegalMoves(false); + CHECK_FALSE(std::find(moves.begin(), moves.end(), "O-O") != moves.end()); + + // White Short Castle impossible 2 + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQK1NR w KQkq - 0 1"); + moves = a.ListLegalMoves(false); + CHECK_FALSE(std::find(moves.begin(), moves.end(), "O-O") != moves.end()); + + // White Short Castle impossible 3 (queen attacks by black) + a.Setup("rnbqkbnr/pppppqpp/8/8/8/8/PPPPP1PP/RNBQK11R w KQkq - 0 1"); + moves = a.ListLegalMoves(false); + CHECK_FALSE(std::find(moves.begin(), moves.end(), "O-O") != moves.end()); + + // White Long Castle possible + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/R3KNBR w KQkq - 0 1"); + moves = a.ListLegalMoves(false); + REQUIRE(moves.size() == 23); + CHECK(find(moves.begin(), moves.end(), "O-O-O") != moves.end()); + + // White Long Castle impossible + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/R3KBNR w Kkq - 0 1"); + moves = a.ListLegalMoves(false); + CHECK_FALSE(std::find(moves.begin(), moves.end(), "O-O-O") != moves.end()); + + // White Long Castle impossible 2 + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RN2KBNR w KQkq - 0 1"); + moves = a.ListLegalMoves(false); + CHECK_FALSE(std::find(moves.begin(), moves.end(), "O-O-O") != moves.end()); + + // White Long Castle impossible 3 (rook attacks by black) + a.Setup("rnbqkbnr/pprppppp/8/8/8/8/PP1PPPPP/R3KBNR w KQkq - 0 1"); + moves = a.ListLegalMoves(false); + CHECK_FALSE(std::find(moves.begin(), moves.end(), "O-O-O") != moves.end()); +} + +TEST_CASE("IsPlayable", "[chessarbiter/IsPlayable]") { + ChessArbiter a; + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK(a.IsPlayable()); + + a.Setup("8/8/1q1k4/8/8/8/5K2/8 w - - 0 1"); + CHECK(a.IsPlayable()); + + a.Setup("8/8/3k4/3q4/8/8/3K4/8 b - - 0 1"); + CHECK_FALSE(a.IsPlayable()); + + a.Setup("8/8/3k4/3q4/8/8/3R4/8 b - - 0 1"); + CHECK_FALSE(a.IsPlayable()); + + a.Setup("8/8/3k4/3q4/8/8/5K2/4K3 b - - 0 1"); + CHECK_FALSE(a.IsPlayable()); + + a.Setup("1k6/8/3k4/3q4/8/8/5K2/8 b - - 0 1"); + CHECK_FALSE(a.IsPlayable()); +} + +TEST_CASE("Play Basic", "[chessarbiter/Play]") { + ChessArbiter a; + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + + // White turn + CHECK(a.Play("e2e3")); + CHECK(a.GetFEN() == + "rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq - 0 1"); + CHECK_FALSE(a.Play("d2d3")); // Black turn + CHECK(a.GetFEN() == + "rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq - 0 1"); + + // Black turn + CHECK(a.Play("e7e5")); + CHECK(a.GetFEN() == + "rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq - 0 2"); + CHECK_FALSE(a.Play("d7d6")); // White turn + CHECK(a.GetFEN() == + "rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq - 0 2"); + + // White turn + CHECK(a.Play("b1c3")); + CHECK(a.GetFEN() == + "rnbqkbnr/pppp1ppp/8/4p3/8/2N1P3/PPPP1PPP/R1BQKBNR b KQkq - 1 2"); +} + +TEST_CASE("IsCheckmate", "[chessarbiter/IsCheckmate]") { + ChessArbiter a; + + // There is no checkmate + a.Setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + CHECK_FALSE(a.IsCheckMate()); + // Ensure fen did not change + CHECK(a.GetFEN() == + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + + // There is a checkmate + a.Setup("r1bqkbnr/1ppp1Qpp/p1n5/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQkq - 0 4"); + CHECK(a.IsCheckMate()); + CHECK(a.GetFEN() == + "r1bqkbnr/1ppp1Qpp/p1n5/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQkq - 0 4"); + + // There is a checkmate + a.Setup("1nb1kbnr/1p3ppp/2p1p3/3p4/2P4B/2qP4/3RPPPP/1r2KBNR w Kk - 0 19"); + CHECK(a.IsCheckMate()); + CHECK(a.GetFEN() == + "1nb1kbnr/1p3ppp/2p1p3/3p4/2P4B/2qP4/3RPPPP/1r2KBNR w Kk - 0 19"); + + // There is no checkmate + a.Setup("1nb1kbnr/1p3ppp/2p1p3/3p4/1QP4B/2qP4/3RPPPP/r3KBNR w Kk - 2 18"); + CHECK_FALSE(a.IsCheckMate()); + CHECK(a.GetFEN() == + "1nb1kbnr/1p3ppp/2p1p3/3p4/1QP4B/2qP4/3RPPPP/r3KBNR w Kk - 2 18"); + + // There is a checkmate + a.Setup("r3qbr1/p1p1pkp1/1p2p1p1/8/8/8/PPPPP1PP/RNBQ1RK1 b - - 1 1"); + CHECK(a.IsCheckMate()); + CHECK(a.GetFEN() == + "r3qbr1/p1p1pkp1/1p2p1p1/8/8/8/PPPPP1PP/RNBQ1RK1 b - - 1 1"); +} |
