fork download
  1. <?php
  2. header("Content-Type: text/plain; charset=utf-8");
  3.  
  4. define('FIRST', '1');
  5. define('SECOND', '2');
  6. define('THIRD', '3');
  7. $phrasesDodge = array(
  8. FIRST => 'наносит резкий удар, лезвие проходит в дюйме от шеи противника.',
  9. SECOND => 'делает ложный выпад и наносит неожиданный удар, но удача была в этот раз на стороне врага.',
  10. THIRD => 'издает победный клич и наносит мощный рубящий удар, цель удара чудом избежала чудовищного удара.'
  11. );
  12.  
  13.  
  14.  
  15.  
  16.  
  17. class Hero
  18. {
  19. public $name;
  20. public $health;
  21. public $armorLow;
  22. public $armorHigh;
  23. public $block;
  24. public $dodgeCrit;
  25. public $crit;
  26. public $attackLow;
  27. public $attackHigh;
  28. public $charisma;
  29. public $agility;
  30. public $skill;
  31. public $hitChance;
  32. public $doubleHit = 0;
  33. public $enemyBlock;
  34. public $enemyArmorLow;
  35. public $enemyArmorHigh;
  36. public $enemyName;
  37.  
  38. public function __construct($name, $attackLow, $attackHigh, $health, $armorLow, $armorHigh, $block, $dodgeCrit, $crit, $charisma, $agility, $skill)
  39. {
  40. $this->name = $name;
  41. $this->attackLow = $attackLow;
  42. $this->attackHigh = $attackHigh;
  43. $this->health = $health;
  44. $this->armorLow = $armorLow;
  45. $this->armorHigh = $armorHigh;
  46. $this->block = $block;
  47. $this->dodgeCrit = $dodgeCrit;
  48. $this->crit = $crit;
  49. $this->charisma = $charisma;
  50. $this->agility = $agility;
  51. $this->skill = $skill;
  52. }
  53. public function getAverageDmg() //средний урон персонажа
  54. {
  55. return mt_rand($this->attackLow, $this->attackHigh);
  56. }
  57. public function getAverageDmgReduction() //среднее число блокируемое доспехами урона
  58. {
  59. return mt_rand($this->enemyArmorLow, $this->enemyArmorHigh);
  60. }
  61. public function isDoubleAttack()
  62. {
  63. $roll = mt_rand(1, 100);
  64. if ($roll <= $this->doubleHit) {
  65. return 1;
  66. } else {
  67. return 0;
  68. }
  69. }
  70.  
  71. }
  72. class Game
  73. {
  74. public $heroes;
  75. public function __construct($heroFirst, $heroSecond)
  76. {
  77. $this->heroes[] = $heroFirst;
  78. $this->heroes[] = $heroSecond;
  79. }
  80. private function makeRoll()
  81. {
  82. return mt_rand(1, 100);
  83. }
  84.  
  85. private function makeOneHit($hero) //шанс на удар->блок->крит
  86. {
  87. global $phrasesDodge;
  88. if ($this->makeRoll() > $hero->hitChance) //true = промах
  89. {
  90. $roll = mt_rand(1, 3);
  91. return 0;
  92. }
  93. if ($this->makeRoll() < $hero->enemyBlock) //true = атака заблокирована
  94. {
  95. return 0;
  96. }
  97. if ($this->makeRoll() > $hero->crit) // true = простая атака
  98. {
  99. $dmg = $hero->getAverageDmg() - $hero->getAverageDmgReduction();
  100. return $dmg;
  101. } else { //крит
  102. $dmg = $hero->getAverageDmg() * 2 - $hero->getAverageDmgReduction(); //урон х 2 за минусом поглощения
  103. return $dmg;
  104. }
  105.  
  106. }
  107. private function makeOneRound()
  108. {
  109. $damage = array();
  110. foreach ($this->heroes as $number => $hero) {
  111. if ($hero->isDoubleAttack()) {
  112. $k = 2;
  113. } else {
  114. $k = 1;
  115. }
  116. for ($i = 1; $i <= $k; $i++) {
  117. $dmg = $this->makeOneHit($hero);
  118. if (!isset($damage[$number])) {
  119. $damage[$number] = 0;
  120. }
  121. $damage[$number] += $dmg;
  122. }
  123. }
  124. return $damage;
  125. }
  126.  
  127.  
  128.  
  129. private function fillNotFilledStrings() //присвоить героям шанс на вторую атаку и шанс на успешное попадание исходя из разницы в харизме
  130. {
  131. $charAbs = abs($this->heroes[0]->charisma - $this->heroes[1]->charisma);
  132. if ($charAbs > 100) {
  133. $charAbs = 100;
  134. }
  135. $charOne = $this->heroes[0]->charisma;
  136. $charTwo = $this->heroes[1]->charisma;
  137. if ($charOne > $charTwo) {
  138. $this->heroes[0]->doubleHit = $charAbs;
  139. } elseif ($charOne < $charTwo) {
  140. $this->heroes[1]->doubleHit = $charAbs;
  141. }
  142. // шанс на попадание
  143. $this->heroes[0]->hitChance = round(($this->heroes[0]->skill / ($this->heroes[1]->skill + $this->heroes[0]->agility)) * 100);
  144. $this->heroes[1]->hitChance = round(($this->heroes[1]->skill / ($this->heroes[0]->skill + $this->heroes[1]->agility)) * 100);
  145. //заполнение строки enemyBlock
  146. $this->heroes[0]->enemyBlock = $this->heroes[1]->block;
  147. $this->heroes[1]->enemyBlock = $this->heroes[0]->block;
  148. //заполнение строки поглощение урона броней
  149. $this->heroes[0]->enemyArmorLow = $this->heroes[1]->armorLow;
  150. $this->heroes[0]->enemyArmorHigh = $this->heroes[1]->armorHigh;
  151. $this->heroes[1]->enemyArmorLow = $this->heroes[0]->armorLow;
  152. $this->heroes[1]->enemyArmorHigh = $this->heroes[0]->armorHigh;
  153. //строка - имя врага
  154. $this->heroes[0]->enemyName = $this->heroes[1]->name;
  155. $this->heroes[1]->enemyName = $this->heroes[0]->name;
  156. }
  157.  
  158.  
  159. public function makeTwentyRounds()
  160. {
  161. $firstFullDmg = 0;
  162. $secondFullDmg = 0;
  163. $this->fillNotFilledStrings();
  164. $str = str_repeat('_', 42);
  165. for ($i = 1; $i <= 20; $i++) {
  166. $dmg = $this->makeOneRound();
  167. list($firstDamage, $secondDamage) = $dmg;
  168. if ($this->heroes[0]->health < $secondDamage) {
  169. $this->heroes[0]->health = 1;
  170. return 1;
  171. }
  172. if ($this->heroes[1]->health < $firstDamage) {
  173. $this->heroes[1]->health = 1;
  174. return 0;
  175. }
  176. $this->heroes[0]->health -= $secondDamage;
  177. $this->heroes[1]->health -= $firstDamage;
  178. $firstFullDmg += $firstDamage;
  179. $secondFullDmg += $secondDamage;
  180. }
  181. if ($firstFullDmg > $secondFullDmg) {
  182. return 0;
  183. } elseif ($firstFullDmg < $secondFullDmg) {
  184. return 1;
  185. } else {
  186. return 2;
  187. }
  188.  
  189. }
  190. }
  191. $hero1 = new Hero('DoctorS', 504, 563, 19520, 225, 276, 39, 25, 51, 1276, 890, 1182);
  192. $hero2 = new Hero('Demarest', 350, 397, 14275, 214, 261, 50, 25, 41, 775, 774, 928);
  193. /*
  194. $hero11 = new Hero('DoctorS', 504, 563, 19520, 225, 276, 39, 25, 51, 1276);
  195. $hero12 = new Hero('BkHitMan', 460, 515, 18919, 216, 264, 31, 23, 28, 1072);
  196. $game2 = new Game($hero11, $hero12);
  197.  
  198. echo "\n\n\n\n\n";
  199. $game2->makeTwentyRounds();
  200. $game->makeTwentyRounds();*/
  201. $game = new Game($hero1, $hero2);
  202. $winOne = 0;
  203. $winTwo = 0;
  204. $draw = 0;
  205. $k = 10000;
  206. for ($i = 1; $i <= $k; $i++) {
  207. $x = $game->makeTwentyRounds();
  208. if ($x == 0) {
  209. $winOne++;
  210. } elseif ($x == 1) {
  211. $winTwo++;
  212. } elseif ($x == 2) {
  213. $draw++;
  214. }
  215. }
  216. $chanceFirstWin = round(($winOne / $k) * 100);
  217. $chanceSecondWin = round(($winTwo / $k) * 100);
  218. $chanceDraw = round(($draw / $k) * 100);
  219. echo "Winner: \n $chanceFirstWin%- first, $chanceSecondWin%- second, $chanceDraw% - draw";
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
Success #stdin #stdout 0.28s 24400KB
stdin
Standard input is empty
stdout
Winner: 
 59%- first, 41%- second, 0% - draw