用于寻找邻居的扫雷算法?

时间:2017-11-14 21:20:17

标签: c algorithm

我在扫雷游戏中编程。 我最后很好。 我对最后一部分只有问题。

在游戏中(见图片)当我点击左上方的字段时,没有我的字段转过来,边界处有数字。

如何找到这个字段并将它们转过来或显示它们的算法....我的意思是绿色圆圈中的字段算法?

MineSweeper

2 个答案:

答案 0 :(得分:1)

我正在从头开始设计,我希望它可以帮助你。

如果我的游戏竞技场是nxn整数矩阵,

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

我可以通过应用这样一个3x3矩阵来模拟在该矩阵中放置炸弹:

1 1 1
1 9 1
1 1 1

这里9表示炸弹,你可能需要使用更大的整数。当我说申请时,我选择位置并将其增加3x3矩阵中的数字。所以,让我们放置1个炸弹:

0 1 1 1 0
0 1 9 1 0
0 1 1 1 0
0 0 0 0 0
0 0 0 0 0

让我们放置另一枚炸弹,就在第一枚炸弹旁边。让我们有点聪明,当单元格中的初始值为9时,不会增加位置。

0 1 2 2 1
0 1 9 9 1
0 1 2 2 1
0 0 0 0 0
0 0 0 0 0 

让我们这次放在另一个地方。

0 1 2 2 1
0 1 9 9 1
0 1 3 3 2
0 0 1 9 1
0 0 1 1 1 

所以,如果我尝试从右下角开始显示数字。我的算法应该是什么?这是我的看法:

function revealCell(location)
{
   if(cellValueIsRevealed(location)) {
       return;
   }
   var value = revealValueOfCell(location);
   if(value > 0) 
   {
       return;
   }

   foreach(neighbor in neighbors) 
   {
       revealCell(neighbor);
   }
}

要实现cellValueIsRevealed方法,一种方法是实现布尔矩阵。

答案 1 :(得分:1)

回答这个问题可能有点晚了,但无论如何我都会这样做,这样如果将来有人看到它可能会帮助他们。这也是用 C# 编写的,但总体思路应该是相同的。

这个想法是有一个要访问的单元格队列,以及一个用于访问单元格的独特集合。首先将当前位置排队,然后评估整个队列,直到它为空。将当前单元出列并检查它是否已经被访问过。如果不是,则检查所有周围的单元格,如果它们是空单元格,则将它们排入队列。完成队列后,哈希集包含所有空单元格。

public void AsQueue(Queue<(int i, int j)> toVisit, HashSet<(int i, int j)> visited, Cell[] grid, int i, int j)
    {
        List<(int i, int j)> neighbours = new();
        toVisit.Enqueue((i, j));
        while (toVisit.Count != 0)
        {
            var temp = toVisit.Dequeue();
            if (!visited.Contains(temp))
            {
                Neighbours(neighbours, i, j, grid.GetLength(0), grid.GetLength(1));
                for (int k = 0; k < neighbours.Count; k++)
                {
                    if (grid[neighbours[k].i, neighbours[k].j].Type == BoxType.Empty &&
                        !(neighbours[k].i == i && neighbours[k].j == j) &&
                        !visited.Contains(neighbours[k]))
                    {
                        toVisit.Enqueue(neighbours[k]);
                    }
                }
            }
            visited.Add(temp);
        }
    }

    private void Neighbours(List<(int i, int j)> neighbours, int i, int j, int maxh, int maxw)
    {
        int[] iOffsets = new int[] { -1, 0, 1 }, jOffsets = new int[] { -1, 0, 1 };

        if (i == 0) iOffsets = new int[] { 0, 1 };
        else if (i == maxh - 1) iOffsets = new int[] { -1, 0 };

        if (j == 0) jOffsets = new int[] { 0, 1 };
        else if (j == maxw - 1) jOffsets = new int[] { -1, 0 };

        neighbours.Clear();
        foreach (var ip in iOffsets)
        {
            foreach (var jp in jOffsets)
            {
                neighbours.Add((i + ip, j + jp));
            }
        }
    }