<?php
header("Content-Type: text/plain; charset=utf-8");
mb_internal_encoding("UTF-8");
class Hero
{
    public $health;
    public $armorLow;
    public $armorHigh;
    public $block;
    public $dodgeCrit;
    public $crit;
    public $attackLow;
    public $attackHigh;
    public $charisma;
    public $agility;
    public $skill;
    public function __construct($attackLow, $attackHigh, $health, $armorLow, $armorHigh, $block, $dodgeCrit, $crit, $charisma, $agility, $skill)
    {
        $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;
        $this->agility    = $agility;
        $this->skill      = $skill;
    }
    public function __destruct()
    {
        
    }
    
    public function isBlock() //прок блока
    {
        if ((mt_rand(1, 100)) < $this->block) {
            return 1;
        }
        return 0;
    }
    public function isCrit()
    {
        if ((mt_rand(1, 100)) < $this->crit) {
            return 1;
        }
        return 0;
    }
    public function makeDmg()
    {
        return mt_rand($this->attackLow, $this->attackHigh);
    }
    public function getDef()
    {
        return mt_rand($this->armorLow, $this->armorHigh);
    }
    public function getDmg($dmg)
    {
        if ($this->health <= $dmg) {
            $this->health = 1;
        } else {
            $this->health -= $dmg;
        }
    }
    public function isAlive()
    {
        if ($this->health == 1) {
            return 0;
        }
        return 1;
    }
    
}
class Game
{
    public $heroes = array();
    public $cloned = array();
    
    public function __construct($hero1, $hero2)
    {
        $this->heroes[] = $hero1;
        $this->heroes[] = $hero2;
        $this->cloned[] = clone $hero1;
        $this->cloned[] = clone $hero2;
    }
    public function getHit($attacker, $target) // передача атакер и цели
    {
        
        $skill = $attacker->skill;
        $dmg   = $attacker->makeDmg();
        $crit  = 1; // коефициент крита умножаемый на основной урон в случае отстутвия крита
        if ($attacker->isCrit()) {
            $crit = 2; // -||- в случае крита
        }
        
        $def             = $target->getDef();
        $block           = 1; // коефициент блока умножаемый на основной урон (в случае отсутствие блока)				
        $avoidAttackStat = $target->skill + $target->agility;
        $avoidCrit       = $target->dodgeCrit;
        if ($target->isBlock()) {
            $block = 0; // -||- в случае успешного блока
        }
        
        $hitChance = round($skill * 100 / $avoidAttackStat);
        $dodge     = 0;
        if ((mt_rand(1, 100)) < $hitChance) {
            $dodge = 1; // коефициент промаха (уменние / (умение и ловкость врага)) умножается на основной урон
        }
        if ($crit == 2 && (mt_rand(1, 100)) < $avoidCrit) // проверка на избежание крита
            {
            $crit = 1;
            
        }
        $dmg = ($dmg - $def) * $crit * $block * $dodge;
        $target->getDmg($dmg);
        return $target->isAlive(); //вернет 1 если жив, и 0 если мертв
    }
    public function isDoubleHit($attacker, $target) // $k - номер героя (0 либо 1)
    {
        
        if ($attacker->charisma <= $target->charisma) {
            return 0; // вернет 0 в случае если у нашего героя меньше либо столько же харизмы как у врага
        }
        $coef = $attacker->charisma - $target->charisma;
        if ((mt_rand(1, 100)) < $coef) {
            return 1; // двойная атака
        } else {
            return 0;
        }
        
    }
    
    public function getRound()
    {
        $x = 0;
        $y = 0;
        
        foreach ($this->heroes as $number => $hero) {
            if ($number == 0) {
                $firstHero = $hero;
            } else {
                $secondHero = $hero;
            }
        }
        if ($this->isDoubleHit($firstHero, $secondHero)) {
            
            $x = 1;
        }
        for ($i = 0; $i <= $x; $i++) {
            if (!($this->getHit($firstHero, $secondHero))) {
                return 1; // вернет 1 если первый убил второго героя
            }
        }
        
        
        if ($this->isDoubleHit($secondHero, $firstHero)) {
            
            $y = 1;
        }
        for ($i = 0; $i <= $y; $i++) {
            if (!($this->getHit($secondHero, $firstHero))) {
                return 2; // вернет 2, если он убил первого героя
            }
        }
        return 3; // вернет 3 в случае если никто не умер 
        
        
        
    }
    public function getTwentyRounds()
    {
        for ($i = 1; $i <= 20; $i++) {
            $x = $this->getRound();
            
            if ($x == 1) {
                return 1;
            } elseif ($x == 2) {
                return 2;
            }
        }
        $health = array();
        foreach ($this->heroes as $number => $hero) {
            $health[$number] = $this->cloned[$number]->health - $hero->health;
        }
        list($healthOne, $healthTwo) = $health;
        if ($healthOne < $healthTwo) {
            return 1; //победа первого 
        } elseif ($healthOne > $healthTwo) {
            return 2; //победа второго
        } elseif ($healthOne == $healthTwo) {
            return 3; //ничья
        }
    }
    public function getGame()
    {
        
        $x = $this->getTwentyRounds();
        foreach ($this->heroes as $number => $hero) {
            $hero->health = $this->cloned[$number]->health;
        }
        
        return $x;
    }
    
}


$hero1 = new Hero(504, 563, 520, 225, 276, 39, 25, 51, 1276, 890, 1182);
$hero2 = new Hero(350, 397, 14275, 25, 27, 50, 25, 41, 775, 774, 928);
$game  = new Game($hero1, $hero2);


$first  = 0;
$second = 0;
$draw   = 0;
$k      = 1000;
for ($i = 1; $i <= $k; $i++) {
    $win = $game->getGame();
    if ($win == 1) {
        $first++;
    } elseif ($win == 2) {
        $second++;
    } elseif ($win == 3) {
        $draw++;
    }
}

$first  = round((($first * 100) / $k), 2);
$second = round((($second * 100) / $k), 2);
$draw   = round((($draw * 100) / $k), 2);
echo $first;
echo "%\n";
echo $second;
echo "%\n";
echo $draw;
echo "%\n";
