<?php
header("Content-Type: text/plain; charset=utf-8");
mb_internal_encoding("UTF-8");

define('FIRST', '1');
define('SECOND', '2');
define('THIRD', '3');
$phrasesDodge = array(
    FIRST => 'наносит резкий удар, лезвие проходит в дюйме от шеи противника.',
    SECOND => 'делает ложный выпад и наносит неожиданный удар, но удача была в этот раз на стороне врага.',
    THIRD => 'издает победный клич и наносит мощный рубящий удар, цель удара чудом избежала чудовищного удара.'
);





class Hero
{
    public $name;
    public $health;
    public $armorLow;
    public $armorHigh;
    public $block;
    public $dodgeCrit;
    public $crit;
    public $attackLow;
    public $attackHigh;
    public $charisma;
    public $agility;
    public $skill;
    public $hitChance;
    public $doubleHit = 0;
    public $enemyBlock;
    public $enemyArmorLow;
    public $enemyArmorHigh;
    public $enemyName;
    
    public function __construct($name, $attackLow, $attackHigh, $health, $armorLow, $armorHigh, $block, $dodgeCrit, $crit, $charisma, $agility, $skill)
    {
        $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;
        $this->agility    = $agility;
        $this->skill      = $skill;
    }
    public function getAverageDmg() //средний урон персонажа
    {
        return mt_rand($this->attackLow, $this->attackHigh);
    }
    public function getAverageDmgReduction() //среднее число блокируемое доспехами урона
    {
        return mt_rand($this->enemyArmorLow, $this->enemyArmorHigh);
    }
    public function isDoubleAttack()
    {
        $roll = mt_rand(1, 100);
        if ($roll <= $this->doubleHit) {
            return 1;
        } else {
            return 0;
        }
    }
    
}
class Game
{
    public $heroes;
    public function __construct($heroFirst, $heroSecond)
    {
        $this->heroes[] = $heroFirst;
        $this->heroes[] = $heroSecond;
    }
    private function makeRoll()
    {
        return mt_rand(1, 100);
    }
    
    private function makeOneHit($hero) //шанс на удар->блок->крит
    {
        global $phrasesDodge;
        if ($this->makeRoll() > $hero->hitChance) //true = промах
            {
            $roll = mt_rand(1, 3);
            return 0;
        }
        if ($this->makeRoll() < $hero->enemyBlock) //true = атака заблокирована
            {
            return 0;
        }
        if ($this->makeRoll() > $hero->crit) // true = простая атака
            {
            $dmg = $hero->getAverageDmg() - $hero->getAverageDmgReduction();
            return $dmg;
        } else { //крит
            $dmg = $hero->getAverageDmg() * 2 - $hero->getAverageDmgReduction(); //урон х 2 за минусом поглощения
            return $dmg;
        }
        
    }
    private function makeOneRound()
    {
        $damage = array();
        foreach ($this->heroes as $number => $hero) {
            if ($hero->isDoubleAttack()) {
                $k = 2;
            } else {
                $k = 1;
            }
            for ($i = 1; $i <= $k; $i++) {
                $dmg = $this->makeOneHit($hero);
                if (!isset($damage[$number])) {
                    $damage[$number] = 0;
                }
                $damage[$number] += $dmg;
            }
        }
        return $damage;
    }
    
    
    
    private function fillNotFilledStrings() //присвоить героям шанс на вторую атаку и шанс на успешное попадание исходя из разницы в харизме
    {
        $charAbs = abs($this->heroes[0]->charisma - $this->heroes[1]->charisma);
        if ($charAbs > 100) {
            $charAbs = 100;
        }
        $charOne = $this->heroes[0]->charisma;
        $charTwo = $this->heroes[1]->charisma;
        if ($charOne > $charTwo) {
            $this->heroes[0]->doubleHit = $charAbs;
        } elseif ($charOne < $charTwo) {
            $this->heroes[1]->doubleHit = $charAbs;
        }
        // шанс на попадание
        $this->heroes[0]->hitChance      = round(($this->heroes[0]->skill / ($this->heroes[1]->skill + $this->heroes[0]->agility)) * 100);
        $this->heroes[1]->hitChance      = round(($this->heroes[1]->skill / ($this->heroes[0]->skill + $this->heroes[1]->agility)) * 100);
        //заполнение строки enemyBlock
        $this->heroes[0]->enemyBlock     = $this->heroes[1]->block;
        $this->heroes[1]->enemyBlock     = $this->heroes[0]->block;
        //заполнение строки поглощение урона броней
        $this->heroes[0]->enemyArmorLow  = $this->heroes[1]->armorLow;
        $this->heroes[0]->enemyArmorHigh = $this->heroes[1]->armorHigh;
        $this->heroes[1]->enemyArmorLow  = $this->heroes[0]->armorLow;
        $this->heroes[1]->enemyArmorHigh = $this->heroes[0]->armorHigh;
        //строка - имя врага
        $this->heroes[0]->enemyName      = $this->heroes[1]->name;
        $this->heroes[1]->enemyName      = $this->heroes[0]->name;
    }
    
    
    public function makeTwentyRounds()
    {
        $firstFullDmg  = 0;
        $secondFullDmg = 0;
        $this->fillNotFilledStrings();
        $str = str_repeat('_', 42);
        for ($i = 1; $i <= 20; $i++) {
            $dmg = $this->makeOneRound();
            list($firstDamage, $secondDamage) = $dmg;
            if ($this->heroes[0]->health < $secondDamage) {
                $this->heroes[0]->health = 1;
                return 1;
            }
            if ($this->heroes[1]->health < $firstDamage) {
                $this->heroes[1]->health = 1;
                return 0;
            }
            $this->heroes[0]->health -= $secondDamage;
            $this->heroes[1]->health -= $firstDamage;
            $firstFullDmg += $firstDamage;
            $secondFullDmg += $secondDamage;
        }
        if ($firstFullDmg > $secondFullDmg) {
            return 0;
        } elseif ($firstFullDmg < $secondFullDmg) {
            return 1;
        } else {
            return 2;
        }
        
    }
}
$hero1  = new Hero('DoctorS', 504, 563, 19520, 225, 276, 39, 25, 51, 1276, 890, 1182);
$hero2  = new Hero('Demarest', 350, 397, 14275, 214, 261, 50, 25, 41, 775, 774, 928);
/*
$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);
$game2 = new Game($hero11, $hero12);

echo "\n\n\n\n\n";
$game2->makeTwentyRounds(); 
$game->makeTwentyRounds();*/
$game   = new Game($hero1, $hero2);
$winOne = 0;
$winTwo = 0;
$draw   = 0;
$k      = 10000;
for ($i = 1; $i <= $k; $i++) {
    $x = $game->makeTwentyRounds();
    if ($x == 0) {
        $winOne++;
    } elseif ($x == 1) {
        $winTwo++;
    } elseif ($x == 2) {
        $draw++;
    }
}
$chanceFirstWin  = round(($winOne / $k) * 100);
$chanceSecondWin = round(($winTwo / $k) * 100);
$chanceDraw      = round(($draw / $k) * 100);
echo "Winner: \n $chanceFirstWin%- first, $chanceSecondWin%- second, $chanceDraw% - draw";








