<?php

abstract class Animal
{
    protected $symbol; //символ на карте
    protected $x;      //координата
    protected $y;      //координата
    protected $name;   //имя животного
    protected $field;  //карта класса Field
    protected $vision; //дальность обзора

    abstract protected function tryToMove();

    //Методы получения к защищенным свойствам для других классов
    public function getX()
    {
        return $this->x;
    }

    public function getY()
    {
        return $this->y;
    }

    //Методы установки защищенных свойств
    public function setX($x)
    {
        $this->x = $x;
    }

    public function setY($y)
    {
        $this->y = $y;
    }

    public function setField(Field $field)
    {
        $this->field = $field;
    }

    //Называем животное
    public function __construct($name)
    {
        $this->name = $name;
    }

    //Метод возвращения символа для вывода на карте
    public function getSymbol()
    {
        return $this->symbol;
    }

    //Метод передвижения в определенную координату
    protected function moveTo($x, $y)
    {
        echo "Я, {$this->name}, хожу x:{$x}, y:{$y}.\n";
        $this->x = $x;
        $this->y = $y;
    }

    //Метод случайного хода без обдумывания побега или охоты
    protected function freeMove(array $possibleMoves)
    {
        //Выбираем случайный ход из возможных и ходим
        $randomTurn = $possibleMoves[mt_rand(0, count($possibleMoves) - 1)];
        $this->moveTo($randomTurn->x, $randomTurn->y);
    }

    //Метод поиска лучшего хода
    protected function searchBestMove(array $foundAnimals, array $possibleMoves, callable $countPoints)
    {
        //Очки за лучшиий за ход мыши. -INF из-за случаев когда лучший ход приносит 0 баллов
        $pointsMax = -INF;
        $bestMove  = NULL;
        foreach ($possibleMoves as $move)
        {
            $points = $countPoints($foundAnimals, $move);
            //Если ход выдал максимальное количество очков - он становится потенциально лучшим ходом
            if ($points > $pointsMax) {
                $pointsMax = $points;
                $bestMove = $move;
            }
        }
        //Возвращаем лучший ход
        return $bestMove;
    }
}

class Mouse extends Animal
{
    public static $counterOfSymbols = 1; //идентификационный символ-номер на карте


    public function  __construct($name)
    {
        parent::__construct($name);
        //Устанавливем символ-номер и дальность обзора
        $this->symbol = self::$counterOfSymbols++;
        $this->vision = 4;
    }

    //Метод хода
    public function tryToMove()
    {
        $foundAnimals  = $this->field->searchForAnimals($this->x, $this->y, $this->vision);
        $possibleMoves = $this->searchPossibleMoves();
        //Если нельзя сдвинуться - стоим
        if (count($possibleMoves) == 0) {
            echo "Стою на месте.\n";
        //Если  нашли кошку - убегаем
        } elseif ($foundAnimals["Cat"] != NULL) {
            echo "У мышки {$this->name} рядом кошка. ";
            $bestMove = $this->searchBestMove($foundAnimals, $possibleMoves, array($this, "countPoints"));
            $this->moveTo($bestMove->x, $bestMove->y);
        } else {
            echo "Кошек рядом нет. ";
            $this->freeMove($possibleMoves);
        }
    }

    //Метод поиска возможных ходов
    private function searchPossibleMoves()
    {
        //Возможые ходы для мышки (4 стороны)
        /**
        for ($x = $this->x - 1, $i = -1; $x <= $this->x + 1; $x++, $i++) {
        for ($y = $this->y - 1, $j = -1; $y <= $this->y + 1; $y++, $j++) {
        //Стоять на месте без причины или ходить по диагонали мыши нельзя
        if ($x == $this->x && $y == $this->y || abs($i) == abs($j)) {
        continue;
        }
        $arrows[] = array('x' => $x, 'y' => $y);
        }
        }
         */
        $arrows[] = new Move($this->x,     $this->y - 1);
        $arrows[] = new Move($this->x + 1, $this->y);
        $arrows[] = new Move($this->x,     $this->y + 1);
        $arrows[] = new Move($this->x - 1, $this->y);
        //Ищем возможные ходы с помощью метода canIMoveTo
        $possibleMoves = array_filter($arrows, array($this->field, "canIMoveTo"));
        //Ключи должны идти с нуля
        $possibleMoves = array_values($possibleMoves);
        //Возвращаем результат
        return $possibleMoves;
    }

