fork download
  1. <?php
  2. header("Content-Type: text/plain");
  3.  
  4. // ООП. Кошки - мышки
  5.  
  6. // Константы
  7. const cat = 'Cat';
  8. const mouse = 'Mouse';
  9.  
  10. // Класс Животного (игрока)
  11. abstract class Animal
  12. {
  13. // Координаты ХY
  14. protected $xy = array();
  15.  
  16. // Кол-во пропускаемых ходов
  17. protected $restingTime = 0;
  18.  
  19. // Hp
  20. protected $hp = 100;
  21.  
  22. // Генератор животного
  23. public function __construct($x, $y)
  24. {
  25. $this->xy['x'] = $x;
  26. $this->xy['y'] = $y;
  27. }
  28.  
  29. // Выбор наилучшего ВариантаХода (большего веса)
  30. public function chooseBestMoveVariant($moveVariants)
  31. {
  32. // Сортировка ВариантовХода по убыванию веса
  33. usort ($moveVariants,
  34. function ($moveVariantA, $moveVariantB ) {
  35. $weightA = $moveVariantA->getWeight();
  36. $weightB = $moveVariantB->getWeight();
  37. if ($weightA==$weightB) return 0;
  38. return ($weightA<$weightB) ? 1 : -1;
  39. });
  40. return $moveVariants[0];
  41. }
  42.  
  43. // Возвращает координаты
  44. public function getXY()
  45. {
  46. return $this->xy;
  47. }
  48. // Установка координат
  49. public function setXY($xy)
  50. {
  51. $this->xy['x'] = $xy['x'];
  52. $this->xy['y'] = $xy['y'];
  53. }
  54. // Возвращает время отдыха
  55. public function getRestingTime()
  56. {
  57. return $this->restingTime;
  58. }
  59. // Возвращает время отдыха
  60. public function setRestingTime($moveQuantity)
  61. {
  62. $this->restingTime = $moveQuantity;
  63. }
  64. // Возвращает время отдыха
  65. public function getHP()
  66. {
  67. return $this->hp;
  68. }
  69. // Игровой ход
  70. abstract function move($animals, $moveVariants);
  71.  
  72. // Скорость перемещения (клеток за ход)
  73. abstract function getSpeed();
  74.  
  75. // Возможность ходить по горизонт, вертикали, диагонали
  76. //abstract function getMoveAbility();
  77.  
  78. // Область видимости вокруг себя
  79. abstract function getVisionLimits();
  80.  
  81. // Оценка ходов
  82. abstract function setRating($animals, $moveVariants);
  83.  
  84. // Исключение занятых ходов
  85. abstract function excludingNonEmptyMove($animals, $moveVariants);
  86.  
  87. // Убийство
  88. public function kill ()
  89. {
  90. $this->hp = 0;
  91. }
  92. }
  93.  
  94. class Mouse extends Animal
  95. {
  96. // Скорость перемещения (клеток за ход)
  97. public function getSpeed()
  98. {
  99. return 1;
  100. }
  101.  
  102. // Область видимости вокруг себя
  103. public function getVisionLimits()
  104. {
  105. return 4;
  106. }
  107. // Игровой ход
  108. public function move($animals, $moveVariants)
  109. {
  110. // Исключение занятых ходов
  111. $moveVariants = $this->excludingNonEmptyMove($animals, $moveVariants);
  112. // Исключения вариантов хода по вертикали
  113. $moveVariants = $this->exlusionVerticalMove($moveVariants);
  114. // Оценка ходов
  115. $this->setRating($animals, $moveVariants);
  116. // Выбор наилучшего хода (наибольший вес)
  117. $bestMoveVariant = $this->chooseBestMoveVariant($moveVariants);
  118. // Ход
  119. $this->setXY($bestMoveVariant->getXY());
  120.  
  121. }
  122.  
  123. // Оценка ходов
  124. public function setRating($animals, $moveVariants)
  125. {
  126. // Присваиваем вес
  127. foreach ($moveVariants as $moveVariant)
  128. {
  129. $moveVariant->setWeight(rand(0,10));
  130. }
  131. }
  132.  
  133. // Метод исключения вариантов хода по вертикали
  134. public function exlusionVerticalMove($moveVariants) {
  135.  
  136. // У вертикальных ходов координаты X Y равны по модулю, относительно текщего положения животного
  137. foreach ($moveVariants as $key => $moveVariant) {
  138. $moveVariantXY=$moveVariant->getXY();
  139. // Исключаем из проверки ход на котором стоим
  140. //echo "an x: {$this->xy['x']} y: {$this->xy['y']}\n";
  141. //echo "mv x: {$moveVariantXY['x']} y: {$moveVariantXY['y']}\n";
  142. if ($moveVariantXY['x'] == $this->xy['x'] &&
  143. $moveVariantXY['y'] == $this->xy['y']) continue;
  144. // Проверяем остальные
  145. if (abs($moveVariantXY['x']-$this->xy['x'])==abs($moveVariantXY['y']-$this->xy['y'])) {
  146. unset($moveVariants[$key]);
  147. }
  148. }
  149. return $moveVariants;
  150. }
  151. // Исключение занятых ходов
  152. public function excludingNonEmptyMove($animals, $moveVariants)
  153. {
  154. foreach ($moveVariants as $key => $moveVariant) {
  155. $moveVariantXY=$moveVariant->getXY();
  156. foreach ($animals as $animal) {
  157. $animalXY=$animal->getXY();
  158. // Исключаем из проверки ход на котором стоим
  159. if ($animalXY['x'] == $this->xy['x'] &&
  160. $animalXY['y'] == $this->xy['y']) continue;
  161. // Проверяем остальные
  162. if ($moveVariantXY['x']==$animalXY['x'] &&
  163. $moveVariantXY['y']==$animalXY['y']) {
  164. unset ($moveVariants[$key]);
  165. }
  166. }
  167. }
  168. return $moveVariants;
  169. }
  170. }
  171. class Cat extends Animal
  172. {
  173. // Скорость перемещения (клеток за ход)
  174. public function getSpeed()
  175. {
  176. return 1;
  177. }
  178.  
  179. // Возможность ходить по горизонт, вертикали, диагонали
  180. public function getMoveAbility()
  181. {
  182. return array(true, true, true);
  183. }
  184. // Область видимости вокруг себя
  185. public function getVisionLimits()
  186. {
  187. return null;
  188. }
  189.  
  190.  
  191. // Игровой ход
  192. public function move($animals, $moveVariants)
  193. {
  194. // Проверка кол-ва пропускаемых ходов
  195. if ($this->getRestingTime()>0 ) {
  196. // Уменьшаем счетчик пропускаемых ходов
  197. $this->setRestingTime($this->getRestingTime()-1);
  198. return;
  199. }
  200. if ($this->getRestingTime() > 0)
  201. // Исключение занятых ходов
  202. $moveVariants = $this->excludingNonEmptyMove($animals, $moveVariants);
  203. // Оценка ходов
  204. $this->setRating($animals, $moveVariants);
  205. // Выбор наилучшего хода (наибольший вес)
  206. $bestMoveVariant = $this->chooseBestMoveVariant($moveVariants);
  207. // Проверка съедания мыши
  208. $eatenMouse = $this->checkEatenMouse($animals, $bestMoveVariant);
  209. if ($eatenMouse) $this->eatMouse($eatenMouse);
  210. // Ход
  211. $this->setXY($bestMoveVariant->getXY());
  212.  
  213. }
  214.  
  215. // Оценка ходов
  216. public function setRating($animals, $moveVariants)
  217. {
  218. // Находим всех мышей
  219. $mouses = array_filter($animals,
  220. function ($animal) {
  221. return (get_class($animal) == mouse);
  222. });
  223. foreach ($moveVariants as $moveVariant)
  224. {
  225. $moveVariant->setWeight(rand(0,10));
  226.  
  227. // Если в клетке мышка, то такой ход +10 баллов
  228. foreach ($mouses as $mouse) {
  229. $mouseXY = $mouse->getXY();
  230. $moveVariantXY = $moveVariant->getXY();
  231.  
  232. if ($mouseXY['x']==$moveVariantXY['x'] &&
  233. $mouseXY['y']==$moveVariantXY['y']) {
  234. $moveVariant->setWeight(100); //$moveVariant->getWeight() + 10
  235. }
  236. }
  237. }
  238. }
  239. // Исключение занятых ходов
  240. public function excludingNonEmptyMove($animals, $moveVariants)
  241. {
  242. foreach ($moveVariants as $key => $moveVariant) {
  243. $moveVariantXY=$moveVariant->getXY();
  244. // Исключаем только кошек
  245. $cats = array_filter($animals,
  246. function ($animal) {
  247. return (get_class($animal) == cat);
  248. });
  249. foreach ($cats as $cat) {
  250. $catXY=$cat->getXY();
  251. // Исключаем из проверки ход на котором стоим
  252. if ($catXY['x'] == $this->xy['x'] &&
  253. $catXY['y'] == $this->xy['y']) continue;
  254. // Проверяем остальные
  255. if ($moveVariantXY['x']==$catXY['x'] &&
  256. $moveVariantXY['y']==$catXY['y']) {
  257. unset ($moveVariants[$key]);
  258. }
  259. }
  260. }
  261. return $moveVariants;
  262. }
  263. // Проверка съедания мыши
  264. public function checkEatenMouse($animals, $bestMoveVariant)
  265. {
  266. $moveVariantXY=$bestMoveVariant->getXY();
  267. // Исключаем только кошек
  268. $mouses = array_filter($animals,
  269. function ($animal) {
  270. return (get_class($animal) == mouse);
  271. });
  272. foreach ($mouses as $mouse) {
  273. $mouseXY = $mouse->getXY();
  274. if ($mouseXY['x'] == $moveVariantXY['x'] &&
  275. $mouseXY['y'] == $moveVariantXY['y']) {
  276. return $mouse;
  277. }
  278. }
  279. }
  280.  
  281. // Поедание мыши
  282. public function eatMouse ($mouse)
  283. {
  284. $mouse->kill();
  285. $this->setRestingTime(2);
  286. }
  287. }
  288.  
  289. // Класс Животные (Игроки)
  290. class Animals
  291. {
  292. private $animals = array();
  293.  
  294. public function __construct ($mousesQuantity, $catsQuantity)
  295. {
  296. // Создание мышей
  297. for ($mousesQuantity; $mousesQuantity > 0; $mousesQuantity--) {
  298. // Генераруем случайные координаты
  299. $xy = $this->newCoordinat();
  300. $this->animals[] = new Mouse($xy['x'], $xy['y']);
  301. }
  302. // Создание кошек
  303. for ($catsQuantity; $catsQuantity > 0; $catsQuantity--) {
  304. $xy = $this->newCoordinat();
  305. $this->animals[] = new Cat($xy['x'], $xy['y']);
  306. }
  307. }
  308. public function __clone()
  309. {
  310. $animalsClones = array();
  311.  
  312. foreach ($this->animals as $animal) {
  313. $animalsClones[] = clone $animal;
  314. }
  315. // Заменяем массив животных массивом клонов
  316. $this->animals = $animalsClones;
  317. }
  318.  
  319. // Запуск цикла ходов для всех животных
  320. public function move()
  321. {
  322. foreach ($this->animals as $animal) {
  323. // Генерация всех возможных ВариантовХода
  324. $moveVariants = fabricMoveVariants::createMoveVariants($animal);
  325. $animal->move($this->animals, $moveVariants);
  326. }
  327. // Чистка убитых животных
  328. $this->cleanUpDeadAnimals();
  329. }
  330.  
  331. // Убираем с поля убитых животных
  332. private function cleanUpDeadAnimals()
  333. {
  334. $liveAnimal = array_filter($this->animals,
  335. function ($animal) {
  336. return ($animal->getHp()>0);
  337. });
  338. $this->animals = $liveAnimal;
  339. }
  340.  
  341. // Функция генерации координат
  342. private function newCoordinat()
  343. {
  344. $xy = array();
  345. $xy['x'] = rand(1, fieldSize);
  346. $xy['y'] = rand(1, fieldSize);
  347.  
  348. return $xy;
  349. }
  350. // Уничтожение животного
  351. public function killAnimal($killingAnimal)
  352. {
  353. foreach ($animals as $key => $animal) {
  354. if ($animal === $killingAnimal) unset ($animals[$key]);
  355. }
  356. }
  357.  
  358. public function getAnimalsAsArray ()
  359. {
  360. return $this->animals;
  361. }
  362. }
  363.  
  364. // Фабрика Вариантов хода
  365. class fabricMoveVariants {
  366.  
  367. static public function createMoveVariants ($animal)
  368. {
  369. // Создание новых ВариантовХода
  370. $moveVariants = array();
  371. $animalXY = $animal->getXY();
  372. $animalSpeed = $animal->getSpeed();
  373.  
  374. // Координаты начала (верхний левый угол)
  375. $animalSpeed = $animal->getSpeed();
  376. do {
  377. $start['x'] = $animalXY['x']-$animalSpeed;
  378. $animalSpeed--;
  379. } while ($start['x']<=0);
  380.  
  381. $animalSpeed = $animal->getSpeed();
  382. do {
  383. $start['y'] = $animalXY['y']-$animalSpeed;
  384. $animalSpeed--;
  385. } while ($start['y']<=0);
  386. // Координаты конца (нижний правый угол)
  387. $animalSpeed = $animal->getSpeed();
  388. do {
  389. $end['x'] = $animalXY['x']+$animalSpeed;
  390. $animalSpeed--;
  391. } while ($end['x']>fieldSize);
  392.  
  393. $animalSpeed = $animal->getSpeed();
  394. do {
  395. $end['y'] = $animalXY['y']+$animalSpeed;
  396. $animalSpeed--;
  397. } while ($end['y']>fieldSize);
  398.  
  399. // Генерация ходов
  400. $y = $start['y'];
  401. while ($y<=$end['y']) {
  402. $x = $start['x'];
  403. while ($x<=$end['x']) {
  404. $moveVariants[] = new MoveVariant($x, $y);
  405. $x++;
  406. }
  407. $y++;
  408. }
  409. return $moveVariants;
  410. }
  411. }
  412.  
  413. // Класс ВариантХода
  414. class MoveVariant
  415. {
  416. // Координаты
  417. private $xy = array();
  418. // Вес
  419. private $weight=0;
  420.  
  421. public function __construct ($moveX, $moveY)
  422. {
  423. $this->xy['x'] = $moveX;
  424. $this->xy['y'] = $moveY;
  425. }
  426.  
  427. // Возвращает координаты
  428. public function getXY()
  429. {
  430. return $this->xy;
  431. }
  432. public function setWeight($weight)
  433. {
  434. $this->weight = $weight;
  435. }
  436. public function getWeight()
  437. {
  438. return $this->weight;
  439. }
  440. }
  441.  
  442. // Кдасс ИгровойРаунд
  443. class GameRaund
  444. {
  445. private $animals; // Объект Животные
  446. private $raundNum; // Номер раунда
  447.  
  448. public function __construct ($animals)
  449. {
  450. $this->animals = clone $animals;
  451. }
  452. // Представление раунда в виде псевдографики (массива строк)
  453. public function getGameRoundAsGraphics()
  454. {
  455. $gameField = array(); // поле игры, содержит строки из клеток
  456. $fieldSize = fieldSize;
  457. // Массив аватаров Животных
  458. $avatars = array(0 => 'm', 1 => 'K');
  459.  
  460. // Формируем поле из точек
  461. // Повторяем для каждой строки
  462. for ($fieldSize; $fieldSize>0; $fieldSize--) {
  463. // Заполняем строку "."
  464. $str = str_repeat(".", fieldSize);
  465. // Добавляем строку в массив
  466. $gameField[] = $str;
  467. }
  468. // Получаем всех Жиаотных массивом
  469. $animals = $this->animals->getAnimalsAsArray();
  470.  
  471. // Проходим по массиву животных
  472. foreach ($animals as $key => $animal) {
  473. // Узнаем координаты каждого персонажа
  474. $xy = $animal->getXY();
  475.  
  476. // Заменяем соответствующую точку в соответствующей строке индексом мышки
  477. $str = $gameField[$xy['y']-1];
  478. // Мышь обозначаем носером
  479. if (get_class($animal)==mouse) {
  480. $str = substr_replace($str, $key+1, $xy['x']-1, 1);
  481. } else {
  482. // Кошку буквой "K" или "@" если спит
  483. if ($animal->getRestingTime()>0) {
  484. $str = substr_replace($str, "@", $xy['x']-1, 1);
  485. } else {
  486. $str = substr_replace($str, "K", $xy['x']-1, 1);
  487. }
  488.  
  489. }
  490. $gameField[$xy['y']-1] = $str;
  491. }
  492. /*
  493.   // Добавляем инфу
  494.   foreach ($animals as $key => $animal) {
  495.   $xy = $animal->getXY();
  496.   $str = $gameField[$key] . " мышь: " . $key . " x: " . $xy['x'] . " y: " . $xy['y'];
  497.   $gameField[$key] = $str;
  498.   }*/
  499.  
  500. return $gameField;
  501. }
  502.  
  503. public function getAnimals ()
  504. {
  505. return $this->animals;
  506. }
  507. }
  508.  
  509. // Класс ГеймСет (Игра)
  510. class GameSet
  511. {
  512. private $raunds = array();
  513. private $animals;
  514.  
  515. public function __construct ($mousesQuantity, $catsQuantity)
  516. {
  517. $this->animals = new Animals ($mousesQuantity, $catsQuantity);
  518. // Начальный раунд (раунд: 0)
  519. $this->raunds[] = new GameRaund($this->animals);
  520. }
  521.  
  522. // Новый игровой раунд
  523. public function newRaund($raundNum)
  524. {
  525. // Ход животных
  526. $this->animals->move();
  527. // Новый раунд номер $raundNum
  528. $this->raunds[] = new GameRaund($this->animals);
  529. }
  530.  
  531. // Печать раунда
  532. public function printGameRound($raundNum)
  533. {
  534. // Получаем раунд в виде псевдографики (массива строк)
  535. $printingRaund = $this->raunds[$raundNum]->getGameRoundAsGraphics();
  536. // Узнаем че по кошкам (мышам)
  537. $animals = $this->raunds[$raundNum]->getAnimals()->getAnimalsAsArray();
  538. $cats = array_filter($animals,
  539. function ($animal) {
  540. return (get_class($animal) == cat);
  541. });
  542. $mouses = array_filter($animals,
  543. function ($animal) {
  544. return (get_class($animal) == mouse);
  545. });
  546. $catsNum = count($cats);
  547. $mousesNum = count($mouses);
  548.  
  549. // Выводим на экран массив построчно
  550. foreach ($printingRaund as $key => $str) {
  551. if ($key == 0) {
  552. echo $str . " " . "Ход: " . "{$raundNum}\n";
  553. } else if ($key == 1) {
  554. echo $str . " " . "Кошек: " . "$catsNum\n";
  555. } else if ($key == 2) {
  556. echo $str . " " . "Мышек: " . "$mousesNum\n";
  557. } else {
  558. echo "{$str}\n";
  559. }
  560. }
  561. echo "\n";
  562. }
  563.  
  564. public function getRaund($raundNum)
  565. {
  566. return $this->raunds[$raundNum];
  567. }
  568. }
  569.  
  570. // Создание новой игры
  571. function createNewGame ()
  572. {
  573. // Вводные данные для создания новой игры
  574. $raundsQuantity = 20;
  575. $mousesQuantity = 4;
  576. $catsQuantity = 2;
  577. $fieldSize = 19;
  578.  
  579. define('fieldSize', $fieldSize);
  580.  
  581. // Создание новой игры (раунд: 0)
  582. $gameSet= new GameSet($mousesQuantity, $catsQuantity);
  583. // Вывести раунд на печать
  584. $gameSet->printGameRound(0);
  585.  
  586. // Цикл раундов (начиная с первого)
  587. for ($raundNum=1; $raundNum<=$raundsQuantity; $raundNum++) {
  588. // Новый раунд
  589. $gameSet->newRaund($raundNum);
  590. // Вывести раунд на печатьs
  591. $gameSet->printGameRound($raundNum);;
  592. }
  593. }
  594. createNewGame();
  595. ?>
