<style>
/* ゲームコンテナのスタイル */
#game-container {
width: 306px;
margin: 50px auto;
text-align: center;
}
/* ゲームボードのスタイル */
#game-board {
display: grid;
grid-template-columns: repeat(3, 100px);
gap: 1px;
border: 1px solid #FFF;
background-color: #FFF;
margin-bottom: 20px;
}
/* 各ブロックのスタイル */
.block {
width: 100px;
height: 100px;
cursor: pointer;
}
/* リセットボタンのスタイル */
#reset-button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>
<div id="game-container">
<div id="game-board"></div>
<button id="reset-button">リセット</button>
</div>
<script>
// グリッドの横のマス目の数
const GRID_WIDTH = 3;
// グリッドの縦のマス目の数
const GRID_HEIGHT = 3;
// ゲームのグリッドを保存する配列
let grid = [];
// グリッドを初期化する関数
function initGrid() {
grid = [];
// game-boardという id を持つ HTML 要素を取得
const board = document.getElementById('game-board');
// 既存のブロックをクリア
board.innerHTML = '';
// 2重のforループを使って、縦と横のマス目を作成
for (let y = 0; y < GRID_HEIGHT; y++) {
grid[y] = []; // 各行(y)に対して新しい配列を作成
for (let x = 0; x < GRID_WIDTH; x++) {
// 新しい div 要素(HTML の箱)を作成
const block = document.createElement('div');
block.className = 'block'; // CSS クラスを設定
// 初期のブロックの背景色を設定
block.style.backgroundColor = '#000000';
// 作成したブロックをゲームボードに追加
board.appendChild(block);
// ブロックがクリックされたときの動作を設定
block.addEventListener('click', () => handleClick(x, y));
// グリッドの初期状態を設定(すべてオフ)
grid[y][x] = false;
}
}
// ランダムにブロックをオンにする
randomizeGrid();
}
// ブロックがクリックされたときの処理
function handleClick(x, y) {
// クリックされたブロックとその周囲のブロックを反転させる
toggleBlock(x, y);
toggleAdjacentBlocks(x, y);
// ゲームの勝利判定を行う
checkWinCondition();
}
// 指定されたブロックを反転させる関数
function toggleBlock(x, y) {
grid[y][x] = !grid[y][x];
updateBlockAppearance(x, y);
}
// ブロックの見た目(背景色)を更新する関数
function updateBlockAppearance(x, y) {
const block = document.getElementsByClassName('block')[y * GRID_WIDTH + x];
block.style.backgroundColor = grid[y][x] ? '#FFFF00' : '#000000';
}
// クリックされたブロックの上下左右のブロックを反転させる関数
function toggleAdjacentBlocks(x, y) {
const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]; // 上下左右
for (let [dx, dy] of directions) {
const newX = x + dx;
const newY = y + dy;
if (newX >= 0 && newX < GRID_WIDTH && newY >= 0 && newY < GRID_HEIGHT) {
toggleBlock(newX, newY);
}
}
}
// ランダムにブロックをオンにする関数
function randomizeGrid() {
// オンにするブロックの数を決定(最大8個)
const maxOnBlocks = Math.min(8, GRID_WIDTH * GRID_HEIGHT - 1);
const numOnBlocks = Math.floor(Math.random() * maxOnBlocks);
// ブロックをランダムに選んでオンにする
for (let i = 0; i < numOnBlocks; i++) {
let x, y;
do {
x = Math.floor(Math.random() * GRID_WIDTH);
y = Math.floor(Math.random() * GRID_HEIGHT);
} while (grid[y][x]); // 既にオンのブロックは選ばない
toggleBlock(x, y);
}
}
// すべてのブロックがオンになっているかチェックする関数
function checkAllOn() {
for (let y = 0; y < GRID_HEIGHT; y++) {
for (let x = 0; x < GRID_WIDTH; x++) {
if (!grid[y][x]) return false;
}
}
return true;
}
// ゲームの勝利判定を行う関数
function checkWinCondition() {
if (checkAllOn()) {
setTimeout(() => {
alert('全てのライトがオンになりました!');
}, 100); // アラートを表示する前に、最後のブロックの色が変わるのを待つ
}
}
// グリッドを初期化
initGrid();
// リセットボタンにイベントリスナーを追加
document.getElementById('reset-button').addEventListener('click', initGrid);
</script>
コメント