    //Метод подсчета очков за ход
    protected function countPoints (array $foundAnimals, Move $move)
    {
        /**
         * Оценка каждого хода.
         * Приоритет 1: Количество клеток до врага. Их должно быть как можно больше. Коэффициент 100
         * Приоритет 2: Количество клеток до ближайших углов в сумме. Как можно больше, чтобы не забиться в угол. Коэфициент 10
         * Приоритет 3: Количество клеток до одной линии с кошкой, удобная позиция для зажатия в угол.
         * Приоритет 4: Количество клеток до собаки. Может стать приоритетом 2 в ситуации когда только собака может спасти от съедения кошкой
         */
        if (!count($foundAnimals["Cat"])) {
            throw new Exception("Ошибка. Должна быть как минимум одна кошка.");
        }
        //Ищем ближайшего врага и считаем шаги до него
        $nearbyEnemy    = $this->field->searchNearbyAnimal($move->x, $move->y, $foundAnimals["Cat"]);
        $stepsToEnemy   = Field::countSteps($move->x, $move->y, $nearbyEnemy->x, $nearbyEnemy->y);
        //Не даем очки, если один шаг чтобы этот ход был максимально плохим вариантом
        if ($stepsToEnemy == 1) {
            $pointsForEnemy = 0;
        } else {
            $pointsForEnemy = $stepsToEnemy * 100;
        }
        //Если оказались на одной линии с кошкой, то плохо, так нас легко будет поймать
        if ($move->x == $nearbyEnemy->x || $move->y == $nearbyEnemy->y) {
            $pointsForOneLine = -30;
        } else {
            $pointsForOneLine = 10 - abs(min($move->x - $nearbyEnemy->x, $move->y - $nearbyEnemy->y));
        }
        //Если есть рядом собаки - используем их в плане побега
        if ($foundAnimals["Dog"]) {
            $nearbyDog  = $this->field->searchNearbyAnimal($move->x, $move->y, $foundAnimals["Cat"]);
            $stepsToDog = Field::countSteps($move->x, $move->y, $nearbyDog->x, $nearbyDog->y);
            //Тот случай когда собака может спамти мышке жизнь
            if ($stepsToDog == 1 && $stepsToEnemy == 1) {
                $pointsForDog = 90;
            //В остальных случаях это наименьший по очкам приоритет
            } else{
                $pointsForDog = -$stepsToDog;
            }
        //Если собак нету - даем отрицательные очки
        } else {
            $pointsForDog = -$this->field->getWidth();
        }
        //Считаем очки за степень приближения к ближайшему краю, стараемся быть дальше от него
        $pointsForCorner = $this->field->countStepsToCorners($move->x, $move->y) * 10;
        //Считаем общее число очков за ход
        $points = $pointsForEnemy  + $pointsForOneLine + $pointsForDog + $pointsForCorner;
        //Если этот ход обогнал лучший результат - он становится лучшим ходом
        return $points;
    }
}

class Cat extends Animal
{
    private $movesInARow      = 0;     //кол-во ходов подряд
    private $turnWhenCatSleep = 8;     //правило "на каком ходу подряд кошка засыпает"
    private $sleepMode        = FALSE; //переключатель спящего режима

    public function __construct($name)
    {
        parent::__construct($name);
        //Устанавливем символ-номер и дальность обзора
        $this->symbol = "K";
        $this->vision = INF;
    }

