aboutsummaryrefslogtreecommitdiff
path: root/src/moves.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/moves.cpp')
-rw-r--r--src/moves.cpp76
1 files changed, 75 insertions, 1 deletions
diff --git a/src/moves.cpp b/src/moves.cpp
index 0059039..7efd00a 100644
--- a/src/moves.cpp
+++ b/src/moves.cpp
@@ -2,9 +2,38 @@
#include <cassert>
#include <cstdint>
#include <sys/types.h>
+#include <vector>
#include "board.hpp"
#include "moves.hpp"
+void GenerateKnightMoves(Board *b, int from, std::vector<Move> &moves) {
+
+ Piece knight = b->pieces[from];
+ if (knight.type != KNIGHT) {
+ assert(false && "Calling generate knight moves on non knight");
+ return;
+ }
+ // Knight moves: https://www.chessprogramming.org/Knight_Pattern
+ constexpr std::array<int, 8> knight_moves{-10, 6, 15, 17, 10, -6, -15, -17};
+
+ for (int offset : knight_moves) {
+ int next = from + offset;
+ if (next >= 64 || next < 0) {
+ continue;
+ }
+ const int fileDelta = std::abs((next % 8) - (from % 8));
+ if (fileDelta != 1 && fileDelta != 2) {
+ continue;
+ };
+ if (b->pieces[next].type != NONE) {
+ if (b->pieces[next].color == b->turn) {
+ continue;
+ };
+ }
+
+ moves.push_back({IndexToPosition(from), IndexToPosition(next)});
+ }
+};
void GeneratePawnMoves(Board *b, int from, std::vector<Move> &moves) {
Piece pawn = b->pieces[from];
if (pawn.type != PAWN) {
@@ -49,7 +78,7 @@ void GeneratePawnMoves(Board *b, int from, std::vector<Move> &moves) {
// the end
}
-std::vector<Move> GetLegalMoves(Board *b) {
+std::vector<Move> GetPseudoLegalMoves(Board *b) {
std::vector<Move> moves;
moves.reserve(50); // almost all position dont have that many moves
@@ -69,6 +98,9 @@ std::vector<Move> GetLegalMoves(Board *b) {
if (piece.type == PAWN) {
GeneratePawnMoves(b, i, moves);
}
+ if (piece.type == KNIGHT) {
+ GenerateKnightMoves(b, i, moves);
+ };
if (piece.type == BISHOP) {
GenerateSlidingMoves(b, i, bishop_Moves, moves);
}
@@ -86,6 +118,48 @@ std::vector<Move> GetLegalMoves(Board *b) {
return moves;
}
+std::vector<Move> GetLegalMoves(Board *b) {
+ std::vector<Move> moves = GetPseudoLegalMoves(b);
+ std::vector<Move> legalMove;
+ for (Move move : moves) {
+ bool isLegal = true;
+ Board testBoard = *b;
+ PlayMove(move, &testBoard);
+ testBoard.turn = !testBoard.turn;
+ auto opponentResponse = GetPseudoLegalMoves(&testBoard);
+ for (Move move : opponentResponse) {
+ if (testBoard.pieces[PositionToIndex(move.To)].type == KING) {
+ isLegal = false;
+ }
+ }
+ if (isLegal) {
+ legalMove.push_back(move);
+ };
+ }
+ if (legalMove.size() == 0) {
+ bool isCheck = false;
+
+ Board testBoard = *b;
+ testBoard.turn = !testBoard.turn;
+ auto opponentResponse = GetPseudoLegalMoves(&testBoard);
+ for (Move move : opponentResponse) {
+ if (testBoard.pieces[PositionToIndex(move.To)].type == KING) {
+ isCheck = true;
+ }
+ }
+
+ if (isCheck) {
+ if (b->turn) {
+ b->state = BLACK_WON;
+ } else {
+ b->state = WHITE_WON;
+ };
+ } else {
+ b->state = STALEMATE;
+ }
+ }
+ return legalMove;
+}
Position IndexToPosition(int i) {
uint8_t rank = i / 8; // 0-7