Files
core/hwe/sammo/TriggerCaller.php
T
Hide_D c5ceff6fb5 feat,refac: 게임 로직 내 '랜덤'을 RandUtil을 활용하여 재설정
- 기존의 랜덤 코드는 deprecated 처리
- 서버 시작 시 랜덤하게 정해진 hiddenSeed를 활용
- 랜덤 생성 단위
  - 월 실행
  - 사령턴 실행 결과
  - 커맨드 실행 결과
  - 작위 보상
  - 부대장 생성
  - 유니크 획득 시도
  - 설문 조사
  - 장수 생성
  - NPC국 생성, NPC 생성, NPC의 토너먼트 베팅
  - 전투
  - 도시 점령
  - 자율 행동 선택
  - 랜덤 턴 변경
- 거래장, 토너먼트 등 구 랜덤 코드를 이용하는 잔여 코드 있음
2022-05-17 03:46:59 +09:00

131 lines
4.0 KiB
PHP

<?php
namespace sammo;
abstract class TriggerCaller{
protected $triggerListByPriority = [];
abstract function checkValidTrigger(ObjectTrigger $trigger):bool;
function isEmpty():bool{
return !$this->triggerListByPriority;
}
function __construct(ObjectTrigger ...$triggerList)
{
if(!$triggerList){
return;
}
$sorted = true;
$maxPriority = ObjectTrigger::PRIORITY_MIN;
foreach($triggerList as $trigger){
if(!$this->checkValidTrigger($trigger)){
throw new \InvalidArgumentException('Invalid Trigger Type');
}
/** @var ObjectTrigger $trigger */
$priority = $trigger->getPriority();
$uniqueID = $trigger->getUniqueID();
if($sorted){
if($maxPriority < $priority){
$maxPriority = $priority;
}
else if($maxPriority > $priority){
$sorted = false;
}
}
if(!key_exists($priority, $this->triggerListByPriority)){
$this->triggerListByPriority[$priority] = [$uniqueID=>$trigger];
continue;
}
$this->triggerListByPriority[$priority][$uniqueID] = $trigger;
}
if(!$sorted){
ksort($this->triggerListByPriority);
}
}
function append(ObjectTrigger $trigger):self{
if(!$this->checkValidTrigger($trigger)){
throw new \InvalidArgumentException('Invalid Trigger Type');
}
$priority = $trigger->getPriority();
$uniqueID = $trigger->getUniqueID();
if(!$this->triggerListByPriority){
$this->triggerListByPriority[$priority] = [$uniqueID=>$trigger];
return $this;
}
$lastKey = Util::array_last_key($this->triggerListByPriority);
if($lastKey < $priority){
$this->triggerListByPriority[$priority] = [$uniqueID=>$trigger];
return $this;
}
if(key_exists($priority, $this->triggerListByPriority)){
$this->triggerListByPriority[$priority][$uniqueID] = $trigger;
}
$this->triggerListByPriority[$priority] = [$uniqueID=>$trigger];
ksort($this->triggerListByPriority);
return $this;
}
function merge(?TriggerCaller $other):self{
if($other === null){
return $this;
}
//NOTE: array_merge로 계속 가야하는가? merge가 많으면 SPL의 LinkedList가 낫지 않나?
$newTriggerList = [];
$iterLhs = new \ArrayIterator($this->triggerListByPriority);
$iterRhs = new \ArrayIterator($other->triggerListByPriority);
while($iterLhs->valid() && $iterRhs->valid()){
if($iterLhs->key() < $iterRhs->key()){
$newTriggerList[$iterLhs->key()] = $iterLhs->current();
$iterLhs->next();
continue;
}
if($iterRhs->key() < $iterLhs->key()){
$newTriggerList[$iterRhs->key()] = $iterRhs->current();
$iterRhs->next();
continue;
}
$newTriggerList[$iterLhs->key()] = array_merge($iterLhs->current(), $iterRhs->current());
$iterLhs->next();
$iterRhs->next();
}
while($iterLhs->valid()){
$newTriggerList[$iterLhs->key()] = $iterLhs->current();
$iterLhs->next();
}
while($iterRhs->valid()){
$newTriggerList[$iterRhs->key()] = $iterRhs->current();
$iterRhs->next();
}
$this->triggerListByPriority = $newTriggerList;
return $this;
}
function fire(RandUtil $rng, array $env, $arg = null):?array{
foreach($this->triggerListByPriority as $priority=>$subTriggerList){
/** @var ObjectTrigger[] $subTriggerList */
foreach($subTriggerList as $trigger){
$env = $trigger->action($rng, $env, $arg);
}
}
return $env;
}
}