    //Метод хода
    public function tryToMove()
    {
        if($this->isSleeping()) {
            //Если спим - то...
            //...переключатель сна перейдет в отрицательное положение
            $this->sleepMode = FALSE;
            //...на поле, показываем результат прошлого хода, мы будем со спящим сиволом
            $this->symbol = "@";
            //...счетчик ходов подряд обнулится
            $this->movesInARow = 0;
            echo "Кошка спит :3\n";
            return;
        } else {
            $this->symbol = "K";
        }
        //Ищем животное в дальности обзора
        $foundAnimals  = $this->field->searchForAnimals($this->x, $this->y, $this->vision);
        //Присваиваем полям найденные результаты
        $possibleMoves = $this->searchPossibleMoves($foundAnimals);
        //Если нельзя сдвинуться - стоим
        if (!count($possibleMoves)) {
            echo "Стою на месте.\n";
        } else {
            $bestMove = $this->searchBestMove($foundAnimals, $possibleMoves, array($this, "countPoints"));
            //Если можно съесть мышь по данным координатам - едим
            if ($this->canIEatIt($bestMove->x, $bestMove->y, $foundAnimals)) {
                $this->eatIt($bestMove->x, $bestMove->y);
            //Если нет - передвигаемся в эту клетку
            } else {
                $this->moveTo($bestMove->x, $bestMove->y);
            }
            //Прибавляем счетчик ходов подряд
            $this->movesInARow++;
        }
    }

    //Метод проверки состояния сна
    private function isSleeping()
    {   //Если ходили заданное по правилам количество ходов или спим после трапезы
        if ($this->movesInARow == $this->turnWhenCatSleep || $this->sleepMode == TRUE) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    //Метод поиска возможных ходов
    private function searchPossibleMoves(array $foundAnimals)
    {
        $arrows = NULL;
        $possibleMoves = NULL;
        //Возможые ходы для кошки (8 сторон);
        for ($x = $this->x - 1; $x <= $this->x + 1; $x++) {
            for ($y = $this->y - 1; $y <= $this->y + 1; $y++) {
                //Стоять на месте по правилам без причины нельзя
                if ($x == $this->x && $y == $this->y) {
                    continue;
                }
                $arrows[] = new Move($x, $y);
            }
        }
        /**
        $arrows["up"]         = array('x' => $this->x,     'y' => $this->y - 1);
        $arrows["up-right"]   = array('x' => $this->x + 1, 'y' => $this->y - 1);
        $arrows["right"]      = array('x' => $this->x + 1, 'y' => $this->y);
        $arrows["right-down"] = array('x' => $this->x + 1, 'y' => $this->y + 1);
        $arrows["down"]       = array('x' => $this->x,     'y' => $this->y + 1);
        $arrows["down-left"]  = array('x' => $this->x - 1, 'y' => $this->y + 1);
        $arrows["left"]       = array('x' => $this->x - 1, 'y' => $this->y);
        $arrows["left-up"]    = array('x' => $this->x - 1, 'y' => $this->y - 1);
         */
        foreach ($arrows as $arrow) {
            //Если на этой клетке собака - сразу отбрасываем этот ход
            if (!$this->field->areChosenAnimalsNearTheCage($arrow->x, $arrow->y, "Dog")) {
                //Если там можно съесть мышь или походить - это возможных ход
                if ($this->canIEatIt($arrow->x, $arrow->y, $foundAnimals)) {
                    $possibleMoves[] = $arrow;
                } elseif ($this->field->canIMoveTo($arrow)) {
                    $possibleMoves[] = $arrow;
                }
            }
        }
        //Возвращаем результат
        return $possibleMoves;
    }

    //Метод подсчета очков за ход
    protected function countPoints(array $foundAnimals, Move $move)
    {
        /**
         * Приоритет 1: Мышку можно съесть. 9999 очков
         * Приоритет 2: Количество клеток до врага. Их должно быть как можно меньше. Коэффициент 100.
         * Приоритет 3: Количество клеток до одной линии с мышью, удобная позиция для зажатия в угол.
         */
        //Ищем ближайшего врага и считаем шаги до него
        $nearbyEnemy = $this->field->searchNearbyAnimal($move->x, $move->y, $foundAnimals["Mouse"]);
        $stepsToEnemy = Field::countSteps($move->x, $move->y, $nearbyEnemy->x, $nearbyEnemy->y);
        //Если можно съесть мышь по указанным координатам - это однозначно лучший ход
        if ($this->canIEatIt($move->x, $move->y, $foundAnimals)) {
            $pointsForEnemy = 9999;
        } else {
            $pointsForEnemy = -$stepsToEnemy * 100;
        }
        //Если кошка на одной линии с мышкой
        if ($move->x == $nearbyEnemy->x || $move->y == $nearbyEnemy->y) {
            $pointsForOneLine = 99;
        } else {
            $pointsForOneLine = -abs(min($move->x - $nearbyEnemy->x, $move->y - $nearbyEnemy->y));
        }
        //Считаем общее очков за ход
        $points = $pointsForEnemy + $pointsForOneLine;
        //Если этот ход обогнал лучший результат - он становится лучшим ходом
        return $points;
    }

    //Метод возможности съедения мышки по данным координатам
    private function canIEatIt($x, $y, array $foundAnimals)
    {
        //Если по данным координатам нет мышки - нет
        if (!$this->field->getAnimal($x, $y) instanceof Mouse) {
            return FALSE;
        //Если там мышка - очевидно возомжно, но еще не можно
        } else {
            //Обнажили зубки
            echo "Пытаюсь съесть {$this->field->getAnimal($x, $y)->name}. ";
            //В переменной oneLine считаем количество мышей, которые рядом с друг другом
            $oneLine = 0;
            foreach ($foundAnimals["Mouse"] as $mouse) {
                if ($this->field->areChosenAnimalsNearTheCage($mouse->x, $mouse->y, "Mouse")) {
                    $oneLine++;
                }
            }
            //Если их меньше трех - омномном
            if ($oneLine < 3) {
                return TRUE;
            //Если больше - мы грустим
            } else {
                echo "Мыши защищают друг друга. ";
                return FALSE;
            }
        }
    }

    //Метод поедения несчастного объекта
    private function eatIt($x, $y)
    {
        //Удаление элемента массива по значению
        $this->field->removeAnimal($x, $y);
        //Ход на освободившуюся клетку
        $this->moveTo($x, $y);
        //Переход в спящий режим
        $this->sleepMode = TRUE;
    }

}

class Dog extends Animal {

