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

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

詳細はこちら
JavaScript

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

Q&A

解決済

2回答

1397閲覧

【JavaScript】神経衰弱のカード判定ができるようにしたい

Matt007

総合スコア8

JavaScript

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

0グッド

0クリップ

投稿2019/12/25 12:55

編集2019/12/26 01:31

神経衰弱のルール

動作の流れとしては以下の通りです。
① 16枚のカードの中から「?」と書かれたものをひとつクリック
② そのカードに書かれている「?」が「1」などの数字に変わる
③ もうひとつ「?」と書かれたものをクリックする
④ その要素に書かれている「?」が「1」などの数字に変わる
⑤ ②と④で表示された数字が一致している場合は、開いた数字はそのままで①に戻る。一致していない場合は1秒後に数字が「?」に戻り①にもどる。
⑥ 全ての要素が開かれたときにアラートで「Game Over」

実現したいこと・発生している問題

現状の問題は2つです。
1つは、1ペアが完成した後にカードの判定ができず全てのカードが開いてしまい、カード判定ができない状況です。(1ペアが完成するまではちゃんとカードの判定ができています)
もう1つは、フラグを用いているにもかかわらずカードを判定する前に3枚目のカードが開いてしまいます。
この2つの問題を調べてみましたが、解決策が分からず質問させていただきました。

該当のソースコード

html

1<!doctype html> 2<html> 3<head> 4<meta charset="UTF-8"> 5<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 6<meta name="format-detection" content="telephone=no"> 7<title></title> 8<link rel="stylesheet" href="css/reset.css"> 9<link rel="stylesheet" href="css/base.css"> 10<link rel="stylesheet" href="css/style.css"> 11</head> 12<body> 13<ul class="lists clearfix"></ul> 14<script type="text/javascript" src="js/jquery.js"></script> 15<script type="text/javascript"> 16//jquery 17</script> 18</body> 19</html>

css

