<?php
header("Content-Type: text/plain; charset=utf-8");
mb_internal_encoding("UTF-8");
class Hero
{
    public $name;
    public $health;
    public $armorLow;
    public $armorHigh;
    public $block;
    public $dodgeCrit;
    public $crit;
    public $attackLow;
    public $attackHigh;
    public $charisma;
    public $doubleHit = 0;
 
    public function __construct($name, $attackLow, $attackHigh, $health, $armorLow, $armorHigh, $block, $dodgeCrit, $crit, $charisma)
    {
        $this->name       = $name;
        $this->attackLow  = $attackLow;
        $this->attackHigh = $attackHigh;
        $this->health     = $health;
        $this->armorLow   = $armorLow;
        $this->armorHigh  = $armorHigh;
        $this->block      = $block;
        $this->dodgeCrit  = $dodgeCrit;
        $this->crit       = $crit;
        $this->charisma   = $charisma;
    }
    public function getAverageDmg() //средний урон персонажа
    {
        $damage = mt_rand($this->attackLow, $this->attackHigh);
        return $damage;
    }
    public function getAverageDmgReduction() //среднее число блокируемое доспехами урона
    {
        $reduction = mt_rand($this->armorLow, $this->armorHigh);
        return $reduction;
    }
    public function getCrit() // рассчет шанса критического урона с возвратом модификатора атаки
    {
        $roll = mt_rand(1, 100);
        if ($roll <= $this->crit) {
            $roll = mt_rand(1, 100);
            if ($roll > $this->dodgeCrit) {
                $critAmplify = 2;
                return $critAmplify;
            }
        }
        $critAmplify = 1;
 
        return $critAmplify;
    }
    public function getBlock() //рассчет блока наподобие крита выше.
    {
        $roll = mt_rand(1, 100);
        if ($roll <= $this->block) {
            $blockAmplify = 0;
        } else {
            $blockAmplify = 1;
        }
        return $blockAmplify;
    }
 
}
class Game
{
    public $heroFirst;
    public $heroSecond;
    public function __construct($heroFirst, $heroSecond)
    {
        $this->heroFirst  = $heroFirst;
        $this->heroSecond = $heroSecond;
    }
    private function makeOneHitFirstHero() // урон первого героя по второму
    {
 
        $block = $this->heroFirst->getBlock();
        $crit  = $this->heroFirst->getCrit();
 
        $damage1 = ($this->heroFirst->getAverageDmg() - $this->heroSecond->getAverageDmgReduction()) * $crit * $block;
        if ($block == 1) {
            if ($crit == 2) {
                echo "{$this->heroFirst->name} наносит критический урон \n";
            }
        } else {
            echo "Урон {$this->heroFirst->name} заблокирован щитом {$this->heroSecond->name} \n";
        }
        echo "{$this->heroFirst->name} наносит $damage1 урона. \n";
        if ($this->heroFirst->doubleHit != 0) {
            $roll = mt_rand(1, 100);
            if ($roll <= $this->heroFirst->doubleHit) {
                echo "Вторая атака за счет преимущества в харизме: \n";
                $block = $this->heroFirst->getBlock();
                $crit  = $this->heroFirst->getCrit();
                 $damage2 = ($this->heroFirst->getAverageDmg() - $this->heroFirst->getAverageDmgReduction()) * $crit * $block;
                if ($block == 1) {
                    if ($crit == 2) {
                        echo "{$this->heroFirst->name} наносит критический урон \n";
                    }
                } else {
                    echo "Урон {$this->heroFirst->name} заблокирован щитом {$this->heroSecond->name} \n";
                }
               
                echo "{$this->heroFirst->name} наносит $damage2 урона. \n";
            }
        }
        if (!isset($damage2)) {
            $damage = $damage1;
        } else {
            $damage = $damage1 + $damage2;
        }
        return $damage;
    }
    private function makeOneHitSecondHero() //урон второго героя по первому
    {
        $block = $this->heroSecond->getBlock();
        $crit  = $this->heroSecond->getCrit();
 
        $damage1 = ($this->heroSecond->getAverageDmg() - $this->heroSecond->getAverageDmgReduction()) * $crit * $block;
                if ($block == 1) {
            if ($crit == 2) {
                echo "{$this->heroSecond->name} наносит критический урон \n";
            }
        } else {
            echo "Урон {$this->heroSecond->name} заблокирован щитом {$this->heroFirst->name} \n";
        }
        echo "{$this->heroSecond->name} наносит $damage1 урона. \n";
        if ($this->heroSecond->doubleHit != 0) {
            $roll = mt_rand(1, 100);
            if ($roll <= $this->heroSecond->doubleHit) {
                echo "Вторая атака за счет преимущества в харизме: \n";
                $block = $this->heroSecond->getBlock();
                $crit  = $this->heroSecond->getCrit();
                $damage2 = ($this->heroSecond->getAverageDmg() - $this->heroFirst->getAverageDmgReduction()) * $crit * $block;
                if ($block == 1) {
                    if ($crit == 2) {
                        echo "{$this->heroSecond->name} наносит критический урон \n";
                    }
                } else {
                    echo "Урон {$this->heroSecond->name} заблокирован щитом {$this->heroFirst->name} \n";
                }
                
                echo "{$this->heroSecond->name} наносит $damage2 урона. \n";
            }
        }
        if (!isset($damage2)) {
            $damage = $damage1;
        } else {
            $damage = $damage1 + $damage2;
        }
 
        return $damage;
    }
 
 
    public function fillDoubleHitString() //присвоить героям шанс на вторую атаку исходя из разницы в харизме
    {
        $charAbs = abs($this->heroFirst->charisma - $this->heroSecond->charisma);
        if ($charAbs > 100) {
            $charAbs = 100;
        }
        $charOne = $this->heroFirst->charisma;
        $charTwo = $this->heroSecond->charisma;
        if ($charOne > $charTwo) {
            $this->heroFirst->doubleHit = $charAbs;
        } elseif ($charOne < $charTwo) {
            $this->heroSecond->doubleHit = $charAbs;
        }
    }
    public function makeTwentyRounds()
    {
    	$firstFullDmg = 0;
    	$secondFullDmg = 0;
        $this->fillDoubleHitString();
        $str = str_repeat('_', 42);
        for ($i = 1; $i <= 20; $i++) {
            echo "$i раунд: \n";
            $firstDmg = $this->makeOneHitFirstHero();
            $firstFullDmg += $firstDmg;
            $secondDmg = $this->makeOneHitSecondHero();
            $secondFullDmg += $secondDmg;
            if ($this->heroFirst->health <= $secondDmg) {
                $secondDmg = $this->heroFirst->health - 1;
            }
            if ($this->heroSecond->health <= $firstDmg) {
                $firstDmg = $this->heroSecond->health - 1;
            }
            $this->heroFirst->health -= $secondDmg;
            $this->heroSecond->health -= $firstDmg;
 
            echo $str . "\n";
            if ($this->heroFirst->health == 1) {
                echo "{$this->heroSecond->name} победил \n";
                break;
            }
            if ($this->heroSecond->health == 1) {
                echo "{$this->heroFirst->name} победил \n";
                break;
            }
 
        }
        if ($firstFullDmg > $secondFullDmg) {
            echo $this->heroFirst->name . " побеждает в поединке. \n {$this->heroSecond->name} пал на землю без сил. \n";
        } elseif ($firstFullDmg < $secondFullDmg) {
            echo "{$this->heroSecond->name} побеждает в поединке. \n {$this->heroFirst->name} пал на землю без сил. \n";
        }
        if ($firstFullDmg == $secondFullDmg) {
            echo "Поединок заканчивается ничьей \n.";
        }
    }
 
}
 
$hero1  = new Hero('DoctorS', 504, 563, 19520, 225, 276, 39, 25, 51, 1276);
$hero2  = new Hero('Demarest', 350, 397, 14275, 214, 261, 50, 25, 41, 775);
$hero11 = new Hero('DoctorS', 504, 563, 19520, 225, 276, 39, 25, 51, 1276);
$hero12 = new Hero('BkHitMan', 460, 515, 18919, 216, 264, 31, 23, 28, 1072);
$game   = new Game($hero1, $hero2);
 
$game->makeTwentyRounds();
$game2 = new Game($hero11, $hero12);
 
echo "\n\n\n\n\n";
$game2->makeTwentyRounds();