【问题标题】:connect four - comparison of evaluation - c连接四-评价比较-c
【发布时间】:2017-10-25 16:50:30
【问题描述】:

我尝试在我的四人连线游戏中实现极小极大算法。 我已经完成了评估函数和算法函数的一半。

我只是找不到“最后一个”问题的解决方案。这是我的功能:

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);
        }
    }
}

该字段是一个包含 f[COLS*ROWS+1] 的数组,其中 f[0] 是深度,其他元素保存在哪些列中被抛出。 “c”-board 代表“图形”板,0 代表免费,1 代表玩家 1,2 代表玩家 2。

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;
}

所以我的问题是,我想不出一个干净的解决方案来比较评估自下而上。我真的认为,我不需要引入新的数据结构(它会变得太大)。就像解决方案就在我面前,但我无法抓住它。

是否可以仅比较递归“返回”的评估?如果是,怎么做?

或者我真的需要引入一些新的更复杂的东西吗?或者也许我完全错过了什么?

谢谢!

【问题讨论】:

    标签: c recursion minimax


    【解决方案1】:

    或者我真的需要引入一些新的更复杂的东西吗?或许 我完全错过了什么?

    不幸的是,答案是后者。 Minimax 不是 void 函数。它返回它所代表的节点的值。这就是评估的比较方式。您还缺少另一个基本概念。您的函数仅将终端节点视为游戏获胜或棋盘已满的节点。虽然这在技术上是正确的,但没有真正的极小极大函数以这种方式工作。节点数约为 7^48,因此您的函数实际上需要十年以上才能在现代 PC 上终止。现实世界的极小极大函数所做的是设置搜索达到的最大深度(除非您添加树修剪,期望这是 5 或 6),并认为该深度的所有节点都是终端并使用启发式(不准确的猜测) 评估函数。在连接四中,这可能基于诸如连续三个的数量之类的东西。如果您知道有赢家,您犯的另一个错误是调用您的 eval 函数。如果您知道哪个玩家获胜而不是直接返回正确的值,则无需调用昂贵的 eval 函数。您也不能像以前那样为 min 和 max 流线化您的函数。您必须为 min 和 max 创建单独的函数,或者使用 negamax 变体。

    我的建议:您似乎并不真正了解应该如何实现该算法。阅读 minimax 和 negamax 伪代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-15
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2020-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多