game* evolve_torus(game* g) { game* next = clone_game(g); //Clone game for evolution int i, j, neighbor_cnt; for (i = 0; i < g->rows; i++) { for (j = 0; j < g->cols; j++) { neighbor_cnt = neighbors_torus(g, i, j); if (g->board[i][j] == ALIVE) { //ALIVE case if (neighbor_cnt == 2 || neighbor_cnt ==3) { ; //Do nothing, stays alive } else { next->board[i][j] = DEAD; //Else it dies } } else { //DEAD case if (neighbor_cnt == 3) { //If it has 3 living neighbors, it comes back to life next->board[i][j] = ALIVE; } } } } return next; }
void evaluate_move(GAME *game, MOVE move, int *vector, int to_depth) { GAME *game2 = clone_game(game); int window[MAX_PLAYERS]; memset(window, 0, sizeof(window)); apply_move(game2, move); search_tree(game2, vector, to_depth, window, game2->current_player); stack_pop(&game_stack, game2); }
MOVE search_tree(GAME *game, int *best_vector, int to_depth, int *window_vector, int window_player) { MOVE moves[MAX_MOVES]; int num_moves; int i; MOVE best_move = MOVE_INVALID; int player; unsigned int hash; if (to_depth <= 0 || game_is_over(game)) { evaluate_game_immediate(game, best_vector); return best_move; } #ifdef USE_TRANSPOSITION_TABLE_SEARCH hash = hash_game(game) % TRANSPOSITION_TABLE_SIZE; if (transposition_table[hash][0] != TABLE_UNUSED) { memcpy(best_vector, transposition_table[hash], sizeof(int)*MAX_PLAYERS); hit_count++; return best_move; } #endif num_moves = generate_valid_moves(game, moves); player = game->current_player; for (i = 0; i < num_moves; i++) { GAME *game2 = clone_game(game); int vector[MAX_PLAYERS]; MOVE move; apply_move(game2, moves[i]); node_count++; move = search_tree(game2, vector, to_depth - 1, best_vector, player); if (move == MOVE_INVALID) move = moves[i]; if (i == 0 || vector[player] > best_vector[player]) { memcpy(best_vector, vector, sizeof(vector)); best_move = moves[i]; } stack_pop(&game_stack, game2); /* Prune if this move is so good for the current player that the potential value for the window player is less than the window. */ if (vector[player] > parameters.total_score - window_vector[window_player]) { break; } } #ifdef USE_TRANSPOSITION_TABLE_SEARCH memcpy(transposition_table[hash], best_vector, sizeof(int)*MAX_PLAYERS); #endif return best_move; }