Success #stdin #stdout 0.04s 52432KB
stdin
Standard input is empty
stdout
...................    Ход: 0
.3.................    Кошек: 2
...................    Мышек: 4
...................
...................
....K..............
............4......
...................
...................
...................
...................
...................
.........K.........
...................
...................
...................
...................
1....2.............
...................

...................    Ход: 1
.3.................    Кошек: 2
...................    Мышек: 4
...................
...................
...................
....K......4.......
...................
...................
...................
...................
.........K.........
...................
...................
...................
...................
1....2.............
...................
...................

...................    Ход: 2
3..................    Кошек: 2
...................    Мышек: 4
...................
...................
...................
..........4........
...K...............
...................
...................
...................
...................
..........K........
...................
...................
...................
1..................
.....2.............
...................

3..................    Ход: 3
...................    Кошек: 2
...................    Мышек: 4
...................
...................
...................
..K......4.........
...................
...................
...................
...................
...................
...................
.........K.........
...................
...................
.1...2.............
...................
...................

.3.................    Ход: 4
...................    Кошек: 2
...................    Мышек: 4
...................
...................
.........4.........
...................
..K................
...................
...................
...................
...................
...................
.........K.........
...................
.....2.............
..1................
...................
...................

3..................    Ход: 5
...................    Кошек: 2
...................    Мышек: 4
...................
...................
.........4.........
...................
..K................
...................
...................
...................
...................
..........K........
...................
...................
..1.2..............
...................
...................
...................

