<?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 isChance($attribute) //общая функция для крита и блока
    {
        if ((mt_rand(1, 100)) < $attribute) {
            return 1;
        }
        return 0;
    }
    public function getDmg()
    {
        return mt_rand($this->attackLow, $this->attackHigh);
    }
    public function getDef()
    {
        return mt_rand($this->armorLow, $this->armorHigh);
    }
    
}
class Game
{
    public $heroes = array();
    public $cloned = array();
    public function __construct($hero1, $hero2)
    {
        $this->heroes[] = $hero1;
        $this->heroes[] = $hero2;
        $hero12         = clone $hero1;
        $hero22         = clone $hero2;
        $this->cloned[] = $hero12;
        $this->cloned[] = $hero22;
    }
    public function getHit($k) // $k = 0 либо 1 (номер игрока который наносит урон)
    {
        foreach ($this->heroes as $number => $hero) {
            if ($number == $k) {
                $skill = $hero->skill;
                $dmg   = $hero->getDmg();
                $crit  = 1; // коефициент крита умножаемый на основной урон в случае отстутвия крита
                if ($hero->isChance($hero->crit)) {
                    $crit = 2; // -||- в случае крита
                }
            } else {
                $def             = $hero->getDef();
                $block           = 1; // коефициент блока умножаемый на основной урон (в случае отсутствие блока)				
                $avoidAttackStat = $hero->skill + $hero->agility;
                $avoidCrit       = $hero->dodgeCrit;
                if ($hero->isChance($hero->block)) {
                    $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;
        return $dmg;
    }
    public function isDoubleHit($k) // $k - номер героя (0 либо 1)
    {
        foreach ($this->heroes as $number => $hero) {
            if ($number == $k) {
                $charMain = $hero->charisma;
            } else {
                $charEnemy = $hero->charisma;
            }
            
        }
        if ($charMain < $charEnemy || $charMain == $charEnemy) {
            return 0; // вернет 0 в случае если у нашего героя меньше либо столько же харизмы как у врага
        }
        $coef = $charMain - $charEnemy;
        if ((mt_rand(1, 100)) < $coef) {
            return 1; // двойная атака
        } else {
            return 0;
        }
        
    }
    public function isAlive($k, $dmg) //номер героя (0,1)
    {
        foreach ($this->heroes as $number => $hero) {
            if ($number != $k) {
                if ($hero->health <= $dmg) {
                    $hero->health = 1;
                    return;
                }
                $hero->health -= $dmg;
            }
            
        }
        
    }
    public function getRound()
    {
        for ($i = 0; $i <= 1; $i++) {
            if ($this->isDoubleHit($i)) {
                $dmg = $this->getHit($i) + $this->getHit($i);
            } else {
                $dmg = $this->getHit($i);
            }
            $this->isAlive($i, $dmg);
        }
    }
    public function getGame()
    {
        for ($i = 1; $i <= 20; $i++) {
            $this->getRound();
        }
        $health = array();
        foreach ($this->heroes as $number => $hero) {
            $health[$number] = $this->cloned[$number]->health - $hero->health;
        }
        list($healthOne, $healthTwo) = $health;
        $this->heroes = $this->cloned;
        if ($healthOne < $healthTwo) {
            return 0; //победа первого 
        } elseif ($healthOne > $healthTwo) {
            return 1; //победа второго
        } elseif ($healthOne == $healthTwo) {
            return 2; //ничья
        }
    }
    
}

$hero1  = new Hero(504, 563, 19520, 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);
$k      = 1000;
$first  = 0;
$second = 0;
$draw   = 0;

for ($i = 1; $i <= $k; $i++) {
    $win = $game->getGame();
    if ($win == 0) {
        $first++;
    } elseif ($win == 1) {
        $second++;
    } elseif ($win == 2) {
        $draw++;
    }
}
echo $first;
echo "\n";
echo $second;
echo "\n";
echo $draw;
echo "\n";
$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";