动态创建Minesweeper游戏的游戏板

为了学习C#,XAML,尤其是MVVM,我开始编写Minesweeper游戏。 我创建的第一个版本没有MVVM部分,我创建并添加了带有C#代码的按钮,而不是通过MVVM方式在XAML中进行。 现在我尝试将MVVM模式应用到游戏中。

我制作了一个自己的用户控件,其中包含一个代表雷区部分的按钮。 此控件还具有ViewModel和Model Class,用于存储某些状态数据并处理某些命令。 在一个测试项目中,我创建了4个自己的用户控件,并尝试将它们放在一个网格中,按钮形成一个2×2按钮的正方形。 在后面的代码中,按钮放在ObservableCollection对象中。 我假设在这个对象中列出的按钮和索引如下:

Button1 Button2 Button3 Button4 

但在演示网格中我希望按钮显示为

 Button1 | Button2 --------+-------- Button3 | Button4 

问题是:我该如何动态地做到这一点? 在我的测试项目中我使用4个按钮进行测试,但在项目中我想使用它,按钮的数量可能会有所不同,具体取决于玩家选择的游戏难度。

第二个问题是我如何弄清楚按钮的neigbhours是什么。 因此,如果网格是4乘5包含20个按钮。 例如,我选择按钮8,该按钮具有作为邻居按钮编号2,3,4,7,9,12,13和14.当列出按钮时,如何到达那些邻居按钮?

我希望我的问题足够清楚。

先感谢您!

您可以使用ItemsControl显示您的集合, ItemsControl的ItemsPanel设置为GridUniformGrid 。 我在这里有一些ItemsControl示例可以帮助您,因为我没有发现MDSN的示例非常有用。

如果您可以将RowsColumns属性绑定到ViewModel的属性,那么UniformGrid将是最简单的,但是这需要所有单元格大小相同,并且我不记得属性RowsColumns是否是参与的属性的DependencyProperties绑定系统与否。

         

如果这对您不起作用,可以使用Grid作为Grid.Column ,并在ItemContainerStyle设置Grid.RowGrid.Column绑定。

这将要求您在ObservableCollection中的每个单元格对象上都有属性来说明该单元格所在的行/列,但我怀疑您无论如何都需要这些来确定单击命令中相邻单元格之类的内容。

此外,没有内置的方法来绑定Grid的行数/列数,因此我倾向于使用一些自定义附加属性 ,这些属性将根据绑定值动态构建Grid的RowDefinitionsColumnDefinitions

所以如果你使用网格你的最终结果可能看起来像这样:

              

使用模型/ ViewModel看起来像这样

 public class GameViewModel { // These should be full properties w/ property change notification // but leaving that out for simplicity right now public int Height; public int Width; public ObservableCollection Cells; } public class CellModel { // Same thing, full properties w/ property change notification public int ColumnIndex; public int RowIndex; public bool IsVisible; public bool IsMine; public int NumberAdjacentMines; } 

最近我解决了Minesweeper游戏逻辑,进行了一种软件开发竞赛。 我认为他的游戏的主要问题是找到相邻的地雷和物品周围的相邻空单元。 在这两种情况下,我们必须考虑到最多每个单元格(项目)可以被八个项目(单元格)包围。 如果我们考虑一个4×4网格(矩阵)由X,Y坐标定义的单元格C,它将被以下单元格包围:

 C1 (X-1,Y-1) C2 (X,Y-1) C3 (X+1,Y-1) C4 (X-1,Y) C5 (X+1,Y) C6 (X-1,Y+1) C7 (X,Y+1) C8 (X+1,Y+1) 

换句话说,我们可以通过平移x和y轴上的点来找到项目的相邻单元格。 我通过游戏逻辑(后端)分割游戏的呈现(前端)来开发类集。
实际上,通过使用此策略,您可以在不同的.Net环境中使用它:我们不会围绕UI元素或组件“锁定”。
你可以在这里下载我的项目:
https://github.com/alchimya/csharp-minesweeper-sdk

脱离我的头顶:

 List 

要跟踪周围的按钮,您需要知道网格的宽度是多少,例如,如果网格宽度为20个按钮,则按钮将如下所示:

 [B-20-1][B-20][B-20+1] [B-1] [B] [B+1] [B+20-1][B+20][B+20+1] 

其中B =按钮点击。

当然,您必须检查没有值离开网格(例如,B-20-1不小于0,B + 20 + 1不大于按钮数量。),但这很容易完成。