1


您好
,我正在尝试创建“我的游戏”的模拟


假设我们有矩阵
0 0 0 0
0 0 -1 0
0 0 0 -1
0 -1 0 -1


现在每个不等于 -1 的单元格应该代表
这里的地雷数代码 for(int i=0;i

for(int j=0;j<N;j++)
 if(box[i][j]!=-1)
  {
  switch (i)
 {
 case 0: 
 iLEFT=0;
 iRIGHT=1;break;
 case 3:
 iRIGHT=0;
 iLEFT=1;
 break;
 case 1:
 iLEFT=1;
 iRIGHT=1;
 break;
 case 2:
 iLEFT=1;
 iRIGHT=1;
 break;
 default:
  iLEFT=1;
 iRIGHT=1; 
   break;
}



switch (j)
  {
case 0:
   jLEFT=0;`
   jRIGHT=1;
   break;
case 3:
   jRIGHT=0;
   jLEFT=1;
   break;
   case 1:
   jLEFT=1;
   jRIGHT=1;
    break;
    case 2:
    jLEFT=1;
    jRIGHT=1;
    break;
    default:
    jLEFT=1;
    jRIGHT=1;
     break;
  } 

// checking neighbor 
     if(box[i][j+jRIGHT]==-1)
         count+=1;
            if(box[i][j-jLEFT]==-1)
         count+=1;              
                    if(box[i+iRIGHT][j]==-1)
                 count+=1;
            if (box[i-iLEFT][j]==-1)
              count+=1; 
                if(box[i-iLEFT][j-jLEFT]==-1)
                {
                    if(i-iLEFT!=i) // trying to avoid double checking
                     count+=1;
                }
                if(box[i+iRIGHT][j-jLEFT]==-1)
                {
                    if(i+iRIGHT!=i)  //trying to avoid double checking
                     count+=1;
                }
                if (box[i-iLEFT][j+jRIGHT]==-1)
                {
                    if(i!=iLEFT) //trying to avoid double checking
                      count+=1;
                }

                if (box[i+iRIGHT][j+jRIGHT]==-1)
                {

                    if(i!=iRIGHT) //trying to avoid double checking
                      count+=1;
                }

                   box[i][j]=count;
                   count=0;
        }


我的算法

iLEFT 当前行左步。
iRIGHT 当前行右移。
列的 jLEFT 和 JRIGHT 相同
假设 i=0,因此如果 i=1,我们只能向右(向下)
迈出一步,我们可以加强并完成..对于 j


“案例声明”更新 iLEFT/iRIGTH 和 jLEFT/jRIGHT 以启用侧边步骤
现在“if”语句检查左/右上/完成框 [i][j] 的 2 个对角线(始终只有一步)
计数计数性能 - box[i][j] 的 1 个相邻值


你可以看到我仍然对相同的单元格进行双重检查
0 1 1 1
0 1 -1 2
1 2 4 -1
2 -1 4 -1

4

2 回答 2

2

您还应该概述您的算法以及代码,以便更好地了解您如何解决问题。如果没有附带的算法,真的很难理解这段代码。

您可以用简单的英语概述您的算法,不必是伪代码。它将帮助您更好地理解问题和解决方案。例如,像这样:

  1. 看看每个矿
  2. 增加所有非我的邻居

我认为您检查边界条件的方式过于复杂。让我们假设雷区在每个方向上是否无限大。如果我们然后选择任何 random cell(i,j),它的8个邻居将位于:

cell(i-1, j-1) // top-left
cell(i-1, j)   // top
cell(i-1, j+1) // top-right
cell(i, j-1)   // left
cell(i, j+1)   // right
cell(i+1, j-1) // bottom-left
cell(i+1, j)   // bottom
cell(i+1, j+1) // bottom-right

现在回到实际的有限长度案例。我建议不要预先计算一个单元格是否在界限内,而应该始终检查所有 8 个邻居,并丢弃无效的邻居。

检查单元格是否有效的函数很容易编写:

bool is_cell_valid(int x, int y, int rows, int cols) {
    if(x < 0 || x >= cols) {
        return false;
    }
    if(y < 0 || y >= rows) {
        return false;
    }
    return true;
}

我现在终于明白你的算法了:)

  1. 查看每个非地雷单元
  2. 将其值更改为相邻地雷的数量

正在发生双重检查,因为您没有检查所有正在更改的变量。例如,在这种情况下,您使用 iLEFT 和 jLEFT 转到左上角的单元格。由于两个变量都被使用,你必须确保它们都是非零的。

if(box[i-iLEFT][j-jLEFT]==-1)
{
    if(i-iLEFT!=i) // trying to avoid double checking
        count+=1;
}

以上应该是

if(iLEFT != 0 && jLEFT != 0)
{
    if(box[i-iLEFT][j-jLEFT]==-1)
        count+=1;
}

并且此检查应应用于 8 个单元格中的每一个,而不仅仅是对角线单元格。


这是一个很小的替代方法,可以遍历与 (x, y) 处的某个单元格相邻的所有 8 个单元格,而不对每个邻居使用 if。

for(int i = -1; i < = 1; i++) {
    for(int j = -1; j <= 1; j++) {
        if(i == 0 && j == 0) {
            continue;
        }
        if(is_cell_valid(x + i, y + j, N, N);
            // cell is adjacent and within boundaries
            // do whatever calculations are needed
        }
    }
}
于 2010-01-17T12:59:39.223 回答
0

我第二次包括你的算法的插图,这将更容易阅读我之前制作的扫雷游戏,这可能是生成函数的大纲

  1. 我们将从空网格开始(全零)
  2. 将每个炸弹随机插入空的地方(还没有炸弹)
  3. 增加所有非炸弹邻居

附加功能 会在第一次单击后延迟炸弹的生成,因此您可以确保不要在用户单击的第一个单元格上放置炸弹

这是一个代码片段

var i = 0
while (i < bombsNum){
    //generate a random location for the bomb
    var col=Math.floor(Math.random()*cols);
    var row=Math.floor(Math.random()*rows);

    //if new location is already a bomb
    if (cellsData[row][col] == -1) continue;

    //if new location is near the start region    
    if (col == startCol-1 || col == startCol || col == startCol +1){
        if (row == startRow -1 || row == startRow || row == startRow+1)
            continue;
    }

    i++;
    cellsData[row][col] = -1;
    //increment all the neighbors cells and make sure to handle the special cases cells (cells at the corner)
}
于 2010-01-17T13:25:47.480 回答