<?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
//Ключи должны идти с нуля
//Возвращаем результат
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);
*/
//Возвращаем результат
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 {
} 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)
{
for ($y = 0; $y <= $this->height; $y++) {
for ($x = 0; $x <= $this->width; $x++) {
//Если первая строка
if ($y == 0) {
//Три пробела, если первый символ оси
if ($x == 0) {
//Номер оси X, если не первый
} else {
}
//Если первый символ оси X, печатаем номер строки ($y)
} elseif ($x == 0) {
//Если нашли животное, выводим его иконку
} elseif ($this->getAnimal($x, $y)) {
$array[$y][$x] = str_pad($this->getAnimal($x, $y)->getSymbol(), 3); //В остальных случаях отображем пустое поле
} else {
}
//Рядом с полем выводим статистику
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 "\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) {
}
}
echo "\n";
}
}
//Метод поиска животных в определенном обзоре
public function searchForAnimals($x, $y, $vision)
{
foreach ($this->animals as $animal) {
//Если обнаружили новый тип животных - добавляем его как ключ
$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();
*/