HTMLとCSSとJavaScriptを使って数独(ナンバープレイス)を作ってみる

スポンサーリンク

このページではソースコードの一部分を簡単な解説をしています。

完成品で遊ぶにはコチラから
完成品のソースコードはgithubにあります

スポンサーリンク

概要

数独(ナンバープレイス)で遊べます。全1問。遊び方は数字を入力したい空いているマスをクリックして、下の1~9の入力したい数字をクリックすると数字が入力されます。正解チェックボタンを押すと正解か不正解か表示されます。

ゲーム画面を描画する

// 問題
const question = [
  [8, 7, 1, 0, 0, 0, 5, 6, 4],
  [0, 9, 5, 0, 1, 7, 2, 3, 8],
  [2, 0, 3, 4, 5, 8, 0, 7, 1],
  [0, 2, 0, 1, 0, 3, 7, 9, 5],
  [0, 1, 9, 2, 7, 0, 8, 4, 3],
  [7, 0, 4, 0, 8, 5, 0, 0, 2],
  [1, 5, 0, 0, 0, 4, 3, 8, 0],
  [0, 8, 7, 5, 0, 0, 0, 0, 6],
  [0, 0, 0, 0, 3, 2, 1, 0, 7],
];

// ゲーム画面生成
function init() {
  const main = document.querySelector(".main");
  const select = document.querySelector(".select");
  
  for (let i = 0; i < 9; i++) {
    let tr = document.createElement("tr");
    for (let j = 0; j < 9; j++) {
      let td = document.createElement("td");
      td.onclick = mainClick;
      tr.appendChild(td);
      if (question[i][j] != 0) {
        td.textContent = question[i][j];
        td.classList.add("clickdisable");
      } else {
        td.textContent = null;
        td.classList.add("clickenable");
      }
    }
    main.appendChild(tr);
  }

  for (let i = 0; i < 9; i++) {
    let td = document.createElement("td");
    td.onclick = selectClick;
    td.value = i + 1;
    select.appendChild(td);
    td.textContent = i + 1;
  }
}

数独の問題は2次元配列の変数questionに数字が元からある場所には数字を入れ空白のマスには0を入力しています。init関数はゲーム画面を描画する関数です。for文の二重ループを使い9×9のマスをtrタグとtdタグで作ると同時に問題の数値もtextContentプロパティで入れていき、空白のマスにはnullを入れています。数値が元から入っているマスはクリックできなくするためにclassList.addメソッドでクラス属性追加してCSSで制御しています。36行目からのfor文は空いてるマスに入れる数字を選ぶボタンをtdタグで作っています。このボタンには ボタンと同じ数字をvalueプロパティに持たせていて、空白に数字を入れるときはこのvalueプロパティを利用しています。

空白のマスに数字を入れる

// クリックされた要素を保持
let place;

// 問題パネルのマスが押された時の処理
function mainClick(e) {
  if (place != undefined) {
    place.classList.remove("mainClick");
  }

  place = e.target;
  place.classList.add("mainClick");
}

// 数字選択のマスが押された時の処理
function selectClick(e) {
  place.textContent = e.target.value;
}

空白のマスをクリックするとmainClick関数が呼び出され、place変数にクリックされた要素が格納されます。数字選択のマスがクリックされるとselectClick関数が呼び出されplace変数のtextContentプロパティに選択された数字ボタンのvalueプロパティを代入しゲーム画面上の空白のマスにも数字が入力されます。

正解か判定する

// 正解判定
function check() {
  const h2 = document.querySelector("h2");
  const tr = document.querySelectorAll(".main tr");
  let checkFlag = true;
  // 横計算
  for (let i = 0; i < 9; i++) {
    let sum = 0;
    let td = tr[i].querySelectorAll("td");
    for (let j = 0; j < 9; j++) {
      sum += Number(td[j].textContent);
    }
    if (sum != 45) {
      checkFlag = false;
      break;
    }
  }
  // 縦計算
  for (let i = 0; i < 9; i++) {
    let sum = 0;
    for (let j = 0; j < 9; j++) {
      let td = tr[j].querySelectorAll("td");
      sum += Number(td[i].textContent);
    }
    if (sum != 45) {
      checkFlag = false;
      break;
    }
  }
  if (checkFlag) {
    h2.textContent = "正解です!!";
  } else {
    h2.textContent = "間違いがあります";
  }
}

正解か不正解の判定は横一行ずつ、縦も一列ずつ加算していき、それぞれの行と列の結果が全て45の場合は正解と判定しています。

最後までお読みいただきありがとうございました。

完成品で遊ぶにはコチラから
完成品のソースコードはgithubにあります

タイトルとURLをコピーしました