<?php
class DeterministicGameEngine { private $gameState; private $randomSeed; public function __construct($seed = 12345) { $this->randomSeed = $seed; $this->gameState = [ 'units' => [], 'players' => [], 'resources' => [], 'frame' => 0 ]; $this->initializeGameState(); }
private function initializeGameState() { $this->gameState['players'] = [ 'player1' => [ 'id' => 'player1', 'resources' => ['gold' => 1000, 'wood' => 500], 'base_position' => ['x' => 0, 'y' => 0] ], 'player2' => [ 'id' => 'player2', 'resources' => ['gold' => 1000, 'wood' => 500], 'base_position' => ['x' => 100, 'y' => 100] ] ]; $this->gameState['units'] = [ 'unit_1' => [ 'id' => 'unit_1', 'owner' => 'player1', 'type' => 'worker', 'position' => ['x' => 10, 'y' => 10], 'health' => 100, 'state' => 'idle' ], 'unit_2' => [ 'id' => 'unit_2', 'owner' => 'player2', 'type' => 'worker', 'position' => ['x' => 90, 'y' => 90], 'health' => 100, 'state' => 'idle' ] ]; }
public function executeFrame($frame, $commands) { srand($this->randomSeed + $frame); $this->processCommands($frame, $commands); $this->updateGameLogic($frame); $this->generateFrameChecksum($frame); $this->gameState['frame'] = $frame; }
private function processCommands($frame, $commands) { foreach ($commands as $playerId => $commandData) { $command = $commandData['command']; $data = $commandData['data']; switch ($command) { case 'move_unit': $this->handleMoveUnit($playerId, $data); break; case 'train_unit': $this->handleTrainUnit($playerId, $data); break; case 'gather_resource': $this->handleGatherResource($playerId, $data); break; case 'attack': $this->handleAttack($playerId, $data); break; default: echo "未知命令: {$command}\n"; } } }
private function handleMoveUnit($playerId, $data) { $unitId = $data['unit_id']; $targetX = $data['target_x']; $targetY = $data['target_y']; if (isset($this->gameState['units'][$unitId])) { $unit = &$this->gameState['units'][$unitId]; if ($unit['owner'] !== $playerId) { echo "错误: 玩家 {$playerId} 试图移动不属于自己的单位 {$unitId}\n"; return; } $unit['target_position'] = ['x' => $targetX, 'y' => $targetY]; $unit['state'] = 'moving'; echo "单位 {$unitId} 开始移动到 ({$targetX}, {$targetY})\n"; } }
private function handleTrainUnit($playerId, $data) { $unitType = $data['unit_type']; $buildingId = $data['building_id']; $cost = $this->getUnitCost($unitType); $player = &$this->gameState['players'][$playerId]; if ($player['resources']['gold'] >= $cost['gold'] && $player['resources']['wood'] >= $cost['wood']) { $player['resources']['gold'] -= $cost['gold']; $player['resources']['wood'] -= $cost['wood']; $unitId = "unit_" . uniqid(); $spawnPosition = $this->getSpawnPosition($playerId); $this->gameState['units'][$unitId] = [ 'id' => $unitId, 'owner' => $playerId, 'type' => $unitType, 'position' => $spawnPosition, 'health' => $this->getUnitHealth($unitType), 'state' => 'idle' ]; echo "玩家 {$playerId} 训练了 {$unitType} ({$unitId})\n"; } else { echo "玩家 {$playerId} 资源不足,无法训练 {$unitType}\n"; } }
private function handleGatherResource($playerId, $data) { $unitId = $data['unit_id']; $resourceId = $data['resource_id']; if (isset($this->gameState['units'][$unitId])) { $unit = &$this->gameState['units'][$unitId]; $unit['state'] = 'gathering'; $unit['target_resource'] = $resourceId; echo "单位 {$unitId} 开始采集资源 {$resourceId}\n"; } }
private function handleAttack($playerId, $data) { $attackerId = $data['attacker_id']; $targetId = $data['target_id']; if (isset($this->gameState['units'][$attackerId]) && isset($this->gameState['units'][$targetId])) { $attacker = &$this->gameState['units'][$attackerId]; $target = &$this->gameState['units'][$targetId]; if ($attacker['owner'] !== $playerId) { echo "错误: 玩家 {$playerId} 试图用不属于自己的单位攻击\n"; return; } $attacker['state'] = 'attacking'; $attacker['attack_target'] = $targetId; echo "单位 {$attackerId} 开始攻击单位 {$targetId}\n"; } }
private function updateGameLogic($frame) { $this->updateUnits($frame); $this->updateCombat($frame); $this->updateResources($frame); }
private function updateUnits($frame) { foreach ($this->gameState['units'] as &$unit) { switch ($unit['state']) { case 'moving': $this->updateUnitMovement($unit); break; case 'attacking': $this->updateUnitAttack($unit, $frame); break; case 'gathering': $this->updateUnitGathering($unit, $frame); break; } } }
private function updateUnitMovement(&$unit) { if (!isset($unit['target_position'])) { return; } $speed = 2.0; $currentPos = $unit['position']; $targetPos = $unit['target_position']; $dx = $targetPos['x'] - $currentPos['x']; $dy = $targetPos['y'] - $currentPos['y']; $distance = sqrt($dx * $dx + $dy * $dy); if ($distance <= $speed) { $unit['position'] = $targetPos; $unit['state'] = 'idle'; unset($unit['target_position']); } else { $unit['position']['x'] += ($dx / $distance) * $speed; $unit['position']['y'] += ($dy / $distance) * $speed; } }
private function updateUnitAttack(&$unit, $frame) { if (!isset($unit['attack_target'])) { $unit['state'] = 'idle'; return; } $targetId = $unit['attack_target']; if (!isset($this->gameState['units'][$targetId])) { $unit['state'] = 'idle'; unset($unit['attack_target']); return; } $target = &$this->gameState['units'][$targetId]; if ($frame % 30 === 0) { $damage = $this->getUnitDamage($unit['type']); $target['health'] -= $damage; echo "单位 {$unit['id']} 攻击 {$targetId}, 造成 {$damage} 伤害\n"; if ($target['health'] <= 0) { echo "单位 {$targetId} 被摧毁\n"; unset($this->gameState['units'][$targetId]); $unit['state'] = 'idle'; unset($unit['attack_target']); } } }
private function updateUnitGathering(&$unit, $frame) { if ($frame % 60 === 0) { $player = &$this->gameState['players'][$unit['owner']]; $player['resources']['gold'] += 10; echo "单位 {$unit['id']} 采集了 10 黄金\n"; } }
private function updateCombat($frame) { }
private function updateResources($frame) { } private function getUnitCost($unitType) { $costs = [ 'worker' => ['gold' => 50, 'wood' => 0], 'soldier' => ['gold' => 100, 'wood' => 25], 'archer' => ['gold' => 75, 'wood' => 50] ]; return $costs[$unitType] ?? ['gold' => 0, 'wood' => 0]; } private function getUnitHealth($unitType) { $health = [ 'worker' => 100, 'soldier' => 150, 'archer' => 80 ]; return $health[$unitType] ?? 100; } private function getUnitDamage($unitType) { $damage = [ 'worker' => 5, 'soldier' => 15, 'archer' => 10 ]; return $damage[$unitType] ?? 10; } private function getSpawnPosition($playerId) { $basePos = $this->gameState['players'][$playerId]['base_position']; return [ 'x' => $basePos['x'] + rand(-10, 10), 'y' => $basePos['y'] + rand(-10, 10) ]; }
private function generateFrameChecksum($frame) { $stateString = serialize($this->gameState); $checksum = md5($stateString); echo "帧 {$frame} 状态校验和: {$checksum}\n"; return $checksum; }
public function getStateChecksum() { return md5(serialize($this->gameState)); }
public function getCurrentState() { return $this->gameState; } }
?>
|