【初心者向け】第三回 メモ帳だけでゲーム作ってみた〈数独・ナンプレ編〉

2020年12月5日

今回も、パソコンに入っている「メモ帳」を使って、HTMLJavaScriptをうまく用いて「数独」を作っていきたいと思います!

今回から、様々なプログラミングの知識を使って進めていくので、少しだけ難しく感じるかもしれませんが、軽く理解できたら十分なので、最後まで是非読んでみてください!

前回の記事を読んでいない方は、ぜひそちらを先に読んでみてください!


今回作るもの

前回は、数独の枠を線で表示していきましたね!

  1. 準備編
  2. 数独の枠を表示させよう! ←前回
  3. 数独の数字を表示させよう! 今回
  4. キー入力で動かせるようにしよう!
  5. キー入力で数字を入力できるようにしよう!
  6. 完成させよう!!

そして、今回は数独の数字を表示していきたいと思います!

完成イメージは以下のとおりです!

何も数字を入れないマスに「0」が入っちゃっていますが、数独っぽくなってきているのではないでしょうか?

ちなみにこの問題は、数独のフリー素材を配布してくださっているサイトからお借りしています。

こちらのページ:http://nanpre.adg5.com/xlsx_down.php

こちらの「問題1」を使って作っていきたいと思いますので、一度解きたい方は先にダウンロードしましょう!


今回必要になる知識

今回もコードを書いていく上で必要になってくる、プログラミングの知識が2つほどあります。

1つ目が、繰り返しです!
繰り返しについて詳しくまとめた記事があるので、参照してください!

そして、2つ目が、配列です!

今回は配列の発展型の「多次元配列」というものを使うのですが、
これについても別の記事でまとめましたので、ぜひ見てください!

【誰でもわかる!】配列とは

皆さんは「配列」という言葉を聞いたことはありますか? プログラミングを学習していくうえで、たまに使う程度かもし…


コードを書いていこう!

というわけでここから実際に前回の続きでメモ帳にコードを書いていきましょう。

今回は先ほども書いた通りに「繰り返し」と「配列」という2つを使ってコードを書いていくので、少し難しく感じるかもしれません。

もし、理解に時間がかかりそうなら次に進めても全然大丈夫です!
プログラミングでは同じようなコードを使うことが多いので、またいつか同じようなコードを使うときに理解すればOKです!


繰り返しを使ってまとめる

前回書いたコードは、すごく縦に長いコードになっていて、見にくいですよね?

そんな時に繰り返しをうまく使えば、きれいにまとめることができます!

まず一つ目に…

CONTEXT.lineWidth = 5;

CONTEXT.beginPath();
CONTEXT.moveTo(150, 0);
CONTEXT.lineTo(150, 450);
CONTEXT.stroke();

CONTEXT.moveTo(300, 0);
CONTEXT.lineTo(300, 450);
CONTEXT.stroke();

CONTEXT.moveTo(0, 150);
CONTEXT.lineTo(450, 150);
CONTEXT.stroke();

CONTEXT.moveTo(0, 300);
CONTEXT.lineTo(450, 300);
CONTEXT.stroke();

このコードをまとめてみます!

繰り返しをうまく使うと…

CONTEXT.lineWidth = 5;

for (let i = 150; i <= 300; i = i + 150) {
  CONTEXT.moveTo(i, 0);
  CONTEXT.lineTo(i, 450);
  CONTEXT.stroke();

  CONTEXT.moveTo(0, i);
  CONTEXT.lineTo(450, i);
  CONTEXT.stroke();
}

こんな感じです!

前回のコードは、縦線を2本引いてから横線を2本引くというコードでしたが、この繰り返しのコードでは、縦横縦横と交互になっています。

こうすることによって表示される画面は変わりませんが、繰り返しを使うことが可能になります!

今のは太い線を引くコードでしたが、次に細いほうの線を引くコードを繰り返しでまとめてみます。

細い線を書くコードはこうなっていましたね!

CONTEXT.lineWidth = 1;

CONTEXT.moveTo(50, 0);
CONTEXT.lineTo(50, 450);
CONTEXT.stroke();

CONTEXT.moveTo(100, 0);
CONTEXT.lineTo(100, 450);
CONTEXT.stroke();

CONTEXT.moveTo(200, 0);
CONTEXT.lineTo(200, 450);
CONTEXT.stroke();

CONTEXT.moveTo(250, 0);
CONTEXT.lineTo(250, 450);
CONTEXT.stroke();

CONTEXT.moveTo(350, 0);
CONTEXT.lineTo(350, 450);
CONTEXT.stroke();

CONTEXT.moveTo(400, 0);
CONTEXT.lineTo(400, 450);
CONTEXT.stroke();

CONTEXT.moveTo(0, 50);
CONTEXT.lineTo(450, 50);
CONTEXT.stroke();

CONTEXT.moveTo(0, 100);
CONTEXT.lineTo(450, 100);
CONTEXT.stroke();

CONTEXT.moveTo(0, 200);
CONTEXT.lineTo(450, 200);
CONTEXT.stroke();

CONTEXT.moveTo(0, 250);
CONTEXT.lineTo(450, 250);
CONTEXT.stroke();

CONTEXT.moveTo(0, 350);
CONTEXT.lineTo(450, 350);
CONTEXT.stroke();

