15拼图随机播放方法问题

时间:2012-10-16 01:09:55

标签: c# .net algorithm winforms

我正在使用C#制作15个益智游戏,允许用户输入最多10 x 10拼图的自定义行和列值。因此,我遇到了shuffle方法的问题。我想做到这一点,这个难题总是可以解决的。通过首先创建一个获胜的拼图然后改变空的空间。问题是每次调用每个点击事件效率太低。我需要一种方法来调用与空白空间相邻但不是对角线的按钮的单击事件。我还使用一个看不见的静态按钮作为空白点。 PuzzlePiece类继承自Button。我不太清楚如何做到这一点。我将不胜感激任何帮助。

由于

这就是我所拥有的:

private void shuffleBoard()
    {
        //5 is just for test purposes
        for (int i = 0; i < 5; i++)
        {
            foreach (Control item in this.Controls)
            {
                if (item is PuzzlePiece)
                {
                    ((PuzzlePiece)item).PerformClick();
                }
            }
        }
    }

 void PuzzlePiece_Click(object sender, EventArgs e)
    {
        PuzzlePiece piece = (PuzzlePiece)sender;

        if (piece.Right == puzzleForm.emptyPiece.Left && piece.Top == puzzleForm.emptyPiece.Top)
        {
            movePiece(piece);
        }
        else if (piece.Left == puzzleForm.emptyPiece.Right && piece.Top == puzzleForm.emptyPiece.Top)
        {
            movePiece(piece);
        }
        else if (piece.Top == puzzleForm.emptyPiece.Bottom && piece.Left == puzzleForm.emptyPiece.Left)
        {
            movePiece(piece);
        }
        else if (piece.Bottom == puzzleForm.emptyPiece.Top && piece.Left == puzzleForm.emptyPiece.Left)
        {
            movePiece(piece);
        }
    }

2 个答案:

答案 0 :(得分:10)

对于15个拼图(和类似的滑动拼图游戏),任何拼贴排列都是可以解决的。当且仅当它具有偶数奇偶校验。

因此,您应该能够随意铺设瓷砖。如果奇偶校验是均匀的那么它可以解决。如果奇偶校验是奇数,那么只需交换两个相邻的块以反转奇偶校验,然后它就可以解决。

有关如何衡量平价的详情,请参阅此处:http://en.wikipedia.org/wiki/Fifteen_puzzle#Solvability


由于维基百科的文章已被更改,因此不再清楚如何计算十五拼图排列的平价,我将在下面进行探讨:

对于任何瓷砖排列,您可以通过以下方式计算反演:

  1. 计算所有“ Inversions ”。从右上角开始,从每个行,向下到左下角的顺序中的任何时间反转都是编号的瓦片而不是前面的瓦片。第一个图块从不计为倒置(因为它之前没有图块,因此它不能低于该图块),并且您不计算空白区域。

  2. 添加空白行的行号减去 1。

  3. 这个总数是一个安排的计数。如果Count 甚至,则排列具有偶数(或0)奇偶校验。如果Count 奇数,则它具有奇数(或1)奇偶校验。

    将起始排列的奇偶校验与目标排列的奇偶校验进行比较。如果它们是相同的,那么这个谜题是可以解决的,否则它是不可解决的。由于标准目标排列(空格,顺序为1-15)有0个反转并且空格的行数为1,因此我们得到0 + (1 - 1)或0的计数,即偶数因此目标的奇偶校验为0.因此任何也为0的起始排列都是可解的。

答案 1 :(得分:2)

如果我是你,我会将你的模型从你的UI中分离出来。

创建一个名为Puzzle的类。这个类将保持拼图状态并对状态执行所有操作。

您可能会实施MoveLeftMoveRightMoveUp&amp; MoveDown方法。为了改变你的棋盘,你可以通过随机调用这四种方法来执行(相当长的)一系列动作。

您的Puzzle类需要为UI提供足够的状态来呈现自己。

这样做可以简化代码并使单元测试更加简单。