Bot plays:
以下が実装例です。注意:このコードは追加検討と改良が必要です。しかし、大枠としてはアルファベータ法に基づいて動作します。
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>5目並べbot</title>
<style>
table { border-collapse: collapse; }
table td { border: 1px solid black; width: 50px; height: 50px; text-align: center; line-height: 50px; font-size: 40px; cursor: pointer;}
.red { color: red; }
.blue { color: blue; }
</style>
</head>
<body>
<table id="board">
<tr><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td></tr>
</table>
<p>Bot plays: <span id="bot" class="red"></span></p>
<script>
let board = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]];
let bot = 1; // 固定で先手
let player = -1;
let emptyCells = 25;
let aiMove = [-1, -1];
let moves = [];
let fullBoard = false;
const table = document.getElementById('board');
const botTag = document.getElementById('bot');
table.addEventListener('click', handleClick);
function handleClick(event) {
const rowIndex = event.target.parentNode.rowIndex;
const cellIndex = event.target.cellIndex;
if (board[rowIndex][cellIndex] !== 0) { return; }
player *= -1;
emptyCells--;
board[rowIndex][cellIndex] = player;
updateView(rowIndex, cellIndex);
if (checkWin(board, player)) {
announceResult(player === bot ? 'bot' : 'you');
return;
} else if (emptyCells === 0) {
announceResult('draw');
return;
}
alphaBeta(board, bot, -Infinity, Infinity, 0);
aiMove = moves[moves.length - 1];
board[aiMove[0]][aiMove[1]] = bot;
updateView(aiMove[0], aiMove[1]);
if (checkWin(board, bot)) {
announceResult('bot');
return;
} else if (emptyCells === 0) {
announceResult('draw');
return;
}
}
function updateView(row, col) {
const cell = table.rows[row].cells[col];
cell.classList.add(player === 1 ? 'red' : 'blue');
cell.textContent = player === 1 ? 'o' : 'x';
botTag.classList.toggle('red', player !== bot);
botTag.classList.toggle('blue', player === bot);
botTag.textContent = (player === bot) ? 'thinking...' : 'done';
}
function checkWin(board, player) {
let win = false;
// horizontal
for (let i = 0; i < 5; i++) {
win = true;
for (let j = 0; j < 5; j++) {
if (board[i][j] !== player) {
win = false;
break;
}
}
if (win) { return true; }
}
// vertical
for (let i = 0; i < 5; i++) {
win = true;
for (let j = 0; j < 5; j++) {
if (board[j][i] !== player) {
win = false;
break;
}
}
if (win) { return true; }
}
// diagonal
win = true;
for(let i = 0; i < 5; i++) {
if(board[i][i] !== player) {
win = false;
break;
}
}
if(win) { return true; }
win = true;
for(let i = 0; i < 5; i++) {
if(board[i][4 - i] !== player) {
win = false;
break;
}
}
if(win) { return true; }
return false;
}
function announceResult(result) {
switch (result) {
case 'bot':
alert('I win! This was easy for me!');
break;
case 'you':
alert('You are the winner! You got lucky.');
break;
case 'draw':
alert('The game ended in a draw. Let us play again!');
break;
}
}
function alphaBeta(state, player, alpha, beta, depth) {
if (depth === 4 || emptyCells === 0) {
return evaluateBoard(state);
}
for (let row = 0; row < 5; row++) {
for (let col = 0; col < 5; col++) {
if (state[row][col] === 0) {
state[row][col] = player;
emptyCells--;
moves.push([row, col]);
let score = alphaBeta(state, player === bot ? player * -1 : bot, alpha, beta, depth + 1);
state[row][col] = 0;
emptyCells++;
moves.pop();
if (player === bot) {
if (score > alpha) {
alpha = score;
if (depth === 0) {
aiMove = [row, col];
}
}
} else {
if (score < beta) {
beta = score;
}
}
if (alpha >= beta) {
return player === bot ? alpha : beta;
}
}
}
}
return player === bot ? alpha : beta;
}
function evaluateBoard(state) {
let score = 0;
const lines = getLines(state);
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const player1 = line.filter(cell => cell === bot).length; // この行で bot が占めている場所の数
const player2 = line.filter(cell => cell === bot*-1).length; // この行でプレイヤー 2 (あなた)が占めている場所の数
if (player1 === 5) { return 100; } // botがすべての場所を占めている場合
if (player2 === 5) { return -100; } // あなたがすべての場所を占めている場合
if (player1 + player2 === 5) {
// この行のすべての場所が占められている場合
// player1 > player2: 多くの場所を取得したbot
// player2 > player1: 多くの場所を取得したあなた
// player1 === player2: 誰も優勢でない
score += player1 > player2 ? 1 : (player1 < player2 ? -1 : 0);
}
}
return score;
}
function getLines(state) {
const lines = [];
// 横、縦、斜めで行の値の配列を取得します。
for (let i = 0; i < 5; i++) {
lines.push(state[i]); // 横
const column = [state[0][i], state[1][i], state[2][i], state[3][i], state[4][i]];
lines.push(column); // 縦
}
const diagonal1 = [state[0][0], state[1][1], state[2][2], state[3][3], state[4][4]];
const diagonal2 = [state[4][0], state[3][1], state[2][2], state[1][3], state[0][4]];
lines.push(diagonal1); // 斜め
lines.push(diagonal2); // 斜め
return lines;
}
</script>
</body>
</html>
```