    public function __construct($name)
    {
        parent::__construct($name);
        $this->symbol = "D";
    }

    //Метод хода
    public function tryToMove()
    {
        $possibleMoves = $this->searchPossibleMoves();
        //Если нельзя сдвинуться - стоим
        if (count($possibleMoves) == 0) {
            echo "Ходить $this->name некуда.\n";
        //Если можно сдвинуться - ходим, как ни странно
        } else {
            $this->freeMove($possibleMoves);
        }
    }

    //Метод поиска возможных ходов
    private function searchPossibleMoves()
    {
        $arrows = NULL;
        //Возможые ходы для собаки (8 сторон)
        for ($x = $this->x - 2; $x <= $this->x + 2; $x += 2) {
            for ($y = $this->y - 2; $y <= $this->y + 2; $y += 2) {
                if ($x == $this->x && $y == $this->y) {
                    continue;
                }
                $arrows[] = new Move($x, $y);
            }
        }
        /**
        $arrows["up"]         = array('x' => $this->x,   'y' => $this->y-2);
        $arrows["up-right"]   = array('x' => $this->x+2, 'y' => $this->y-2);
        $arrows["right"]      = array('x' => $this->x+2, 'y' => $this->y);
        $arrows["right-down"] = array('x' => $this->x+2, 'y' => $this->y+2);
        $arrows["down"]       = array('x' => $this->x,   'y' => $this->y+2);
        $arrows["down-left"]  = array('x' => $this->x-2, 'y' => $this->y+2);
        $arrows["left"]       = array('x' => $this->x-2, 'y' => $this->y);
        $arrows["left-up"]    = array('x' => $this->x-2, 'y' => $this->y-2);
         */
        $possibleMoves = array_filter($arrows, array($this->field, "canIMoveTo"));
        $possibleMoves = array_values($possibleMoves);
        //Возвращаем результат
        return $possibleMoves;
    }


}

class Field {
    private $width;              //ширина
    private $height;             //высота
    private $numberOfTurns = 30; //количество ходов
    private $animals = array();  //массив животных

