aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <adammegarules1@gmail.com>2026-07-26 17:00:49 +0200
committerAdam <adammegarules1@gmail.com>2026-07-26 17:00:49 +0200
commit60637ce41b3f033561343c5735eb16227ef240cf (patch)
tree8a09fcedb007442890b484ccb8877123dcfaf4f5
parenta2d5bfa42379b2d8087f0910ef9b672fcf5a79f5 (diff)
adding king and formating
-rw-r--r--src/moves.cpp96
-rw-r--r--src/moves.hpp2
-rw-r--r--tests/pawn_moves_test.cpp54
3 files changed, 55 insertions, 97 deletions
diff --git a/src/moves.cpp b/src/moves.cpp
index 0a997db..5c8c07e 100644
--- a/src/moves.cpp
+++ b/src/moves.cpp
@@ -1,15 +1,14 @@
#include <array>
+#include <cassert>
#include <cstdint>
#include <sys/types.h>
#include "board.hpp"
#include "moves.hpp"
-
-static 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)
- {
+ if (pawn.type != PAWN) {
+ assert(false && "Calling generate pawn moves on non pawn");
return;
}
Position position = IndexToPosition(from);
@@ -17,46 +16,40 @@ static void GeneratePawnMoves(board *b, int from, std::vector<Move> &moves)
int next = from + step;
// wrap check
- if (position.rank + (pawn.color ? -1 : 1) < 0 || position.rank + (pawn.color ? -1 : 1) >= 8)
- {
+ if (position.rank + (pawn.color ? -1 : 1) < 0 ||
+ position.rank + (pawn.color ? -1 : 1) >= 8) {
return;
}
// if piece it want to move to is none and it as legal move
- if (b->pieces[next].type == NONE)
- {
+ if (b->pieces[next].type == NONE) {
moves.push_back({position, IndexToPosition(next)}); // adding legal move
// 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)
- {
+ if (position.rank == startingRank && b->pieces[twoSteps].type == NONE) {
moves.push_back({position, IndexToPosition(twoSteps)});
}
}
// check
- for (int fileOffset : {-1, 1})
- {
+ for (int fileOffset : {-1, 1}) {
int targetFile = position.file + fileOffset;
- if (targetFile < 0 || targetFile >= 8)
- {
+ if (targetFile < 0 || targetFile >= 8) {
continue;
}
int target = (position.rank + (pawn.color ? -1 : 1)) * 8 + targetFile;
if (b->pieces[target].type != NONE &&
- b->pieces[target].color != pawn.color)
- {
+ b->pieces[target].color != pawn.color) {
moves.push_back({position, IndexToPosition(target)});
}
}
// 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
@@ -65,8 +58,7 @@ std::vector<Move> GetLegalMoves(board *b)
for (uint i = 0; i < sizeof(b->pieces) / sizeof(b->pieces[0]); i++) {
Piece piece = b->pieces[i];
- if (piece.type == NONE)
- {
+ if (piece.type == NONE) {
continue;
}
if (piece.color != b->turn)
@@ -74,30 +66,28 @@ std::vector<Move> GetLegalMoves(board *b)
// add support for knight and king later
- if (piece.type == PAWN)
- {
+ if (piece.type == PAWN) {
GeneratePawnMoves(b, i, moves);
}
- if (piece.type == BISHOP)
- {
+ if (piece.type == BISHOP) {
GenerateSlidingMoves(b, i, bishop_Moves, moves);
}
- if (piece.type == ROOK)
- {
+ if (piece.type == ROOK) {
GenerateSlidingMoves(b, i, rook_Moves, moves);
}
- if (piece.type == QUEEN)
- {
+ if (piece.type == QUEEN) {
GenerateSlidingMoves(b, i, rook_Moves, moves);
GenerateSlidingMoves(b, i, bishop_Moves, moves);
}
+ if (piece.type == KING) {
+ GenerateKingMoves(b, i, moves);
+ };
};
return moves;
}
-Position IndexToPosition(int i)
-{
+Position IndexToPosition(int i) {
uint8_t rank = i / 8; // 0-7
uint8_t file = i % 8; // 0-7
return {rank, file};
@@ -110,36 +100,56 @@ void GenerateSlidingMoves(board *b, int from,
int direction = directions[i];
int i2 = from;
- while (true)
- {
+ while (true) {
i2 += direction;
int oldFile = (i2 - direction) % 8;
int newFile = i2 % 8;
if (direction == 7 || direction == -7 || direction == 9 ||
- direction == -9)
- {
+ direction == -9) {
if (std::abs(newFile - oldFile) != 1)
break;
}
- if (i2 >= 64 || i2 < 0)
- {
+ if (i2 >= 64 || i2 < 0) {
break;
}
- if (b->pieces[i2].color == b->turn && b->pieces[i2].type != NONE)
- {
+ if (b->pieces[i2].color == b->turn && b->pieces[i2].type != NONE) {
break;
}
if ((direction == 1 || direction == -1) &&
- (i2 / 8 != (i2 - direction) / 8))
- {
+ (i2 / 8 != (i2 - direction) / 8)) {
break;
}
moves.push_back({IndexToPosition(from), IndexToPosition(i2)});
- if (b->pieces[i2].color != b->turn && b->pieces[i2].type != NONE)
- {
+ if (b->pieces[i2].color != b->turn && b->pieces[i2].type != NONE) {
break;
}
}
};
};
+
+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;
+ }
+ if (b->pieces[from].color != b->turn) {
+ assert(false && "calling generate king moves on king of opposite color");
+ return;
+ }
+ constexpr std::array<int, 8> king_moves{-1, 1, 8, -8, -9, 9, -7, 7};
+ for (int offset : king_moves) {
+ int next = from + offset;
+ if (next >= 64 || next < 0) {
+ continue;
+ }
+ if (std::abs((next % 8) - (from % 8)) > 1) {
+ continue;
+ };
+ 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 d99fc68..2cede49 100644
--- a/src/moves.hpp
+++ b/src/moves.hpp
@@ -9,5 +9,7 @@ Position IndexToPosition(int i);
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);
#endif /* SRC_MOVES_H_ */
diff --git a/tests/pawn_moves_test.cpp b/tests/pawn_moves_test.cpp
deleted file mode 100644
index 47b8ceb..0000000
--- a/tests/pawn_moves_test.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "moves.hpp"
-#include <cassert>
-
-bool HasMove(const std::vector<Move> &moves, int from, int to) {
- Position expectedFrom = IndexToPosition(from);
- Position expectedTo = IndexToPosition(to);
- for (const Move &move : moves) {
- if (move.From.rank == expectedFrom.rank &&
- move.From.file == expectedFrom.file && move.To.rank == expectedTo.rank &&
- move.To.file == expectedTo.file) {
- return true;
- }
- }
- return false;
-}
-
-int CountMovesFrom(const std::vector<Move> &moves, int from) {
- Position expected = IndexToPosition(from);
- int count = 0;
- for (const Move &move : moves) {
- if (move.From.rank == expected.rank && move.From.file == expected.file) {
- count++;
- }
- }
- return count;
-}
-
-int main() {
- board white{};
- white.turn = true;
- white.pieces[52] = createPiece(PAWN, true); // e2
- white.pieces[43] = createPiece(ROOK, false); // d3
- white.pieces[45] = createPiece(ROOK, true); // f3
-
- std::vector<Move> whiteMoves = GetLegalMoves(&white);
- assert(CountMovesFrom(whiteMoves, 52) == 3);
- assert(HasMove(whiteMoves, 52, 44)); // e2-e3
- assert(HasMove(whiteMoves, 52, 36)); // e2-e4
- assert(HasMove(whiteMoves, 52, 43)); // e2xd3
-
- white.pieces[44] = createPiece(KING, true); // block e3 and e4
- std::vector<Move> blockedMoves = GetLegalMoves(&white);
- assert(CountMovesFrom(blockedMoves, 52) == 1);
- assert(HasMove(blockedMoves, 52, 43)); // capture remains legal
-
- board black{};
- black.turn = false;
- black.pieces[12] = createPiece(PAWN, false); // e7
-
- std::vector<Move> blackMoves = GetLegalMoves(&black);
- assert(CountMovesFrom(blackMoves, 12) == 2);
- assert(HasMove(blackMoves, 12, 20)); // e7-e6
- assert(HasMove(blackMoves, 12, 28)); // e7-e5
-}