N-Puzzle伪随机改组?

时间:2011-05-23 23:58:25

标签: java android algorithm puzzle

我正在开发N-Puzzle游戏(也称为15-puzzle ...),你可以在正方形网格上分割图像,移除一个图像并随机播放。我对解谜的解决方案不太感兴趣,因为这取决于用户。但我想伪随机地洗牌。

我知道所有可能的洗牌中有一半会让董事会无法解决。假设我有一些rand() - esc函数并且我知道电路板的大小,是否有一种简单的伪随机方法来生成一个混洗状态?

我在内存中有一个游戏板,一个多维的整数数组。 我的方法只是将图像按相反的顺序放置,在偶数板上用倒数第二个图像切换最后一个图像。 我当前的功能如下,我正在使用Java。

private void shuffle()
{
    gameState = new int[difficulty][difficulty];
    int i = 0, N = (difficulty * difficulty) -1;

    while (i < N)
        gameState[(int)(i / difficulty)][i % difficulty] = N - ++i;
    gameState[difficulty-1][difficulty-1] = N;

    // N id even when the remainder of N/2 is 0
    if ((difficulty % 2) == 0)
    {
        // swap 2nd to last and 3rd to last element
        int tmpEl = gameState[difficulty-1][difficulty-2];
        if (difficulty == 2)
        {
            gameState[1][0] = gameState[0][1];
            gameState[0][1] = tmpEl;
        }
        else
        {
            gameState[difficulty-1][difficulty-2] = gameState[difficulty-1][difficulty-3];
            gameState[difficulty-1][difficulty-3] = tmpEl;
        }
    }
}

3 个答案:

答案 0 :(得分:6)

这个问题基本上归结为做一个小扭曲的标准shuffle算法。

关键的观察结果是,对于可以解决的15-puzzle,排列的奇偶性和空白方块的奇偶性必须相同。

首先使用标准算法为此目的创建随机排列。例如Knuth shuffle算法:Random Permutations

使用Knuth的shuffle(或Fisher-Yates shuffle)的优势在于它涉及交换数字,因此您可以轻松跟踪排列的奇偶校验。每次交换都保持奇偶校验(如果您交换1和3),或更改奇偶校验(如果您交换1和2)。

将空白方块放在与排列奇偶校验相同的奇偶校验上,然后就完成了。 如果置换具有奇数奇偶校验,则将空白放置为奇数平方(1,3,5,......随机选择)。如果排列具有偶数奇偶校验,则将空白放在偶数平方上。

答案 1 :(得分:3)

我的建议是跟踪阵列中的空方块(您已移除的部分) 然后,选择这个空方块的随机边(确保进行必要的边界检查)并将那边的那块用空方块“交换”。这模拟了玩家可以做的滑动动作 多次重复此操作(设置简单难度 - 难度设置您进行的迭代次数),每次在整个数组中“滑动”空方块。

使用这种方法,您只需跟踪空方块的位置,然后选择一个随机边移动。

希望这会对你有所帮助 - 我这里没有提供任何代码,只是一个简单的算法供你使用。

答案 2 :(得分:2)

只需生成随机谜题,直到您生成具有偶数奇偶校验的谜题。 http://heuristicswiki.wikispaces.com/N+-+Puzzle