利用Python实现了一个人机棋子博弈游戏
随机生成4堆棋子(棋子数为10以内的整数),人先选,电脑后选,选到最后一个棋子胜,每次只能从一堆中选棋子,个数不限
将每堆棋子的个数转为二进制a1,a2,a3,a4,进行二进制不进位相加得到a,规定a=0这个状态为偶状态,那么最后四堆全空也是偶状态。所以只要保证每轮选择完成后为偶状态,无论下一轮另一个怎么选择,都会破坏偶状态,再按照上面的方法恢复偶状态,循坏直到最后四堆全空的偶状态即胜利。如果最开始相加得出的a不为0,那么a1,a2,a3,a4中必有至少一个ai在a的最高位为1(若a为0100,则a1,a2,a3,a4中必有至少一个ai的第二位为1,注意从第0位开始),为了保证a=0,那么就在ai这堆中选择棋子,才能使a的最高位变为0。假设选择bi个,剩下(ai-bi)个,为了使a=0,必须保证剩下的(ai-bi)与另外三堆棋子的二进制和为0,即
- (a1-b1)+a2+a3+a4=0(假设i=1)
- 又 ∵ a1+a2+a3+a4=a
- ∴ a1-b1=a1-a
- ∵a1-b1为十进制运算,a1-a为二进制运算,二进制不进位相减即为相加
- ∴a1-b1=a+a1
- 即ai-bi(十进制减法)=a+ai(二进制不进位加法)
由此可得,每轮电脑要在ai这堆中剩下的棋子数为(a+ai)(二进制)个,那么电脑每轮要取走的棋子数bi,即
- bi=ai-(a+ai)
- 将二进制的a+ai转为十进制后,这是剩下的棋子个数,用总个数ai进行十进制减法即可得到取走的棋子数bi
若最初的a=0,则后选有必胜策略,若a!=0,则先选有必胜的策略,在这个程序中随机生成的一般a!=0,那么人先选,人如果知道这个算法,电脑必输
下面是摘自网上的一个例子 1)假设各堆棋子数为12、19、21、23、26,先将各堆的棋子数(12,19,21,23,26)换算成二进制数 12:1100 19:10011 21:10101 23:10111 26:11010
2)将上面所有二进制数进行不进位加法运算(0?0=0,0?1=1,1?0=1,1?1=0)得出00111,其中第3位(从右数起)为1,且高于第3位的数都是0。
3)在各堆的棋子数(12,19,21,23,26)找出满足其二进制数与2)中得出的二进制数(00111)在第(3)位都是1的棋子数12(或21或23)。
4)将3)选出的一堆棋子的二进制数1100(或10101或10111)与2)中得出的二进制数(00111)再进行不进位加法运算,并将计算得出的数1011(或10010或10000)转成十进制数11(或18或16)。
5)在3)中选出的一堆12(或21或23)中,拿去一些石子,使得剩余棋子数为4)最后得到的数11(或18或16)。
6)每当乙取完后,甲再按1)~5)的方法取棋子,就能获胜。