int alpha_beta(game_state state, int depth, int alpha, int beta) { if (alpha == beta) { return alpha; } vector<pair<int, int> > children = state.get_all_no_tipping_moves(); if (depth == 0) { return (int) children.size(); } if (depth % 2 == 0) { // get max, only alpha // minimax 2(2,3), 1(0), 3(1,4,1)->first for (int i = 0; i < children.size(); i ++) { int value = alpha_beta(state.move_fast(children[i]), depth-1, alpha, beta); if (value > alpha) { alpha = value; } if (alpha >= beta) { return alpha; } } return alpha; } else { // get min, only beta // maxmini 2, 1, 3->second for (int i = 0; i < children.size(); i ++) { int value = alpha_beta(state.move_fast(children[i]), depth-1, alpha, beta); if (value < beta) { beta = value; } if (beta <= alpha) { return beta; } } return beta; } }
pair<int, int> ai_move(game_state state) { vector<pair<int, int> > all_moves = state.get_all_no_tipping_moves(); if (all_moves.size() == 0) { // if all moves would tip, surrender return pair<int, int>(-1, 16); } // find best solution int alpha = -1000; int beta = 1000; int best_index = 0; if (state.game_turn < 15) { ai_depth = 3; } else { ai_depth = 4 + (state.game_turn-15) / 3; } cout << "[[TURN:" << state.game_turn << "]]\n"; cout << "======= depth: " << ai_depth << " ==========\n"; time_t s_time = time(NULL); for (int ii = 0; ii < all_moves.size(); ii ++) { int i = ii; if (ai_depth % 2 == 0) { i = (int) all_moves.size() - ii - 1; } int this_value = alpha_beta(state.move_fast(all_moves[i]), ai_depth-1, alpha, beta); // cout << all_moves[i].first << "," << all_moves[i].second << " : " << this_value << "\n"; if (ai_depth % 2 == 0) { // minimax 2(2,3), 1(0), 3(1,4,1)->first if (this_value > alpha) { alpha = this_value; best_index = i; } } else { // maxmini 2,1,3->second if (this_value < beta) { beta = this_value; best_index = i; } } if (alpha >= beta) { break; } } time_t e_time = time(NULL); cout << "======used: " << e_time-s_time << " seconds=======\n"; return all_moves[best_index]; }