...................    Ход: 6
3..................    Кошек: 2
...................    Мышек: 4
...................
...................
..........4........
...................
.K.................
...................
...................
...................
.........K.........
...................
...................
..1................
....2..............
...................
...................
...................

...................    Ход: 7
...................    Кошек: 2
3..................    Мышек: 4
...................
...................
..........4........
..K................
...................
...................
...................
.........K.........
...................
...................
...................
.1..2..............
...................
...................
...................
...................

...................    Ход: 8
...................    Кошек: 2
3..................    Мышек: 4
...................
...................
..K......4.........
...................
...................
...................
........K..........
...................
...................
...................
....2..............
1..................
...................
...................
...................
...................

...................    Ход: 9
...................    Кошек: 2
.3.................    Мышек: 4
...................
...................
...................
..K......4.........
...................
...................
.........K.........
...................
...................
...................
...2...............
.1.................
...................
...................
...................
...................

...................    Ход: 10
.3.................    Кошек: 2
...................    Мышек: 4
...................
...................
...................
........4..........
...K...............
...................
........K..........
...................
...................
...................
...................
..12...............
...................
...................
...................
...................

...................    Ход: 11
3..................    Кошек: 2
...................    Мышек: 4
...................
...................
...................
..K......4.........
...................
...................
.......K...........
...................
...................
...................
...................
.1.................
...2...............
...................
...................
...................