1.lists { 2 border: 10px #CCC solid; 3} 4.lists > li { 5 float: left; 6 width: 25%; 7 background-color: #EEE; 8 border-top: 2px #CCC solid; 9 border-right: 2px #CCC solid; 10 font-size: 20px; 11 font-weight: bold; 12 line-height: 75px; 13 text-align: center; 14 cursor: pointer; 15 -webkit-box-sizing: border-box; 16 box-sizing: border-box; 17} 18.lists > li:nth-child(-n + 4) { 19 border-top: none; 20} 21.lists > li:nth-child(4n) { 22 border-right: none; 23}

javascript

1/** 2 * (説明) 3 * @type {array} cardNum ← カードの配列 4 * @type {string} totalCard ← カードの枚数 5 * @param {object} $card ← カードの引数 6 * @type {string} $firstCard ← カードをめくる1枚目 7 * @type {string} $secondCard ← カードをめくる2枚目 8 * @type {firstNum} $firstNum ← カードに書かれている数字 9 * @type {secondNum} $secondNum ← カードに書かれてる数字 10 * @type {string} $openedCard ← めくられたカード 11 * @type {string} f←フラグ 12 * 13**/ 14 15$(function() { 16 let cardNum = []; 17 let totalCard = 16; 18 let f = false; 19 20 function open($card) { 21 $card 22 .css("pointer-events", "none") 23 .text($card.data("num")) 24 .addClass("fliped"); //openが走ったら、クラスはすべてに付与 25 if ($(".fliped").length === 2) compare(); //2枚flipされていたら比較 26 } 27 28 function close($card) { 29 $(".fliped") 30 .css("pointer-events", "") 31 .text("?") 32 .removeClass("fliped"); 33 } 34 35 function compare() { 36 let $firstCard = $(".fliped").eq(0); //比較対象1枚目 37 let $secondCard = $(".fliped").eq(1); //比較対象2枚目 38 39 let firstNum = $firstCard.data("num"); 40 let secondNum = $secondCard.data("num"); 41 42 if (firstNum === secondNum) { 43 $firstCard.add($secondCard).removeClass("unopened"); 44 45 if ($(".unopened").length === 0) { 46 alert("Game Over"); 47 } 48 } else { 49 setTimeout(function() { 50 close(); 51 }, 1000); 52 } 53 } 54 55 //初期配置 56 (() => { 57 // カードの中身を作成 58 for (var i = 1; i <= totalCard / 2; i++) cardNum.push(i, i); 59 // ランダムに並べ替えて 60 // li要素を作成して 61 // listに追加 62 cardNum 63 .sort(() => { 64 return Math.random() - Math.random(); 65 }) 66 .map(num => { 67 return "<li class='unopened' data-num='" + num + "'>?</li>"; 68 }) 69 .forEach(element => { 70 $(".lists").append(element); 71 }); 72 })(); 73 74 //クリックイベント 75 $(".lists li").on("click", function() { 76 if (f) return; 77 f = true; 78 open($(this)); 79 f = false; 80 }); 81});

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

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

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

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

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

guest

回答2

0

ベストアンサー

1ペアが完成した後にカードの判定ができず全てのカードが開いてしまい、カード判定ができない状況

開いたカードにflipedクラスが付与されていますが、ペア完成時にこのクラスが除去されないため、let $firstCard = $(".fliped").eq(0);は完成したペアを含めて取得されます。

解決方法は、ペア完成時に$(".fliped").removeClass("fliped"); とすることです。

フラグを用いているにもかかわらずカードを判定する前に3枚目のカードが開いてしまいます

js

1 open($(this)); 2 f = false;

としていますが、compare関数の中で、

js

1 setTimeout(function() { 2 close(); 3 }, 1000);

と非同期でclose関数を呼んでいますので、想定と異なりフラグを下すタイミングはclose関数が呼ばれる前になっています。

解決方法は、close関数の最後と、ペア完成したのでclose関数を通らなかった場合と、1枚目でcompare関数を通らなかった場合、の3か所でフラグを下せばいいのではないかと思います。

投稿2019/12/26 03:13

編集2019/12/26 04:53
Lhankor_Mhy

総合スコア36928

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

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

Matt007

2019/12/26 13:26

回答ありがとうございます。 フラグができてないですが、1ペア完成後全てのカードが開いてしまう部分は解決できました。
guest

0

選択しているかしていないかを、フラグ用クラス、.flipedのみで判別させているのが原因です。
下記のように、数カ所、.flipedかつ.unopenedであれば処理、というふうにすれば解決するでしょう。

javascript

1/** 2 * (説明) 3 * @type {array} cardNum ← カードの配列 4 * @type {string} totalCard ← カードの枚数 5 * @param {object} $card ← カードの引数 6 * @type {string} $firstCard ← カードをめくる1枚目 7 * @type {string} $secondCard ← カードをめくる2枚目 8 * @type {firstNum} $firstNum ← カードに書かれている数字 9 * @type {secondNum} $secondNum ← カードに書かれてる数字 10 * @type {string} $openedCard ← めくられたカード 11 * @type {string} f←フラグ 12 * 13**/ 14 15$(function() { 16 let cardNum = []; 17 let totalCard = 16; 18 let f = false; 19 20 function open($card) { 21 $card 22 .css("pointer-events", "none") 23 .text($card.data("num")) 24 .addClass("fliped"); //openが走ったら、クラスはすべてに付与 25 // flipだけでなく、unopenedも判別対象に 26 if ($(".fliped.unopened").length === 2) compare(); //2枚flipされていたら比較 27 } 28 29 function close($card) { 30 // flipだけでなく、unopenedも判別対象に。両方ついてるやつだけ閉じる 31 $(".fliped.unopened") 32 .css("pointer-events", "") 33 .text("?") 34 .removeClass("fliped"); 35 } 36 37 function compare() { 38 // flipだけでなく、unopenedも判別対象に。両方ついてるやつだけを比較対象にする 39 let $firstCard = $(".fliped.unopened").eq(0); //比較対象1枚目 40 let $secondCard = $(".fliped.unopened").eq(1); //比較対象2枚目 41 42 let firstNum = $firstCard.data("num"); 43 let secondNum = $secondCard.data("num"); 44 45 if (firstNum === secondNum) { 46 $firstCard.add($secondCard).removeClass("unopened"); 47 48 if ($(".unopened").length === 0) { 49 alert("Game Over"); 50 } 51 } else { 52 setTimeout(function() { 53 close(); 54 }, 1000); 55 } 56 } 57 58 //初期配置 59 (() => { 60 // カードの中身を作成 61 for (var i = 1; i <= totalCard / 2; i++) cardNum.push(i, i); 62 // ランダムに並べ替えて 63 // li要素を作成して 64 // listに追加 65 cardNum 66 .sort(() => { 67 return Math.random() - Math.random(); 68 }) 69 .map(num => { 70 return "<li class='unopened' data-num='" + num + "'>?</li>"; 71 }) 72 .forEach(element => { 73 $(".lists").append(element); 74 }); 75 })(); 76 77 //クリックイベント 78 $(".lists li").on("click", function() { 79 if (f) return; 80 f = true; 81 open($(this)); 82 f = false; 83 }); 84});

投稿2019/12/26 02:34

miyabi_takatsuk

総合スコア9555

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

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

Matt007

2019/12/26 13:21

回答ありがとうございます。 全てのカードが開いてしまうほうはおかげさまで解決できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問