所以我为UWP制作扫雷克隆。而且,当然,我有数字说明有多少地雷。所以这就是问题(你可以在图片上看到它):
左上角,上方,右上角和左上角只是缺少数字。但是,当我第二次点击时(我没有实施预防,第二次点击打开的字段),他们添加了1个(因为我重新启动应用程序以获取另一个屏幕截图,因此放置的地雷不同):
我试图通过添加2而不是1来解决这个问题,但问题仍然存在,但更加奇怪。
首先点击:
第二次点击:
所以,最后这里去了codez:
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace Mynesweeper
{
public class Cell
{
public enum CellType
{
Safe = 0,
Bomb = 1,
Flag = 2,
FirstClick = 3
}
public CellType cellState;
public bool covered = true;
}
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MineField : Page
{
Cell[,] cells = new Cell[0, 0];
bool isGenerated = false;
Button[,] fieldBtns = new Button[0, 0];
int maxMines = 0;
int[,] nearbyBombs = new int[0, 0];
public MineField()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string param = e.Parameter.ToString();
if (param == "tutorial")
{
MinesAmount.Text = "4";
GenerateLevel(25, 25, 4);
}
else
{
TextBlock errTxtBlck = new TextBlock() { Name = "ErrorTextBlock", Text = "Error: no or incorrect parameter was specified when navigating to MineField.xaml\r\n\r\nIf you're the player and've downloaded the game through Windows Store, then let me know about this error by contacting me at artyomisflash@mail.ru. If you're not a player then maybe you're me and you have to fix this error.", HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Stretch, Margin = new Windows.UI.Xaml.Thickness(16, 0, 16, 0), TextWrapping = Windows.UI.Xaml.TextWrapping.Wrap, VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center, FontSize = 24, TextAlignment = Windows.UI.Xaml.TextAlignment.Center };
MainGrid.Children.Add(errTxtBlck);
SmileyFace.Text = "...";
}
}
public static int Clamp(int val, int min, int max)
{
if (val < min)
{
return min;
}
else if (val > max)
{
return max;
}
else
{
return val;
}
}
void GenerateLevel(int x, int y, int mines)
{
cells = new Cell[x, y];
StackPanel[] fieldRows = new StackPanel[y];
fieldBtns = new Button[x, y];
maxMines = mines;
nearbyBombs = new int[x, y];
for (int i = 0; i < y; i++)
{
fieldRows[i] = new StackPanel() { Name = "MineFieldPanelRow" + i, Orientation = Orientation.Horizontal };
MineFieldPanelRows.Children.Add(fieldRows[i]);
for (int j = 0; j < x; j++)
{
fieldBtns[j, i] = new Button() { Name = "MineFieldButton" + j + "_" + i, Width = 64, Height = 64, Margin = new Thickness(4), Padding = Margin = new Thickness(0) };
fieldBtns[j, i].Click += MineFieldButtonClick;
fieldBtns[j, i].Content = new FontIcon() { Glyph = "\uE890", FontSize = 32 };
fieldRows[i].Children.Add(fieldBtns[j, i]);
cells[j, i] = new Cell()
{
covered = true
};
nearbyBombs[j, i] = 0;
}
}
}
void PlaceMines()
{
Random rnd = new Random();
for (int i = 0; i < maxMines; i++)
{
int x = rnd.Next(0, cells.GetLength(0));
int y = rnd.Next(0, cells.GetLength(1));
while (cells[x, y].cellState == Cell.CellType.Bomb || cells[x, y].cellState == Cell.CellType.FirstClick)
{
x = rnd.Next(0, cells.GetLength(0));
y = rnd.Next(0, cells.GetLength(1));
}
cells[x, y].cellState = Cell.CellType.Bomb;
}
}
private void MineFieldButtonClick(object sender, RoutedEventArgs e)
{
if (!isGenerated)
{
for (int i = 0; i < fieldBtns.GetLength(1); i++)
{
for (int j = 0; j < fieldBtns.GetLength(0); j++)
{
if (fieldBtns[j, i] == sender)
{
cells[j, i].cellState = Cell.CellType.FirstClick;
break;
}
}
}
PlaceMines();
isGenerated = true;
}
for (int i = 0; i < cells.GetLength(1); i++)
{
for (int j = 0; j < cells.GetLength(0); j++)
{
if (cells[j, i].cellState == Cell.CellType.Bomb)
{
fieldBtns[j, i].Content = new FontIcon() { Glyph = "\uE783", FontSize = 32 };
nearbyBombs[j, i] = -1;
if (i - 1 > -1)
{
if (j - 1 > -1)
{
nearbyBombs[j - 1, i - 1]+=2;
}
nearbyBombs[j, i - 1]+=2;
if (j + 1 <= nearbyBombs.GetLength(0) - 1)
{
nearbyBombs[j + 1, i - 1]+=2;
}
}
if (j - 1 > -1)
{
nearbyBombs[j - 1, i]+=2;
}
if (j + 1 <= nearbyBombs.GetLength(0) - 1)
{
nearbyBombs[j + 1, i]++;
}
if (i + 1 <= nearbyBombs.GetLength(1) - 1)
{
if (j - 1 >= 0)
{
nearbyBombs[j - 1, i + 1]++;
}
nearbyBombs[j, i + 1]++;
if (j + 1 <= nearbyBombs.GetLength(0) - 1)
{
nearbyBombs[j + 1, i + 1]++;
}
}
}
else if (nearbyBombs[j, i] == 0)
{
fieldBtns[j, i].Content = null;
}
else
{
int bombsNearby = nearbyBombs[j, i];
fieldBtns[j, i].Content = new TextBlock() { Text = bombsNearby.ToString(), FontSize = 32 };
}
}
}
}
}
}
XAML部分是:
<Page
x:Class="Mynesweeper.MineField"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Mynesweeper"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="MainGrid">
<Grid.Transitions>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True"/>
</TransitionCollection>
</Grid.Transitions>
<StackPanel x:Name="Stats" Margin="16,16,16,0" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<TextBlock x:Name="TimeAmount" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" FontSize="32" Width="64" TextAlignment="Right" Margin="0,0,16,0"/>
<Button x:Name="Smiley" Padding="0" Width="64" Height="64" HorizontalAlignment="Center" VerticalAlignment="Stretch" FontSize="32" d:LayoutOverrides="LeftMargin, RightMargin, LeftPosition, RightPosition">
<TextBlock x:Name="SmileyFace" Text=":)" TextLineBounds="Tight" TextAlignment="Center"/>
</Button>
<TextBlock x:Name="MinesAmount" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" FontSize="32" Width="64" Margin="16,0,0,0"/>
</StackPanel>
<StackPanel x:Name="MineFieldPanelRows" Margin="0,16,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<StackPanel.RenderTransform>
<CompositeTransform ScaleX="0.25" ScaleY="0.25"/>
</StackPanel.RenderTransform> <!-- specially downscaled to fit the whole field on the screen -->
</StackPanel>
</Grid>
</Page>
我真的不知道为什么会出现这个问题。也许我在某处弄错了?请帮忙!
答案 0 :(得分:1)
你的问题是这句话:
else if (nearbyBombs[j, i] == 0)
当你仍在穿越你的网格并设置炸弹数时,你正在检查一个单元的炸弹数是否为零,所以在进行这项检查时,并不是所有的单元计算都已执行。 / p>
解决方案是首先进行一次通过来计算炸弹数量,一旦完成,然后再做一次传递来创建按钮并在其中显示炸弹数量。
答案 1 :(得分:0)
以下代码:
if (j - 1 > -1)
{
nearbyBombs[j - 1, i]+=2;
}
位于检查以确保i > 0
的任何块之外。因此,如果你在i = 0时遇到过我的代码,那么你的代码将会爆炸。这让我相信你的错综复杂的if
陈述是完全错误的,而且它们太错综复杂,无法试图找出准确的你弄乱你的计数的地方。就像在大海捞针一样,从我已经发现另一个错误的那一刻开始就不值得。
让我建议一个不同的方法:
当您的意思是x
和y
时,请使用height
和width
退出,当使用i
和j
时,请务必退出你的意思是x
和y
。笛卡尔坐标中坐标名称的惯例是&#39; x&#39;对于横轴和&#39; y&#39;对于自17世纪中期以来的纵轴(Wikipedia),您不需要在2017年发明新的公约。
有人告诉你,即使你有一个由单个语句组成的块,也应该总是使用大括号。如果您认为这是明智的建议,请继续使用花括号敲打自己,但至少在堆栈溢出中避免使用大括号垃圾邮件,其中简洁性非常重要。
在您的代码工作之前停止使用Random()
。在特定的一组坐标上放置一定数量的炸弹,确保你的东西在引入随机性之前有效。
退出嵌套if
语句的复杂不可读的级联锯齿形意大利面,并做一些更简单的事情。
像这样:
void updateBombCountsAroundBomb( int bombY, int bombX, int height, int width )
{
for( y = bombY - 1; y <= bombY + 1; y++ )
for( x = bombX - 1; x <= bombX + 1; x++ )
if( y != bombY && x != bombX )
if( y >= 0 && y < height && x >= 0 && x < width )
nearbyBombs[y, x]++;
}
一旦你有了这个工作,你可以尝试优化它,如果你想这样做,知道如果你不小心打破它,你总是可以恢复到以前的版本工作。 (测试规则。)