好的,我必须制作一个nim游戏并尝试找到总是通过以下nim游戏获胜的策略:
21场比赛,每场比赛1和2每场比赛需要1,2,3,4或5场比赛,其中一场比赛不能获得前一场比赛所需的相同数量的比赛。如果/当他们参加最后一场比赛时,电子游戏将获胜。
我必须为此编程,但我甚至不明白是要开始。如何通过这种类型的nim游戏找到获胜策略?
编辑:
所以我认为当你仍然处于中间的7场比赛时,你总能获胜。另一个可以拿2-5,最多可以加7个。当另一个取1时,你取3(另一个不能取3)然后必须选择1或2,在这种情况下你将获得一个并获胜。
然而,从21岁到7岁对我来说是一个难题,我无法弄清楚你如何能够永远成为7岁的人。
编辑2: 好吧,如果没有规则,你不能像以前的玩家一样,我认为这很简单。
你要使k = 5 + 1 = 6.然后你应该进行第一次移动,使得匹配离开然后%6 = 0.所以在这种情况下先取3然后再填充另一个的移动玩家到6.但是在这种情况下,这将无法工作,因为其他玩家可以采取3后,你不能采取3来填补6.所以有我的问题。有什么想法吗?
EDIT3:
好的,所以你说我可以逼7场比赛。但是假设我对14-7比赛步骤采取相同的想法。 (然后是轮到他人了)然后有两种情况: 1:他拿下2-5,我把它填到七,让7在那里,我赢了。 2:他拿1分,所以剩下13分。当我在(7-0)步骤中取3时,它变为10.然后他取5,我不能再拿5来完成,我会松开。
这就是问题所在,方案2在(7-0)步骤中没有问题。我该如何解决这个问题?
是的,解决方案:
顺便说一句,na speler 1意味着:在玩家1轮之后等(我是荷兰人)。
好的,所以我尝试了一些东西,我想我有解决方案。你必须先将1场比赛作为第一名球员。然后其他人可以参加2-5场比赛。你匹配(双关语)他的金额最多为7,所以你总共会有(21-1-7 =)13场比赛。然后又是玩家2的回合,并且有两种情况:玩家2需要1,2,4或者5场比赛,在这种情况下,您将获得与左侧将有7个匹配的匹配。 (正如之前所说的那样,当你进行比赛时,剩下7分,你总会获胜)。第二种情况是,玩家2需要3场比赛,在这种情况下,当轮到你时,中间有10场比赛。你不能拿3来制作7,因为你不能拿2倍相同的金额。所以你拿5分,剩下5分。玩家2然后不能拿5赢,并且必须选择1-4,之后你可以拿下其余的并获胜。
这是我猜的解决方案。我不知何故来到它,因为我注意到了这一点:
使用模数等的正常Nim游戏:
P2 1 2 3 4 5
P1 5 4 3 2 1
------------------
6 6 6 6 6
但你不能在这里做3,3所以这就是谎言:
p2 1 2 3 4 5
p1 5 4 3 2 1
---------------------
7 7 7 7
所以你每次都能做7次,1次是特例。我不知道为什么,但我直觉地把1作为起点,因为你觉得你需要主动控制对方的动作。 (一个人不能做两次1,所以另一个人必须拿2-5才能让你掌控)
无论如何,感谢所有的帮助。也为整个程序编写。我无法使用它,因为它不会编译为缺乏良好的Java技能:)我也想自己解决它。
无论如何,我看到这是一个维基,祝未来的人们好好解决这个问题!
答案 0 :(得分:8)
在这样的游戏中,你需要保持处于获胜位置的不变性(如果你已经在一个位置)。所以你需要知道如何从一个胜利的位置开始,然后回到它无论你的对手做什么动作。
以下是三个提示:
在modular arithmetic的概念中解释了我想要的概念,如果有帮助的话。
编辑:但是,不采取相同数量的匹配的限制使事情变得有趣。我们将不得不在以后作为一个角落案例解决这个问题,但让我们首先看看你是如何看到我到目前为止所说的。请随时评论。
编辑2:你的第二次编辑是正确的(如果不存在重复移动的规则,我的意思是)。但是你的第一次编辑是在正确的轨道上:你可以让事情在7年代起作用。
不断质疑和回答自己:
问:如何通过让AI进行最后一场比赛来可靠地强制获胜? 答:强制AI留下7场比赛,然后用你的策略迫使AI拿下第7个。这是因为您可以强制减去7个匹配项 问:那么如何通过确保AI进行最后一场比赛(但是七场)来强制赢得AI?
不要过度思考它。拿走你已经知道的东西 - 你已经可以做到的AI - 并尽可能多地应用这一步。
编辑3:这只是我想到的一个小问题,可以帮助您解决在第三次编辑中提到的问题。
如果,对于移动组中的所有X(1,2,3,4,5),当AI轮到时仍然有2X个匹配,那么你可以通过X匹配来强制获胜。 (您在第三次编辑中详细说明了除了其他玩家之外的其他方式)
不幸的是,这不是你可以强迫的,因为我说的是在AI轮到之前有2X匹配,而其他战略获胜条件取决于之后的位置 AI转向,因此AI的举动可以迫使它。
同样,你要避免让AI的移动结果为任何一个X的2X匹配。
答案 1 :(得分:2)
如果您需要缩短运行时间,请使用Minimax algorithm,可能还需要使用alpha-beta修剪。
基本上,您可以详尽地搜索可能移动的树,然后再向上工作以确定最佳结果。
编辑:这里有一些代码向您展示制作完美代理是多么容易。编码花了大约5分钟。
public class MinimaxNim {
public static int getBestMove(int matchesLeft, int lastVal) {
int max = Integer.MIN_VALUE;
int bestMove = matchesLeft > 0 ? 1 : 0;
for ( int move = 1; move <= 5 && move <= matchesLeft; move++ ) {
if ( move == lastVal )
continue;
int val = minValue(matchesLeft - move, move);
if ( val > max ) {
bestMove = move;
max = val;
}
}
return bestMove;
}
private static int maxValue(int matchesLeft, int lastVal) {
if ( matchesLeft == 0 )
return -1; //min has won
int max = Integer.MIN_VALUE;
for ( int toTake = 1; toTake <= 5 && toTake <= matchesLeft; toTake++) {
if ( toTake == lastVal )
continue;
int val = minValue(matchesLeft - toTake, toTake);
if ( val > max ) {
max = val;
}
}
return max;
}
private static int minValue(int matchesLeft, int lastVal) {
if ( matchesLeft == 0 )
return 1; //max has won
int min = Integer.MAX_VALUE;
for ( int toTake = 1; toTake <= 5 && toTake <= matchesLeft; toTake++) {
if ( toTake == lastVal )
continue;
int val = maxValue(matchesLeft - toTake, toTake);
if ( val < min ) {
min = val;
}
}
return min;
}
}
你可以用这个来测试:
public static void main(String[] args) {
int count = 21;
int move = -1;
for ( ;; ) {
move = getBestMove(count, move);
System.out.println("Player 1 takes " + move);
count -= move;
if ( count == 0 ) {
System.out.println("Player 1 has won");
break;
}
move = getBestMove(count, move);
System.out.println("Player 2 takes " + move);
count -= move;
if ( count == 0 ) {
System.out.println("Player 2 has won");
break;
}
}
}
但我建议用自己或随机代理替换玩家1或玩家2,以便检查完美玩家所做的动作。
同样,这并没有向您展示最佳策略,但它会展现出对任何对手的最佳游戏(虽然未经测试)。
修改2
如果您感到好奇,从初始状态开始,只有26705个终端状态(玩家赢了)需要检查。随着你做出更多动作,这变得越来越少。这对于极小极大运动来说是完美的,就是总是取得进步......一旦你还剩下15场比赛,你就不能回到17,例如在象棋这样的游戏中你可以在搜索树中获得循环,因为玩家可以在棋盘上跳舞,回到以前的状态等等。
答案 2 :(得分:1)
正如需要考虑的更多数据一样,我针对游戏中可能存在的每种可能情况运行我的代理(剩余1-21次,最后5次移动)。其中一些状态是不可能的(例如20,最后一步是2)。我从表中删除了大部分内容,但更多可能仍然存在。
如果该组合有一个值,则表示在该点播放该移动肯定会导致获胜(假设持续完美的比赛)。
标有x的那个意味着处于该状态肯定会导致失败而不管移动(假设对手的完美发挥)。
0 1 2 3 4 5
21 1
20 x
19 3
18 5 5 5
17 4 4 5
16 3 3 x 3 3
15 2 1 1 1 1
14 x 1 1 1 1
13 x x x x x
12 5 5 5 5 x
11 4 4 4 x 4
10 3 3 5 3 3
9 2 3 2 2 2
8 4 1 1 1 1
7 x x x x x
6 3 3 x 3 3
5 5 5 5 5 x
4 4 4 4 x 4
3 3 3 x 3 3
2 2 1 1 1 1
1 x 1 1 1 1
因此,如果您坚持进行分析,您可以在此表中查找(或者,如果有多个最佳动作)最佳移动是在该特定状态。
有一点需要注意的是,到目前为止你的分析完全符合你的要求:如果这是你的举动,而且剩下7支,你就搞砸了!但注13也是如此。