aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/board.cpp3
-rw-r--r--src/board.hpp21
-rw-r--r--src/bot.cpp64
-rw-r--r--src/moves.cpp20
-rw-r--r--src/uci.cpp19
6 files changed, 111 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 461b652..1adb011 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ tmp/
tmp
.cache/
uci_log.txt
+moves.txt
diff --git a/src/board.cpp b/src/board.cpp
index e058df4..5107a0f 100644
--- a/src/board.cpp
+++ b/src/board.cpp
@@ -137,7 +137,8 @@ void PlayMove(Move move, Game *b) {
}
if (piece.type == PAWN && move.To.rank == (piece.color ? 0 : 7)) {
- piece.type = QUEEN;
+ // TODO parse the promote type from uci isntead of ignoreting it
+ piece.type = move.promotion == NONE ? QUEEN : move.promotion;
}
if (b->halfMoveClock >= 50) {
b->state = DRAW;
diff --git a/src/board.hpp b/src/board.hpp
index 592b438..e9e3570 100644
--- a/src/board.hpp
+++ b/src/board.hpp
@@ -52,7 +52,26 @@ struct Move {
Position From;
Position To;
- bool operator==(const Move &) const = default;
+ PieceType promotion = NONE;
+ bool operator==(const Move &other) const {
+ return From == other.From && To == other.To && promotion == other.promotion;
+ }
+};
+struct UndoMove {
+ Piece movedPiece;
+ Piece capturedPiece;
+
+ Position from;
+ Position to;
+
+ bool oldTurn;
+ bool oldCanEnpassant;
+ Position oldEnPassant;
+ std::string oldCaslte;
+ int oldHalfMoveClock;
+ int oldMoveClock;
+ std::unordered_map<uint64_t, int> OldThreeFoldMap;
+ GameState oldState;
};
void printBoard(Game *b);
Piece createPiece(PieceType type, bool color, bool moved = false);
diff --git a/src/bot.cpp b/src/bot.cpp
index e976d11..c8842bd 100644
--- a/src/bot.cpp
+++ b/src/bot.cpp
@@ -6,21 +6,58 @@
#include <cmath>
int PAWN_VALUE = 100;
-int KNIGHT_VALUE = 200;
-int BISHOP_VALUE = 300;
-int ROOK_VALUE = 400;
+int KNIGHT_VALUE = 320;
+int BISHOP_VALUE = 330;
+int ROOK_VALUE = 500;
int QUEEN_VALUE = 900;
-int CHECK = 20;
+int CHECK = 10;
int MATE = 10000;
-int KNIGHT_TABLE[64] = {-50, -40, -30, -30, -30, -30, -40, -50, -40, -20, 0,
- 0, 0, 0, -20, -40, -30, 0, 10, 15, 15, 10,
- 0, -30, -30, 5, 15, 20, 20, 15, 5, -30, -30,
- 0, 15, 20, 20, 15, 0, -30, -30, 5, 10, 15,
- 15, 10, 5, -30, -40, -20, 0, 5, 5, 0, -20,
- -40, -50, -40, -30, -30, -30, -30, -40, -50};
-
-const int SEARCH_DEPTH = 3;
+const int PAWN_TABLE[64] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, // last rank promotes to a quuen
+ 50, 50, 50, 50, 50, 50, 50, 50, // comments to stop formating to ruin it
+ 10, 10, 20, 30, 30, 20, 10, 10, //
+ 5, 5, 10, 25, 25, 10, 5, 5, //
+ 0, 0, 0, 20, 20, 0, 0, 0, //
+ 5, -5, -10, 0, 0, -10, -5, 5, //
+ 5, 10, 10, -20, -20, 10, 10, 5, //
+ 0, 0, 0, 0, 0, 0, 0, 0 //
+};
+
+int KNIGHT_TABLE[64] = {
+ -50, -40, -30, -30, -30, -30, -40, -50, //
+ -40, -20, 0, 0, 0, 0, -20, -40, //
+ -30, 0, 10, 15, 15, 10, 0, -30, //
+ -30, 5, 15, 20, 20, 15, 5, -30, //
+ -30, 0, 15, 20, 20, 15, 0, -30, //
+ -30, 5, 10, 15, 15, 10, 5, -30, //
+ -40, -20, 0, 5, 5, 0, -20, -40, //
+ -50, -40, -30, -30, -30, -30, -40, -50, //
+};
+
+int BISHOP_TABLE[64] = {
+ -20, -10, -10, -10, -10, -10, -10, -20, //
+ -10, 5, 0, 0, 0, 0, 5, -10, //
+ -10, 10, 10, 10, 10, 10, 10, -10, //
+ -10, 0, 10, 15, 15, 10, 0, -10, //
+ -10, 5, 5, 10, 10, 5, 5, -10, //
+ -10, 0, 5, 10, 10, 5, 0, -10, //
+ -10, 0, 0, 0, 0, 0, 0, -10, //
+ -20, -10, -10, -10, -10, -10, -10, -20, //
+};
+
+int ROOK_TABLE[64] = {
+ 0, 0, 5, 10, 10, 5, 0, 0, //
+ 5, 10, 10, 10, 10, 10, 10, 5, //
+ -5, 0, 0, 0, 0, 0, 0, -5, //
+ -5, 0, 0, 5, 5, 0, 0, -5, //
+ -5, 0, 0, 5, 5, 0, 0, -5, //
+ -5, 0, 0, 0, 0, 0, 0, -5, //
+ 5, 10, 10, 10, 10, 10, 10, 5, //
+ 0, 0, 5, 10, 10, 5, 0, 0, //
+};
+
+const int SEARCH_DEPTH = 5;
#include <fstream>
@@ -139,6 +176,7 @@ float EvaluateBoardForWhite(Game *b) {
switch (piece.type) {
case PAWN:
value = PAWN_VALUE;
+ value += PAWN_TABLE[PSTIndex(i, piece.color)];
break;
case KNIGHT:
value = KNIGHT_VALUE;
@@ -146,9 +184,11 @@ float EvaluateBoardForWhite(Game *b) {
break;
case BISHOP:
value = BISHOP_VALUE;
+ value += BISHOP_TABLE[PSTIndex(i, piece.color)];
break;
case ROOK:
value = ROOK_VALUE;
+ value += ROOK_TABLE[PSTIndex(i, piece.color)];
break;
case QUEEN:
value = QUEEN_VALUE;
diff --git a/src/moves.cpp b/src/moves.cpp
index 3463fe8..bba85e7 100644
--- a/src/moves.cpp
+++ b/src/moves.cpp
@@ -52,9 +52,16 @@ void GeneratePawnMoves(Game *b, int from, std::vector<Move> &moves) {
// if piece it want to move to is none and it as legal move
if (b->pieces[next].type == NONE) {
- moves.push_back({position, IndexToPosition(next)}); // adding legal move
+ if (position.rank + (pawn.color ? -1 : 1) == 0 ||
+ position.rank + (pawn.color ? -1 : 1) == 7) {
+ moves.push_back({position, IndexToPosition(next), QUEEN});
+ moves.push_back({position, IndexToPosition(next), ROOK});
+ moves.push_back({position, IndexToPosition(next), BISHOP});
+ moves.push_back({position, IndexToPosition(next), KNIGHT});
+ } else {
+ moves.push_back({position, IndexToPosition(next)});
+ }
- // todo find why this code is here and what it does
int startingRank = pawn.color ? 6 : 1;
int twoSteps = from + step * 2;
if (position.rank == startingRank && b->pieces[twoSteps].type == NONE) {
@@ -79,7 +86,14 @@ void GeneratePawnMoves(Game *b, int from, std::vector<Move> &moves) {
if (b->pieces[target].type != NONE &&
b->pieces[target].color != pawn.color) {
- moves.push_back({position, IndexToPosition(target)});
+ if (targetRank == 0 || targetRank == 7) {
+ moves.push_back({position, IndexToPosition(target), QUEEN});
+ moves.push_back({position, IndexToPosition(target), ROOK});
+ moves.push_back({position, IndexToPosition(target), BISHOP});
+ moves.push_back({position, IndexToPosition(target), KNIGHT});
+ } else {
+ moves.push_back({position, IndexToPosition(target)});
+ }
}
}
// the end
diff --git a/src/uci.cpp b/src/uci.cpp
index a2c3672..42be55d 100644
--- a/src/uci.cpp
+++ b/src/uci.cpp
@@ -5,6 +5,7 @@
#include "moves.hpp"
#include <algorithm>
+#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdlib>
@@ -99,6 +100,24 @@ void Uci() {
cout << "bestmove ";
cout << (char)(best.From.file + 'a') << 8 - best.From.rank
<< (char)(best.To.file + 'a') << 8 - best.To.rank;
+ if (best.promotion != NONE) {
+ switch (best.promotion) {
+ case QUEEN:
+ cout << "q";
+ break;
+ case ROOK:
+ cout << "r";
+ break;
+ case KNIGHT:
+ cout << "n";
+ break;
+ case BISHOP:
+ cout << "b";
+ break;
+ default:
+ assert(false && "Unexepted promotion type");
+ }
+ }
println();
cout.flush();