FR

Zombi Ubisoft (1986) PHP

par espritm · Remakes
pas encore noté
▶ Jouer 💬 Avis 1 Sources 🕘 Versions Éditer GitHub
games/zombi-ubisoft-1986-php / tests / RangedStatsTest.php · commit 8af5764
<?phpnamespace App\Tests;use App\Model\World;use PHPUnit\Framework\TestCase;/** Controlled RNG/phase fixtures correspond to the native probe preconditions. */final class RangedStatsTest extends TestCase{    private function world(): World    {        return new World(json_decode(file_get_contents(__DIR__.'/../assets/original/game.json'),true,512,JSON_THROW_ON_ERROR));    }    private function gunner(int $seed=57): World    {        $w=$this->world();$s=$w->export();$s['enemySeed']=$seed;$s['raidersArrived']=true;        $s['party'][3]['position']=array_search(41,$s['map'],true);        $s['rooms'][41]['hp']=35;$s['rooms'][41]['strength']=30;$s['rooms'][41]['shooter']=true;        $s['alertTicks']=255.0;$s['rangedArmed']=true;$s['rangedPending']=false;        self::assertTrue($w->restore($s));return $w;    }    public function testInitialZombiesUseTheNativeRanges(): void    {        $w=$this->world();foreach($w->rooms as $r){if(!$r['prefix'][6]){continue;}            self::assertGreaterThanOrEqual(26,$r['hp']);self::assertLessThanOrEqual(41,$r['hp']);            self::assertSame(58,$r['hp']+$r['strength']);self::assertFalse($r['shooter']);        }    }    public function testNextOpponentUsesObservedRandomInputsAndShooterBoundary(): void    {        foreach([10=>0,31=>1,45=>7,2=>15] as $seed=>$raw){            foreach([false,true] as $phase){                $w=$this->world();$s=$w->export();$s['enemySeed']=$seed;$s['raidersArrived']=$phase;                $s['party'][3]['position']=array_search(41,$s['map'],true);$s['party'][3]['held']=34;$s['rooms'][41]['prefix'][6]=2;                self::assertTrue($w->restore($s));$w->chooseAction(3);$w->activateAction();$w->confirm();                self::assertSame(($phase?30:26)+$raw,$w->current()['hp']);                self::assertSame($phase?65:58,$w->current()['hp']+$w->current()['strength']);            }        }        foreach([29177=>true,17774=>false] as $seed=>$armed){            $w=$this->gunner($seed);$w->rooms[41]['prefix'][6]=2;$w->party[3]['held']=34;            $w->chooseAction(3);$w->activateAction();$w->confirm();            self::assertSame(35,$w->current()['hp']);self::assertSame(30,$w->current()['strength']);self::assertSame($armed,$w->current()['shooter']);        }    }    public function testReplyWaitsFor256TicksAndCostsSixOnBothGauges(): void    {        $w=$this->gunner();$w->advance(0.019);self::assertSame([70,80,80],$w->person()['gauges']);        $w->advance(0.002);self::assertSame([64,74,80],$w->person()['gauges']);self::assertFalse($w->export()['rangedPending']);        $w->advance(0);self::assertSame([64,74,80],$w->person()['gauges']);    }    public function testBusyActionsQueueOneReplyAndSaveIt(): void    {        foreach(['inventory','aim','combat'] as $mode){            $w=$this->gunner();$w->mode=$mode;$w->advance(0.02);            self::assertTrue($w->export()['rangedPending']);self::assertSame([70,80,80],$w->person()['gauges']);            $copy=$this->world();self::assertTrue($copy->restore($w->export()));$copy->advance(0);            self::assertSame([64,74,80],$copy->person()['gauges']);self::assertFalse($copy->export()['rangedPending']);        }    }    public function testWeakScoreLeavesReplyPendingAndRetriesWithoutAnotherPeriod(): void    {        $w=$this->gunner(83);$s=$w->export();$s['alertTicks']=0.0;$s['rangedPending']=true;self::assertTrue($w->restore($s));        $w->advance(0);self::assertTrue($w->export()['rangedPending']);self::assertSame([70,80,80],$w->person()['gauges']);        $s=$w->export();$s['enemySeed']=57;self::assertTrue($w->restore($s));$w->advance(0);        self::assertFalse($w->export()['rangedPending']);self::assertSame([64,74,80],$w->person()['gauges']);    }    public function testFatalRangedDamagePreservesTheUnwrittenGauge(): void    {        foreach([[6,80],[70,6]] as [$f,$h]){            $w=$this->gunner();$w->party[3]['gauges'][0]=$f;$w->party[3]['gauges'][1]=$h;$w->advance(0.02);            self::assertSame([0,$h,80],$w->person()['gauges']);self::assertSame(64,$w->person()['state']);        }    }    public function testAimTimeoutEntersMeleeWithoutDispatchingThePendingReply(): void    {        $w=$this->gunner();$w->mode='aim';$w->advance(10.24);        self::assertSame('combat',$w->mode);self::assertTrue($w->export()['rangedPending']);        self::assertSame([70,80,80],$w->person()['gauges']);    }    public function testUnarmedAndZombieCasesDoNotScheduleShotsAndIdleStartsMelee(): void    {        $w=$this->gunner();$s=$w->export();$s['rangedArmed']=false;$s['rooms'][41]['shooter']=false;self::assertTrue($w->restore($s));        $w->advance(0.02);self::assertSame([70,80,80],$w->person()['gauges']);self::assertFalse($w->export()['rangedPending']);        $s=$w->export();$s['alertTicks']=511.0;self::assertTrue($w->restore($s));$w->advance(0.02);        self::assertSame('combat',$w->mode);self::assertSame([70,80,80],$w->person()['gauges']);        $z=$this->world();$z->party[3]['position']=array_search(41,$z->map,true);$z->advance(5.12);        self::assertFalse($z->export()['rangedPending']);self::assertSame([70,80,80],$z->person()['gauges']);    }    public function testAlertSaveValidationAndVersion08Migration(): void    {        $w=$this->gunner();$save=$w->export();        foreach(['alertTicks'=>65536,'rangedPending'=>1,'rangedArmed'=>0] as $field=>$value){$bad=$save;$bad[$field]=$value;self::assertFalse($w->restore($bad));self::assertSame($save,$w->export());}        $bad=$save;$bad['rooms'][41]['shooter']=1;self::assertFalse($w->restore($bad));        $old=$save;$old['version']='0.8.0';unset($old['alertTicks'],$old['rangedPending'],$old['rangedArmed']);foreach($old['rooms'] as &$r){unset($r['shooter']);}unset($r);        self::assertTrue($w->restore($old));self::assertSame(35,$w->current()['hp']);self::assertSame(30,$w->current()['strength']);        self::assertSame(0.0,$w->export()['alertTicks']);self::assertFalse($w->current()['shooter']);    }}