minmax对连接4没有效率

时间:2016-07-08 18:46:41

标签: java minimax minmax

像我看到的许多其他人一样,我对游戏Connect4的Minmax算法的实现有问题。在下面的示例中,算法不会尝试阻止播放器两个,我不明白为什么。我的评估函数非常基本:二元函数。也许这是因为深度,但我不这么认为。

代码:

public class Moteur {

public static void addPawn(int[][] game, int column, int player) {
    int i = 0; 
    while (i < 6 && game[i][column] == 0) {
        i++; 
    }
    game[(i==6)?5:i-1][column] = player; 
}

public static void kickPawn(int[][] game, int column) {
    int i = 0; 
    while (i < 6 && game[i][column] == 0) {
        i++; 
    }
    game[i][column] = 0; 
}

public static void AI_play(int[][] game, int depth) {
    int max = -10000; 
    int tmp = 0; 
    int maxj = -5; 
    int j; 

    for (j = 0; j < 7; j++) {
        if(game[0][j] == 0) {
            addPawn(game, j, 1); 
            tmp = Min(game, depth - 1); 

            if (tmp > max) {
                max = tmp; 
                maxj = j; 
            }
            kickPawn(game, j); 
        }
    }
    addPawn(game, maxj, 1); 
}



public static int Max(int[][] game, int depth) {

    if(depth == 0 || winner(game) != 0) {
        return eval(game); 
    }

    int max = -10000; 
    int j, tmp; 

    for(j = 0; j < 7; j++) {
        if(game[0][j] == 0) {
            addPawn(game, j, 2); 
            tmp = Min(game, depth - 1); 

            if(tmp > max) {
                max = tmp; 
            }
            kickPawn(game, j); 
        }
    }
    return max; 
}


public static int Min(int[][] game, int depth) {

    if(depth == 0 || winner(game) != 0) {
        return eval(game); 
    }

    int min = 10000; 
    int j, tmp; 

    for(j = 0; j < 7; j++) {
        if(game[0][j] == 0) {
            addPawn(game, j, 1); 
            tmp = Max(game, depth - 1); 

            if(tmp < min) {
                min = tmp; 
            }
            kickPawn(game, j); 
        }
    }
    return min; 
}

public static int eval(int[][] game) {

    int gameWinner, nb_pawns = 0; 

    for (int i = 0; i < game.length; i++) {
        for (int j = 0; j < game[0].length; j++) {
            if(game[i][j] != 0) {
                nb_pawns++; 
            }
        }
    }
    gameWinner = winner(game); 
    if(gameWinner == 1) {
        return 1000 - nb_pawns; 
    } else if (gameWinner == 2) {
        return -1000 + nb_pawns; 
    } else {
        return 0; 
    }
}


public static int winner(int[][] game) {
    Integ e = new Integ(); 
    for (int j = 0; j < game[0].length; j++) {
        if(game[5][j]!= 0 && testWinner(game, j, e)) {
            return e.getI(); 
        }
    }
    return 0; 
}

public static boolean testWinner(int[][] game, int lastColumn, Integ e) {

    int lastRow = 0; 
    while (lastRow < 6 && game[lastRow][lastColumn] == 0) {
        lastRow++; 
    }
    lastRow = lastRow; 

    int i = 0; 
    int j = 0; 
    int currentPlayer = game[lastRow][lastColumn]; 
    e.setI(currentPlayer);
    int sequence = 0; 

    i = lastRow; 
    boolean b = i < 3
            && game[i][lastColumn] == currentPlayer 
            && game[i+1][lastColumn] == currentPlayer
            && game[i+2][lastColumn] == currentPlayer
            && game[i+3][lastColumn] == currentPlayer; 
    if(b) {
        return true; 
    }

    sequence = 0; 
    j = lastColumn; 
    do {
        j--;
    } while(0 < j && game[lastRow][j] == currentPlayer); 
    if(j < 0 || game[lastRow][j] != currentPlayer) {
        j++; 
    }
    while(j <= 6 && game[lastRow][j] == currentPlayer) {
        j++; 
        sequence++; 
    }
    if (sequence >= 4) {
        return true; 
    }


    sequence = 0; 
    i = lastRow; 
    j = lastColumn; 
    do {
        i--; 
        j--; 
    } while(0 < i && 0 < j && game[i][j] == currentPlayer); 
    if(i < 0 || j < 0 || game[i][j] != currentPlayer) {
        i++; 
        j++; 
    }
    while(i <= 5 && j <= 6 && game[i][j] == currentPlayer) {
        i++; 
        j++; 
        sequence++; 
    }
    if (sequence >= 4) {
        return true; 
    }


    sequence = 0; 
    i = lastRow; 
    j = lastColumn; 
    do {
        i++; 
        j--; 
    } while(i < 5 && 0 < j && game[i][j] == currentPlayer); 
    if (5 < i || j < 0 || game[i][j] != currentPlayer) {
        i--; 
        j++; 
    }
    while(0 <= i && j <= 6 && game[i][j] == currentPlayer) {
        i--; 
        j++; 
        sequence++; 
    }
    if (sequence >= 4) {
        return true; 
    }

    return false; 
}


public static void main(String[] args) {
    int[][] game = new int[6][7]; 
    int depth = 5; 
    game[5][3] = 2; 
    game[4][3] = 2; 
    game[3][3] = 2; 

    AI_play(game, depth); 
    //game[4][0] = 2; 
    //AI_play(game, depth); 
    //game[5][2] = 2; 
    //AI_play(game, depth); 
    //game[5][3] = 2; 
    //AI_play(game, depth); 
    //game[1][0] = 2; 
    //AI_play(game, depth); 
    //game[5][4] = 2; 
    //AI_play(game, depth); 

    for (int i = 0; i < game.length; i++) {
        for (int j = 0; j < game[0].length; j++) {
            System.out.print(game[i][j]);
        }
        System.out.println("");
    }

}

private static class Integ {

    private int i; 

    public Integ() {
        this.i = 0; 
    }

    public void increment() {
        this.i = this.i + 1; 
    }

    public int getI() {
        return this.i;
    }

    public void setI(int i) {
        this.i = i;
    }

}
}

0 个答案:

没有答案