火曜日, 12月 17, 2024

Let's start JavaScript 48 
HTML上で○×ゲーム

唐突にHTML上で○×ゲームを作成してみました。最も唐突ではなくて数ヶ月ダラダラと作っていました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport"
        content="width=device-width, initial-scale=1.0">
<title>○×ゲーム</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: powderblue;
}
.game-container {
text-align: center;
}
.board {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
gap: 5px;
margin-bottom: 20px;
}
.cell {
width: 100px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
background-color: white;
border: 1px solid #ccc;
font-size: 2em;
cursor: pointer;
}
.cell.taken {
cursor: not-allowed;
}
.status {
font-size: 1.2em;
}
.restart {
padding: 5px 15px;
font-size: 1em;
cursor: pointer;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
}
.restart:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="game-container">
<div class="board" id="board">
<!-- マスは左上から
0 1 2
3 4 5
6 7 9 -->
<div class="cell" data-index="0"></div>
<div class="cell" data-index="1"></div>
<div class="cell" data-index="2"></div>
<div class="cell" data-index="3"></div>
<div class="cell" data-index="4"></div>
<div class="cell" data-index="5"></div>
<div class="cell" data-index="6"></div>
<div class="cell" data-index="7"></div>
<div class="cell" data-index="8"></div>
</div>
<div class="status" id="status">プレイヤー X の番です</div>
<button class="restart" id="restart">リスタート</button>
</div>

<script>
const board = document.getElementById('board');
const status = document.getElementById('status');
const restartButton = document.getElementById('restart');
let currentPlayer = 'X';
let gameActive = true;
let gameState = ["", "", "", "", "", "", "", "", ""];

/* 勝利条件(横・縦・斜め) */
const winningConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];

function handleCellClick(event) {
const clickedCell = event.target;
const clickedIndex =
                parseInt(clickedCell.getAttribute('data-index'));

if (gameState[clickedIndex] !== "" || !gameActive) {
return;
}

gameState[clickedIndex] = currentPlayer;
clickedCell.textContent = currentPlayer;
clickedCell.classList.add('taken');

/* 勝者を表示 */
if (checkWin()) {
status.textContent =
                    `プレイヤー ${currentPlayer} の勝ちです!`;
gameActive = false;
return;
}

/* 引き分けを表示 */
if (gameState.every(cell => cell !== "")) {
status.textContent = "引き分けです!";
gameActive = false;
return;
}

/* 次のプレイヤーを促す */
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
status.textContent =
                `プレイヤー ${currentPlayer} の番です`;
}

function checkWin() {
return winningConditions.some(condition => {
return condition.every(index =>
                    gameState[index] === currentPlayer);
});
}

/* リスタート */
function restartGame() {
currentPlayer = 'X';
gameActive = true;
gameState = ["", "", "", "", "", "", "", "", ""];
status.textContent = "プレイヤー X の番です";
document.querySelectorAll('.cell').forEach(cell => {
cell.textContent = "";
cell.classList.remove('taken');
});
}

board.addEventListener('click', handleCellClick);
restartButton.addEventListener('click', restartGame);
</script>
</body>
</html>

表示直後の状態。

指示に従って「×」と「○」をプロットしていきます。

引き分けの結果。

勝った場合の結果。ちなみに勝つのは難しいというか、私には無理かも(^o^)