-1

Javascript で簡単な掃海艇ゲームを作成しようとしています。地雷なしタイルをクリックしたときに地雷なしエリア全体を開く機能とは別に、これは適切に機能します。隣接するタイルのチェックを開始しますが、最初の隣接タイルに地雷があると停止します。

下のスクリーンショット (タイル 1/5 をクリックした後) でわかるように、最初の「1」までのタイルのみが開かれます。実際には、はるかに大きな領域を開く必要があります。

エリア内のすべての地雷のないタイルが開かれているわけではありません

私はかなり近いようです。これは私のコードです:

const gridSize = 10

// generate grid
const board = document.querySelector("#minesweeper");
// loop over num for rows
let header = 0;
for(let i = 0; i < gridSize+1; i++) {
  const row = document.createElement("tr");
  // loop over num for cols
  for (let j = 0; j < gridSize+1; j++) {
  // add col to row
    if ( i === 0 ) {
      row.insertAdjacentHTML("beforeend", `<th>${header}</th>`);
      header += 1;
    } else if (j === 0) {
      row.insertAdjacentHTML("beforeend", `<th>${header-10}</th>`);
      header += 1;
    } else {
      row.insertAdjacentHTML("beforeend", `<td class='unopened' dataset-column=${j}></td>`);
    };
  };
  // add row to board
  board.append(row);
};

// functions -------------------

function getNeighbour(tile, i, j) {
  const column = tile.cellIndex; // so the columns get the cellIndex
  const row = tile.parentElement.rowIndex; // row gets the rowIndex(tr) 
  const offsetY = row + i;
  const offsetX = column + j;
  return document.querySelector(`[data-row="${offsetY}"][data-column="${offsetX}"]`);
}
// count mines of neighbours

function countMines(tile) {
  let mines = 0;

  for(i = -1; i <= 1; i++) {
    for(j = -1; j <= 1; j++ ) {
      // check if neighbour has mine
      // get cell values from neighbour in DOM
      nb = getNeighbour(tile, i, j);
      if (nb && nb.classList.contains('has-mine') || (nb && nb.classList.contains('mine'))) mines += 1; // if nb exists and has a mine increase mines
    }
  }

  // write into DOM
  if (mines === 0) {
    tile.classList.add(`opened`);
  } else {
    tile.classList.add(`neighbour-${mines}`);
  }
  tile.classList.remove(`unopened`);

  // if mines are 0, go to neigbours and count mines there
  // console.log(tile.classList);
  if (mines === 0) {
    // alert("mines are zero");
    for (i = -1; i <= 1; i+=1) {
      for (j = -1; j <= 1; j+=1) {
        nb = getNeighbour(tile, i, j);
        if (nb && nb.classList.contains("unopened")) {
          countMines(nb);
        }
      }   
    }
  }
  return mines;
}

// function open tile on click
function openTile(event) {
  const tile = event.currentTarget;

    // if there is a mine you lose
    if (tile.classList.contains("has-mine")) {
      document.querySelectorAll(".has-mine").forEach((cell) => {
        cell.classList.remove("has-mine", "unopened");
        cell.classList.add("mine", "opened");
      });
      alert("booooooooom!");
    } else {
      countMines(tile);
    }
  }
  

const tiles = document.querySelectorAll("td");

tiles.forEach((td) => {
  td.dataset.column = td.cellIndex; // so the columns get the cellIndex
  td.dataset.row = td.parentElement.rowIndex; // row gets the rowIndex(tr) 

  // add mines randomly
  const freq = 0.1;
  if (Math.random() < freq) {
    td.classList.add("has-mine");
  } 


  // eventlisteners per tile
  td.addEventListener("click", openTile);
});

私はそれについて何時間も考えてきましたが、このコードで作業する方法を見つけることができませんでした. 私が近いのか、それともアプローチ全体を変更する必要があるのか​​ わかりませんか?

アイデアをありがとう!

4

1 に答える 1