先攻後攻ボタンを追加しよう
まずは index.html を開き、先攻後攻ボタンを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html> <head> ︙ </head> <body> <div class="buttons"> <h1>〇×ゲーム</h1> <button id="atk_first" class="attack">先攻</button><button id="atk_after" class="attack">後攻</button><br> <button id="start">スタート</button> </div> <div id="game" style="display: none;"> ︙ </div> <script src="./js/index.js"></script> </body> </html> |
javascriptで操作をするために、2つとものボタンに attack クラスを付与しています。また、各ボタンには違う名前のidを付与します。
続いて style.css を開き、先攻後攻ボタンを押した際に、ボタンが押し続けられた状態になるスタイル(色をグレーにし、文字色を反転)を追加します。
1 2 3 4 |
.pushed { background-color: gray; color: white; } |
配置を真ん中に、周囲の余白を20px確保するように設定します。
index.js に処理を追加します。
先攻後攻ボタンについて、押したボタンにより先攻後攻を判断し man_attack 変数に結果を格納します。
押したボタンに pushed クラスを付与し、押下した状態を保持し続けるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$(function() { // 定数定義 const FIRST = 0 const LAST = 1 ︙ let man_attack = FIRST // 自分が先攻か後攻か ︙ /** * 「スタート」ボタン押下 */ $("#start").click(function() { $("#game").css("display", "block") }) ︙ /** * 「先攻後攻」ボタン押下 */ $(".attack").click(function() { let id_name = $(this).attr("id") // 「先攻」ボタン押下時 if (id_name == 'atk_first') { man_attack = FIRST } // 「後攻」ボタン押下時 else { man_attack = LAST } $(this).addClass("pushed") }) }) |
COM入力処理とその制御をしよう
このページでは、空いているマス目からランダムに選択し、入力する処理を作成します。index.js に処理を追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
$(function() { // 定数定義 let last_cells_count = 9 let finished_com = true // COMによる自動入力が完了したかどうか ︙ $("td").click(function() { // 入力済みのセルをタップした場合 if ($(this).html()) { alert("入力できません") // 勝敗がついたあとに空のセルをタップした場合 } else if (got_match) { alert("リセットボタンを押してください") } else { ︙ // 決着がついていない場合、COMの操作を継続 if (! got_match) { input_by_com() } } }) ︙ /** * COMによる自動入力 */ function input_by_com() { finished_com = false // 自動入力開始 setTimeout(function() { let com_result_symbol = do_input_by_com() now_attack = !now_attack // 先攻後攻入れ替え last_cells_count-- // 勝敗判定 if (check_complete()) { got_match = !got_match alert(com_result_symbol + "の勝ち!") } // 引き分け判定 if (! last_cells_count) { alert("引き分け!") return } finished_com = true // 自動入力完了 }, 500) } /** * COMによる自動入力実行 */ function do_input_by_com() { // 現在の入力情報を取得 let results = $("td").get() // COMのマーク let com_result_symbol = now_attack ? BATSU : MARU let empty_cells = [] // 未入力セル情報 // ゲーム盤情報確認 for (let cnt = 0; cnt < results.length; cnt++) { // 未入力の場合 if (! $(results[cnt]).html()) { empty_cells.push(results[cnt]) } } // 未入力セルがある場合 if (empty_cells.length) { logic(empty_cells, com_result_symbol) } return com_result_symbol } /** * ロジック */ function logic(empty_cells, com_result_symbol) { let target // ランダムに1つ取得 target = empty_cells[Math.floor(Math.random() * empty_cells.length)] // 結果を入れる $(target).html(com_result_symbol) } }) |
実際に表示してみよう
index.html ファイルを再度読み直してください。コンピュータ対戦ができていれば問題ありません。
演習
1. 先攻 or 後攻を押下後にもう一方を選択すると、下図のように2つとも選択される表示となります。
先攻と後攻の両方が選択されることは望ましくなく、どちらか一方のみの選択状態としたいです。
このような場合に、もう一方の選択状態を解除するようにしてください。
【ヒント】pushed クラスをjQueryで付与する前後で、片方のボタンに付与されている pushed クラスを削除する。
2.先攻・後攻を選択していなくても「スタート」を押せばゲームが始まってしまいます。ボタンを押していない場合、下図のように「先攻・後攻を選択してください。」というアラートを出し、ゲームを開始させないでください。
【ヒント】「スタート」ボタン押下時に、.attack クラスが付与されたボタンに .pushed クラスがついている要素があるかどうかを判定する。
3.COMが入力完了するまで、プレイヤーが入力できないように制御してください。現在、プレイヤーが入力完了してから0.5秒後に入力をするように制御していますが、0.5秒たたないうちにプレイヤーが入力可能な状態であり、競合する可能性があります。
【ヒント】冒頭にある、マス目をクリックした際の入力可否、画面リロードorリセットを促すアラートを出す箇所にて、COMが入力中である場合はアラートを出すように制御してください。
4. 「リセット」ボタンを押下した際に、先攻後攻の選択状態が解除されるように、実装を修正してください。
5.「後攻」を選択した場合、COMが先に入力するように制御してください。
【ヒント】「スタート」ボタン押下時に、先攻後攻フラグを確認し、後攻である場合にCOMによる自動入力を開始する。