为Mine游戏创建2D阵列

时间:2010-01-17 12:48:41

标签: minesweeper


你好
我正试图创建“我的游戏”的模拟


假设我们有矩阵
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”语句检查左/右上/下2个对角线为方框[i] [j](总共只有一步)
计数盒[i] [j]

的-1值邻居的计数性能


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

2 个答案:

答案 0 :(得分:2)

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

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

  1. 看看每个矿井
  2. 增加所有非矿井邻居
  3. 我认为你检查边界条件的方式过于复杂。让我们假设雷区在每个方向上都是无限大的。如果我们随后挑选了任何随机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. 将其值更改为 邻近的矿山
    3. 正在进行双重检查,因为您没有检查所有正在变化的变量。例如,在这种情况下,您使用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
              }
          }
      }
      

答案 1 :(得分:0)

我的第二个包括你的算法的插图,这将更容易阅读 我以前做过minesweeper游戏的方式,这可能是生成函数的轮廓

  1. 我们将从空格开始(完整 (零)
  2. 将每个炸弹随机插入空中 地方(还没有炸弹)
  3. 增加所有非炸弹 邻居
  4. 附加功能 在第一次点击后延迟炸弹的产生,这样你就可以确保不在用户点击的第一个牢房上放置炸弹

    这是一段代码片段

    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)
    }
    
相关问题