    //Задаем ширину, высоту
    public function __construct($width, $height)
    {
        $this->width = $width;
        $this->height = $height;
    }


    //Метод получения защищенных свойств для других классов
    public function getWidth()
    {
        return $this->width;
    }

    public function getHeight()
    {
        return $this->height;
    }

    //Метод размещения животного на карте
    public function addAnimal(Animal $animal)
    {
        //Добавляем животное в список
        $this->animals[] = $animal;
        //Передаем карту в поле животного для удобства
        $animal->setField($this);
        //Координаты могут быть заняты, если мы вручную их забиваем тестируя возможные ситуации
        if ($animal->getX() == NULL && $animal->getY() == NULL) {
            //Получаем свободные координаты
            $this->getRandomCoords($animal);
        }
    }

    //Метод получения свободных координат
    private function getRandomCoords (Animal $animal)
    {
        //Рандомим пока не найдем пустую клетку
        $i = 0;
        do {
            $x = mt_rand(1, $this->width);
            $y = mt_rand(1, $this->height);
        } while ($this->getAnimal($x, $y) || $i++ < 100);
        //Инициализурем удачные координаты
        $animal->setX($x);
        $animal->setY($y);
    }

    //Метод определения возможности животного походить по указанным координатам
    public function canIMoveTo(Move $move)
    {
        //Если ход за пределы карты или клетка занята - нет
        if ($move->x < 1             ||
            $move->y < 1             ||
            $move->x > $this->width  ||
            $move->y > $this->height ||
            $this->getAnimal($move->x, $move->y)) {
            return FALSE;
        } else {
            return TRUE;
        }
    }

    //Метод подсчета шагов до ближайших углов
    public function countStepsToCorners($x, $y)
    {
        //Находимся ли мы слева от центра или справа, вверху или внизу
        $stepsToCornerX = ($x < $this->width/2)  ? $x - 1 : $this->width - $x;
        $stepsToCornerY = ($y < $this->height/2) ? $y - 1 : $this->height - $y;
        return $stepsToCornerX + $stepsToCornerY;
    }


    //Метод получения объекта по координатам из массива животных
    public function getAnimal ($x, $y)
    {
        foreach ($this->animals as $animal)
        {
            if ($x == $animal->getX() && $y == $animal->getY()) {
                return $animal;
            }
        }
    }

    //Метод удаления животного из списка
    public function removeAnimal($x, $y)
    {
        if(($key = array_search($this->getAnimal($x, $y), $this->animals)) !== FALSE){
            unset($this->animals[$key]);
        }
    }

    //Метож вывода карты
    private function showField($turn)
    {
        $array = array();
        for ($y = 0; $y <= $this->height; $y++) {
            for ($x = 0; $x <= $this->width; $x++) {
                //Если первая строка
                if ($y == 0) {
                    //Три пробела, если первый символ оси
                    if ($x == 0) {
                        $array[$y][$x] = str_pad("", 3);
                    //Номер оси X, если не первый
                    } else {
                        $array[$y][$x] = str_pad($x, 3);
                    }
                //Если первый символ оси X, печатаем номер строки ($y)
                } elseif ($x == 0) {
                    $array[$y][$x] = str_pad($y, 3);
                //Если нашли животное, выводим его иконку
                } elseif ($this->getAnimal($x, $y)) {
                    $array[$y][$x] = str_pad($this->getAnimal($x, $y)->getSymbol(), 3);
                //В остальных случаях отображем пустое поле
                } else {
                    $array[$y][$x] = str_pad(".", 3);
                }
                //Рядом с полем выводим статистику
                if     ($y == 1 && $x == $this->width) $array[$y][$x] .= "  Ход: {$turn}";
                elseif ($y == 2 && $x == $this->width) $array[$y][$x] .= "  Мышек: {$this->countAnimals('Mouse')}";
                elseif ($y == 3 && $x == $this->width) $array[$y][$x] .= "  Кошек: {$this->countAnimals('Cat')}";
                elseif ($y == 4 && $x == $this->width) $array[$y][$x] .= "  Собак: {$this->countAnimals('Dog')}";
            }
        }
        //Выводи массив как строку
        foreach ($array as $string) {
            echo implode($string);
            echo "\n";
        }
    }

