我在解决Misere Nim游戏中的缺陷在哪里

时间:2017-01-02 06:27:05

标签: c# algorithm game-theory

游戏中你有N堆石头,每个玩家轮到他必须从一堆中移除至少一块石头,并且移除最后一块石头的玩家输了。

我从基础案例

开始,在十几个案例中写出了胜利者
/*
    stones             | winner  | N | ones 
    ========================================
    {1}                | Second  | 1 |  1   
    {i}, i>1           | First   | 1 |  0
    {1,1}              | First   | 2 |  2
    {1,i}, i>1         | First   | 2 |  1
    {i,j}, i,j>1       | Second  | 2 |  0
    {1,1,1}            | Second  | 3 |  3
    {1,1,i}, i>1       | First   | 3 |  2
    {1,i,j}, i,j>1     | First   | 3 |  1
    {i,j,k}, i,j,k>1   | First   | 3 |  0
    {1,1,1,1}          | First   | 4 |  4
    {1,1,1,i}          | First   | 4 |  3
    {1,1,i,j}, i,j>1   | Second  | 4 |  2
    {1,i,j,k}, i,j,k>1 | First   | 4 |  1
    {i,j,k,m}, ...     | Second  | 4 |  0
*/

从那以后我想我推导了一个公式

static string GetWinner(int[] piles)
{
    int n = piles.Length, m = piles.Count(stones => stones == 1);
    if(m == n) // one stone per pile
        return n % 2 == 0 ? "First" : "Second";
    // if here, m < n
    return n % 2 == 0 ? (m % 2 == 0 ? "Second" : "First") : "First";
}

但这导致测试用例{2,1,3}失败,导致"Second"

我尝试使用以下事实。

  • 如果22,那么堆积中任意数量大于2的宝石都会产生相同的结果。原因是因为如果它大于1且玩家在该转弯时没有将桩缩小到ul li:first-child { //some css } 那么玩家基本上已经让他的对手转弯了。

然而,可能有些事我错了..

1 个答案:

答案 0 :(得分:2)

我认为您的以下陈述是关闭的:

  

堆积中任何数量大于2的石头如果是2

,都会得到相同的结果

如果状态是{1,2,2}第一位玩家可以通过移除1石头获胜。如果状态是{1,2,3},则第一个玩家无法获胜。因此,如果石头的数量是2或3,则存在差异。

  

因为如果它大于2且玩家在该转弯时没有将桩缩小到1,那么玩家基本上会让对手转弯。

这是正确的,除了有时候“转向另一位玩家”,即通过转弯是“理想的”。

最优策略与二进制表示中每个堆中项目数的XOR有关。有关最佳解决方案和详细信息,请参阅https://en.wikipedia.org/wiki/Nim