Added more methods to the Battle class and tests

If a battle is over or not can now be tested using this->isOver(). If the
battle is over, battle->getWinner() can be used to get the winner of this
fight, battle->getLooser() for the looser.
This commit is contained in:
Basilius Sauter
2016-05-23 18:19:01 +02:00
parent 38068dd0a5
commit 2609d67e38
7 changed files with 175 additions and 9 deletions
+51 -4
View File
@@ -6,6 +6,8 @@ namespace LotGD\Core;
use LotGD\Core\{
DiceBag,
Exceptions\ArgumentException,
Exceptions\BattleIsOverException,
Exceptions\BattleNotOverException,
Models\FighterInterface
};
@@ -21,6 +23,9 @@ class Battle
protected $player;
protected $monster;
protected $diceBag;
protected $isOver = false;
protected $winner;
protected $looser;
public function __construct(FighterInterface $player, FighterInterface $monster)
{
@@ -39,6 +44,39 @@ class Battle
}
/**
* Returns true if the battle is over.
* @return type
*/
public function isOver()
{
return $this->isOver;
}
/**
* Returns the winner of this fight
* @return FighterInterface
*/
public function getWinner(): FighterInterface
{
if (is_null($this->winner)) {
throw new BattleNotOverException('There is no winner yet.');
}
return $this->winner;
}
/**
* Returns the looser of this fight
* @return FighterInterface
*/
public function getLooser(): FighterInterface
{
if (is_null($this->looser)) {
throw new BattleNotOverException('There is no looser yet.');
}
return $this->looser;
}
/**
* Fights the number of rounds given by the parameter $n and returns the number
* of actual rounds fought.
@@ -52,11 +90,20 @@ class Battle
throw new ArgumentException('$firstDamageRound must not be 0.');
}
if ($this->isOver === true) {
throw new BattleIsOverException('This battle has already ended. You cannot fight anymore rounds.');
}
for ($count = 0; $count < $n; $count++) {
if ($this->player->isAlive() > 0 && $this->monster->isAlive()) {
$this->fightOneRound($firstDamageRound);
$isSurprised = self::DAMAGEROUND_BOTH;
} else {
$this->fightOneRound($firstDamageRound);
$isSurprised = self::DAMAGEROUND_BOTH;
// If one of the participants is dead, abort.
if ($this->player->isAlive() === false || $this->monster->isAlive() === false) {
$this->isOver = true;
$this->winner = $this->player->isAlive() ? $this->player : $this->monster;
$this->looser = $this->player->isAlive() ? $this->monster : $this->player;
break;
}
}
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a specific, required argument is missing
*/
class BattleException extends CoreException
{
}
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a specific, required argument is missing
*/
class BattleIsOverException extends BattleException
{
}
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a specific, required argument is missing
*/
class BattleNotOverException extends BattleException
{
}
+2 -2
View File
@@ -213,7 +213,7 @@ class Character implements CharacterInterface, CreateableInterface
*/
public function getAttack(): int
{
return $this->level;
return $this->level * 2;
}
/**
@@ -221,7 +221,7 @@ class Character implements CharacterInterface, CreateableInterface
*/
public function getDefense(): int
{
return $this->level;
return $this->level * 2;
}
/**
+63 -2
View File
@@ -32,7 +32,7 @@ class BattleTest extends ModelTestCase
$this->assertSame($monster->getMaxHealth(), $monster->getHealth());
}
public function testBattle()
public function testFairBattle()
{
$em = $this->getEntityManager();
@@ -50,11 +50,72 @@ class BattleTest extends ModelTestCase
$this->assertLessThanOrEqual($oldPlayerHealth, $character->getHealth());
$this->assertLessThanOrEqual($oldMonsterHealth, $monster->getHealth());
if ($character->isAlive() === false && $monster->isAlive() === false) {
if ($battle->isOver()) {
break;
}
}
$this->assertTrue($battle->isOver());
$this->assertTrue($character->isAlive() xor $monster->isAlive());
}
public function testPlayerWinBattle()
{
$em = $this->getEntityManager();
$highLevelPlayer = $em->getRepository(Character::class)->find(2);
$lowLevelMonster = $em->getRepository(Monster::class)->find(3);
$battle = new Battle($highLevelPlayer, $lowLevelMonster);
for ($n = 0; $n < 99; $n++) {
$oldPlayerHealth = $highLevelPlayer->getHealth();
$oldMonsterHealth = $lowLevelMonster->getHealth();
$battle->fightNRounds(1);
$this->assertLessThanOrEqual($oldPlayerHealth, $highLevelPlayer->getHealth());
$this->assertLessThanOrEqual($oldMonsterHealth, $lowLevelMonster->getHealth());
if ($battle->isOver()) {
break;
}
}
$this->assertTrue($highLevelPlayer->isAlive());
$this->assertFalse($lowLevelMonster->isAlive());
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getWinner(), $highLevelPlayer);
}
public function testPlayerLooseBattle()
{
$em = $this->getEntityManager();
$lowLevelPlayer = $em->getRepository(Character::class)->find(3);
$highLevelMonster = $em->getRepository(Monster::class)->find(2);
$battle = new Battle($lowLevelPlayer, $highLevelMonster);
for ($n = 0; $n < 99; $n++) {
$oldPlayerHealth = $lowLevelPlayer->getHealth();
$oldMonsterHealth = $highLevelMonster->getHealth();
$battle->fightNRounds(1);
$this->assertLessThanOrEqual($oldPlayerHealth, $lowLevelPlayer->getHealth());
$this->assertLessThanOrEqual($oldMonsterHealth, $highLevelMonster->getHealth());
if ($battle->isOver()) {
break;
}
}
$this->assertFalse($lowLevelPlayer->isAlive());
$this->assertTrue($highLevelMonster->isAlive());
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getWinner(), $highLevelMonster);
}
}
+23 -1
View File
@@ -6,8 +6,30 @@ characters:
health: 100
maxhealth: 100
level: 10
-
id: 2
name: "High Level Char"
displayName: "High Level Char"
health: 1000
maxhealth: 1000
level: 100
-
id: 3
name: "Low Level Char"
displayName: "Low Level Char"
health: 10
maxhealth: 10
level: 1
monsters:
-
id: 1
name: "Evil Monster"
level: 5
level: 5
-
id: 2
name: "High Dragon"
level: 100
-
id: 3
name: "Stone"
level: 1