    //Метод игры
    public function startGame()
    {
        //Делаем заданное заранее количество ходов
        for ($turn = 0; $turn <= ($this->numberOfTurns); $turn++) {
            //Выводим поле
            $this->showfield($turn);
            //Каждое животное делает ход
            //Так как в цикле foreach копия массива надо проверять данные с изменениями через ссылку
            for ($i = 0; $i < count($this->animals); $i++) {
                //Животное делает ход
                $this->animals[$i]->tryToMove();
                //Если всех мышей съели - конец игры
                if ($this->countAnimals("Mouse") == 0) {
                    die("Конец игры.");
                }
                $this->animals = array_values($this->animals);
            }

            echo "\n";
        }
    }

    //Метод поиска животных в определенном обзоре
    public function searchForAnimals($x, $y, $vision)
    {
        $foundAnimals = array();
        foreach ($this->animals as $animal) {
            //Если обнаружили новый тип животных - добавляем его как ключ
            if (!array_key_exists($animalType = get_class($animal), $foundAnimals)) {
                $foundAnimals[$animalType] = NULL;
            }
            //Если нашли самого себя - не добавляем оьъект в массив найденных животных
            if ($animal->getX() == $x && $animal->getY() == $y) {
                continue;
            } elseif ($animal->getX() >= $x - $vision &&
                      $animal->getX() <= $x + $vision ||
                      $vision == INF) {
                if ($animal->getY() >= $y - $vision &&
                    $animal->getY() <= $y + $vision ||
                    $vision == INF) {
                    $foundAnimals[$animalType][] = $animal;
                }
            }
        }
        //Возвращаем результат
        return $foundAnimals;
    }

    //Метод подсчета животных. Считает определенных животных
    private function countAnimals($nameOfTheAnimal)
    {
        $counter = 0;
        //Если нужное животное есть в массиве - прибавляем счетчик
        foreach ($this->animals as $animal) {
            if ($animal instanceof $nameOfTheAnimal) {
                $counter++;
            }
        }
        return $counter;
    }

    //Метод определяющий наличие опреденного вида животных с данными координатами
    public function areChosenAnimalsNearTheCage($x, $y, $typeOfAnimal)
    {
        foreach ($this->animals as $animal)
        {
            //Наши координаты не влияют на ответ на поставленный вопрос
            if ($animal->getX() == $x && $animal->getY() == $y) {
                continue;
            }
            if ($animal instanceof $typeOfAnimal) {
                if (self::countSteps($x, $y, $animal->getX(), $animal->getY()) == 1) {
                    return TRUE;
                }
            }
        }
        //В остальных случаях ответ - нет
        return FALSE;
    }

    //Метод подсчета шагов между двумя точками
    public static function countSteps($point1X, $point1Y, $point2X, $point2Y)
    {
        //Подсчет шагов по оси X
        $countStepsX = abs($point1X - $point2X);
        //ПОдсчет шагов по оси Y
        $countStepsY = abs($point1Y - $point2Y);
        //Возвращаем наибольшее
        return max($countStepsX, $countStepsY);
    }

    //Метод нахождения ближайшего животного из определенного массива
    public function searchNearbyAnimal($x, $y, array $animals)
    {
        //Лучший результат по умолчанию
        $stepsNearestAnimal = INF;
        foreach ($animals as $animal) {
            //Считаем  шаги между животным и координатами
            $countSteps = self::countSteps($x, $y, $animal->getX(), $animal->getY());
            //Если меньше лучшего результата - это лучший результат
            if ($countSteps < $stepsNearestAnimal) {
                $nearbyAnimal = $animal;
                $stepsNearestAnimal = $countSteps;
                //Если на одном расстоянии с результатом - продалжаем поиск
            }
        }
        //Возвращаем ближайшее животное
        return $nearbyAnimal;
    }
}

//Класс с координатами хода
class Move {
    public $x;
    public $y;

