feat(combat): water traversal costs 3 and ends the turn

This commit is contained in:
Keith Solomon
2026-07-26 23:38:13 -05:00
parent fb06da3f28
commit 09f2bda924
10 changed files with 153 additions and 10 deletions
-1
View File
@@ -56,7 +56,6 @@ final class MatchStateTest extends TestCase
*/
public static function impassableTerrainProvider(): iterable
{
yield 'water' => [Terrain::Water];
yield 'blocking' => [Terrain::Blocking];
}
+2 -2
View File
@@ -28,7 +28,7 @@ final class ScenarioValidatorTest extends TestCase
public function testItRejectsAnObjectiveOnImpassableTerrain(): void
{
$scenario = $this->validScenario(
terrain: ['4:4' => Terrain::Water],
terrain: ['4:4' => Terrain::Blocking],
objectivePosition: new Position(4, 4),
);
@@ -81,7 +81,7 @@ final class ScenarioValidatorTest extends TestCase
public function testItRejectsDeploymentPositionsOnImpassableTerrain(): void
{
$units = $this->unitSet();
$battlefield = new Battlefield(8, 8, ['0:0' => Terrain::Water]);
$battlefield = new Battlefield(8, 8, ['0:0' => Terrain::Blocking]);
$scenario = new Scenario(
id: 'demo',
name: 'Demo',
+40
View File
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace BattleForge\Tests\Unit\Domain;
use BattleForge\Domain\Terrain;
use PHPUnit\Framework\TestCase;
final class TerrainTest extends TestCase
{
public function testOpenCostsOne(): void
{
self::assertSame(1, Terrain::Open->movementCost());
self::assertSame(0, Terrain::Open->defenseBonus());
}
public function testForestCostsTwoAndGivesOneDefense(): void
{
self::assertSame(2, Terrain::Forest->movementCost());
self::assertSame(1, Terrain::Forest->defenseBonus());
}
public function testRoughCostsTwoAndGivesNoDefense(): void
{
self::assertSame(2, Terrain::Rough->movementCost());
self::assertSame(0, Terrain::Rough->defenseBonus());
}
public function testWaterCostsThreeAndGivesNoDefense(): void
{
self::assertSame(3, Terrain::Water->movementCost());
self::assertSame(0, Terrain::Water->defenseBonus());
}
public function testBlockingIsImpassable(): void
{
self::assertNull(Terrain::Blocking->movementCost());
}
}
+20
View File
@@ -229,12 +229,32 @@ final class UnitStateTest extends TestCase
self::assertFalse($started->hasUsedAbility);
}
public function testStartTurnResetsWadedFlag(): void
{
$unit = $this->unit(wadedThisTurn: true);
$started = $unit->startTurn();
self::assertFalse($started->wadedThisTurn);
}
public function testWithWadedSetsAndClearsFlag(): void
{
$unit = $this->unit();
self::assertFalse($unit->wadedThisTurn);
$wading = $unit->withWaded(true);
self::assertTrue($wading->wadedThisTurn);
$dry = $wading->withWaded(false);
self::assertFalse($dry->wadedThisTurn);
}
private function unit(
int $health = 10,
int $actionsRemaining = 2,
bool $hasAttacked = false,
int $attackBonus = 0,
bool $hasUsedAbility = false,
bool $wadedThisTurn = false,
): UnitState {
return new UnitState(
'unit-1',