1

我正在为一个 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 是单击空白块的情况,因此需要修改此代码,但我真的想不出该怎么做。

据我所知,我需要revealGridContents();从案例 0 调用该函数,但为我要检查的每个正方形传入 xClick 和 yClick 的新值(数组位置的 x 和 y 值)。

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

4

2 回答 2

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);
        }    
    }
}
于 2013-10-30T15:17:14.457 回答
0

就像一般建议一样,您需要更好地分离游戏模型和 UI。

下面开始我对扫雷游戏的解读:

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() 函数。

试试这个演示(点击 'run with JS' 几次,直到你不输并打 0):http: //jsbin.com/iqeganU/1/edit

于 2013-10-30T15:31:25.440 回答