diff options
author | eug-vs <eugene@eug-vs.xyz> | 2022-09-08 15:25:26 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2022-09-08 15:25:26 +0300 |
commit | 98611e2e9d5a9a4a98d755f76f9e182a0226de3e (patch) | |
tree | 20b51ce77d8ec6a9943685374109091c68109ab8 | |
parent | 909f073d9eb9ddcedc04cd9915c22b717d14768d (diff) | |
download | c-chess-98611e2e9d5a9a4a98d755f76f9e182a0226de3e.tar.gz |
feat: adequately generate pseudolegal moves
-rw-r--r-- | src/main.c | 82 |
1 files changed, 79 insertions, 3 deletions
@@ -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++; + } + } + } } } |