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() 関数にあります。

このデモを試してください (負けて 0 になるまで、「Run with JS」を数回クリックしてください): http://jsbin.com/iqeganU/1/edit

于 2013-10-30T15:31:25.440 に答える