できる気になっているJSを改めてチュートリアルからやってみる 2日目

~~ プログラマの考え方 ~~

最近ちょっとずつまた学びなおす必要が出てきたなぁと思い、いろいろプログラムを勉強しなおしているところなんですが、実はもう今使っている知識は古いのかもと思って、アップデートしようとおもいやってみる会。

実施するのは、この記事

MDN - Javascript

完全な初心者向けと書かれたチュートリアルは全然初心者向けではないって話。アップデートしていきましょう。

JavaScript への最初のダイブ

今日は簡単な「数字を当てるゲーム」を作ることをします。

プログラマーのように考える

プログラミングで一番難しいのは、書き方を覚える事ではなく、現実の問題にどう適用するかという事です。

文法、お沙穂も大事だけど少しの想像力も必要よ。

上司からこんなことを言われます。

数字を予想する単純なゲームを作って欲しい。ランダムな 1 から 100 の数字を決めて、プレイヤーに 10 回以内に当ててもらうゲームだ。プレイヤーには予想する都度、正解か間違いかを表示する。もしプレイヤーが間違っていれば、プレイヤーが予想した数字に応じて、大きすぎるか小さすぎるかを表示する。また、プレイヤーの前回の予想がどうだったかも表示する。ゲームはプレイヤーの予想が正しかった場合、もしくは回数の上限に達した場合に終了する。ゲームが終了したら、プレイヤーはもう一度プレイ開始できるようにする。

これをできるだけプログラマーのように考えるとこの概要から最初に行うのは簡潔に実行可能な単位でわけること!

1. 1から100までのランダムな数字を決める
2. プレイヤーの予想した回数を記録する。最初は1から
3. プレイヤーが数字が何かを予想する方法を用意する
4. 予想が入力されたら、プレイヤーが以前の予想を見られるように、どこかに記録する
5. 入力された数字が正しいかどうかを調べる
6. 入力された数字が正しい場合
   1. 正解したお祝いメッセージを表示する
   2. プレイヤーが次の予想をできないようにする。(ゲームがおかしくならないように)
   3. プレイヤーが次のゲームを始められるようなコントロールを表示する
7. プレイヤーの予想が間違いで、予想回数の上限にはまだ達していない場合
   1. プレイヤーが間違っていることを表示する
   2. 次の予想を入力できるようにする
   3. 予想回数に1を加算する
8. プレイヤーの予想が間違いで、予想回数の上限に達した場合
   1. プレイヤーにゲームオーバーであることを伝える
   2. プレイヤーが次の予想をできないようにする。(ゲームがおかしくならないように)
   3. プレイヤーが次のゲームを始められるようなコントロールを表示する
9. ゲームがもう一度始まったら、画面とロジックが完全にリセットされるようにして、1.に戻る

みたいなかんじ。自分でも確かにこのくらいのことをさっと考えるかと思い、ちょっと誇りたくなりました。

で、用意されたHTMLファイルにScriptを書き込んでいきます。

データを保持する変数を追加

ざっと変数を用意。

<script>

   let randomNumber = Math.floor(Math.random() * 100);

   const guesses = document.querySelector('.guesses');
   const lastResult = document.querySelector('.lastResult');
   const lowOrHi = document.querySelector('.lowOrHi');

   const guessSubmit = document.querySelector(".guessSubmit");
   const guessField = document.querySelector(".guessField");

   let guessCount = 1;
   let resetButton;

</script>

変数は let ( or var ) キーワードで書きます。変数とは基本的には値(数字、文字など)の入れ物です。
定数は const キーワードで書きます。定数は変更しない値を保持するものです。(ひゃー知らなかった)

それぞれ、

randomNumber - 1から100までのランダムに選択された数字が入ります。
guesses, lastResult, lowOrHi - ResultParas内の3要素。後ほど、値を追加するために使用します。
guessSubmit, guessField - 入力されたテキストと送信ボタンの場所が保持されてます。
guessCount, resetButton - プレイヤーが予想した回数を記録するためと、まだ存在していないリセットボタンの場所

続いて関数、演算子について書かれてましたが一つだけ。

=== と !== しか書かれてませんでした。

もう == や != は使ってないけど、これからもそれを貫き通します。

条件式と関数

function checkGuess(){
   let userGuess = Number(guessField.value);
   if(guessCount === 1){
       guesses.textContent = '前回の予想:'
   }
   guesses.textContent += userGuess + ' ';

   if(userGuess ==== randomNumber){
       lastResult.textContent = 'おめでとう!正解です!';
       lastResult.style.backgroundColor = 'green';
       lowOrHi.textContent = '';
       setGameOver();
   }
   else if(guessCount === 10){
       lastResult.textContent = '!!!ゲームオーバー!!!';
       setGameOver();
   }
   else{
       lastResult.textContent = '間違いです!';
       lastResult.style.backgroundColor = 'red';
       if(userGuess < randomNumber){
           lowOrHi.textContent = '今の予想は小さすぎです!もっと大きな数字です。';
       }
       else if(userGuess > randomNumber){
           lowOrHi.textContent = '今の予想は大きすぎです!もっと小さな数字です。'
       }
   }

   guessCount++;
   guessField.value = '';
   guessField.focus();
}

※変数はつながってるもんだと思ってください。

ここで気が付いたのは、やることが決まっている場合は先に関数名を定義して作ってしまうという事。(setGameOverの部分)

あとはfocus() できっちり次の入力をさせようとするのもいいなと思った。

イベント

guessSubmit.addEventListener('click', checkGuess);

​イベントが発生したことを確認するのがイベントリスナー
発生したイベントに反応して実行されるコードがイベントハンドラ-

addEventListenerの中で関数を渡す場合は()いらないよ

ゲームを完成させる

さっき作らなかった。setGameOver関数。

function setGameOver(){
   guessField.disabled = true;
   guessSubmit.disabled = true;
   resetButton = document.createElement('button');
   resetButton.textContent = '新しいゲームを始める';
   document.body.appendChild(resetButton);
   resetButton.addEventListener('click',resetGame);
}

ここで注目するのは、

- テキストエリアと、送信ボタンをそれぞれdisabledして使えなくすることで誤作動をなくすこと。
- createElementして、そのままtextContentをぶち込む書き方。

で、resetGame関数が出てきたのでそれを作ります。

function resetGame(){
   guessCount = 1;

   const resetParas = document.querySelectorAll('.resultParas p');
   for(let i = 0; i < resetParas.length; i++){
       resetParas[i].textContent = '';
   }

   resetButton.parentNode.removeChild(resetButton);
   guessField.disabled = false;
   guessSubmit.disabled = false;
   guessField.value = '';
   guessField.focus();

   lastResult.style.backgroundColor = 'white';

   randomNumber = Math.floor(Math.random() * 100);
}

ここでは、やっぱり 基本 var なんて使わず let なんだという事がきにありました。

これでゲームができるよー!!!ということでした。ループの説明などもありましたが特に気にある点はなかったので飛ばします。

オブジェクト

原文ママ

JavaScript では、すべてのものはオブジェクトです。オブジェクトというのは 1 か所に関連する機能をまとめたものです。

はい。明日以降も楽しみです。終わり。


この記事が気に入ったらサポートをしてみませんか?