feat,refac: 게임 로직 내 '랜덤'을 RandUtil을 활용하여 재설정

- 기존의 랜덤 코드는 deprecated 처리
- 서버 시작 시 랜덤하게 정해진 hiddenSeed를 활용
- 랜덤 생성 단위
  - 월 실행
  - 사령턴 실행 결과
  - 커맨드 실행 결과
  - 작위 보상
  - 부대장 생성
  - 유니크 획득 시도
  - 설문 조사
  - 장수 생성
  - NPC국 생성, NPC 생성, NPC의 토너먼트 베팅
  - 전투
  - 도시 점령
  - 자율 행동 선택
  - 랜덤 턴 변경
- 거래장, 토너먼트 등 구 랜덤 코드를 이용하는 잔여 코드 있음
This commit is contained in:
2022-05-17 03:46:59 +09:00
parent 2cb697f3dc
commit c5ceff6fb5
136 changed files with 1000 additions and 784 deletions
+33 -19
View File
@@ -1,37 +1,51 @@
<?php
namespace sammo\Event\Action;
use \sammo\GameConst;
use \sammo\Util;
use \sammo\DB;
use sammo\LiteHashDRBG;
use sammo\RandUtil;
use sammo\UniqueConst;
use function sammo\pickGeneralFromPool;
//기존 event_3.php
class CreateManyNPC extends \sammo\Event\Action{
class CreateManyNPC extends \sammo\Event\Action
{
protected $npcCount;
protected $fillCnt;
protected $avgGen;
public function __construct($npcCount = 10, $fillCnt = 0){
public function __construct($npcCount = 10, $fillCnt = 0)
{
$this->npcCount = $npcCount;
$this->fillCnt = $fillCnt;
}
protected function generateNPC($env, int $cnt){
$pickTypeList = ['무'=>1, '지'=>1];
protected function generateNPC($env, int $cnt)
{
$pickTypeList = ['무' => 1, '지' => 1];
$age = Util::randRangeInt(20, 25);
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
'CreateManyNPC',
$env['year'],
$env['month']
)));
$age = $rng->nextRangeInt(20, 25);
$birthYear = $env['year'] - $age;
$deathYear = $env['year'] + Util::randRangeInt(10, 50);
$deathYear = $env['year'] + $rng->nextRangeInt(10, 50);
$result = [];
foreach(pickGeneralFromPool(DB::db(), 0, $cnt) as $pickedNPC){
foreach (pickGeneralFromPool(DB::db(), $rng, 0, $cnt) as $pickedNPC) {
$newNPC = $pickedNPC->getGeneralBuilder();
$newNPC->setNationID(0)
->setNPCType(3)
->setMoney(1000, 1000)
->setExpDed(0, 0)
->setLifeSpan($birthYear, $deathYear);
if($newNPC->getStat()[0]===null){
->setNPCType(3)
->setMoney(1000, 1000)
->setExpDed(0, 0)
->setLifeSpan($birthYear, $deathYear);
if ($newNPC->getStat()[0] === null) {
$newNPC->fillRandomStat($pickTypeList);
}
$newNPC->fillRemainSpecAsZero($env);
@@ -45,14 +59,15 @@ class CreateManyNPC extends \sammo\Event\Action{
}
public function run(array $env){
if($this->npcCount <= 0 && $this->fillCnt <= 0){
public function run(array $env)
{
if ($this->npcCount <= 0 && $this->fillCnt <= 0) {
return [__CLASS__, []];
}
$moreGenCnt = 0;
if($this->fillCnt){
if ($this->fillCnt) {
$db = DB::db();
$nations = $db->queryFirstColumn('SELECT nation FROM general WHERE npc < 3 AND officer_level = 12');
$regGens = $db->queryFirstField('SELECT count(*) FROM general WHERE nation IN %li AND npc < 4', $nations);
@@ -63,12 +78,11 @@ class CreateManyNPC extends \sammo\Event\Action{
$logger = new \sammo\ActionLogger(0, 0, $env['year'], $env['month']);
$genCnt = count($result);
if($genCnt == 1){
if ($genCnt == 1) {
$npcName = $result[0][0];
$josaRa = \sammo\JosaUtil::pick($npcName, '라');
$logger->pushGlobalActionLog("<Y>$npcName</>{$josaRa}는 장수가 <S>등장</>하였습니다.");
}
else{
} else {
$logger->pushGlobalActionLog("장수 <C>{$genCnt}</>명이 <S>등장</>하였습니다.");
}
$logger->pushGlobalHistoryLog("장수 <C>{$genCnt}</>명이 <S>등장</>했습니다.", \sammo\ActionLogger::NOTICE_YEAR_MONTH);
@@ -76,4 +90,4 @@ class CreateManyNPC extends \sammo\Event\Action{
return [__CLASS__, $result];
}
}
}
+16 -6
View File
@@ -7,6 +7,8 @@ use sammo\CityConst;
use sammo\DB;
use sammo\Json;
use sammo\KVStorage;
use sammo\LiteHashDRBG;
use sammo\RandUtil;
use sammo\Scenario\GeneralBuilder;
use sammo\Scenario\Nation;
use sammo\UniqueConst;
@@ -140,6 +142,14 @@ class RaiseInvader extends \sammo\Event\Action
], true);
$year = $env['year'];
$month = $env['month'];
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
'RaiseInvader',
$year,
$month,
)));
$invaderNationIDList = [];
refreshNationStaticInfo();
@@ -154,10 +164,10 @@ class RaiseInvader extends \sammo\Event\Action
$invaderName = $cityObj->name;
$nationName = "{$invaderName}";
$nationObj = new Nation($invaderNationID, $nationName, '#800080', 9999999, 9999999, "중원의 부패를 물리쳐라! 이민족 침범!", $tech, "che_병가", 2, [$cityObj->name]);
$nationObj = new Nation($rng, $invaderNationID, $nationName, '#800080', 9999999, 9999999, "중원의 부패를 물리쳐라! 이민족 침범!", $tech, "che_병가", 2, [$cityObj->name]);
$nationObj->build($env);
$ruler = (new GeneralBuilder("{$invaderName}대왕", false, null, $lastNationID))
$ruler = (new GeneralBuilder($rng, "{$invaderName}대왕", false, null, $lastNationID))
->setEgo('che_패권')
->setSpecial('che_인덕', 'che_척사')
->setLifeSpan($year - 20, $year + 20)
@@ -172,7 +182,7 @@ class RaiseInvader extends \sammo\Event\Action
$nationObj->addGeneral($ruler);
foreach (Util::range(1, $npcEachCount) as $invaderGenIdx) {
$gen = (new GeneralBuilder("{$invaderName}장수{$invaderGenIdx}", false, null, $invaderNationID))
$gen = (new GeneralBuilder($rng, "{$invaderName}장수{$invaderGenIdx}", false, null, $invaderNationID))
->setEgo('che_패권')
->setSpecial('che_인덕', 'che_척사')
->setLifeSpan($year - 20, $year + 20)
@@ -182,11 +192,11 @@ class RaiseInvader extends \sammo\Event\Action
->setExpDed($exp, null)
->setGoldRice(99999, 99999);
$leadership = Util::randRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4));
$mainStat = Util::randRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4));
$leadership = $rng->nextRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4));
$mainStat = $rng->nextRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4));
$subStat = $specAvg * 3 - $leadership - $mainStat;
if (Util::randBool()) {
if ($rng->nextBit()) {
//무장
$dexTable = [$dex * 2, $dex, $dex];
shuffle($dexTable);
+16 -10
View File
@@ -9,6 +9,8 @@ use sammo\DB;
use sammo\GameConst;
use sammo\Json;
use sammo\KVStorage;
use sammo\LiteHashDRBG;
use sammo\RandUtil;
use sammo\Scenario\GeneralBuilder;
use sammo\Scenario\Nation;
use sammo\UniqueConst;
@@ -28,7 +30,7 @@ class RaiseNPCNation extends \sammo\Event\Action
const MIN_DIST_USERNATION = 3;
const MIN_DIST_NPCNATION = 2;
private function calcAvgNationCity(array $cities)
private function calcAvgNationCity(RandUtil $rng, array $cities)
{
if (count($cities) == 0) {
throw new InvalidArgumentException();
@@ -55,7 +57,7 @@ class RaiseNPCNation extends \sammo\Event\Action
$cityCnt = count($targetCities);
if ($cityCnt == 0) {
$target = Util::choiceRandom($cities);
$target = $rng->choice($cities);
$randCity = [];
foreach (static::CITY_KEYS as $key) {
$randCity[$key] = $target["{$key}_max"];
@@ -136,7 +138,7 @@ class RaiseNPCNation extends \sammo\Event\Action
return Util::toInt($techSum / $nationCnt);
}
private function buildNation(int $nationID, int $tech, array $baseCity, array $avgCity, int $genCnt, $env)
private function buildNation(RandUtil $rng, int $nationID, int $tech, array $baseCity, array $avgCity, int $genCnt, $env)
{
$db = DB::db();
@@ -153,11 +155,11 @@ class RaiseNPCNation extends \sammo\Event\Action
$cityName = $baseCity['name'];
$nationName = "{$cityName}";
$color = Util::choiceRandom(GetNationColors());
$nationObj = new Nation($nationID, $nationName, $color, 0, 2000, "우리도 할 수 있다! {$cityName}", $tech, null, 2, [$cityName]);
$color = $rng->choice(GetNationColors());
$nationObj = new Nation($rng, $nationID, $nationName, $color, 0, 2000, "우리도 할 수 있다! {$cityName}", $tech, null, 2, [$cityName]);
$nationObj->build($env);
$ruler = (new GeneralBuilder("{$cityName}태수", false, null, $nationID))
$ruler = (new GeneralBuilder($rng, "{$cityName}태수", false, null, $nationID))
->setOfficerLevel(12)
->setCityID($cityID)
->setNPCType(6)
@@ -172,9 +174,9 @@ class RaiseNPCNation extends \sammo\Event\Action
$birthYear = $env['year'] - 20;
$deadYearMin = $env['year'] + 10;
foreach (pickGeneralFromPool(DB::db(), 0, $genCnt - 1) as $pickedNPC) {
foreach (pickGeneralFromPool(DB::db(), $rng, 0, $genCnt - 1) as $pickedNPC) {
//대충 10년후부터 6년마다 절반?
$deadYear = $deadYearMin + Util::toInt(60 * (1 - log(Util::randRange(1, 1024), 2) / 10));
$deadYear = $deadYearMin + Util::toInt(60 * (1 - log($rng->nextRange(1, 1024), 2) / 10));
$newNPC = $pickedNPC->getGeneralBuilder();
$newNPC->setNationID($nationID)
->setCityID($cityID)
@@ -204,7 +206,11 @@ class RaiseNPCNation extends \sammo\Event\Action
$occupiedCities = [];
$npcCities = [];
$avgCity = $this->calcAvgNationCity($allCities);
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed, 'RaiseNPCNation', $env['year'], $env['month']
)));
$avgCity = $this->calcAvgNationCity($rng, $allCities);
foreach ($allCities as $city) {
if ($city['nation'] == 0) {
@@ -257,7 +263,7 @@ class RaiseNPCNation extends \sammo\Event\Action
//TODO: 거리 측정
$lastNationID += 1;
$this->buildNation($lastNationID, $avgTech, $emptyCity, $avgCity, $avgGenCnt, $env);
$this->buildNation($rng, $lastNationID, $avgTech, $emptyCity, $avgCity, $avgGenCnt, $env);
$npcCities[$cityID] = $emptyCity;
$npcCitiesID[] = $cityID;
}
+18 -13
View File
@@ -1,33 +1,38 @@
<?php
namespace sammo\Event\Action;
use sammo\LiteHashDRBG;
use sammo\RandUtil;
//이전 RegNPC 함수를 EventAction으로 재구성
class RegNPC extends \sammo\Event\Action{
/** @var \sammo\Scenario\GeneralBuilder */
private $npc;
public function __construct(
int $affinity,
string $name,
$picturePath,
int $affinity,
string $name,
$picturePath,
int $nationID,
$locatedCity,
int $leadership,
int $strength,
int $intel,
$locatedCity,
int $leadership,
int $strength,
int $intel,
int $officerLevel,
int $birth = 160,
int $death = 300,
int $birth = 160,
int $death = 300,
$ego = null,
$char = '',
$char = '',
$text = ''
){
$rng = new RandUtil(new LiteHashDRBG(bin2hex(random_bytes(16))));
$this->npc=(new \sammo\Scenario\GeneralBuilder(
$name,
$rng,
$name,
false,
$picturePath,
$nationID
$picturePath,
$nationID
))
->setCity($locatedCity)
->setStat($leadership, $strength, $intel)
+21 -13
View File
@@ -1,31 +1,39 @@
<?php
namespace sammo\Event\Action;
use sammo\LiteHashDRBG;
use sammo\RandUtil;
use sammo\UniqueConst;
use sammo\Util;
class RegNeutralNPC extends \sammo\Event\Action{
/** @var \sammo\Scenario\GeneralBuilder */
private $npc;
public function __construct(
int $affinity,
string $name,
$picturePath,
int $affinity,
string $name,
$picturePath,
int $nationID,
$locatedCity,
int $leadership,
int $strength,
int $intel,
int $birth = 160,
int $death = 300,
$locatedCity,
int $leadership,
int $strength,
int $intel,
int $birth = 160,
int $death = 300,
$ego = null,
$char = '',
$char = '',
$text = ''
){
$rng = new RandUtil(new LiteHashDRBG(bin2hex(random_bytes(16))));
$this->npc=(new \sammo\Scenario\GeneralBuilder(
$name,
$rng,
$name,
false,
$picturePath,
$nationID
$picturePath,
$nationID
))
->setCity($locatedCity)
->setStat($leadership, $strength, $intel)