CONTEXT.moveTo(0, 400);
CONTEXT.lineTo(450, 400);
CONTEXT.stroke();

非常に長くて醜いですね…

これを繰り返しでまとめると…

CONTEXT.lineWidth = 1;

for (let i = 50; i < 450; i = i + 50) {
  CONTEXT.moveTo(i, 0);
  CONTEXT.lineTo(i, 450);
  CONTEXT.stroke();

  CONTEXT.moveTo(0, i);
  CONTEXT.lineTo(450, i);
  CONTEXT.stroke();
}

ここまでスッキリすることができます!

これも先ほどと同じように、縦横縦横…といった形で線を引くようになっていますね!

そしてもう一つ気が付いてほしいことがあります。

それは、この細い線を引くコードは、すでに太い線を引いている部分にも線を引いていることです。

実際に太い線の上に細い線が表示されるので、重なって細い線が見えなくなるので画面の見た目が変わることはありません。

このようにわざわざ意味のない線を書くコードを挟むことで、繰り返しがうまく使えるようになるんですね!

プログラミングでは繰り返しを使うとスッキリすることが非常に多いので、少し考えて使ってみましょう!


変数を作る

次に、数字を表示させるコードを書いていく際に必要になる変数を作っていきます!

…
const CONTEXT = CANVAS.getContext("2d");

let number = [
  [6, 0, 5, 0, 0, 3, 4, 0, 0],
  [7, 0, 3, 0, 0, 5, 0, 8, 2],
  [4, 8, 0, 1, 0, 0, 6, 0, 5],
  [9, 2, 4, 0, 3, 1, 7, 5, 8],
  [0, 0, 0, 9, 0, 8, 2, 0, 3],
  [0, 3, 7, 0, 4, 0, 0, 9, 6],
  [5, 6, 9, 0, 8, 4, 3, 7, 0],
  [2, 7, 1, 3, 0, 0, 8, 6, 4],
  [0, 4, 8, 7, 1, 6, 0, 2, 0]
];

*「, 」や 「[」、「] 」の位置に気を付けましょう!

「number」という多次元配列を一つ追加しました。

中の数字を見ればわかると思いますが、数独で最初に配置されている数字をここに書き、空いているマスは「0」を入れています。

これをあとはそのまま表示するコードを書けば完成イメージのようになりますね!


数字を配列を使って表示させる

先ほど作った多次元変数の「number」に数独の数字の情報をしまいました。

なので多次元配列から数字の情報を取り出して表示すればいいですね!

ちなみに復習ですが、例えばnumber[2][3]は1になりますよね!

コンピューターが数字を数えるときには「0」があることを思い出しましょう!

ではまず、何も考えずに下の3行を書いてみましょう。

  …
  CONTEXT.stroke();
}

CONTEXT.font = "30px serif";
CONTEXT.textAlign = "center";
CONTEXT.fillText(number[0][0], 25, 35);

すると、左上に「6」が表示されたはずです!

1つ目の

CONTEXT.font = "30px serif";

というのは、

30pxの文字の大きさで、「serif」というフォントで表示させる、といった意味があります。

今回は30pxがちょうどよかったので30pxにしていますが、ここは好みによって変えてみましょう。

そして2つ目の、

CONTEXT.textAlign = "center";

は、textAlignは文字位置を決めていて、今回は「center」なので中央にしています。

つまり文字位置が中央(=center)で、

数字がが真ん中に来るようになっています

そして最後の

CONTEXT.fillText(number[0][0], 25, 35);

括弧の中は、

fillText(表示させる文字, x座標, y座標 )

といった意味を持っています。

x座標とy座標も私があらかじめいい場所に来る数値を調べて、この上の数値になっています。

前回に座標の話をしたので、少し忘れている方は復習をしておきましょう。

あとは最後の「fillText」というのを81マス文書けばいいんですが、これも明らかに面倒くさいですよね。

なのでここでも繰り返しを使います!

いきなり答えのコードを書くので、少し考えたい方はスクロールを止めましょう!

…
CONTEXT.font = "30px serif";
CONTEXT.textAlign = "center";


for (let i = 0; i < 9; i++) {
  for (let j = 0; j < 9; j++) {
    CONTEXT.fillText(number[i][j], 25 + 50 * j, 35 + 50 * i);
  }
}

繰り返しの中に繰り返しが入っている形になっていてすごくややこしいですね。

これでブラウザで確認すれば、完成イメージと同じになっているはずです!

このコードを完全に理解するには、少し時間がかかると思いますので、第四回までの宿題にでもしておきます笑

完全に理解する必要はありませんが、なんで「i」や「j」がその場所に入るのか程度は理解できるようになりましょう!


うまくいかなかった方向け

うまくいかなかった方は、まずエラーが出ていないか確認しましょう!

エラーの確認方法については、別の記事で詳しくまとめたので、ぜひそちらを参考にしてください!

前回同様うまくいかなかった方のために、サンプルコードを用意しました!
ダウンロードして、自分のコードと比較してみましょう!


第三回はここまで!

ということで第三回はここまでとします!

数字が表示できると、少しずつ完成に近づいて行っているのがわかりますね!

次回は、キーボード入力で動かせるポインターを作っていきたいと思います!

長くなってしまいましたが、

最後まで読んでいただきありがとうございました!

第四回はこちらから!