/* * return moves. in each move: * start = start_cord * end = one of the cords in end_cords (there can be at most 31 end cords) * board = currend board + piece moved from start to end. * this method is not relevant for pawns. */ moves cords_to_moves(cord start_cord, cord end_cords[32], char board[BOARD_SIZE][BOARD_SIZE], int color) { cord end_cord; int i = 0; move * new_move; moves new_moves = { 0 }; while (is_valid_cord(end_cord = end_cords[i++])) { new_move = malloc(sizeof(move)); if (new_move == NULL) { free_list(&new_moves, &free); return error_moves; } new_move->start = start_cord; new_move->end = end_cord; new_move->promotion = FALSE; new_move->is_castle = FALSE; board_copy(board, new_move->board); move_from_to(new_move->board, start_cord, end_cord); // check if psaudo-legal move is legal if (is_king_checked(color, new_move->board)){ // free(new_move); continue; } else if (!add_node(&new_moves, new_move, sizeof(move))){ free(new_move); free_list(&new_moves, &free); return error_moves; } free(new_move); } return new_moves; }
moves pawn_moves(settings * set, cord curr, int color) { moves piece_simple_moves; piece_simple_moves.len = 0; cord dest; move * single_move; moves promotions; int dest_color; int y_dir = (color == WHITE) ? 1 : -1; dest.y = curr.y + y_dir; for (int x = -1; x <= 1; x++) { single_move = malloc(sizeof(move)); if (single_move == NULL) { free_list(&piece_simple_moves, &free); return error_moves; } single_move->start = curr; single_move->promotion = FALSE; single_move->is_castle = FALSE; dest.x = curr.x + x; if (is_valid_cord(dest)) { dest_color = which_color(board_piece(set->board, dest)); //logical XOR: check if pawn can eat XOR move up if (color == dest_color) { free(single_move); continue; } if ((x == 0) != (dest_color == other_player(color))) { single_move->end = dest; board_copy(set->board, single_move->board); move_from_to(single_move->board, curr, dest); // check if psaudo-legal move is legal if (is_king_checked(color, single_move->board)) { free(single_move); continue; } if (dest.y == promotion_row(color)) { promotions = promote(single_move); if (promotions.len == -1){ free(single_move); free_list(&piece_simple_moves, &free); return promotions; } concat(&piece_simple_moves, promotions); } else if (!add_node(&piece_simple_moves, single_move, sizeof(move))) { //could not add node to linked list free(single_move); free_list(&piece_simple_moves, &free); return error_moves; } free(single_move); } } } return piece_simple_moves; }
move get_castling_move(settings * set, cord curr, int color) { cord c0 = { 0, curr.y }; cord c1 = { 1, curr.y }; cord c2 = { 2, curr.y }; cord c3 = { 3, curr.y }; cord c5 = { 5, curr.y }; cord c6 = { 6, curr.y }; cord c7 = { 7, curr.y }; move castle = error_move; cord king_dest; cord king_loc = { 4, (color == WHITE) ? 0 : 7 }; castle.start = curr; castle.is_castle = TRUE; castle.promotion = FALSE; board_copy(set->board, castle.board); int king_moved = (color == WHITE) ? set->white_king_moved : set->black_king_moved; int rook1_moved = (color == WHITE) ? set->white_rook_1_moved : set->black_rook_1_moved; int rook2_moved = (color == WHITE) ? set->white_rook_2_moved : set->black_rook_2_moved; int relevant_rook_moved = (!rook1_moved && (curr.x == 0) || !rook2_moved && (curr.x == 7)); if (!king_moved && !is_king_checked(color, set->board) && !relevant_rook_moved) { if ((curr.x == 0) && //relevant rook is rook1 (big castle) ((board_piece(set->board, c1) == EMPTY) && (board_piece(set->board, c2) == EMPTY) && (board_piece(set->board, c3) == EMPTY) && !is_cord_checked(c3, color, set->board))) { castle.end = c3; king_dest = c6; } else if ((curr.x == 7) && (board_piece(set->board, c5) == EMPTY) && (board_piece(set->board, c6) == EMPTY) && !is_cord_checked(c6, color, set->board)) { castle.end = c5; king_dest = c6; } move_from_to(castle.board, castle.start, castle.end); move_from_to(castle.board, king_loc, king_dest); } return castle; }
int solve_from_pos(int board[], int pos) { neighbours_t neighbours; init_board(board); while (get_free_neighbours(board, pos, neighbours) > 0) { int best_neighbour = choose_best_neighbour(board, neighbours); move_from_to(board, pos, best_neighbour); pos = best_neighbour; } move_from_to(board, pos, pos); if (board_completed(board) != 0) { return -1; } return 0; }