神経衰弱のルール
動作の流れとしては以下の通りです。
① 16枚のカードの中から「?」と書かれたものをひとつクリック
② そのカードに書かれている「?」が「1」などの数字に変わる
③ もうひとつ「?」と書かれたものをクリックする
④ その要素に書かれている「?」が「1」などの数字に変わる
⑤ ②と④で表示された数字が一致している場合は、開いた数字はそのままで①に戻る。一致していない場合は1秒後に数字が「?」に戻り①にもどる。
⑥: 全ての要素が開かれたときにアラートで「Game Over」
実現したいこと
現状、カードをクリックするたびにcompare関数に値を投げて処理を書いてますが、compareするのは2枚目をクリックしたときだと書き終わったときに気付きました。
そうすると、
$('.firstOpen').length == 0
この辺の処理が不要になるというところまでは理解できました。
そうなると、クリックイベントではなく、カードオープンの処理には枚数チェックと比較関数へ飛ばす処理を書けば良いと思うんですが、以下の比較関数の記事を参考にやってみましたが、上手く処理を書けず困っています。
https://www.sejuku.net/blog/62904
※該当のソースコードは動作するコードです。
該当のソースコード
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$(function(){ 15 let cardNum = []; 16 let totalCard = 16; 17 let f = false; 18 19 function open($card){ 20 $card.css('pointer-events', 'none'); 21 $card.text($card.data('num')); 22 } 23 24 function close($card){ 25 $card.css('pointer-events', ''); 26 $card.text('?'); 27 } 28 29 function compare($card){ 30 // 1枚目に開いたカードが存在するか確認 31 // 存在すれば、即ち、現在は2枚目のカードを開いたところ 32 if($('.firstOpen').length == 0){ 33 // 開いたカードが一枚目のカードであれば、 34 // この要素が1枚目であることがわかるようにするため、 35 // firstOpenのクラスを付与しておく 36 f = false; 37 $card.addClass('firstOpen'); 38 }else{ 39 // 1枚目のカードのjQueryオブジェクト 40 let $firstCard = $('.firstOpen'); 41 // 2枚目のカードのjQueryオブジェクト 42 let $secondCard = $card; 43 44 // 1枚目のカードの数字 45 let firstNum = $firstCard.data('num'); 46 // 2枚目のカードの数字 47 let secondNum = $secondCard.data('num'); 48 49 // 1枚目識別用のクラスを削除 50 $firstCard.removeClass('firstOpen'); 51 52 // 一致している場合、両方からunopenedを削除する 53 // その後、unopenedが付与された要素の数を確認し、 54 // 0個であれば、アラートを表示する 55 if(firstNum === secondNum){ 56 f = false; 57 $firstCard.removeClass('unopened'); 58 $secondCard.removeClass('unopened'); 59 60 if($('.unopened').length === 0){ 61 alert("Game Over"); 62 } 63 // 一致していない場合、二枚とも閉じる 64 // カードを比較 65 // 1秒ほど待機させてから比較させる 66 // ※待機しないと二枚目のカードの番号が表示されるとほぼ同時ぐらいに比較が終わり 67 // 二枚目のカードの数字がわかりにくいため 68 }else{ 69 setTimeout(function(){ 70 f = false; 71 close($firstCard); 72 close($secondCard); 73 }, 1000); 74 } 75 } 76 } 77 78 // カードの中身を作成 79 for (var i = 1; i <= totalCard/2; i++){ 80 cardNum.push(i,i); 81 } 82 83 // ランダムに並べ替えて 84 // li要素を作成して 85 // listに追加 86 cardNum 87 .sort(function(){ 88 return Math.random() - Math.random(); 89 }) 90 .map(function(num){ 91 return "<li class='unopened' data-num='" + num + "'>?</li>"; 92 }) 93 .forEach(function(element){ 94 $(".lists").append(element); 95 }); 96 97 $('.lists li').on('click', function(){ 98 // クリックされたカード(li要素)のjQueryオブジェクト 99 if (f) return; 100 f = true; 101 let $openedCard = $(this); 102 103 // カードをオープン 104 open($openedCard); 105 compare($openedCard); 106 }); 107});
回答1件
あなたの回答
tips
プレビュー