    public function __construct ($x, $y)
    {
        $this->x = $x;
        $this->y = $y;
    }
}

//Создаем карту
$field  = new Field(10,10);
//Создаем и именум зверье
$mouse1 = new Mouse("mouse1");
$field->addAnimal($mouse1);
$mouse2 = new Mouse("mouse2");
$field->addAnimal($mouse2);
$mouse3 = new Mouse("mouse3");
$field->addAnimal($mouse3);
$cat1   = new Cat("cat1");
$field->addAnimal($cat1);
$cat2   = new Cat("cat2");
$field->addAnimal($cat2);
$dog1   = new Dog("dog1");
$field->addAnimal($dog1);
$dog2   = new Dog("dog2");
$field->addAnimal($dog2);
//Начинаем игру
$field->startGame();


//Тест на два огня
/**
$field  = new Field(5, 6);
$mouse1 = new Mouse("mouse1");
$mouse1->x = 3;
$mouse1->y = 3;
$mouse1->symbol = 1;
$field->addAnimal($mouse1);
$cat1   = new Cat("cat1");
$cat1->x = 1;
$cat1->y = 3;
$field->addAnimal($cat1);
$cat2   = new Cat("cat2");
$cat2->x = 5;
$cat2->y = 3;
$field->addAnimal($cat2);
$dog1 = new Dog("dog1");
$dog1->x = 5;
$dog1->y = 6;
$field->addAnimal($dog1);
$field->startGame();
 */

//Тест на мышинную оборону
/**
$field  = new Field(10, 10);
$cat1   = new Cat("cat1");
$cat1->x   = 2;
$cat1->y   = 1;
$field->addAnimal($cat1);
$mouse1 = new Mouse("mouse1");
$mouse1->x = 1;
$mouse1->y = 1;
$mouse1->symbol = 1;
$field->addAnimal($mouse1);
$mouse2 = new Mouse("mouse2");
$mouse2->x = 2;
$mouse2->y = 2;
$mouse2->symbol = 2;
$field->addAnimal($mouse2);
$mouse3 = new Mouse("mouse3");
$mouse3->x = 3;
$mouse3->y = 1;
$mouse3->symbol = 3;
$field->addAnimal($mouse3);
$dog1   = new Dog("dog1");
$dog1->x = 5;
$dog1->y = 5;
//$field->addAnimal($dog1);
$field->startGame();
*/

//Тест на пирамиду котов
/**
$field  = new Field(7, 7);
$mouse1 = new Mouse("mouse1");
$mouse1->x = 3;
$mouse1->y = 4;
$mouse1->symbol = 1;
$field->addAnimal($mouse1);
$cat1    = new Cat("cat1");
$cat1->x = 1;
$cat1->y = 3;
$field->addAnimal($cat1);
$cat2    = new Cat("cat2");
$cat2->x = 2;
$cat2->y = 2;
$field->addAnimal($cat2);
$cat3    = new Cat("cat3");
$cat3->x = 3;
$cat3->y = 1;
$field->addAnimal($cat3);
$cat4    = new Cat("cat4");
$cat4->x = 4;
$cat4->y = 2;
$field->addAnimal($cat4);
$cat5    = new Cat("cat5");
$cat5->x = 5;
$cat5->y = 3;
$field->addAnimal($cat5);
$dog1    = new Dog("dog1");
$dog1->x = 7;
$dog1->y = 7;
$field->addAnimal($dog1);
$field->startGame();
 */

//Тест на два огня #2
/**
$field          = new Field(8, 8);
$mouse1         = new Mouse("mouse1");
$mouse1->x      = 3;
$mouse1->y      = 4;
$mouse1->symbol = 1;
$field->addAnimal($mouse1);
$cat1           = new Cat("cat1");
$cat1->x        = 1;
$cat1->y        = 3;
$field->addAnimal($field, $cat1);
$cat2   = new Cat("cat2");
$cat2->x        = 5;
$cat2->y        = 5;
$field->addAnimal($cat2);
$dog1 = new Dog("dog1");
$dog1->x        = 8;
$dog1->y        = 8;
$field->addAnimal($dog1);
$field->startGame();
 */
