我正在尝试模拟以下游戏: 该游戏由2名玩家组成。想象一下,你有一个带有顶点和边的图。每转一圈,你可以移除一条边,如果你隔离一个顶点,你得到一个点,你可以删除另一个。你一直玩,直到没有更多的边缘,点数最多的玩家赢得游戏。
我用数组表示图形,我从一个由另一个程序生成的单独文件中读取,例如这个:
0 1 1 0
1 0 1 1
1 1 0 0
0 1 0 0
玩家1可以用4/0获胜,但玩家2也可以获胜。 对于玩家1,最好的结果是1/3。
编辑:“玩家怎么能用4/0获胜?” :
A--B--D
| /
c
A--B--D
|
C
A B--D
|
C
正如你所看到的,如果中间边缘被移除,第一个玩家将得到4分,否则另一个玩家将得到4分。
我可以为每个球员获得最好的结果,但是其他球员每回合都不会选择最好的回合。我花了很多时间尝试它,但我总是遇到同样的问题。
编辑:我认为我现在已经非常接近解决这个问题了(然后我一直在思考这个问题),我只需要为每个回合保存2个分数,然后不知何故我必须做到这一点只接受当前玩家的最高分。这样我就能够让玩家忽略4/0的移动...... 编辑:我试图实施这个建议,但不幸的是我再次陷入困境。我得到一个奇怪的输出太高,或者函数只是给我-2作为答案,但它不适用于其他更大的图形。我已经尝试了很多东西来解决它,但它只是不起作用。下面的代码就是我现在正在尝试的,不幸的是它也不起作用:int Matrix::getTurn (bool** array) {
if (edges == 0)
return 0;
for (int i=0; i<edges; i++) {
for (int j=0; j<edges; j++) {
if (array[i][j] == true) {
array[i][j] = false;
array[j][i] = false;
score = getScore (array, i, j);
if (score > 0)
score += getTurn (array);
else score -= getTurn (array);
if (score > maxScore)
maxScore = score;
array[i][j] = true;
array[j][i] = true;
}
}
}
return maxScore;
}
maxScore和score是该类的成员变量。有人可以指出它需要纠正的部分吗?
另一个编辑,仍然无法正常工作,现在我根本没有看到错误。它保持输出1,就像它从未改变过maxScore ... Takken是剩下的边数,我尝试使用数组的边界,但它没有任何区别..
int Matrix::berekenZet (bool** array) {
if (takken == 0)
return 0;
int maxScore = 0, score = 0;
for (int i=0; i<takken; i++) {
for (int j=0; j<takken; j++) {
if (array[i][j] == true) {
array[i][j] = false;
array[j][i] = false;
takken -= 1;
score = berekenScore (array, i, j);
if (score > 0)
score += berekenZet (array);
else score -= berekenZet (array);
if (score > maxScore)
maxScore = score;
array[i][j] = true;
array[j][i] = true;
takken += 1;
score = 0;
}
}
}
return maxScore;
}
提前致谢。
答案 0 :(得分:1)
您似乎正在尝试实施某种形式的Minimax算法。这为玩家找到了最好的分数,假设两个玩家都为自己做出了最好的动作。
但是你的代码中有一些奇怪的东西:分数变量太多,在函数中间无条件地分配给maxScore
(从而失去旧值),我看不出分数如何可能会收到非零值。
这是我在伪代码中实现的。函数getScore(graph)
将为轮到它的玩家返回最佳分数(假设两个玩家都玩最大化他们自己的分数),其中“分数”表示玩家的分数减去其他玩家的分数。我正在使用minimax的Negamax变体。这使用了这样的事实:一个玩家的+ x分数与另一个玩家的-x分数相同,以避免必须两次写东西。甚至没有必要跟踪它的转向,因为两个玩家都可以做出完全相同的动作。
int getScore(graph):
if no possible moves:
return 0
maxScore = -infinity
for each possible move:
make the move
score = the score directly obtained by this move
if the player gets another turn:
score += getScore(graph)
else: //opponent turn - subtract opponent's best score from player score
score -= getScore(graph)
maxScore = max(maxScore, score)
undo the move
return maxScore