3..................    Ход: 12
...................    Кошек: 2
...................    Мышек: 4
...................
...................
..K......4.........
...................
...................
...................
........K..........
...................
...................
...................
.1.................
...................
..2................
...................
...................
...................

3..................    Ход: 13
...................    Кошек: 2
...................    Мышек: 4
...................
.........4.........
.K.................
...................
...................
...................
.......K...........
...................
...................
...................
.1.................
...................
.2.................
...................
...................
...................

.3.................    Ход: 14
...................    Кошек: 2
...................    Мышек: 4
...................
...................
.........4.........
..K................
...................
......K............
...................
...................
...................
.1.................
...................
.2.................
...................
...................
...................
...................

.3.................    Ход: 15
...................    Кошек: 2
...................    Мышек: 4
...................
.........4.........
...................
...K...............
.......K...........
...................
...................
...................
.1.................
...................
...................
.2.................
...................
...................
...................
...................

3..................    Ход: 16
...................    Кошек: 2
...................    Мышек: 4
...................
.........4.........
...................
..K................
...................
.......K...........
...................
...................
...................
.1.................
...................
...................
.2.................
...................
...................
...................

...................    Ход: 17
3..................    Кошек: 2
...................    Мышек: 4
...................
.........4.........
...................
...K...............
...................
...................
........K..........
...................
.1.................
...................
...................
...................
...................
.2.................
...................
...................

...................    Ход: 18
.3.................    Кошек: 2
...................    Мышек: 4
...................
...................
.........4.........
..K................
...................
...................
...................
.......K...........
.1.................
...................
...................
...................
...................
..2................
...................
...................

...................    Ход: 19
.3.................    Кошек: 2
...................    Мышек: 4
...................
...................
...................
...K.....4.........
...................
...................
...................
......K............
..1................
...................
...................
...................
...................
...2...............
...................
...................

...................    Ход: 20
3..................    Кошек: 2
...................    Мышек: 4
...................
...................
..K................
..........4........
...................
...................
...................
.......K...........
...1...............
...................
...................
...................
...................
...2...............
...................
...................