🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1450閲覧

クイズゲームでランダムな文字と入力された文字の正誤判定を行いたい。

yuuhi55

総合スコア1

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/01/11 04:50

前提・実現したいこと

プログラミングの初学者です。質問内容や文章で見づらい部分・用語間違いなどが多数あると思いますが、どうぞよろしくお願い致します。

現在javascriptにて簡単なクイズゲームを製作しております。
ゲーム自体はボタンを押すと配列[a,b,c,......]からランダムに出題されます。
配列の中には既存の言葉[ミ.ル.ク.テ.ィ.ー]などが収納されていて、出題時にその単語をランダムに混ぜ([クルティーミ]など)、それらを解答欄にて回答するというものです。

ランダムに出題をするという部分と、出題時に文字列を混ぜるという部分は実装できたのですが、解答欄に入力された文字とランダムに出題された文字との正誤判定が実装できず困っております。

ランダムに出題するときに取得した配列[]と解答ボタンを押したときの処理内で取得している要素が違うためだと思うのですが、スコープ外?の為同じ定数が使えずに問題が起きていると推測しております。

発生している問題

解答ボタンを押したとき表示されている文字列と同じものを入力しても不正解と表示されてしまう。

//問題文 現状わかりやすい単語で代用中 a = ["ミ","ル","ク","テ","ィ","ー"]; // この時点で[].join("")記入すると下の文でシャッフルできない。理由不明 b = ["ペ","ッ","ト","ボ","ト","ル"]; c = ["エ","コ","バ","ッ","グ"]; q = [a,b,c]; // ボタンを押すとa,b,c....の配列からランダムに出題される function ran(){ const y = q[Math.floor(Math.random() * q.length)]; for(i = y.length -1;i>0;i--){ //乱数生成を使ってランダムに取り出す値を決める r = Math.floor(Math.random()*(i+1)); //取り出した値と箱の外の先頭の値を交換する tmp = y[i]; y[i] = y[r]; y[r] = tmp; return y; } } document.getElementById("button").addEventListener("click", () => { document.getElementById("question").textContent = ran().join(""); // 最終的に表示する場面で.join("")で""を外す。 }); // 出題時の配列内文字と、入力された文字が合っているかの正誤判定をしたい。 document.getElementById("cheak").addEventListener("click", () => { if(document.getElementById("answer").value === a.join("")) { // 上記a.joinが多分ボタンを押したときの返り値?とかになるのだと思う。yはスコープ外?で使えない window.alert("正解"); } else { window.alert("不正解") } });

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <link rel="stylesheet" href="style.css"> 7 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> 8 <title>Ptying</title> 9</head> 10<body> 11 <div class="container"> 12 <div class="row"> 13 <div class="title col-12 mt-5 mb-5">Ptying(programming Typing Game)</div> 14 </div> 15 </div> 16 17 18 <div class="container"> 19 <div class="row"> 20 <div id="question" class="question col-12">問題</div> 21 </div> 22 </div> 23 24 <div class="button-wrapper"> 25 <button id="button" type="button" class="btn btn-secondary col-6 mt-3">表示する</button> 26 </div> 27 28 <div class="container"> 29 <div class="row text-area mt-5"> 30 <input type="text" id="answer" value=""> 31 <input type="button" id="cheak" value="回答"> 32 33 </div> 34 </div> 35 36 37<script src="main.js"></script> 38</body> 39</html>

試したこと

ランダム出題ではなく、問題を固定して正誤判定などは試して成功しています。

補足情報(FW/ツールのバージョンなど)

VSCODEを使用しております。問題文は20~30単語になる予定でいます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

現状の問題点:
1.正解に選んだ配列自体をシャッフルしてしまっているため、問題と正解が同じデータになってしまっています。
対応→正解に選んだ配列はとっておき、コピーして作った別の変数をシャッフルする。

2.(これはテストした時のコードがそのままになっているだけかもしれませんが)
正解判定部分で、問題a(["ミ","ル","ク","テ","ィ","ー"])と比較してしまっています。
このため、ran()の最初の部分( q[Math.floor(Math.random() * q.length)])で、
「a」以外の問題が選ばれても、常にaと比較することになるため、正しく判定できません。
対応→正解の配列は、別変数として保管しておく。

1.の対応策として、正解の配列はsliceを使ってコピーします。

上記をふまえて修正したのが下記です。コメントをつけているところが修正点になります。
注:下記は変更を最低限にしたコードのため、必ずしもベストではありません

a = ["ミ","ル","ク","テ","ィ","ー"]; b = ["ペ","ッ","ト","ボ","ト","ル"]; c = ["エ","コ","バ","ッ","グ"]; q = [a,b,c]; // 回答を格納する変数 answer = []; function ran(){ // 回答を格納 answer = q[Math.floor(Math.random() * q.length)]; // シャッフルするためにコピーする const y = answer.slice() for(i = y.length -1;i>0;i--){ r = Math.floor(Math.random()*(i+1)); tmp = y[i]; y[i] = y[r]; y[r] = tmp; return y; } } document.getElementById("button").addEventListener("click", () => { document.getElementById("question").textContent = ran().join(""); }); document.getElementById("cheak").addEventListener("click", () => { // 格納していた回答と比較する。 if(document.getElementById("answer").value === answer.join("")) { window.alert("正解"); } else { window.alert("不正解") } });

もっとブラッシュアップするとすれば

a = ["ミ","ル","ク","テ","ィ","ー"]; // この時点で[].join("")記入すると下の文でシャッフルできない。理由不明

これはsplit()関数を使用することで対応できます。

a = "ミルクティー"; console.log(a.split("")); ↓ ["ミ","ル","ク","テ","ィ","ー"]

これを利用すれば、もうすこしすっきりしたコードにできると思います。

投稿2021/01/11 07:24

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuuhi55

2021/01/11 09:05

非常にわかりやすく、丁寧な解説をして頂き誠にありがとうございます。 2の部分に関しましては自分で何となく理解しておりましたが、1の部分が全く分からずに困っておりました。 私の勉強不足で現状まだ完全に理解は出来ておりませんが、教えていただいた事を基に少しずつ上達していこうと思います。この度はありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問