summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2022-09-08 15:25:26 +0300
committereug-vs <eugene@eug-vs.xyz>2022-09-08 15:25:26 +0300
commit98611e2e9d5a9a4a98d755f76f9e182a0226de3e (patch)
tree20b51ce77d8ec6a9943685374109091c68109ab8
parent909f073d9eb9ddcedc04cd9915c22b717d14768d (diff)
downloadc-chess-98611e2e9d5a9a4a98d755f76f9e182a0226de3e.tar.gz
feat: adequately generate pseudolegal moves
-rw-r--r--src/main.c82
1 files changed, 79 insertions, 3 deletions
diff --git a/src/main.c b/src/main.c
index c84fb6a..13013f8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -468,9 +468,85 @@ int generate_pseudolegal_moves(Move* moves, int* board, int color) {
for (int rank = 7; rank >= 0; rank--) {
for (int file = 0; file < 8; file++) {
- int destination = rank * 16 + file;
- Move* next_ptr = moves ? moves + moves_count : NULL;
- moves_count += generate_moves_with_destination(next_ptr, board, color, destination);
+ int origin = rank * 16 + file;
+ int piece = board[origin];
+ int* ray_move = NULL;
+ if (piece % 2 == color) {
+ switch (piece & NO_COLOR) {
+ case KNIGHT:
+ ray_move = knightMoves;
+ break;
+ case BISHOP:
+ ray_move = bishopMoves;
+ break;
+ case ROOK:
+ ray_move = rookMoves;
+ break;
+ case QUEEN:
+ ray_move = queenMoves;
+ break;
+ case KING:
+ ray_move = kingMoves;
+ break;
+ default:
+ break;
+ }
+
+ while(ray_move && *ray_move) {
+ for (int destination = origin + *ray_move; !(destination & 0x88); destination += *ray_move) {
+ if (board[destination] == EMPTY || board[destination] % 2 != color) {
+ if (moves) moves[moves_count] = (Move){ origin, destination, 0 };
+ moves_count++;
+ }
+ // Knights and kings do not actually have "ray" moves
+ if ((piece & NO_COLOR) == KNIGHT || (piece & NO_COLOR) == KING) break;
+
+ // Stop ray move after we hit anything
+ if (board[destination] != EMPTY) break;
+ }
+ ray_move++;
+ }
+
+ // Handle pawns separately
+ if (piece == (PAWN | WHITE)) {
+ if (rank < 7 && board[origin + 16] == EMPTY) {
+ if (moves) moves[moves_count] = (Move){ origin, origin + 16, 0 };
+ moves_count++;
+ if (rank == 1 && board[origin + 32] == EMPTY) { // Pawns on rank 1 can move 2 squares up
+ if (moves) moves[moves_count] = (Move){ origin, origin + 32, 0 };
+ moves_count++;
+ }
+ }
+ // Attacks
+ if ((board[origin + 15] != EMPTY) && board[origin + 15] % 2 == BLACK) {
+ if (moves) moves[moves_count] = (Move){ origin, origin + 15, 0 };
+ moves_count++;
+ }
+ if ((board[origin + 17] != EMPTY) && board[origin + 17] % 2 == BLACK) {
+ if (moves) moves[moves_count] = (Move){ origin, origin + 17, 0 };
+ moves_count++;
+ }
+ }
+ if (piece == (PAWN | BLACK)) {
+ if (rank > 0 && board[origin - 16] == EMPTY) {
+ if (moves) moves[moves_count] = (Move){ origin, origin - 16, 0 };
+ moves_count++;
+ if (rank == 6 && board[origin - 32] == EMPTY) { // Pawns on rank 6 can move 2 squares down
+ if (moves) moves[moves_count] = (Move){ origin, origin - 32, 0 };
+ moves_count++;
+ }
+ }
+ // Attacks
+ if ((board[origin - 15] != EMPTY) && board[origin - 15] % 2 == WHITE) {
+ if (moves) moves[moves_count] = (Move){ origin, origin - 15, 0 };
+ moves_count++;
+ }
+ if ((board[origin - 17] != EMPTY) && board[origin - 17] % 2 == WHITE) {
+ if (moves) moves[moves_count] = (Move){ origin, origin - 17, 0 };
+ moves_count++;
+ }
+ }
+ }
}
}