wip: process_war에서 defenderList 변경
- defenderList를 General[] 에서 WarUnit[]으로 변경 - extractBattleOrder를 WarUnit을 받도록 변경
This commit is contained in:
+265
-219
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
use Ds\Map;
|
use Ds\Map;
|
||||||
@@ -15,48 +16,48 @@ $userID = Session::getUserID();
|
|||||||
increaseRefresh("시뮬레이터", 0);
|
increaseRefresh("시뮬레이터", 0);
|
||||||
|
|
||||||
$query = Util::getPost('query');
|
$query = Util::getPost('query');
|
||||||
if($query === null){
|
if ($query === null) {
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>'입력값이 없습니다.'
|
'reason' => '입력값이 없습니다.'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = Util::getPost('action');
|
$action = Util::getPost('action');
|
||||||
if($action === null || !in_array($action, ['reorder', 'battle'])){
|
if ($action === null || !in_array($action, ['reorder', 'battle'])) {
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>'원하는 동작이 지정되지 않았습니다.'
|
'reason' => '원하는 동작이 지정되지 않았습니다.'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = Json::decode($query);
|
$query = Json::decode($query);
|
||||||
if($query === null){
|
if ($query === null) {
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>'올바르지 않은 JSON입니다.'
|
'reason' => '올바르지 않은 JSON입니다.'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$defaultCheck = [
|
$defaultCheck = [
|
||||||
'required'=>[
|
'required' => [
|
||||||
'attackerGeneral', 'attackerCity', 'attackerNation',
|
'attackerGeneral', 'attackerCity', 'attackerNation',
|
||||||
'defenderGenerals', 'defenderCity', 'defenderNation',
|
'defenderGenerals', 'defenderCity', 'defenderNation',
|
||||||
'year', 'month', 'repeatCnt'
|
'year', 'month', 'repeatCnt'
|
||||||
],
|
],
|
||||||
'integer'=>[
|
'integer' => [
|
||||||
'year','month','repeatCnt'
|
'year', 'month', 'repeatCnt'
|
||||||
],
|
],
|
||||||
'between'=>[
|
'between' => [
|
||||||
['month', [1, 12]]
|
['month', [1, 12]]
|
||||||
],
|
],
|
||||||
'in'=>[
|
'in' => [
|
||||||
['repeatCnt', [1, 1000]]
|
['repeatCnt', [1, 1000]]
|
||||||
],
|
],
|
||||||
'min'=>[
|
'min' => [
|
||||||
['year', 0]
|
['year', 0]
|
||||||
],
|
],
|
||||||
'array'=>[
|
'array' => [
|
||||||
'attackerGeneral', 'attackerCity', 'attackerNation',
|
'attackerGeneral', 'attackerCity', 'attackerNation',
|
||||||
'defenderGenerals', 'defenderCity', 'defenderNation'
|
'defenderGenerals', 'defenderCity', 'defenderNation'
|
||||||
],
|
],
|
||||||
@@ -64,10 +65,10 @@ $defaultCheck = [
|
|||||||
|
|
||||||
$v = new Validator($query);
|
$v = new Validator($query);
|
||||||
$v->rules($defaultCheck);
|
$v->rules($defaultCheck);
|
||||||
if(!$v->validate()){
|
if (!$v->validate()) {
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>$v->errorStr()
|
'reason' => $v->errorStr()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,20 +87,110 @@ $rawDefenderNation = $query['defenderNation'];
|
|||||||
|
|
||||||
$warSeed = $query['seed'] ?? '';
|
$warSeed = $query['seed'] ?? '';
|
||||||
|
|
||||||
|
$cityCheck = [
|
||||||
|
'required' => [
|
||||||
|
'city', 'nation', 'supply', 'name',
|
||||||
|
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
|
||||||
|
'trust', 'level',
|
||||||
|
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
||||||
|
'dead', 'state', 'conflict',
|
||||||
|
],
|
||||||
|
'numeric' => [
|
||||||
|
'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead'
|
||||||
|
],
|
||||||
|
'integer' => [
|
||||||
|
'city', 'nation', 'supply',
|
||||||
|
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
||||||
|
'state',
|
||||||
|
],
|
||||||
|
'min' => [
|
||||||
|
['def', 0],
|
||||||
|
['wall', 0],
|
||||||
|
['trust', 0],
|
||||||
|
['pop', 0],
|
||||||
|
['comm', 0],
|
||||||
|
['secu', 0],
|
||||||
|
['city', 1],
|
||||||
|
['nation', 0]
|
||||||
|
],
|
||||||
|
'in' => [
|
||||||
|
['level', array_keys(getCityLevelList())]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$v = new Validator($rawAttackerCity);
|
||||||
|
$v->rules($cityCheck);
|
||||||
|
if (!$v->validate()) {
|
||||||
|
Json::die([
|
||||||
|
'result' => false,
|
||||||
|
'reason' => '[출병도시]' . $v->errorStr()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$v = new Validator($rawDefenderCity);
|
||||||
|
$v->rules($cityCheck);
|
||||||
|
if (!$v->validate()) {
|
||||||
|
Json::die([
|
||||||
|
'result' => false,
|
||||||
|
'reason' => '[수비도시]' . $v->errorStr()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$nationCheck = [
|
||||||
|
'required' => [
|
||||||
|
'type', 'tech', 'level', 'capital',
|
||||||
|
'nation', 'name', 'gold', 'rice', 'gennum'
|
||||||
|
],
|
||||||
|
'integer' => [
|
||||||
|
'level', 'capital', 'nation', 'gennum',
|
||||||
|
],
|
||||||
|
'numeric' => [
|
||||||
|
'tech', 'gold', 'rice'
|
||||||
|
],
|
||||||
|
'min' => [
|
||||||
|
['tech', 0],
|
||||||
|
['gold', 0],
|
||||||
|
['rice', 0],
|
||||||
|
['gennum', 1],
|
||||||
|
],
|
||||||
|
'in' => [
|
||||||
|
['type', GameConst::$availableNationType],
|
||||||
|
['level', array_keys(getNationLevelList())]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$v = new Validator($rawAttackerNation);
|
||||||
|
$v->rules($nationCheck);
|
||||||
|
if (!$v->validate()) {
|
||||||
|
Json::die([
|
||||||
|
'result' => false,
|
||||||
|
'reason' => '[출병국]' . $v->errorStr()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$v = new Validator($rawDefenderNation);
|
||||||
|
$v->rules($nationCheck);
|
||||||
|
if (!$v->validate()) {
|
||||||
|
Json::die([
|
||||||
|
'result' => false,
|
||||||
|
'reason' => '[수비국]' . $v->errorStr()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$generalCheck = [
|
$generalCheck = [
|
||||||
'required'=>[
|
'required' => [
|
||||||
'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train',
|
'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train',
|
||||||
'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item',
|
'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item',
|
||||||
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
||||||
'recent_war', 'warnum', 'killnum', 'killcrew',
|
'recent_war', 'warnum', 'killnum', 'killcrew',
|
||||||
],
|
],
|
||||||
'integer'=>[
|
'integer' => [
|
||||||
'no', 'nation', 'crew', 'crewtype', 'atmos', 'train',
|
'no', 'nation', 'crew', 'crewtype', 'atmos', 'train',
|
||||||
'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp',
|
'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp',
|
||||||
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
||||||
'warnum', 'killnum', 'killcrew',
|
'warnum', 'killnum', 'killcrew',
|
||||||
],
|
],
|
||||||
'min'=>[
|
'min' => [
|
||||||
['no', 1],
|
['no', 1],
|
||||||
['nation', 1],
|
['nation', 1],
|
||||||
['crew', 0],
|
['crew', 0],
|
||||||
@@ -118,14 +209,14 @@ $generalCheck = [
|
|||||||
['killnum', 0],
|
['killnum', 0],
|
||||||
['killcrew', 0],
|
['killcrew', 0],
|
||||||
],
|
],
|
||||||
'between'=>[
|
'between' => [
|
||||||
['train', [40, GameConst::$maxTrainByWar]],
|
['train', [40, GameConst::$maxTrainByWar]],
|
||||||
['atmos', [40, GameConst::$maxAtmosByWar]],
|
['atmos', [40, GameConst::$maxAtmosByWar]],
|
||||||
['explevel', [0, 300]],
|
['explevel', [0, 300]],
|
||||||
['injury', [0, 80]],
|
['injury', [0, 80]],
|
||||||
['officer_level', [1, 12]]
|
['officer_level', [1, 12]]
|
||||||
],
|
],
|
||||||
'in'=>[
|
'in' => [
|
||||||
['personal', array_merge(GameConst::$availablePersonality, GameConst::$optionalPersonality)],
|
['personal', array_merge(GameConst::$availablePersonality, GameConst::$optionalPersonality)],
|
||||||
['special2', array_merge(GameConst::$availableSpecialWar, GameConst::$optionalSpecialWar)],
|
['special2', array_merge(GameConst::$availableSpecialWar, GameConst::$optionalSpecialWar)],
|
||||||
['crewtype', array_keys(GameUnitConst::all())],
|
['crewtype', array_keys(GameUnitConst::all())],
|
||||||
@@ -134,11 +225,11 @@ $generalCheck = [
|
|||||||
['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])],
|
['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])],
|
||||||
['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])],
|
['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])],
|
||||||
],
|
],
|
||||||
'array'=>['inheritBuff'],
|
'array' => ['inheritBuff'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$inheritBuffCheck = [
|
$inheritBuffCheck = [
|
||||||
'between'=>[
|
'between' => [
|
||||||
[TriggerInheritBuff::WAR_AVOID_RATIO, [0, 5]],
|
[TriggerInheritBuff::WAR_AVOID_RATIO, [0, 5]],
|
||||||
[TriggerInheritBuff::WAR_CRITICAL_RATIO, [0, 5]],
|
[TriggerInheritBuff::WAR_CRITICAL_RATIO, [0, 5]],
|
||||||
[TriggerInheritBuff::WAR_MAGIC_TRIAL_PROB, [0, 5]],
|
[TriggerInheritBuff::WAR_MAGIC_TRIAL_PROB, [0, 5]],
|
||||||
@@ -149,49 +240,67 @@ $inheritBuffCheck = [
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if(!$warSeed){
|
||||||
|
$warSeed = bin2hex(random_bytes(16));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$repeatCnt = 1;
|
||||||
|
}
|
||||||
|
$tmpRNG = new RandUtil(new LiteHashDRBG($warSeed));
|
||||||
|
|
||||||
$v = new Validator($rawAttacker);
|
$v = new Validator($rawAttacker);
|
||||||
$v->rules($generalCheck);
|
$v->rules($generalCheck);
|
||||||
if(!$v->validate()){
|
if (!$v->validate()) {
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>'[출병자]'.$v->errorStr()
|
'reason' => '[출병자]' . $v->errorStr()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$rawAttacker['aux'] = [];
|
$rawAttacker['aux'] = [];
|
||||||
if(key_exists('inheritBuff', $rawAttacker)){
|
if (key_exists('inheritBuff', $rawAttacker)) {
|
||||||
$v = new Validator($rawAttacker['inheritBuff']);
|
$v = new Validator($rawAttacker['inheritBuff']);
|
||||||
$v->rules($inheritBuffCheck);
|
$v->rules($inheritBuffCheck);
|
||||||
if(!$v->validate()){
|
if (!$v->validate()) {
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>'[출병자]'.$v->errorStr()
|
'reason' => '[출병자]' . $v->errorStr()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$rawAttacker['aux']['inheritBuff'] = $rawAttacker['inheritBuff'];
|
$rawAttacker['aux']['inheritBuff'] = $rawAttacker['inheritBuff'];
|
||||||
}
|
}
|
||||||
$rawAttacker['aux'] = Json::encode($rawAttacker['aux']);
|
$rawAttacker['aux'] = Json::encode($rawAttacker['aux']);
|
||||||
$rawAttacker['owner'] = 0;
|
$rawAttacker['owner'] = 0;
|
||||||
|
$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month);
|
||||||
|
$attacker = new WarUnitGeneral(
|
||||||
|
$tmpRNG,
|
||||||
|
$attackerGeneral,
|
||||||
|
$rawAttackerNation,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/** @var WarUnit[] */
|
||||||
$defenderList = [];
|
$defenderList = [];
|
||||||
foreach($rawDefenderList as $idx=>$rawDefenderGeneral){
|
|
||||||
|
foreach ($rawDefenderList as $idx => $rawDefenderGeneral) {
|
||||||
$v = new Validator($rawDefenderGeneral);
|
$v = new Validator($rawDefenderGeneral);
|
||||||
$v->rules($generalCheck);
|
$v->rules($generalCheck);
|
||||||
if(!$v->validate()){
|
if (!$v->validate()) {
|
||||||
$idx+=1;
|
$idx += 1;
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>"[수비자{$idx}]".$v->errorStr()
|
'reason' => "[수비자{$idx}]" . $v->errorStr()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$rawDefenderGeneral['aux'] = [];
|
$rawDefenderGeneral['aux'] = [];
|
||||||
if(key_exists('inheritBuff', $rawDefenderGeneral)){
|
if (key_exists('inheritBuff', $rawDefenderGeneral)) {
|
||||||
$v = new Validator($rawDefenderGeneral['inheritBuff']);
|
$v = new Validator($rawDefenderGeneral['inheritBuff']);
|
||||||
$v->rules($inheritBuffCheck);
|
$v->rules($inheritBuffCheck);
|
||||||
if(!$v->validate()){
|
if (!$v->validate()) {
|
||||||
$idx+=1;
|
$idx += 1;
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>"[수비자{$idx}]".$v->errorStr()
|
'reason' => "[수비자{$idx}]" . $v->errorStr()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$rawDefenderGeneral['aux']['inheritBuff'] = $rawDefenderGeneral['inheritBuff'];
|
$rawDefenderGeneral['aux']['inheritBuff'] = $rawDefenderGeneral['inheritBuff'];
|
||||||
@@ -199,126 +308,41 @@ foreach($rawDefenderList as $idx=>$rawDefenderGeneral){
|
|||||||
$rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']);
|
$rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']);
|
||||||
$rawDefenderGeneral['owner'] = 0;
|
$rawDefenderGeneral['owner'] = 0;
|
||||||
|
|
||||||
$defenderList[] = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true);
|
$defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true);
|
||||||
|
|
||||||
|
$defenderList[] = new WarUnitGeneral(
|
||||||
|
$tmpRNG,
|
||||||
|
$defenderGeneral,
|
||||||
|
$rawDefenderNation,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($action == 'reorder') {
|
||||||
|
$noRng = NoRNG::rngInstance();
|
||||||
|
|
||||||
$cityCheck = [
|
usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) {
|
||||||
'required'=>[
|
return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker));
|
||||||
'city', 'nation', 'supply', 'name',
|
|
||||||
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
|
|
||||||
'trust', 'level',
|
|
||||||
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
|
||||||
'dead', 'state', 'conflict',
|
|
||||||
],
|
|
||||||
'numeric'=>[
|
|
||||||
'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead'
|
|
||||||
],
|
|
||||||
'integer'=>[
|
|
||||||
'city', 'nation', 'supply',
|
|
||||||
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
|
||||||
'state',
|
|
||||||
],
|
|
||||||
'min'=>[
|
|
||||||
['def', 0],
|
|
||||||
['wall', 0],
|
|
||||||
['trust', 0],
|
|
||||||
['pop', 0],
|
|
||||||
['comm', 0],
|
|
||||||
['secu', 0],
|
|
||||||
['city', 1],
|
|
||||||
['nation', 0]
|
|
||||||
],
|
|
||||||
'in'=>[
|
|
||||||
['level', array_keys(getCityLevelList())]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
$v = new Validator($rawAttackerCity);
|
|
||||||
$v->rules($cityCheck);
|
|
||||||
if(!$v->validate()){
|
|
||||||
Json::die([
|
|
||||||
'result'=>false,
|
|
||||||
'reason'=>'[출병도시]'.$v->errorStr()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$v = new Validator($rawDefenderCity);
|
|
||||||
$v->rules($cityCheck);
|
|
||||||
if(!$v->validate()){
|
|
||||||
Json::die([
|
|
||||||
'result'=>false,
|
|
||||||
'reason'=>'[수비도시]'.$v->errorStr()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$nationCheck = [
|
|
||||||
'required'=>[
|
|
||||||
'type', 'tech', 'level', 'capital',
|
|
||||||
'nation', 'name', 'gold', 'rice', 'gennum'
|
|
||||||
],
|
|
||||||
'integer'=>[
|
|
||||||
'level', 'capital', 'nation', 'gennum',
|
|
||||||
],
|
|
||||||
'numeric'=>[
|
|
||||||
'tech', 'gold', 'rice'
|
|
||||||
],
|
|
||||||
'min'=>[
|
|
||||||
['tech', 0],
|
|
||||||
['gold', 0],
|
|
||||||
['rice', 0],
|
|
||||||
['gennum', 1],
|
|
||||||
],
|
|
||||||
'in'=>[
|
|
||||||
['type', GameConst::$availableNationType],
|
|
||||||
['level', array_keys(getNationLevelList())]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
$v = new Validator($rawAttackerNation);
|
|
||||||
$v->rules($nationCheck);
|
|
||||||
if(!$v->validate()){
|
|
||||||
Json::die([
|
|
||||||
'result'=>false,
|
|
||||||
'reason'=>'[출병국]'.$v->errorStr()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$v = new Validator($rawDefenderNation);
|
|
||||||
$v->rules($nationCheck);
|
|
||||||
if(!$v->validate()){
|
|
||||||
Json::die([
|
|
||||||
'result'=>false,
|
|
||||||
'reason'=>'[수비국]'.$v->errorStr()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month);
|
|
||||||
|
|
||||||
if($action == 'reorder'){
|
|
||||||
|
|
||||||
usort($defenderList, function(General $lhs, General $rhs) use ($attackerGeneral){
|
|
||||||
return -(extractBattleOrder($lhs, $attackerGeneral) <=> extractBattleOrder($rhs, $attackerGeneral));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$order = [];
|
$order = [];
|
||||||
foreach($defenderList as $defenderGeneral){
|
foreach ($defenderList as $defender) {
|
||||||
$order[] = $defenderGeneral->getID();
|
$order[] = $defender->getGeneral()->getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>true,
|
'result' => true,
|
||||||
'reason'=>'success',
|
'reason' => 'success',
|
||||||
'order'=>$order
|
'order' => $order
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
usort($defenderList, function(General $lhs, General $rhs) use ($attackerGeneral){
|
usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) {
|
||||||
return -(extractBattleOrder($lhs, $attackerGeneral) <=> extractBattleOrder($rhs, $attackerGeneral));
|
return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker));
|
||||||
});
|
});
|
||||||
|
|
||||||
$rawDefenderList = array_map(function(General $general){
|
$rawDefenderList = array_map(function (WarUnit $unit) {
|
||||||
return $general->getRaw();
|
return $unit->getRaw();
|
||||||
}, $defenderList);
|
}, $defenderList);
|
||||||
unset($defenderList);
|
unset($defenderList);
|
||||||
|
|
||||||
@@ -326,11 +350,12 @@ $db = DB::db();
|
|||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
$startYear = $gameStor->startyear;
|
$startYear = $gameStor->startyear;
|
||||||
|
|
||||||
function extractRankVar(array $rawVal):Map{
|
function extractRankVar(array $rawVal): Map
|
||||||
|
{
|
||||||
$rankVars = new Map;
|
$rankVars = new Map;
|
||||||
foreach($rawVal as $rawKey=>$rawVal){
|
foreach ($rawVal as $rawKey => $rawVal) {
|
||||||
$key = RankColumn::tryFrom($rawKey);
|
$key = RankColumn::tryFrom($rawKey);
|
||||||
if($key === null){
|
if ($key === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$rankVars[$key] = $rawVal;
|
$rankVars[$key] = $rawVal;
|
||||||
@@ -339,12 +364,19 @@ function extractRankVar(array $rawVal):Map{
|
|||||||
}
|
}
|
||||||
|
|
||||||
function simulateBattle(
|
function simulateBattle(
|
||||||
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
|
$rawAttacker,
|
||||||
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
|
$rawAttackerCity,
|
||||||
$startYear, $year, $month, $warSeed
|
$rawAttackerNation,
|
||||||
){
|
$rawDefenderList,
|
||||||
|
$rawDefenderCity,
|
||||||
|
$rawDefenderNation,
|
||||||
|
$startYear,
|
||||||
|
$year,
|
||||||
|
$month,
|
||||||
|
$warSeed
|
||||||
|
) {
|
||||||
|
|
||||||
if(!$warSeed){
|
if (!$warSeed) {
|
||||||
$warSeed = bin2hex(random_bytes(16));
|
$warSeed = bin2hex(random_bytes(16));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,61 +391,70 @@ function simulateBattle(
|
|||||||
);
|
);
|
||||||
$city = new WarUnitCity($warRng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
|
$city = new WarUnitCity($warRng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
|
||||||
|
|
||||||
$iterDefender = new \ArrayIterator($rawDefenderList);
|
/** @var WarUnit[] */
|
||||||
|
$defenderList = [];
|
||||||
|
|
||||||
|
foreach ($rawDefenderList as $rawDefenderGeneral) {
|
||||||
|
$defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true);
|
||||||
|
|
||||||
|
$defenderList[] = new WarUnitGeneral(
|
||||||
|
$warRng,
|
||||||
|
$defenderGeneral,
|
||||||
|
$rawDefenderNation,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$defenderList[] = $city;
|
||||||
|
|
||||||
|
|
||||||
|
$iterDefender = new \ArrayIterator($defenderList);
|
||||||
$iterDefender->rewind();
|
$iterDefender->rewind();
|
||||||
|
|
||||||
$battleResult = [];
|
$battleResult = [];
|
||||||
|
|
||||||
$attackerRice = $rawAttacker['rice'];
|
$attackerRice = $attacker->getGeneral()->getVar('rice');
|
||||||
$defenderRice = 0;
|
$defenderRice = 0;
|
||||||
|
|
||||||
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext)
|
$getNextDefender = function (?WarUnit $prevDefender, bool $reqNext)
|
||||||
use ($warRng, $iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, &$battleResult, &$defenderRice, $attackerGeneral) {
|
use ($iterDefender, &$battleResult, &$defenderRice, $attacker): ?WarUnit {
|
||||||
if($prevDefender !== null){
|
if ($prevDefender !== null) {
|
||||||
$prevDefender->getLogger()->rollback();
|
$prevDefender->getLogger()->rollback();
|
||||||
$battleResult[] = $prevDefender;
|
$battleResult[] = $prevDefender;
|
||||||
if($prevDefender instanceof WarUnitGeneral){
|
if ($prevDefender instanceof WarUnitGeneral) {
|
||||||
$defenderRice -= $prevDefender->getVar('rice');
|
$defenderRice -= $prevDefender->getVar('rice');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$reqNext){
|
if (!$reqNext) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$iterDefender->valid()){
|
if (!$iterDefender->valid()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$defenderObj = new General($iterDefender->current(), extractRankVar($iterDefender->current()), $rawDefenderCity, $rawDefenderNation, $year, $month);
|
/** @var WarUnit */
|
||||||
if(extractBattleOrder($defenderObj, $attackerGeneral) <= 0){
|
$defender = $iterDefender->current();
|
||||||
|
|
||||||
|
if (extractBattleOrder($defender, $attacker) <= 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$defenderRice += $defenderObj->getVar('rice');
|
$defenderRice += $defender->getVar('rice');
|
||||||
|
|
||||||
$retVal = new WarUnitGeneral(
|
|
||||||
$warRng,
|
|
||||||
$defenderObj,
|
|
||||||
$rawDefenderNation,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
$iterDefender->next();
|
$iterDefender->next();
|
||||||
return $retVal;
|
return $defender;
|
||||||
};
|
};
|
||||||
|
|
||||||
$conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city, $year - $startYear);
|
$conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city);
|
||||||
|
|
||||||
$rawDefenderCity = $city->getRaw();
|
|
||||||
$updateAttackerNation = [];
|
|
||||||
$updateDefenderNation = [];
|
|
||||||
|
|
||||||
$attackerRice -= $attacker->getVar('rice');
|
$attackerRice -= $attacker->getVar('rice');
|
||||||
|
|
||||||
if($city->getPhase() > 0){
|
if ($city->getPhase() > 0) {
|
||||||
$rice = $city->getKilled() / 100 * 0.8;
|
$rice = $city->getKilled() / 100 * 0.8;
|
||||||
$rice *= $city->getCrewType()->rice;
|
$rice *= $city->getCrewType()->rice;
|
||||||
$rice *= getTechCost($rawDefenderNation['tech']);
|
$rice *= getTechCost($city->getRawNation()['tech']);
|
||||||
$rice *= $city->getCityTrainAtmos() / 100 - 0.2;
|
$rice *= $city->getCityTrainAtmos() / 100 - 0.2;
|
||||||
Util::setRound($rice);
|
Util::setRound($rice);
|
||||||
|
|
||||||
@@ -421,8 +462,8 @@ function simulateBattle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
$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];
|
return [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice];
|
||||||
}
|
}
|
||||||
@@ -448,18 +489,26 @@ $avgWar = 0;
|
|||||||
$attackerActivatedSkills = [];
|
$attackerActivatedSkills = [];
|
||||||
$defendersActivatedSkills = [];
|
$defendersActivatedSkills = [];
|
||||||
|
|
||||||
if($warSeed){
|
|
||||||
$repeatCnt = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(Util::range($repeatCnt) as $repeatIdx){
|
foreach (Util::range($repeatCnt) as $repeatIdx) {
|
||||||
|
if($repeatIdx > 0){
|
||||||
|
$warSeed = bin2hex(random_bytes(16));
|
||||||
|
}
|
||||||
|
|
||||||
/** @var WarUnit $attacker */
|
/** @var WarUnit $attacker */
|
||||||
[$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle(
|
[$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle(
|
||||||
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
|
$rawAttacker,
|
||||||
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
|
$rawAttackerCity,
|
||||||
$startYear, $year, $month, $warSeed
|
$rawAttackerNation,
|
||||||
|
$rawDefenderList,
|
||||||
|
$rawDefenderCity,
|
||||||
|
$rawDefenderNation,
|
||||||
|
$startYear,
|
||||||
|
$year,
|
||||||
|
$month,
|
||||||
|
$warSeed
|
||||||
);
|
);
|
||||||
$lastWarLog = Util::mapWithKey(function($key, $values){
|
$lastWarLog = Util::mapWithKey(function ($key, $values) {
|
||||||
return ConvertLog(join('<br>', $values));
|
return ConvertLog(join('<br>', $values));
|
||||||
}, $attacker->getLogger()->rollback());
|
}, $attacker->getLogger()->rollback());
|
||||||
|
|
||||||
@@ -482,48 +531,45 @@ foreach(Util::range($repeatCnt) as $repeatIdx){
|
|||||||
|
|
||||||
$avgWar += count($battleResult) / $repeatCnt;
|
$avgWar += count($battleResult) / $repeatCnt;
|
||||||
|
|
||||||
foreach($attacker->getActivatedSkillLog() as $skillName => $skillCnt){
|
foreach ($attacker->getActivatedSkillLog() as $skillName => $skillCnt) {
|
||||||
if(!key_exists($skillName, $attackerActivatedSkills)){
|
if (!key_exists($skillName, $attackerActivatedSkills)) {
|
||||||
$attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
$attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
$attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($battleResult as $idx=>$defender){
|
foreach ($battleResult as $idx => $defender) {
|
||||||
while($idx >= count($defendersActivatedSkills)){
|
while ($idx >= count($defendersActivatedSkills)) {
|
||||||
$defendersActivatedSkills[] = [];
|
$defendersActivatedSkills[] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$activatedSkills = &$defendersActivatedSkills[$idx];
|
$activatedSkills = &$defendersActivatedSkills[$idx];
|
||||||
foreach($defender->getActivatedSkillLog() as $skillName => $skillCnt){
|
foreach ($defender->getActivatedSkillLog() as $skillName => $skillCnt) {
|
||||||
if(!key_exists($skillName, $activatedSkills)){
|
if (!key_exists($skillName, $activatedSkills)) {
|
||||||
$activatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
$activatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$activatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
$activatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>true,
|
'result' => true,
|
||||||
'datetime'=>$rawAttacker['turntime'],
|
'datetime' => $rawAttacker['turntime'],
|
||||||
'reason'=>'success',
|
'reason' => 'success',
|
||||||
'lastWarLog'=>$lastWarLog,
|
'lastWarLog' => $lastWarLog,
|
||||||
'avgWar'=>$avgWar,
|
'avgWar' => $avgWar,
|
||||||
'phase'=>$avgPhase,
|
'phase' => $avgPhase,
|
||||||
'killed'=>$attackerKilled,
|
'killed' => $attackerKilled,
|
||||||
'maxKilled'=>$attackerMaxKilled,
|
'maxKilled' => $attackerMaxKilled,
|
||||||
'minKilled'=>$attackerMinKilled,
|
'minKilled' => $attackerMinKilled,
|
||||||
'dead'=>$attackerDead,
|
'dead' => $attackerDead,
|
||||||
'maxDead'=>$attackerMaxDead,
|
'maxDead' => $attackerMaxDead,
|
||||||
'minDead'=>$attackerMinDead,
|
'minDead' => $attackerMinDead,
|
||||||
'attackerRice'=>$attackerAvgRice,
|
'attackerRice' => $attackerAvgRice,
|
||||||
'defenderRice'=>$defenderAvgRice,
|
'defenderRice' => $defenderAvgRice,
|
||||||
'attackerSkills'=>$attackerActivatedSkills,
|
'attackerSkills' => $attackerActivatedSkills,
|
||||||
'defendersSkills'=>$defendersActivatedSkills,
|
'defendersSkills' => $defendersActivatedSkills,
|
||||||
]);
|
]);
|
||||||
|
|||||||
+22
-18
@@ -37,16 +37,24 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
|
|||||||
$city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
|
$city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
|
||||||
|
|
||||||
$defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city'));
|
$defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city'));
|
||||||
$defenderList = General::createGeneralObjListFromDB($defenderIDList, null, 2);
|
$defenderGeneralList = General::createGeneralObjListFromDB($defenderIDList, null, 2);
|
||||||
|
|
||||||
usort($defenderList, function (General $lhs, General $rhs) use ($attackerGeneral) {
|
/** @var WarUnit[] */
|
||||||
return - (extractBattleOrder($lhs, $attackerGeneral) <=> extractBattleOrder($rhs, $attackerGeneral));
|
$defenderList = [];
|
||||||
|
foreach($defenderGeneralList as $defenderGeneral){
|
||||||
|
$defenderList[] = new WarUnitGeneral($rng, $defenderGeneral, $rawDefenderNation, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$defenderList[] = $city;
|
||||||
|
|
||||||
|
usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) {
|
||||||
|
return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker));
|
||||||
});
|
});
|
||||||
|
|
||||||
$iterDefender = new \ArrayIterator($defenderList);
|
$iterDefender = new \ArrayIterator($defenderList);
|
||||||
$iterDefender->rewind();
|
$iterDefender->rewind();
|
||||||
|
|
||||||
$getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) use ($rng, $iterDefender, $rawDefenderNation, $rawDefenderCity, $db, $attackerGeneral) {
|
$getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $db, $attacker) {
|
||||||
if ($prevDefender !== null) {
|
if ($prevDefender !== null) {
|
||||||
$prevDefender->applyDB($db);
|
$prevDefender->applyDB($db);
|
||||||
}
|
}
|
||||||
@@ -59,24 +67,16 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var WarUnit */
|
||||||
$nextDefender = $iterDefender->current();
|
$nextDefender = $iterDefender->current();
|
||||||
$nextDefender->setRawCity($rawDefenderCity);
|
if (extractBattleOrder($nextDefender, $attacker) <= 0) {
|
||||||
if (extractBattleOrder($nextDefender, $attackerGeneral) <= 0) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$retVal = new WarUnitGeneral(
|
|
||||||
$rng,
|
|
||||||
$nextDefender,
|
|
||||||
$rawDefenderNation,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
$iterDefender->next();
|
$iterDefender->next();
|
||||||
return $retVal;
|
return $nextDefender;
|
||||||
};
|
};
|
||||||
|
|
||||||
$conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city, $year - $startYear);
|
$conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city);
|
||||||
|
|
||||||
$attacker->applyDB($db);
|
$attacker->applyDB($db);
|
||||||
|
|
||||||
@@ -180,8 +180,13 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
|
|||||||
], $attacker->getGeneral(), $city->getRaw());
|
], $attacker->getGeneral(), $city->getRaw());
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractBattleOrder(General $general, General $attackerGeneral)
|
function extractBattleOrder(WarUnit $defender, WarUnit $attacker)
|
||||||
{
|
{
|
||||||
|
if($defender instanceof WarUnitCity){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$general = $defender->getGeneral();
|
||||||
if ($general->getVar('crew') == 0) {
|
if ($general->getVar('crew') == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -212,7 +217,6 @@ function processWar_NG(
|
|||||||
WarUnitGeneral $attacker,
|
WarUnitGeneral $attacker,
|
||||||
callable $getNextDefender,
|
callable $getNextDefender,
|
||||||
WarUnitCity $city,
|
WarUnitCity $city,
|
||||||
int $relYear
|
|
||||||
): bool {
|
): bool {
|
||||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user