Минимакс для манкалы - PullRequest
       72

Минимакс для манкалы

0 голосов
/ 25 сентября 2019

Я пытаюсь написать настольную игру Mancala для случайных игроков и игроков.Игра отлично работает для случайных игроков и людей, но у меня есть проблемы с реализацией Minimax.Есть метод move (), он принимает одно целое число action в качестве параметра (номер пита) и соответственно изменяет игровое поле.Для игроков-людей int action читается с помощью Scanner, для Random он генерируется случайным образом с классом Random (), но для AI я хочу, чтобы это число было возвращено методом minimaxDecision (State s).Мой код возвращает java.lang.ArrayIndexOutOfBoundsException: индекс -1 за пределами для ошибки длины 14.

    //IMPLEMENTATION OF AI PART STARTS HERE


State transition (State initial_state, int action) {

    Board fake_board = this.board; //create a copy of the real board (not to mess up the real board)

    Board end_board = this.move(fake_board, action);

    int player;

    if(this.type == 1) player = 0;
    else player = 1;

    State final_state = new State(player, end_board);

    return final_state;
}


int maxValue(State state) {
    int MAX = -99999;

    if(state.isTerminal()) return state.getUtility();

    List <Integer> actions = state.getActions();

    for(int i = 0; i < actions.size(); i++) {

        State temp = this.transition(state, actions.get(i));
        int v = this.minValue(temp);

        if(v > MAX) {
            MAX = v;
        }
    }
    return MAX;
}

int minValue(State state) {

    if(state.isTerminal()) return state.getUtility();

    int MIN = 999999;

    List <Integer> actions = state.getActions();

    for(int i = 0; i < actions.size(); i++) {

        State temp = this.transition(state, actions.get(i));
        int v = this.maxValue(temp);
        if(v < MIN) {
            MIN = v;
        }
    }

    return MIN;
}

int minimaxDecision (State s) {

    int action_max = 3;
    int v = 0;

    List <Integer> actions = s.getActions();

    for(int i = 0; i < actions.size(); i++){

        State temp = this.transition(s, actions.get(i));
        int arg_max = this.minValue(temp);

        if(arg_max > v) {
            v = arg_max;
            action_max = actions.get(i);
        }
    }

    return action_max;
}

Методы класса состояния: isTerminal - возвращает true, если любая из сторон доски пуста, getUtility - возвращает разницу в количестве камней для 1-го и 2-го игроков;getActions - возвращает ArrayList со всеми непустыми ямами.

public class State {

int player;
Board board;

public State(int player, Board board) {

    this.player = player;
    this.board = board;
}

boolean isTerminal() {
    return this.board.isHalfEmpty();
}

List <Integer> getActions(){

    List <Integer> actions = new ArrayList<Integer> ();

    if(this.player == 1) {

        for(int i = 0; i <= 5; i++) {

            if(this.board.holes[i].num_stones > 0) {

                actions.add(i);
            }
        }
    }

    else {
        for(int i = 7; i<=12; i++) {
            if(this.board.holes[i].num_stones > 0) {
                actions.add(i);
            }
        }
    }

    return actions;
}

int getUtility() {

int util1 = 0;

for(int i = 0; i <= 5; i++) {

    util1 += this.board.holes[i].num_stones;
}

int util2 = 0;

for(int i = 7; i <= 12; i++) {

    util2 += this.board.holes[i].num_stones;
}

if(this.player == 1) return util1 - util2;
else return util2 - util1;

}

}

Я строго следовал инструкциям учебника AI Modern Approach.Может кто-нибудь сказать, пожалуйста, что я делаю не так?Заранее спасибо

...