課題: バカ話ジェネレーター
この課題では、このモジュールでこれまでに学んだ知識を活かして、ランダムでふざけた物語を生成する楽しいアプリを作成します。その過程で、変数、数学、文字列、配列に関する知識が検査されます。楽しんでください!
出発点
始めるには、以下のコードパネルのいずれかにある Play ボタンをクリックし、MDN Playground で指定されたサンプルを開いてください。その後、[プロジェクト概要]の手順に従ってページを適切にスタイル設定してください。
<div>
<label for="custom-name">人の名前を入力:</label>
<input id="custom-name" type="text" placeholder="" />
</div>
<fieldset>
<legend>ロケールを選択:</legend>
<label for="us">米国</label
><input id="us" type="radio" name="uk-us" value="us" checked />
<label for="uk">英国</label
><input id="uk" type="radio" name="uk-us" value="uk" />
</fieldset>
<div>
<button class="generate">ランダムなお話を生成</button>
</div>
<!-- Thanks a lot to Willy Aguirre for his help with the code for this assessment -->
<p class="story"></p>
// 変数と乱数関数の定義
const customName = document.getElementById("custom-name");
const generateBtn = document.querySelector(".generate");
const story = document.querySelector(".story");
function randomValueFromArray(array) {
const random = Math.floor(Math.random() * array.length);
return array[random];
}
// 生のテキスト文字列
// ゴブリンのウィリー
// ビッグダディ
// サンタクロース
// スープキッチン
// ディズニーランド
// ホワイトハウス
// 自然発火した
// 歩道の上で水たまりになった
// ナメクジに変身して、這って逃げ去った
// ランダム文字列の一部を返す関数
function returnRandomStoryString() {
// 外は華氏 94 度もあったので、:insertx:は散歩に出かけた。:inserty:に着くと、しばらくの間、恐怖のあまり呆然と立ち尽くしていたが、やがて:insertz:。ボブはその一連のことがすべて目撃したが、驚くことはなかった ―― :insertx:の体重は 300 ポンドもあるし、その日は暑い日だったからだ。
return storyText;
}
// イベントリスナーと部分的な生成関数の定義
generateBtn.addEventListener("click", generateStory);
function generateStory() {
if (customName.value !== "") {
const name = customName.value;
}
if (document.getElementById("uk").checked) {
const weight = Math.round(300);
const temperature = Math.round(94);
}
// TODO: "" を正しい式に置き換えましょう
story.textContent = "";
story.style.visibility = "visible";
}
プロジェクト概要
少しのテキストと JavaScript 関数がありますね。JavaScript を必要なだけ書いて、下記のような動作をするプログラムを書きましょう。
- "ランダムなお話を生成" ボタンが押された時にバカな話を生成する。
- バカな話を生成するボタンが押される前に "人の名前を入力" のテキストフィールドに名前が入力されていた場合には、既定の "Bob" という名前を入力された名前に置き換える。
- バカな話を生成するボタンが押される前に UK のラジオボタンがチェックされていた場合のみ、既定の US (米国) の重さと気温を UK (英国) の同等な単位に変換する。
- ボタンが押される度に新しいバカ話がランダムに生成されます。
初期変数と関数
この JavaScript のコードにおいて、「変数定義と乱数関数を完成させましょう」というコメントの下に、以下の参照を格納するために、3 つの定数があります。
- "人の名前を入力" テキストフィールド:
customName - "ランダムなお話を生成" ボタン:
generateBtn - 記事がコピーされる HTML 本体の下部にある
<p>要素:story
さらに randomValueFromArray() という、引数として配列を取りその配列からランダムに 1 つの項目を返値として返す関数が使えるようになります。
「生のテキスト文字列」というコメントの下に、プログラムへの入力となるコメントアウトされた文字列がいくつかあります。これらの文字列のコメントを外し、同様に定数の中に格納しましょう。
- 最初の 3 つの文字列を、
charactersという名前の配列に格納しましょう。 - 2 つ目の 3 つの文字列のセットを、
placesという名前の配列に格納しましょう。 - 3 つ目の 3 つの文字列のセットを、
eventsという名前の配列に格納しましょう。
returnRandomStoryString() 関数を完成させる
「ランダム文字列の一部を返す関数」というコメントの下には、長いコメント付きのテキストと、storyText という値を返す return 文を含む、未完成の returnRandomStoryString() があります。
この関数を完成させるには、次のようにします。
- 長い文字列のコメントを外し、
storyTextという変数に格納してください。これはテンプレートリテラルである必要があります。 - テンプレートリテラルの一番上に、
randomCharacter、randomPlace、randomEventという 3 つの定数を追加してください。これらは、それぞれcharacters、places、events配列からランダムな文字列を返す 3 回のrandomValueFromArray()の呼び出しに等しく設定する必要があります。 - テンプレートリテラル内で、
:insertx:、:inserty:、および:insertz:を、それぞれrandomCharacter、randomPlace、randomEventを含む埋め込み式に置き換えてください。
generateStory() 関数を完成させる
「イベントリスナーと部分的な生成関数の定義」というコメントの下に、いくつかのコードアイテムがあります。
generateBtn変数にclickイベントのリスナーを追加する行です。これにより、この変数が表すボタンがクリックされた際に、generateStory()関数が実行されます。- 半分できている
generateStory()関数の定義の一部です。この課題の残りの部分では、この関数内の行を埋めて、関数を完了させ、正しく動作するようにします。
以下の手順に従って、この関数を完成させてください。
-
newStoryという名前の新しい変数を作成し、その値をreturnRandomStoryString()の呼び出し結果に設定します。この関数は、ボタンが押されるたびに新しいランダムな話を生成するために必要です。もしnewStoryの値を直接storyTextに設定してしまうと、新しい話を生成できるのは一度きりになってしまいます。
- 最初の
ifブロックで、newStoryの文字列内で見つかる 'Bob' という文字列をname変数の値で置換するため、別の文字列置換のメソッド呼び出し追加します。このブロック内では、「もし (if)customNameテキストフィールドに何かが入力されていれば、Bob をその文字列で置き換える」ということを言っています。 - 次の
ifブロックの中では、ukのラジオボタンが選択されているかどうかを調べています。もし選択されているのなら、重さと温度の単位をポンド・華氏から、ストーン・摂氏に変換したいと思います。そのために必要なことは...- ポンドからストーンへ変換する公式、および、華氏から摂氏へ変換する公式を調べます。
weight変数が宣言されている行内の、300 をポンドからストーンに変換した値で置き換えます。そして" stone"(ストーン) をMath.round()の結果に対して、その後ろに結合します。temperature変数が宣言されている行内の、94を華氏から摂氏に変換した値で置き換えます。" Celsius"(摂氏~度) という文字をMath.round()の結果に対して、後ろに結合します。- 上記 2 つの変数の宣言の直後に、さらにもう 2 つ文字列を置換するコードを書いて、
300 poundsをweight変数の内容に、94 Fahrenheitをtemperature変数の内容に、それぞれ置換します。
- 最後に、関数の下から 2 行目にある、
story変数のtextContentプロパティ(段落を参照している) を、newStory変数の内容で置き換えます。
ヒントとコツ
- JavaScript を HTML に適用する以外に、HTML を変更する必要は全くありません。
Math.round()は JavaScript の組み込みメソッドで、計算結果を整数値に四捨五入します。- 置き換える必要のある文字列のインスタンスは 3 つあります。
replace()メソッドを複数回繰り返しても、replaceAll()を使用しても構いません。文字列は不変であることを覚えておいてください。
例
完成したアプリは、以下のライブ例のように動作するはずです。
ここをクリックすると、模範解答を表示します。
完成した JavaScript は、次のような感じになるはずです。
// 変数定義と乱数関数を完成させましょう
const customName = document.getElementById("custom-name");
const generateBtn = document.querySelector(".generate");
const story = document.querySelector(".story");
function randomValueFromArray(array) {
const random = Math.floor(Math.random() * array.length);
return array[random];
}
// 模範解答: 生のテキスト文字列
const characters = ["ゴブリンのウィリー", "ビッグダディ", "サンタクロース"];
const places = ["スープキッチン", "ディズニーランド", "ホワイトハウス"];
const events = [
"自然発火した",
"歩道の上で水たまりになった",
"ナメクジに変身して、這って逃げ去った",
];
// 模範解答: ランダム文字列の一部を返す関数
function returnRandomStoryString() {
const randomCharacter = randomValueFromArray(characters);
const randomPlace = randomValueFromArray(places);
const randomEvent = randomValueFromArray(events);
let storyText = `外は華氏 94 度もあったので、${randomCharacter}は散歩に出かけた。${randomPlace}に着くと、しばらくの間、恐怖のあまり呆然と立ち尽くしていたが、やがて${randomEvent}。ボブはその一連のことがすべて目撃したが、驚くことはなかった ―― ${randomCharacter}の体重は 300 ポンドもあるし、その日は暑い日だったからだ。`;
return storyText;
}
// 模範解答: イベントリスナーと部分的な生成関数の定義
generateBtn.addEventListener("click", generateStory);
function generateStory() {
let newStory = returnRandomStoryString();
if (customName.value !== "") {
const name = customName.value;
newStory = newStory.replace("ボブ", name);
}
if (document.getElementById("uk").checked) {
const weight = `${Math.round(300 / 14)} ストーン`;
const temperature = `摂氏 ${Math.round((94 - 32) * (5 / 9))} 度`;
newStory = newStory.replace("300 ポンド", weight);
newStory = newStory.replace("華氏 94 度", temperature);
}
story.textContent = newStory;
story.style.visibility = "visible";
}