Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
连接四个-评估比较-c_C_Recursion_Minimax - Fatal编程技术网

连接四个-评估比较-c

连接四个-评估比较-c,c,recursion,minimax,C,Recursion,Minimax,我尝试在我的connect four游戏中实现minimax算法。 我完成了求值函数,完成了算法函数的一半 我就是找不到解决“最后一个”问题的办法。以下是我的职能: void minimax(field f){ int i; field c; convert_1D_to_2D(f, c); for(i=0;i<COLS;i++) { if(can_throw(c, i) == 0) { throw(f, i); convert_1D_to_2D(f,

我尝试在我的connect four游戏中实现minimax算法。 我完成了求值函数,完成了算法函数的一半

我就是找不到解决“最后一个”问题的办法。以下是我的职能:

void minimax(field f){
int i;
field c;
convert_1D_to_2D(f, c);
for(i=0;i<COLS;i++) {
    if(can_throw(c, i) == 0) {
        throw(f, i);
        convert_1D_to_2D(f, c);
        if((is_winner(c) == 0) && (is_board_full(f) == 0)) { //no winner, board not full
            minimax(f);
        }
        else if(is_winner(c) == 1) { //there is a winner
            evaluate_turn(f);
            //compare evaluation
            undo_turn(f);
        }
        else if(is_winner(c) == 0 && (is_board_full(f) == 1)) { //no winner, board full
            evaluate_turn(f);
            //compare evaluation
            undo_turn(f);
        }
    }
}
所以我的问题是,我想不出一个干净的解决方案来比较自下而上的评估。我真的认为,我不需要引入一个新的数据结构(它会变得太大)。好像解决方案就在我面前,但我抓不住它

是否可以在递归的“返回方式”上比较计算结果?如果是,如何进行

还是我真的需要介绍一些更复杂的新东西?或者我完全错过了什么

谢谢

还是我真的需要介绍一些更复杂的新东西?或许 我完全错过了什么

不幸的是,答案是后者。极小极大不是一个空函数。它返回它所表示的节点的值。这就是评价的比较方式。您还缺少另一个基本概念。您的函数仅将终端节点视为赢得游戏或棋盘已满的节点。虽然这在技术上是正确的,但没有真正的minimax函数是这样工作的。节点的数量大约为7^48,因此您的函数在现代pc上终止实际上需要10年以上。现实世界中的minimax函数所做的是设置搜索要达到的最大深度(除非您添加树修剪,否则这将是5或6),并考虑在该深度的所有节点是终端,并使用启发式(不精确猜测)评估函数对它们进行评估。在connectfour中,这可以基于一行中的三个数字。您犯的另一个错误是,如果您知道有赢家,则调用eval函数。如果你知道哪个玩家赢了,那么直接返回正确的值,就不需要调用昂贵的eval函数。您也不能像以前那样将函数的最小值和最大值都流线化。必须为最小值和最大值创建单独的函数,或使用negamax变量

我的建议是:看来你并不真正理解该算法应该如何实现。阅读minimax和negamax伪代码

static int evaluate_turn(field f) {
field c;
convert_1D_to_2D(f, c);
if (((f[0] % 2) == 1) && (current_player == 1) && (is_winner(c) == 1) ) { //player 1 won, max for him || +1
    return 1;
}
else if (((f[0] % 2) == 2) && (current_player == 2) && (is_winner(c) == 1) ) { //player 2 won, max for him || +1
    return 1;
}
if (((f[0] % 2) == 1) && (current_player == 2) && (is_winner(c) == 1) ) { //player 2 won, counting for 1 || -1
    return -1;
}
else if (((f[0] % 2) == 2) && (current_player == 1) && (is_winner(c) == 1) ) { //player 1 won, counting for 2 || -1
    return -1;
}
else if ((is_board_full(f) == 1) && (is_winner(c) == 0)) { //draw || 0
    return 0;
}