전투 시뮬레이션 구현 (동작)

This commit is contained in:
2018-08-27 01:23:45 +09:00
parent eabd5e9acc
commit 6b4a7ee03b
5 changed files with 124 additions and 18 deletions
+87 -16
View File
@@ -268,7 +268,11 @@ $startYear = $gameStor->startyear;
$cityRate = Util::round(($year - $startYear) / 1.5) + 60; $cityRate = Util::round(($year - $startYear) / 1.5) + 60;
function simulateBattle($rawAttacker, $rawAttackerCity, $rawAttackerNation, $defenderList, $rawDefenderCity, $rawDefenderNation, $startYear, $year, $month, $cityRate){ function simulateBattle(
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
$defenderList, $rawDefenderCity, $rawDefenderNation,
$startYear, $year, $month, $cityRate
){
$attacker = new WarUnitGeneral($rawAttacker, $rawAttackerCity, $rawAttackerNation, true, $year, $month); $attacker = new WarUnitGeneral($rawAttacker, $rawAttackerCity, $rawAttackerNation, true, $year, $month);
$city = new WarUnitCity($rawDefenderCity, $rawDefenderNation, $year, $month, $cityRate); $city = new WarUnitCity($rawDefenderCity, $rawDefenderNation, $year, $month, $cityRate);
@@ -277,10 +281,17 @@ function simulateBattle($rawAttacker, $rawAttackerCity, $rawAttackerNation, $def
$battleResult = []; $battleResult = [];
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext) use ($battleResult, $iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, $db) { $attackerRice = $rawAttacker['rice'];
$defenderRice = 0;
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext)
use ($iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, &$battleResult, &$defenderRice) {
if($prevDefender !== null){ if($prevDefender !== null){
$prevDefender->getLogger()->rollback();
$battleResult[] = $prevDefender; $battleResult[] = $prevDefender;
//TODO: 전투 결과! if($prevDefender instanceof WarUnitGeneral){
$defenderRice -= $prevDefender->getVar('rice');
}
} }
if(!$reqNext){ if(!$reqNext){
@@ -296,6 +307,8 @@ function simulateBattle($rawAttacker, $rawAttackerCity, $rawAttackerNation, $def
return null; return null;
} }
$defenderRice += $rawGeneral['rice'];
$retVal = new WarUnitGeneral($rawGeneral, $rawDefenderCity, $rawDefenderNation, false, $year, $month); $retVal = new WarUnitGeneral($rawGeneral, $rawDefenderCity, $rawDefenderNation, false, $year, $month);
$iterDefender->next(); $iterDefender->next();
return $retVal; return $retVal;
@@ -307,27 +320,85 @@ function simulateBattle($rawAttacker, $rawAttackerCity, $rawAttackerNation, $def
$updateAttackerNation = []; $updateAttackerNation = [];
$updateDefenderNation = []; $updateDefenderNation = [];
if($city->getVar('supply')){ $attackerRice -= $attacker->getVar('rice');
if($city->getPhase() > 0){
$rice = $city->getKilled() / 100 * 0.8;
$rice *= $city->getCrewType()->rice;
$rice *= getTechCost($rawDefenderNation['tech']);
$rice *= $cityRate / 100 - 0.2;
Util::setRound($rice);
$updateDefenderNation['rice'] = max(0, $rawDefenderNation['rice'] - $rice); if($city->getPhase() > 0){
} $rice = $city->getKilled() / 100 * 0.8;
else if($conquerCity){ $rice *= $city->getCrewType()->rice;
$updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 500; $rice *= getTechCost($rawDefenderNation['tech']);
} $rice *= $cityRate / 100 - 0.2;
Util::setRound($rice);
$defenderRice += $rice;
} }
$totalDead = $attacker->getKilled() + $attacker->getDead(); $totalDead = $attacker->getKilled() + $attacker->getDead();
$attackerCityDead = $totalDead * 0.4; $attackerCityDead = $totalDead * 0.4;
$defenderCityDead = $totalDead * 0.6; $defenderCityDead = $totalDead * 0.6;
return [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice];
}
$lastWarLog = [];
$attackerKilled = 0;
$attackerDead = 0;
$attackerAvgRice = 0;
$defenderAvgRice = 0;
$attackerActivatedSkills = [];
$defendersActivatedSkills = [];
foreach(range(1, $repeatCnt) as $repeatIdx){
[$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle(
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
$defenderList, $rawDefenderCity, $rawDefenderNation,
$startYear, $year, $month, $cityRate
);
$lastWarLog = $attacker->getLogger()->rollback();
$attackerKilled += $attacker->getKilled() / $repeatCnt;
$attackerDead += $attacker->getDead() / $repeatCnt;
$attackerAvgRice += $attackerRice /= $repeatCnt;
$defenderAvgRice += $defenderRice /= $repeatCnt;
foreach($attacker->getActivatedSkillLog() as $skillName => $skillCnt){
if(!key_exists($skillName, $attackerActivatedSkills)){
$attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt;
}
else{
$attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt;
}
}
foreach($battleResult as $idx=>$defender){
while($idx >= count($defendersActivatedSkills)){
$defendersActivatedSkills[] = [];
}
$activatedSkills = &$defendersActivatedSkills[$idx];
foreach($defender->getActivatedSkillLog() as $skillName => $skillCnt){
if(!key_exists($skillName, $activatedSkills)){
$activatedSkills[$skillName] = $skillCnt / $repeatCnt;
}
else{
$activatedSkills[$skillName] += $skillCnt / $repeatCnt;
}
}
}
} }
Json::die([ Json::die([
'result'=>true, 'result'=>true,
'reason'=>'NYI' 'reason'=>'success',
'lastWarLog'=>$lastWarLog,
'attackerKilled'=>$attackerKilled,
'attackerDead'=>$attackerDead,
'attackerRice'=>$attackerAvgRice,
'defenderRice'=>$defenderAvgRice,
'attackerActivatedSkills'=>$attackerActivatedSkills,
'defendersActivatedSkills'=>$defendersActivatedSkills,
]); ]);
+12
View File
@@ -43,6 +43,16 @@ class ActionLogger{
} }
public function rollback(){ public function rollback(){
$backup = [
'generalHistoryLog'=>$this->generalHistoryLog,
'generalActionLog'=>$this->generalActionLog,
'generalBattleResultLog'=>$this->generalBattleResultLog,
'generalBattleDetailLog'=>$this->generalBattleDetailLog,
'nationalHistoryLog'=>$this->nationalHistoryLog,
'globalHistoryLog'=>$this->globalHistoryLog,
'globalActionLog'=>$this->globalActionLog,
];
$this->generalHistoryLog = []; $this->generalHistoryLog = [];
$this->generalActionLog = []; $this->generalActionLog = [];
$this->generalBattleResultLog = []; $this->generalBattleResultLog = [];
@@ -50,6 +60,8 @@ class ActionLogger{
$this->nationalHistoryLog = []; $this->nationalHistoryLog = [];
$this->globalHistoryLog = []; $this->globalHistoryLog = [];
$this->globalActionLog = []; $this->globalActionLog = [];
return $backup;
} }
public function flush(){ public function flush(){
+23 -2
View File
@@ -28,11 +28,32 @@ class WarUnit{
protected $warPowerMultiply = 1.0; protected $warPowerMultiply = 1.0;
protected $activatedSkill = []; protected $activatedSkill = [];
protected $logActivatedSkill = [];
protected $isFinished = false; protected $isFinished = false;
private function __construct(){ private function __construct(){
} }
protected function clearActivatedSkill(){
foreach($this->activatedSkill as $skillName=>$state){
if(!$state){
continue;
}
if(!key_exists($skillName, $this->logActivatedSkill)){
$this->logActivatedSkill[$skillName] = 1;
}
else{
$this->logActivatedSkill[$skillName] += 1;
}
}
$this->activatedSkill = [];
}
function getActivatedSkillLog():array{
return $this->logActivatedSkill;
}
function getRaw():array{ function getRaw():array{
return $this->raw; return $this->raw;
} }
@@ -183,7 +204,7 @@ class WarUnit{
$this->oppose = $oppose; $this->oppose = $oppose;
$this->killedCurr = 0; $this->killedCurr = 0;
$this->deadCurr = 0; $this->deadCurr = 0;
$this->activatedSkill = []; $this->clearActivatedSkill();
} }
function getOppose():?WarUnit{ function getOppose():?WarUnit{
@@ -312,7 +333,7 @@ class WarUnit{
} }
function beginPhase():void{ function beginPhase():void{
$this->activatedSkill = []; $this->clearActivatedSkill();
$this->computeWarPower(); $this->computeWarPower();
} }
+1
View File
@@ -90,6 +90,7 @@ class WarUnitCity extends WarUnit{
if($this->isFinished){ if($this->isFinished){
return; return;
} }
$this->clearActivatedSkill();
$this->isFinished = true; $this->isFinished = true;
$this->updateVar('def', Util::round($this->getHP() / 10)); $this->updateVar('def', Util::round($this->getHP() / 10));
+1
View File
@@ -954,6 +954,7 @@ class WarUnitGeneral extends WarUnit{
if($this->isFinished){ if($this->isFinished){
return; return;
} }
$this->clearActivatedSkill();
$this->isFinished = true; $this->isFinished = true;
$this->increaseVar('killcrew', $this->killed); $this->increaseVar('killcrew', $this->killed);