<?php
/**
* バトルクラス
*/
class Battle
{
public const TURN_DEFAULT = 1;
private const TURN_LIMIT = 1000;
/** @var BattleAble $player プレイヤー */
private BattleAble $player;
/** @var BattleAble $enemy 敵 */
private BattleAble $enemy;
/** @var int $turn ターン数 */
private int $turn = self::TURN_DEFAULT;
/**
* constructor
*
* @param BattleAble $player
* @param BattleAble $enemy
*/
private function __construct(BattleAble $player, BattleAble $enemy)
{
$this->player = $player;
$this->enemy = $enemy;
}
/**
* バトル開始
*
* @param BattleAble $player
* @param BattleAble $enemy
* @return void
*/
public static function start(BattleAble $player, BattleAble $enemy): void
{
(new self($player, $enemy))->run();
}
/**
* バトル実行
*
* @return void
*/
private function run(): void
{
Logger::add('バトル開始');
Logger::add($this->player);
Logger::add($this->enemy);
Logger::add('');
$participants = [$this->player, $this->enemy];
while (!$this->isTurnLimit()) {
Logger::add("{$this->turn}ターン目");
// 感情に変化が起きたら感情を更新する
foreach ($participants as $participant) {
if ($participant instanceof HasEmotion) {
$emotionAnalyzer = new EmotionAnalyzer($this->turn, $participant, $this->getTarget($participant));
$emotion = $emotionAnalyzer->analyze();
if ($participant->getEmotion() !== $emotion) {
$participant->updateEmotion($emotion);
Logger::add("{$participant->getName()}は{$emotion->value}している。");
}
}
}
// 行動
foreach ($participants as $participant) {
$action = $participant->action($this->getTarget($participant))->execute();
if ($action->shouldBreak()) {
break 2;
}
}
$this->turn++;
Logger::add('');
}
Logger::add('バトル終了');
}
/**
* ターン上限か
*
* @return bool true:上限, false:上限でない
*/
private function isTurnLimit(): bool
{
return $this->turn >= self::TURN_LIMIT;
}
/**
* ターゲットを取得
*
* @param BattleAble $performer 行動実行者
* @return BattleAble
*/
private function getTarget(BattleAble $performer): BattleAble
{
if ($this->player === $performer) {
return $this->enemy;
} else {
return $this->player;
}
}
}