用于检查2d数组的递归函数

时间:2013-10-30 14:49:44

标签: javascript arrays recursion

我正在为一个javascript项目创建一个扫雷游戏,并遇到了一个我无法理解的问题。当你在扫雷游戏中为那些不知道的人点击一个空单元格(一个没有任何地雷并因此没有显示数字的单元格)时,这将显示相​​邻的空单元格的整个块,当找到包含这些空块的“数字墙”时停止。示例如下:

[1] http://datagenetics.com/blog/june12012/hole.png

这需要一个递归函数来确定要显示哪些块。我的代码目前只显示点击的块:

 function revealGridContents()
    {
    switch (positionClickContents)
    {
    case 0:
            ctx.drawImage(clickedImage, (xClick*20), (yClick*20));
            break;
    case 1:
            ctx.drawImage(num1Image, (xClick*20), (yClick*20));
            break;
    case 2:
            ctx.drawImage(num2Image, (xClick*20), (yClick*20));
            break;
    case 3:
            ctx.drawImage(num3Image, (xClick*20), (yClick*20));
            break;
    case 4:
            ctx.drawImage(num4Image, (xClick*20), (yClick*20));
            break;
    case 5:
            ctx.drawImage(num5Image, (xClick*20), (yClick*20));
            break;
    case 6:
            ctx.drawImage(num6Image, (xClick*20), (yClick*20));
            break;
    case 7:
            ctx.drawImage(num7Image, (xClick*20), (yClick*20));
            break;
    case 8:
            ctx.drawImage(num8Image, (xClick*20), (yClick*20));
            break;
    };
    };

传递给switch语句的数字是数组grid[xClick][yClick]中数据的值;例如,4表示一个区域,周围有4个地雷,因此将显示4的图像。

案例0是单击空白块的情况,因此需要修改此代码,但我真的不知道该怎么做。

根据我的理解,我需要从案例0调用revealGridContents();函数,但为每个方格传递xClick和yClick的新值(数组位置的x和y值)想检查一下。

任何有助于阐明我下一步需要做什么的帮助都将不胜感激!

2 个答案:

答案 0 :(得分:1)

如果不了解您的程序,就很难为您提供准确的解决方案。你可能需要一个单独的功能才能做到这一点,因为只需使用相同的功能就可以显示所有内容(这显然不是游戏的工作原理)。你还需要一些方法来跟踪显示的细胞,否则你会进入一个循环(我假设它存储在另一个2d数组revealed[x][y]中)。

您可能想要做这样的事情(我没有对此进行测试,因此可能存在错误 - 道歉):

function revealGridContents(){
    switch (positionClickContents){
        case 0:
            ctx.drawImage(clickedImage, (xClick*20), (yClick*20));
            checkAdjacentCells(xClick, yClick);
            break;
        ...
    }
}

function checkAdjacentCells(x,y){
    var cellsToCheck = [ 
        [x,y+1],
        [x,y-1],
        [x+1,y],
        [x-1,y]];
    var x,y;
    for(var i=0; i<=cellsToCheck.length; i++){
        x = cellsToCheck[i][0];
        y = cellsToCheck[i][1];
        if(!revealed[x][y] && grid[x][y] == 0){
             ctx.drawImage(clickedImage, x*20, y*20);
             checkAdjacentCells(x,y);
        }    
    }
}

答案 1 :(得分:0)

正如一般建议,您需要在游戏模型和用户界面之间进行更好的分离。

这是我对扫雷游戏的解释的开始:

function init() {
  var i,j; // indexes  
  map = []; // global map, because i'm lazy

  for (i=0; i<10; i++) {
    var row = [];
    for (j=0; j<10; j++)
      row.push({
        bomb : Math.round(Math.random()-0.4), // set bombs randomly, change to your correct ratio
        revealed : false, // nothing is visible at start
        count : 0 // counts will be computed after all the map is created
      });
    map.push(row);
  }

  // set adjacent bomb counts
  for (i=0; i<10; i++) 
    for (j=0; j<10; j++) {
      if (map[i-1] && map[i-1][j-1] && map[i-1][j-1].bomb) map[i][j].count++;
      if (map[i-1] && map[i-1][j] && map[i-1][j].bomb) map[i][j].count++;
      if (map[i-1] && map[i-1][j+1] && map[i-1][j+1].bomb) map[i][j].count++;
      if (map[i] && map[i][j-1] && map[i][j-1].bomb) map[i][j].count++;
      if (map[i] && map[i][j+1] && map[i][j+1].bomb) map[i][j].count++;
      if (map[i+1] && map[i+1][j-1] && map[i+1][j-1].bomb) map[i][j].count++;
      if (map[i+1] && map[i+1][j] && map[i+1][j].bomb) map[i][j].count++;
      if (map[i+1] && map[i+1][j+1] && map[i+1][j+1].bomb) map[i][j].count++;
  }

}

function print() { // uses console to display instead of canvas
  var output = '\n';
  for (var i=0; i<10; i++) {
    for (var j=0; j<10; j++) {
      var item = map[i][j];
      output += (item.revealed ? item.count : 'x') + ' ';
    }
    output += '\n';
  }
  console.log(output);
}

function click(x,y) {
  reveal(x,y);  
  print(map);  
}

function reveal(x,y) {
  // break early if click is invalid (invalid clicks are generated)
  if (x < 0 || x > 9 || y < 0 || y > 9 || map[x][y].revealed) return;

  // mark the square as clicked
  map[x][y].revealed = true;

  if (map[x][y].bomb) { // losing click
    console.log('You lost');    
  } else if (map[x][y].count === 0) { // click on 0 adjacent bombs
      reveal(x-1, y);
      reveal(x, y-1);
      reveal(x, y+1);
      reveal(x+1, y);   
  }
}   


init();
console.log('First print');
print();
console.log('Click 1,3');
click(1,3);

困难的部分在click()函数中。

试试这个演示(点击&#39;用JS&#39运行几次,直到你不输,然后命中0): http://jsbin.com/iqeganU/1/edit