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

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;
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);
$city = new WarUnitCity($rawDefenderCity, $rawDefenderNation, $year, $month, $cityRate);
@@ -277,10 +281,17 @@ function simulateBattle($rawAttacker, $rawAttackerCity, $rawAttackerNation, $def
$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){
$prevDefender->getLogger()->rollback();
$battleResult[] = $prevDefender;
//TODO: 전투 결과!
if($prevDefender instanceof WarUnitGeneral){
$defenderRice -= $prevDefender->getVar('rice');
}
}
if(!$reqNext){
@@ -296,6 +307,8 @@ function simulateBattle($rawAttacker, $rawAttackerCity, $rawAttackerNation, $def
return null;
}
$defenderRice += $rawGeneral['rice'];
$retVal = new WarUnitGeneral($rawGeneral, $rawDefenderCity, $rawDefenderNation, false, $year, $month);
$iterDefender->next();
return $retVal;
@@ -307,27 +320,85 @@ function simulateBattle($rawAttacker, $rawAttackerCity, $rawAttackerNation, $def
$updateAttackerNation = [];
$updateDefenderNation = [];
if($city->getVar('supply')){
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);
$attackerRice -= $attacker->getVar('rice');
$updateDefenderNation['rice'] = max(0, $rawDefenderNation['rice'] - $rice);
}
else if($conquerCity){
$updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 500;
}
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);
$defenderRice += $rice;
}
$totalDead = $attacker->getKilled() + $attacker->getDead();
$attackerCityDead = $totalDead * 0.4;
$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([
'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(){
$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->generalActionLog = [];
$this->generalBattleResultLog = [];
@@ -50,6 +60,8 @@ class ActionLogger{
$this->nationalHistoryLog = [];
$this->globalHistoryLog = [];
$this->globalActionLog = [];
return $backup;
}
public function flush(){
+23 -2
View File
@@ -28,11 +28,32 @@ class WarUnit{
protected $warPowerMultiply = 1.0;
protected $activatedSkill = [];
protected $logActivatedSkill = [];
protected $isFinished = false;
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{
return $this->raw;
}
@@ -183,7 +204,7 @@ class WarUnit{
$this->oppose = $oppose;
$this->killedCurr = 0;
$this->deadCurr = 0;
$this->activatedSkill = [];
$this->clearActivatedSkill();
}
function getOppose():?WarUnit{
@@ -312,7 +333,7 @@ class WarUnit{
}
function beginPhase():void{
$this->activatedSkill = [];
$this->clearActivatedSkill();
$this->computeWarPower();
}
+1
View File
@@ -90,6 +90,7 @@ class WarUnitCity extends WarUnit{
if($this->isFinished){
return;
}
$this->clearActivatedSkill();
$this->isFinished = true;
$this->updateVar('def', Util::round($this->getHP() / 10));
+1
View File
@@ -954,6 +954,7 @@ class WarUnitGeneral extends WarUnit{
if($this->isFinished){
return;
}
$this->clearActivatedSkill();
$this->isFinished = true;
$this->increaseVar('killcrew', $this->killed);