<?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 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 false;
        }
        return true;
    }
}
class Game
{
    public $firstHero;
    public $secondHero;
    
    public function __construct($hero1, $hero2)
    {
        $this->firstHero  = $hero1;
        $this->secondHero = $hero2;
    }
    public function makeAvoid(Hero $attacker, Hero $target)
    {
        $avoidAttackStat = $target->skill + $target->agility;
        $hitChance       = round($attacker->skill * 100 / $avoidAttackStat);
        if ((mt_rand(1, 100)) < $hitChance) {
            return 1; // коефициент (1 если нет промаха) (уменние / (умение и ловкость врага)) умножается на основной урон
        }
        return 0;
    }
    public function getHit(Hero $attacker, Hero $target) // передача атакер и цели
    {
        $dmg  = $attacker->makeDmg();
        $crit = 1; // коефициент крита умножаемый на основной урон в случае отсутcтвия крита
        if ($attacker->isCrit()) {
            $crit = 2; // -||- в случае крита
        }
        $def       = $target->getDef();
        $block     = 1; // коефициент блока умножаемый на основной урон (в случае отсутствие блока)	       
        $avoidCrit = $target->dodgeCrit;
        if ($target->isBlock()) {
            $block = 0; // -||- в случае успешного блока
        }
        if ($crit == 2 && (mt_rand(1, 100)) < $avoidCrit) // проверка на избежание крита
            {
            $crit = 1;
        }
        $dmg = ($dmg - $def) * $crit * $block * $this->makeAvoid($attacker, $target);
        $target->getDmg($dmg);
    }
    public function isDoubleHit(Hero $attacker, Hero $target) // $k - номер героя (0 либо 1)
    {
        
        if ($attacker->charisma <= $target->charisma) {
            return false; // вернет 0 в случае если у нашего героя меньше либо столько же харизмы как у врага
        }
        $coef = $attacker->charisma - $target->charisma;
        if ((mt_rand(1, 100)) < $coef) {
            return true; // двойная атака
        } else {
            return false;
        }
    }
    
    public function getRound(Hero $attacker, Hero $target)
    {
    	$x = 0;
    	$y = 0;
        if ($this->isDoubleHit($attacker, $target)) {
            $x = 1;
        }
        for ($i = 0; $i <= $x; $i++) {
            $this->getHit($attacker, $target);
            if (!($target->isAlive())) {
                return 1; // вернет 1 если первый убил второго героя
            }
        }
        if ($this->isDoubleHit($target, $attacker)) {
            
            $y = 1;
        }
        for ($i = 0; $i <= $y; $i++) {
            $this->getHit($target, $attacker);
            if (!($attacker->isAlive())) {
                return 2; // вернет 2, если он убил первого героя
            }
        }
        return 3; // вернет 3 в случае если никто не умер               
    }
    public function getGame()
    {
        $first  = clone $this->firstHero;
        $second = clone $this->secondHero;
        for ($i = 1; $i <= 20; $i++) {
            $x = $this->getRound($first, $second);
            if ($x == 1) {
                return 1;
            } elseif ($x == 2) {
                return 2;
            }
        }
        $healthOne = $this->firstHero->health - $first->health;
        $healthTwo = $this->secondHero->health - $second->health;
        if ($healthOne < $healthTwo) {
            return 1; //победа первого 
        } elseif ($healthOne > $healthTwo) {
            return 2; //победа второго
        } elseif ($healthOne == $healthTwo) {
            return 3; //ничья
        }
    }
}

/*
if($_POST['submit'])
{
if ($_POST['dmg1'] > $_POST['dmg2'] || $_POST['armorLow'] > $_POST['armorHigh'] || $_POST['dmg21'] > $_POST['dmg22'] || $_POST['armorLow1'] > $_POST['armorHigh2'])
{
echo "<HTML><HEAD> 
<META HTTP-EQUIV='Refresh' CONTENT='3; URL=http://localhost/php2/lessons/index.html'> 
</HEAD></HTML>"; 
echo "Проверьте правильность заполненных данных";
}	else {
$attackLow1 = (int)$_POST['dmg1']; 
$attackHigh1 = (int)$_POST['dmg2']; 
$hp1 = (int)$_POST['HP'];
$armorLow1 = (int)$_POST['armorLow'];
$armorHigh1 = (int)$_POST['armorHigh'];
$block1 = (int)$_POST['block'];
$dodgeCrit1 = (int)$_POST['critDodge'];
$crit1 = (int)$_POST['crit'];
$charisma1 = (int)$_POST['charisma'];
$agility1 = (int)$_POST['agility'];
$skill1 = (int)$_POST['skill'];

$attackLow2 = (int)$_POST['dmg21']; 
$attackHigh2 = (int)$_POST['dmg22']; 
$hp2 = (int)$_POST['HP2'];
$armorLow2 = (int)$_POST['armorLow2'];
$armorHigh2 = (int)$_POST['armorHigh2'];
$block2 = (int)$_POST['block2'];
$dodgeCrit2 = (int)$_POST['critDodge2'];
$crit2 = (int)$_POST['crit2'];
$charisma2 = (int)$_POST['charisma2'];
$agility2 = (int)$_POST['agility2'];
$skill2 = (int)$_POST['skill2'];
$firstHero = new Hero ($attackLow1, $attackHigh1, $hp1, $armorLow1, $armorHigh1, $block1, $dodgeCrit1, $crit1, $charisma1, $agility1, $skill1);
$secondHero = new Hero  ($attackLow2, $attackHigh2, $hp2, $armorLow2, $armorHigh2, $block2, $dodgeCrit2, $crit2, $charisma2, $agility2, $skill2);
$together = array ($firstHero, $secondHero); 	
$game = new Game ($together);
}
} 
*/

$hero1  = new Hero(504, 563, 11120, 225, 276, 39, 25, 51, 276, 890, 1182);
$hero2  = new Hero(350, 397, 14275, 225, 227, 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 "Вероятность победы: \n Первого героя: ";
echo $first;
echo "%\n Второго героя: ";
echo $second;
echo "%\n Ничья: ";
echo $draw;
echo "%\n";
