Untitled

mail@pastecode.io avatar
unknown
c_cpp
6 months ago
1.7 kB
1
Indexable
Never
#include <cstdlib>

#include "../state/state.hpp"
#include "./minimax.hpp"
#define INF 1e9


/**
 * @brief get a legal action by minimax
 * S
 * @param state Now state
 * @param depth You may need this for other policy
 * @return Move 
 */
int Minimax::minimax(State *state, int dpth, int player){
  if(player == 0 && state->game_state == WIN)
    return INF;
  if(player == 1 && state->game_state == WIN)
    return -INF;
  if(dpth == 0 || state->game_state == DRAW){
    return state->evaluate();
  }
  if(player == 0){
    int value = -INF;
    auto actions = state->legal_actions;
    for(auto it : actions){
      if(state->next_state(it) == state)
        continue;
      value = std::max(value, minimax(state->next_state(it), dpth - 1, 1));
    }
    return value;
  }
  else{
    int value = INF;
    auto actions = state->legal_actions;
    for(auto it : actions){
      if(state->next_state(it) == state)
        continue;
      value = std::min(value, minimax(state->next_state(it), dpth - 1, 0));
    }
    return value;
  }
}

Move Minimax::get_move(State *state, int depth){
  if(!state->legal_actions.size())
    state->get_legal_actions();
  int maxVal = -INF;
  int minVal = INF;
  Move maxMove, minMove;
  auto actions = state->legal_actions;
  for(auto it : actions){
    int val = minimax(state->next_state(it), depth, state->next_state(it)->player);
    if(val > maxVal){
        maxVal = val;
        maxMove = it;
    }
    if(val < minVal){
        minVal = val;
        minMove = it;
    }
  }
  if(state->player == 0) // white plays first
    return maxMove;
  else
    return minMove; // Black
}