本文目录导读:

我来给你详细介绍如何用PHP实现一个AI对战系统,这里我提供几种不同层次的实现方案:
基础版:简单规则AI
<?php
class SimpleAI {
private $difficulty;
public function __construct($difficulty = 'easy') {
$this->difficulty = $difficulty;
}
public function makeMove($board) {
// 简单AI:随机选择一个空位
$emptyCells = [];
foreach ($board as $row => $cols) {
foreach ($cols as $col => $value) {
if ($value === 0) {
$emptyCells[] = [$row, $col];
}
}
}
if (empty($emptyCells)) {
return null; // 棋盘已满
}
// 按难度选择移动
switch ($this->difficulty) {
case 'easy':
return $this->randomMove($emptyCells);
case 'medium':
return $this->mediumMove($board, $emptyCells);
case 'hard':
return $this->hardMove($board, $emptyCells);
default:
return $this->randomMove($emptyCells);
}
}
private function randomMove($emptyCells) {
$index = array_rand($emptyCells);
return $emptyCells[$index];
}
private function mediumMove($board, $emptyCells) {
// 中等AI:尝试获胜或阻挡对手
// 简单的策略:如果有必胜,选择必胜
foreach ($emptyCells as $cell) {
$board[$cell[0]][$cell[1]] = 1; // 假设AI是1
if ($this->isWinner($board, 1)) {
$board[$cell[0]][$cell[1]] = 0;
return $cell;
}
$board[$cell[0]][$cell[1]] = 0;
}
// 防守策略:阻挡对手
foreach ($emptyCells as $cell) {
$board[$cell[0]][$cell[1]] = 2; // 对手是2
if ($this->isWinner($board, 2)) {
$board[$cell[0]][$cell[1]] = 0;
return $cell;
}
$board[$cell[0]][$cell[1]] = 0;
}
return $this->randomMove($emptyCells);
}
private function hardMove($board, $emptyCells) {
// 高级AI:使用Minimax算法
$bestScore = -INF;
$bestMove = null;
foreach ($emptyCells as $cell) {
$board[$cell[0]][$cell[1]] = 1;
$score = $this->minimax($board, 0, false);
$board[$cell[0]][$cell[1]] = 0;
if ($score > $bestScore) {
$bestScore = $score;
$bestMove = $cell;
}
}
return $bestMove ?? $this->randomMove($emptyCells);
}
private function minimax($board, $depth, $isMaximizing) {
// 检查胜负
if ($this->isWinner($board, 1)) return 10 - $depth;
if ($this->isWinner($board, 2)) return $depth - 10;
if ($this->isBoardFull($board)) return 0;
if ($isMaximizing) {
$bestScore = -INF;
foreach ($board as $row => $cols) {
foreach ($cols as $col => $value) {
if ($value === 0) {
$board[$row][$col] = 1;
$score = $this->minimax($board, $depth + 1, false);
$board[$row][$col] = 0;
$bestScore = max($score, $bestScore);
}
}
}
return $bestScore;
} else {
$bestScore = INF;
foreach ($board as $row => $cols) {
foreach ($cols as $col => $value) {
if ($value === 0) {
$board[$row][$col] = 2;
$score = $this->minimax($board, $depth + 1, true);
$board[$row][$col] = 0;
$bestScore = min($score, $bestScore);
}
}
}
return $bestScore;
}
}
private function isWinner($board, $player) {
// 检查胜利条件(以井字棋为例)
$winLines = [
[[0,0],[0,1],[0,2]], [[1,0],[1,1],[1,2]], [[2,0],[2,1],[2,2]], // 行
[[0,0],[1,0],[2,0]], [[0,1],[1,1],[2,1]], [[0,2],[1,2],[2,2]], // 列
[[0,0],[1,1],[2,2]], [[0,2],[1,1],[2,0]] // 对角
];
foreach ($winLines as $line) {
$win = true;
foreach ($line as $cell) {
if ($board[$cell[0]][$cell[1]] !== $player) {
$win = false;
break;
}
}
if ($win) return true;
}
return false;
}
private function isBoardFull($board) {
foreach ($board as $row) {
foreach ($row as $cell) {
if ($cell === 0) return false;
}
}
return true;
}
}
进阶版:概率模型AI
<?php
class ProbabilisticAI {
private $probabilityMatrix;
private $history;
public function __construct() {
$this->probabilityMatrix = [];
$this->history = [];
}
public function makeMove($gameState) {
// 学习历史,预测对手行为
$action = $this->getAction($gameState);
$this->updateHistory($gameState, $action);
return $action;
}
private function getAction($gameState) {
$actionValues = [];
$possibleActions = $this->getPossibleActions($gameState);
foreach ($possibleActions as $action) {
// 计算Q值(期望回报)
$qValue = 0;
if (isset($this->probabilityMatrix[md5(serialize($gameState))])) {
$qValue = $this->probabilityMatrix[md5(serialize($gameState))][md5(serialize($action))] ?? 0;
}
$actionValues[$action] = $qValue;
}
// 使用epsilon贪心策略
$epsilon = 0.1;
if (rand(0, 100) / 100 < $epsilon) {
// 探索:随机选择
return $possibleActions[array_rand($possibleActions)];
} else {
// 利用:选择Q值最高的动作
arsort($actionValues);
return array_key_first($actionValues);
}
}
private function updateHistory($state, $action) {
$key = md5(serialize($state)) . '-' . md5(serialize($action));
$this->history[] = [
'state' => $state,
'action' => $action,
'timestamp' => time()
];
}
}
完整示例:五子棋AI对战
<?php
class GomokuAI {
private $board;
private $size;
private $player = 1; // AI的棋子
private $opponent = 2; // 对手的棋子
public function __construct($size = 15) {
$this->size = $size;
$this->board = array_fill(0, $size, array_fill(0, $size, 0));
}
public function getBestMove() {
// 使用极大极小搜索 + Alpha-Beta剪枝
$bestScore = -PHP_INT_MAX;
$bestMove = null;
for ($i = 0; $i < $this->size; $i++) {
for ($j = 0; $j < $this->size; $j++) {
if ($this->board[$i][$j] === 0) {
$this->board[$i][$j] = $this->player;
$score = $this->alphaBeta(4, -PHP_INT_MAX, PHP_INT_MAX, false);
$this->board[$i][$j] = 0;
if ($score > $bestScore) {
$bestScore = $score;
$bestMove = [$i, $j];
}
}
}
}
return $bestMove;
}
private function alphaBeta($depth, $alpha, $beta, $isMaximizing) {
// 检查胜负
if ($this->checkWinner($this->player)) return 100000;
if ($this->checkWinner($this->opponent)) return -100000;
if ($depth === 0) return $this->evaluateBoard();
if ($isMaximizing) {
$maxScore = -PHP_INT_MAX;
$moves = $this->getHeuristicMoves();
foreach ($moves as $move) {
$this->board[$move[0]][$move[1]] = $this->player;
$score = $this->alphaBeta($depth - 1, $alpha, $beta, false);
$this->board[$move[0]][$move[1]] = 0;
$maxScore = max($maxScore, $score);
$alpha = max($alpha, $score);
if ($beta <= $alpha) break;
}
return $maxScore;
} else {
$minScore = PHP_INT_MAX;
$moves = $this->getHeuristicMoves();
foreach ($moves as $move) {
$this->board[$move[0]][$move[1]] = $this->opponent;
$score = $this->alphaBeta($depth - 1, $alpha, $beta, true);
$this->board[$move[0]][$move[1]] = 0;
$minScore = min($minScore, $score);
$beta = min($beta, $score);
if ($beta <= $alpha) break;
}
return $minScore;
}
}
private function evaluateBoard() {
$score = 0;
// 评估所有方向上的局势
$directions = [[0,1],[1,0],[1,1],[1,-1]];
foreach ($directions as $dir) {
$score += $this->evaluateDirection($dir[0], $dir[1], $this->player);
$score -= $this->evaluateDirection($dir[0], $dir[1], $this->opponent);
}
return $score;
}
private function evaluateDirection($dx, $dy, $player) {
$score = 0;
for ($i = 0; $i < $this->size; $i++) {
for ($j = 0; $j < $this->size; $j++) {
if ($this->board[$i][$j] === $player) {
$count = 1;
$blocked = [false, false];
// 向前检查
for ($k = 1; $k < 5; $k++) {
$nx = $i + $dx * $k;
$ny = $j + $dy * $k;
if ($nx < 0 || $nx >= $this->size || $ny < 0 || $ny >= $this->size) {
$blocked[0] = true;
break;
}
if ($this->board[$nx][$ny] === $player) {
$count++;
} else if ($this->board[$nx][$ny] === 0) {
break;
} else {
$blocked[0] = true;
break;
}
}
// 向后检查
for ($k = 1; $k < 5; $k++) {
$nx = $i - $dx * $k;
$ny = $j - $dy * $k;
if ($nx < 0 || $nx >= $this->size || $ny < 0 || $ny >= $this->size) {
$blocked[1] = true;
break;
}
if ($this->board[$nx][$ny] === $player) {
$count++;
} else if ($this->board[$nx][$ny] === 0) {
break;
} else {
$blocked[1] = true;
break;
}
}
// 根据棋子数和阻塞情况打分
if ($count >= 5 && !$blocked[0] && !$blocked[1]) {
$score += 10000;
} else if ($count === 4 && !($blocked[0] && $blocked[1])) {
$score += 1000;
} else if ($count === 3 && !($blocked[0] && $blocked[1])) {
$score += 100;
} else if ($count === 2 && !($blocked[0] && $blocked[1])) {
$score += 10;
} else if ($count === 1 && !($blocked[0] && $blocked[1])) {
$score += 1;
}
}
}
}
return $score;
}
private function getHeuristicMoves() {
$moves = [];
// 只考虑周围有棋子的位置
for ($i = 0; $i < $this->size; $i++) {
for ($j = 0; $j < $this->size; $j++) {
if ($this->board[$i][$j] !== 0 && $this->hasNeighbor($i, $j)) {
$moves[] = [$i, $j];
}
}
}
return $moves;
}
private function hasNeighbor($x, $y) {
for ($i = -1; $i <= 1; $i++) {
for ($j = -1; $j <= 1; $j++) {
if ($i === 0 && $j === 0) continue;
$nx = $x + $i;
$ny = $y + $j;
if ($nx >= 0 && $nx < $this->size && $ny >= 0 && $ny < $this->size) {
if ($this->board[$nx][$ny] !== 0) {
return true;
}
}
}
}
return false;
}
private function checkWinner($player) {
$directions = [[0,1],[1,0],[1,1],[1,-1]];
for ($i = 0; $i < $this->size; $i++) {
for ($j = 0; $j < $this->size; $j++) {
if ($this->board[$i][$j] === $player) {
foreach ($directions as $dir) {
$count = 1;
for ($k = 1; $k < 5; $k++) {
$nx = $i + $dir[0] * $k;
$ny = $j + $dir[1] * $k;
if ($nx < 0 || $nx >= $this->size || $ny < 0 || $ny >= $this->size) {
break;
}
if ($this->board[$nx][$ny] === $player) {
$count++;
} else {
break;
}
}
if ($count >= 5) return true;
}
}
}
}
return false;
}
}
使用示例
<?php
// 简单对战示例
session_start();
// 游戏状态管理
function initGame() {
$_SESSION['board'] = array_fill(0, 3, array_fill(0, 3, 0));
$_SESSION['currentPlayer'] = 1; // 1 = 人类, 2 = AI
$_SESSION['gameOver'] = false;
}
function playGame() {
if (!isset($_SESSION['board'])) {
initGame();
}
$ai = new SimpleAI('hard');
// 人类走棋
if (isset($_POST['move']) && $_SESSION['currentPlayer'] === 1) {
$move = json_decode($_POST['move'], true);
$_SESSION['board'][$move['row']][$move['col']] = 1;
// 检查胜负
if (checkWin($_SESSION['board'], 1)) {
$_SESSION['gameOver'] = true;
echo json_encode(['result' => 'win', 'board' => $_SESSION['board']]);
return;
}
$_SESSION['currentPlayer'] = 2;
}
// AI走棋
if ($_SESSION['currentPlayer'] === 2 && !$_SESSION['gameOver']) {
// 添加延迟模拟"思考"
sleep(1);
$move = $ai->makeMove($_SESSION['board']);
if ($move !== null) {
$_SESSION['board'][$move[0]][$move[1]] = 2;
// 检查AI是否获胜
if (checkWin($_SESSION['board'], 2)) {
$_SESSION['gameOver'] = true;
echo json_encode(['result' => 'lose', 'board' => $_SESSION['board'], 'aiMove' => $move]);
return;
}
$_SESSION['currentPlayer'] = 1;
echo json_encode(['result' => 'continue', 'board' => $_SESSION['board'], 'aiMove' => $move]);
} else {
echo json_encode(['result' => 'draw', 'board' => $_SESSION['board']]);
}
}
}
function checkWin($board, $player) {
// 检查胜利逻辑
// ... 实现检查逻辑
}
// 前端AJAX处理
if (isset($_POST['action'])) {
if ($_POST['action'] === 'move') {
playGame();
} else if ($_POST['action'] === 'reset') {
session_destroy();
initGame();
echo json_encode(['success' => true, 'board' => $_SESSION['board']]);
}
}
前端HTML
<!DOCTYPE html>
<html>
<head>PHP AI对战</title>
<style>
.board {
display: grid;
grid-template-columns: repeat(3, 100px);
gap: 5px;
margin: 20px;
}
.cell {
width: 100px;
height: 100px;
border: 1px solid #000;
font-size: 40px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
</style>
</head>
<body>
<div class="board" id="board"></div>
<button onclick="resetGame()">重新开始</button>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
let currentBoard = Array(3).fill(null).map(() => Array(3).fill(0));
function renderBoard() {
let boardHtml = '';
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let symbol = '';
if (currentBoard[i][j] === 1) symbol = 'X';
if (currentBoard[i][j] === 2) symbol = 'O';
boardHtml += `<div class="cell" onclick="makeMove(${i}, ${j})">${symbol}</div>`;
}
}
$('#board').html(boardHtml);
}
function makeMove(row, col) {
if (currentBoard[row][col] !== 0) return;
// 人类走棋
currentBoard[row][col] = 1;
renderBoard();
// AI走棋
$.ajax({
url: 'game.php',
method: 'POST',
data: {
action: 'move',
board: JSON.stringify(currentBoard)
},
success: function(response) {
const result = JSON.parse(response);
currentBoard = result.board;
renderBoard();
if (result.result === 'win') {
alert('你赢了!');
} else if (result.result === 'lose') {
alert('AI赢了!');
} else if (result.result === 'draw') {
alert('平局!');
}
}
});
}
function resetGame() {
$.ajax({
url: 'game.php',
method: 'POST',
data: {
action: 'reset'
},
success: function(response) {
const result = JSON.parse(response);
currentBoard = result.board;
renderBoard();
}
});
}
renderBoard();
</script>
</body>
</html>
优化建议
-
性能优化:
- 使用缓存存储游戏状态
- 使用Redis/Memcached存储大量对局数据
- 使用异步处理提升响应速度
-
AI算法改进:
- 引入机器学习模型(需要PHP ML库)
- 使用更复杂的评估函数
- 实现蒙特卡洛树搜索(MCTS)
-
架构改进:
- 使用WebSocket实现实时对战
- 添加用户系统和对战记录
- 实现多局对战和排名系统
这个基础框架可以根据你的具体需求进行调整和扩展,需要我详细解释某个部分吗?