CSSだけでマルバツゲームを作成する方法を紹介します。
順を追って説明していきますので、サンプルソースをコピーしてマルバツゲームを作成してみてください。また、一部の手順では詳細を説明していますので、仕組みを知りたい方は参考にしてみてください。
はじめに
マルバツゲームの作成方法を順に追って説明していきます。基本的に後に追記するようにしてください。指定がある場合、その場所に追記してください。
手順によっては詳細を説明するようにしています。
手順1.〇と×を配置するボードを作成します
〇と×を配置するボードのイメージは、以下のようになります。
HTMLとCSSは、以下のようになります。
<!-- 手順3はここに記載します -->
<div class="board-grid board-display">
<div id="display-1" class="board-display-item"></div>
<div id="display-2" class="board-display-item"></div>
<div id="display-3" class="board-display-item"></div>
<div id="display-4" class="board-display-item"></div>
<div id="display-5" class="board-display-item"></div>
<div id="display-6" class="board-display-item"></div>
<div id="display-7" class="board-display-item"></div>
<div id="display-8" class="board-display-item"></div>
<div id="display-9" class="board-display-item"></div>
</div>
.board-grid {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
column-gap: 5px;
row-gap: 5px;
padding: 15px;
width: max-content;
}
.board-display {
background: #333;
border-radius: 15px;
}
.board-display .board-display-item {
background-color: #55ff55;
}
ボードの表示方法について
ボードの表示には、3×3のマス目を表現するために「display: grid;」を利用します。
横方向のマス目の幅・数は「grid-template-columns」で表現し、縦方向のマスの高さ・幅は「grid-template-rows」で表現しています。
マス目の隙間は「column-gap」「row-gap」で表現しています。
手順2.〇と×の選択個所を作成します
〇と×の選択個所は以下のように表現します。赤色が〇で青色が×になります。
HTMLとCSSは、以下のようになります。
board-item-voidクラスを非表示にして、board-itemクラスだけ表示させています。そのため、基本的にボードの色違いになります。board-item-voidクラスは後で利用していきます。
<div class="board-grid board-precedence">
<label class="board-item item-1" for="precedence-1"></label>
<div class="board-item-void item-1"></div>
<label class="board-item item-2" for="precedence-2"></label>
<div class="board-item-void item-2"></div>
<label class="board-item item-3" for="precedence-3"></label>
<div class="board-item-void item-3"></div>
<label class="board-item item-4" for="precedence-4"></label>
<div class="board-item-void item-4"></div>
<label class="board-item item-5" for="precedence-5"></label>
<div class="board-item-void item-5"></div>
<label class="board-item item-6" for="precedence-6"></label>
<div class="board-item-void item-6"></div>
<label class="board-item item-7" for="precedence-7"></label>
<div class="board-item-void item-7"></div>
<label class="board-item item-8" for="precedence-8"></label>
<div class="board-item-void item-8"></div>
<label class="board-item item-9" for="precedence-9"></label>
<div class="board-item-void item-9"></div>
</div>
<div class="board-grid board-second">
<label class="board-item item-1" for="second-1"></label>
<div class="board-item-void item-1"></div>
<label class="board-item item-2" for="second-2"></label>
<div class="board-item-void item-2"></div>
<label class="board-item item-3" for="second-3"></label>
<div class="board-item-void item-3"></div>
<label class="board-item item-4" for="second-4"></label>
<div class="board-item-void item-4"></div>
<label class="board-item item-5" for="second-5"></label>
<div class="board-item-void item-5"></div>
<label class="board-item item-6" for="second-6"></label>
<div class="board-item-void item-6"></div>
<label class="board-item item-7" for="second-7"></label>
<div class="board-item-void item-7"></div>
<label class="board-item item-8" for="second-8"></label>
<div class="board-item-void item-8"></div>
<label class="board-item item-9" for="second-9"></label>
<div class="board-item-void item-9"></div>
</div>
/* 〇の場合 */
.board-precedence .board-item {
background-color: #cc5555;
}
/* ×の場合 */
.board-second .board-item {
background-color: #5555cc;
}
/* 選択済みの表現で利用します。 */
.board-item-void {
display: none;
}
手順3.〇と×の選択個所を表現します
〇と×の選択可能な個所を表現していきます。選択された箇所は、以下のように非表示になります。以下の画像は、真ん中を選択した例になります。
HTMLの最初 または 「<!– 手順3をここに記入します。 –>」の個所に以下のHTMLを記載します。
<!-- 〇の選択 -->
<input id="precedence-1" class="chk-board-item item-1" type="checkbox">
<input id="precedence-2" class="chk-board-item item-2" type="checkbox">
<input id="precedence-3" class="chk-board-item item-3" type="checkbox">
<input id="precedence-4" class="chk-board-item item-4" type="checkbox">
<input id="precedence-5" class="chk-board-item item-5" type="checkbox">
<input id="precedence-6" class="chk-board-item item-6" type="checkbox">
<input id="precedence-7" class="chk-board-item item-7" type="checkbox">
<input id="precedence-8" class="chk-board-item item-8" type="checkbox">
<input id="precedence-9" class="chk-board-item item-9" type="checkbox">
<!-- ×の選択 -->
<input id="second-1" class="chk-board-item item-1" type="checkbox">
<input id="second-2" class="chk-board-item item-2" type="checkbox">
<input id="second-3" class="chk-board-item item-3" type="checkbox">
<input id="second-4" class="chk-board-item item-4" type="checkbox">
<input id="second-5" class="chk-board-item item-5" type="checkbox">
<input id="second-6" class="chk-board-item item-6" type="checkbox">
<input id="second-7" class="chk-board-item item-7" type="checkbox">
<input id="second-8" class="chk-board-item item-8" type="checkbox">
<input id="second-9" class="chk-board-item item-9" type="checkbox">
CSSは、以下のようになります。
.chk-board-item {
display: none;
}
.chk-board-item.item-1:checked ~ .board-grid .board-item.item-1,
.chk-board-item.item-2:checked ~ .board-grid .board-item.item-2,
.chk-board-item.item-3:checked ~ .board-grid .board-item.item-3,
.chk-board-item.item-4:checked ~ .board-grid .board-item.item-4,
.chk-board-item.item-5:checked ~ .board-grid .board-item.item-5,
.chk-board-item.item-6:checked ~ .board-grid .board-item.item-6,
.chk-board-item.item-7:checked ~ .board-grid .board-item.item-7,
.chk-board-item.item-8:checked ~ .board-grid .board-item.item-8,
.chk-board-item.item-9:checked ~ .board-grid .board-item.item-9 {
display: none;
}
.chk-board-item.item-1:checked ~ .board-grid .board-item-void.item-1,
.chk-board-item.item-2:checked ~ .board-grid .board-item-void.item-2,
.chk-board-item.item-3:checked ~ .board-grid .board-item-void.item-3,
.chk-board-item.item-4:checked ~ .board-grid .board-item-void.item-4,
.chk-board-item.item-5:checked ~ .board-grid .board-item-void.item-5,
.chk-board-item.item-6:checked ~ .board-grid .board-item-void.item-6,
.chk-board-item.item-7:checked ~ .board-grid .board-item-void.item-7,
.chk-board-item.item-8:checked ~ .board-grid .board-item-void.item-8,
.chk-board-item.item-9:checked ~ .board-grid .board-item-void.item-9 {
display: block;
}
選択された箇所を非表示にする方法について
選択された箇所を非表示にするために、board-item-voidクラスとboard-itemクラスの表示を切り替えています。表示の切り替えには、chk-board-itemクラスの選択状態を利用しています。
chk-board-itemクラスが選択されたときに同階層のboard-gridクラスを指定するために間接セレクタ(~)を利用しています。間接セレクタ(~)は基準となる要素以降に要素を指定することができます。
以下のCSSの場合、item-1クラスのchk-board-itemクラスが選択されることで、item-1クラスのboard-item-voidクラスとboard-itemクラスの表示を切り替えます。
.chk-board-item.item-1:checked ~ .board-grid .board-item.item-1 {
display: none;
}
.chk-board-item.item-1:checked ~ .board-grid .board-item-void.item-1 {
display: block;
}
デモを用意しましたので体験してみてください。
手順4.〇と×をボードに配置します
〇と×の選択個所が選択されたときに、対応するボードの位置に〇と×を以下のように配置していきます。
CSSは、以下のようになります。〇と×の表示にはカスタムプロパティ(–mark)を利用しています。〇と×の選択個所が選択されることで「–mark」の値が更新され、ボードに〇か×が表示されます。
.board-display-item {
display: flex;
align-items: center;
justify-content: center;
}
.board-display-item::before {
--mark: "";
content: var(--mark);
font-size: 100px;
}
#precedence-1:checked ~ .board-grid #display-1::before,
#precedence-2:checked ~ .board-grid #display-2::before,
#precedence-3:checked ~ .board-grid #display-3::before,
#precedence-4:checked ~ .board-grid #display-4::before,
#precedence-5:checked ~ .board-grid #display-5::before,
#precedence-6:checked ~ .board-grid #display-6::before,
#precedence-7:checked ~ .board-grid #display-7::before,
#precedence-8:checked ~ .board-grid #display-8::before,
#precedence-9:checked ~ .board-grid #display-9::before {
--mark: "〇";
}
#second-1:checked ~ .board-grid #display-1::before,
#second-2:checked ~ .board-grid #display-2::before,
#second-3:checked ~ .board-grid #display-3::before,
#second-4:checked ~ .board-grid #display-4::before,
#second-5:checked ~ .board-grid #display-5::before,
#second-6:checked ~ .board-grid #display-6::before,
#second-7:checked ~ .board-grid #display-7::before,
#second-8:checked ~ .board-grid #display-8::before,
#second-9:checked ~ .board-grid #display-9::before {
--mark: "×";
}
手順5.ターンを制御します
手順3で用意した選択個所を交互に表示させてターンを表現します。
CSSは、以下のようになります。
.board-grid.board-precedence {
display: var(--precedence-board);
}
.board-grid.board-second {
display: var(--second-board);
}
.board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid {
--precedence-board: grid;
--second-board: none;
}
.chk-board-item:checked ~ .board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid {
--precedence-board: none;
--second-board: grid;
}
ターンの制御について
ターンの制御は、chk-board-itemクラスの選択された数で行っています。chk-board-itemクラスの選択された数が偶数の場合は〇のターンになります。奇数の場合は×になります。
手順6.結果を表示します
結果を以下のように表示するようにします。分かりやすく赤枠で囲っていますが、実際は囲われていません。
また、結果を表示する際に選択個所を非表示にすることでゲームを終了させます。
HTMLとCSSは、以下のようになります。
<div class="board-result"></div>
.board-result::before {
--result: "";
content: var(--result);
}
#precedence-1:checked ~ #precedence-2:checked ~ #precedence-3:checked ~ .board-result::before,
#precedence-4:checked ~ #precedence-5:checked ~ #precedence-6:checked ~ .board-result::before,
#precedence-7:checked ~ #precedence-8:checked ~ #precedence-9:checked ~ .board-result::before,
#precedence-1:checked ~ #precedence-4:checked ~ #precedence-7:checked ~ .board-result::before,
#precedence-2:checked ~ #precedence-5:checked ~ #precedence-8:checked ~ .board-result::before,
#precedence-3:checked ~ #precedence-6:checked ~ #precedence-9:checked ~ .board-result::before,
#precedence-1:checked ~ #precedence-5:checked ~ #precedence-9:checked ~ .board-result::before,
#precedence-3:checked ~ #precedence-5:checked ~ #precedence-7:checked ~ .board-result::before {
--result: "〇の勝利";
}
#second-1:checked ~ #second-2:checked ~ #second-3:checked ~ .board-result::before,
#second-4:checked ~ #second-5:checked ~ #second-6:checked ~ .board-result::before,
#second-7:checked ~ #second-8:checked ~ #second-9:checked ~ .board-result::before,
#second-1:checked ~ #second-4:checked ~ #second-7:checked ~ .board-result::before,
#second-2:checked ~ #second-5:checked ~ #second-8:checked ~ .board-result::before,
#second-3:checked ~ #second-6:checked ~ #second-9:checked ~ .board-result::before,
#second-1:checked ~ #second-5:checked ~ #second-9:checked ~ .board-result::before,
#second-3:checked ~ #second-5:checked ~ #second-7:checked ~ .board-result::before {
--result: "×の勝利";
}
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-result::before {
--result: "引き分け";
}
/* 勝敗が追加時に選択できないようにします。 */
#precedence-1:checked ~ #precedence-2:checked ~ #precedence-3:checked ~ .board-grid,
#precedence-4:checked ~ #precedence-5:checked ~ #precedence-6:checked ~ .board-grid,
#precedence-7:checked ~ #precedence-8:checked ~ #precedence-9:checked ~ .board-grid,
#precedence-1:checked ~ #precedence-4:checked ~ #precedence-7:checked ~ .board-grid,
#precedence-2:checked ~ #precedence-5:checked ~ #precedence-8:checked ~ .board-grid,
#precedence-3:checked ~ #precedence-6:checked ~ #precedence-9:checked ~ .board-grid,
#precedence-1:checked ~ #precedence-5:checked ~ #precedence-9:checked ~ .board-grid,
#precedence-3:checked ~ #precedence-5:checked ~ #precedence-7:checked ~ .board-grid,
#second-1:checked ~ #second-2:checked ~ #second-3:checked ~ .board-grid,
#second-4:checked ~ #second-5:checked ~ #second-6:checked ~ .board-grid,
#second-7:checked ~ #second-8:checked ~ #second-9:checked ~ .board-grid,
#second-1:checked ~ #second-4:checked ~ #second-7:checked ~ .board-grid,
#second-2:checked ~ #second-5:checked ~ #second-8:checked ~ .board-grid,
#second-3:checked ~ #second-6:checked ~ #second-9:checked ~ .board-grid,
#second-1:checked ~ #second-5:checked ~ #second-9:checked ~ .board-grid,
#second-3:checked ~ #second-5:checked ~ #second-7:checked ~ .board-grid,
.chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .chk-board-item:checked ~ .board-grid {
--precedence-board: none;
--second-board: none;
}
勝利条件について
勝利条件は、縦・横・斜めで8通り存在しています。
その勝利条件は以下のCSSで表現しています。以下のCSSは〇のパターンになります。
#precedence-1:checked ~ #precedence-2:checked ~ #precedence-3:checked ~ .board-result::before,
#precedence-4:checked ~ #precedence-5:checked ~ #precedence-6:checked ~ .board-result::before,
#precedence-7:checked ~ #precedence-8:checked ~ #precedence-9:checked ~ .board-result::before,
#precedence-1:checked ~ #precedence-4:checked ~ #precedence-7:checked ~ .board-result::before,
#precedence-2:checked ~ #precedence-5:checked ~ #precedence-8:checked ~ .board-result::before,
#precedence-3:checked ~ #precedence-6:checked ~ #precedence-9:checked ~ .board-result::before,
#precedence-1:checked ~ #precedence-5:checked ~ #precedence-9:checked ~ .board-result::before,
#precedence-3:checked ~ #precedence-5:checked ~ #precedence-7:checked ~ .board-result::before {
--result: "〇の勝利";
}
ボードの番号は以下のようになっております。例えば「1」「2」「3」が〇で選択された場合、〇の勝利になります。
手順7.ボードと選択個所を重ねます
ボードと選択個所がずれているので重ねていきます。
今まで記載してきたHTMLを以下のHTMLで囲みます。
<div class="board">
<!-- 今までの内容はここに記載します -->
</div>
CSSは、以下のようになります。
/* 手順7 */
.board {
position: relative;
}
.board-precedence,
.board-second {
top:0;
left: 0;
position: absolute;
}
完成!!
今まで記載した内容は、以下のようになります。デモもありますので楽しんでみてください。
おまけ:見た目をゲームのようにしてみる
当記事で紹介した内容を利用して以下のように見た目をよりゲームのようにしてみました。見た目を変更するためにHTML・CSSを変更していますが、基本的に当記事で紹介した内容を利用しています。
実際に遊ぶことができますので、よければ体験してみてください。
やり直しボタンについて
やり直しボタンは、buttonタグのtype属性を「reset」にすることでHTMLだけで表現しています。
buttonタグのtype属性「reset」をformタグで囲むことにより、buttonタグが選択された時にformタグ内のinputタグが初期化されます。