我正在创建一个扫雷克隆.到目前为止,当点击的瓷砖没有相邻的地雷时,我已经开始显示相邻的瓷砖,下面是我揭露地雷的方法.
struct data
{
public Button tile;
public bool mine, flag, clicked;
public int adjMines;
}
data[,] dat;
//Defaults
Size gridSize = new Size(16, 16);
Size tileSize = new Size(16, 16);
int mines = 40, flags = 0;
bool valid(int x, int y)
{
return (x >= 0 && y >= 0 && y < gridSize.Height && x < gridSize.Width);
}
void reveal(Button btn)
{
btn.BackColor = Color.DimGray;
start = true;
btn.Enabled = false;
//find button clicked, forget everything you ever learned about efficiency.
for (int i = 0; i < gridSize.Width; i++)
for (int j = 0; j < gridSize.Height; j++)
if (dat[i, j].tile == btn)
{
if (dat[i, j].adjMines == 0)
{
for (int ii = -1; ii <= 1; ii++)
for (int jj = -1; jj <= 1; jj++)
if (valid(i + ii, j + jj))
reveal(dat[i + ii, j + jj].tile);
}
else
btn.Text = dat[i, j].adjMines.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我一直StackOverflowException在运行它,这并不是一个惊喜,但我不知道如何解决它而不去除struct,这是一个要求.有任何想法吗?
问题在于,当你"揭露"时,你揭示了所有的邻居.当邻居则透露,它揭示的是它的邻国,包括第一位的,而现在你有一个无限递归.
诀窍是:在你揭示第一个之前,制作一个"正在进行中显示"的哈希集.在递归之前,将当前按钮添加到"进行中"设置.如果按钮已在进行中集中,则在显示方法中立即返回.你知道它的所有邻居都已经被揭露了,所以没有工作可做.
如果您没有递归尝试显示相同的磁贴,这可能会有所帮助:
for (int ii = -1; ii <= 1; ii++)
for (int jj = -1; jj <= 1; jj++)
if (valid(i + ii, j + jj) && !(ii == 0 && jj == 0))
reveal(dat[i + ii, j + jj].tile);
Run Code Online (Sandbox Code Playgroud)
注意!(ii == 0 && jj == 0)添加的测试 - 这将停止堆栈溢出的原因之一.除此之外,您还需要在递归之前将节点标记为"已启用",否则它将继续反复弹跳.
它不是一个你选择实现的非常有效的方法,但它应该适用于此修复.
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |