| <?php |
| $boardSize = 15; |
| ?> |
| <!DOCTYPE html> |
| <html lang="zh"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>五子棋:人机对战(智能版)</title> |
|
|
| <style> |
| table { border-collapse: collapse; margin: 20px auto; } |
| td { |
| width: 30px; height: 30px; |
| border: 1px solid |
| text-align: center; |
| font-size: 24px; |
| cursor: pointer; |
| } |
| .black { color: black; } |
| .white { color: red; background-color: transparent; } |
| h2 { text-align: center; } |
| </style> |
|
|
| </head> |
| <body> |
| <h2>五子棋:人机对战(智能版)</h2> |
| <table id="board"> |
| <?php for ($i = 0; $i < $boardSize; $i++): ?> |
| <tr> |
| <?php for ($j = 0; $j < $boardSize; $j++): ?> |
| <td data-x="<?= $i ?>" data-y="<?= $j ?>"></td> |
| <?php endfor; ?> |
| </tr> |
| <?php endfor; ?> |
| </table> |
|
|
| <script> |
| const boardSize = <?= $boardSize ?>; |
| const board = Array.from({ length: boardSize }, () => Array(boardSize).fill(0)); |
| let gameOver = false; |
|
|
| function checkWin(x, y, player) { |
| const directions = [[1,0],[0,1],[1,1],[1,-1]]; |
| for (let [dx, dy] of directions) { |
| let count = 1; |
| for (let dir = -1; dir <= 1; dir += 2) { |
| let nx = x + dx * dir; |
| let ny = y + dy * dir; |
| while ( |
| nx >= 0 && ny >= 0 && nx < boardSize && ny < boardSize && |
| board[nx][ny] === player |
| ) { |
| count++; |
| nx += dx * dir; |
| ny += dy * dir; |
| } |
| } |
| if (count >= 5) return true; |
| } |
| return false; |
| } |
|
|
| function scorePosition(x, y, player) { |
| let score = 0; |
| const directions = [[1,0],[0,1],[1,1],[1,-1]]; |
| for (let [dx, dy] of directions) { |
| let count = 0; |
| for (let dir = -1; dir <= 1; dir += 2) { |
| let nx = x + dx * dir; |
| let ny = y + dy * dir; |
| while ( |
| nx >= 0 && ny >= 0 && nx < boardSize && ny < boardSize && |
| board[nx][ny] === player |
| ) { |
| count++; |
| nx += dx * dir; |
| ny += dy * dir; |
| } |
| } |
| score += count * count; |
| } |
| return score; |
| } |
|
|
| function computerMove() { |
| if (gameOver) return; |
| let bestScore = -1; |
| let move = null; |
|
|
| for (let i = 0; i < boardSize; i++) { |
| for (let j = 0; j < boardSize; j++) { |
| if (board[i][j] !== 0) continue; |
|
|
| |
| let attack = scorePosition(i, j, 2); |
| let defense = scorePosition(i, j, 1); |
| let total = attack + defense * 1.5; |
|
|
| if (total > bestScore) { |
| bestScore = total; |
| move = [i, j]; |
| } |
| } |
| } |
|
|
| if (!move) return; |
| const [x, y] = move; |
| board[x][y] = 2; |
| const cell = document.querySelector(`td[data-x="${x}"][data-y="${y}"]`); |
| cell.classList.add('white'); |
| cell.textContent = '○'; |
| if (checkWin(x, y, 2)) { |
| alert('电脑获胜!'); |
| gameOver = true; |
| } |
| } |
|
|
| document.querySelectorAll('td').forEach(cell => { |
| cell.addEventListener('click', () => { |
| if (gameOver) return; |
| const x = parseInt(cell.dataset.x); |
| const y = parseInt(cell.dataset.y); |
| if (board[x][y] !== 0) return; |
|
|
| board[x][y] = 1; |
| cell.classList.add('black'); |
| cell.textContent = '●'; |
|
|
| if (checkWin(x, y, 1)) { |
| alert('你赢了!'); |
| gameOver = true; |
| return; |
| } |
|
|
| setTimeout(computerMove, 300); |
| }); |
| }); |
| </script> |
| </body> |
| </html> |
|
|