<?php
abstract class Animal
{
    protected $x;
    protected $y;
    protected $previousX;
    protected $previousY;
    protected $icon;
    
    public function __construct($coordinateX, $coordinateY, $symbol)
    {
        $this->x    = $coordinateX;
        $this->y    = $coordinateY;
        $this->icon = $symbol;
    }
    public function getCoordinateX()
    {
        return $this->x;
    }
    public function getCoordinateY()
    {
        return $this->y;
    }
    
    public function getPreviousX()
    {
        return $this->previousX;
    }
    
    public function getPreviousY()
    {
        return $this->previousY;
    }
    
    
    public function getIcon()
    {
        return $this->icon;
    }
}

class Mouse extends Animal
{
    
}

class Cat extends Animal
{
    
    
    
    public function makeMove($target)
    {
        if ($target['x'] > $this->x) {
            $this->x = $this->x + 1;
        } elseif ($target['x'] < $this->x) {
            $this->x = $this->x - 1;
        }
        
        if ($target['y'] > $this->y) {
            $this->y = $this->y + 1;
        } elseif ($target['y'] < $this->y) {
            $this->y = $this->y - 1;
        }
    }
    
    
}


class GameField
{
    protected $field;
    protected $animals = array();
    protected $height;
    protected $width;
    
    public function __construct($height, $width)
    {
        $this->height = $height;
        $this->width  = $width;
    }
    public function printField()
    {
        $this->field = array_fill(0, $this->height, array_fill(0, $this->width, " . "));
        
        foreach ($this->animals as $animal) {
            $x                   = $animal->getCoordinateX();
            $y                   = $animal->getCoordinateY();
            $this->field[$x][$y] = $animal->getIcon();
        }
        
        foreach ($this->field as $value) {
            foreach ($value as $dot) {
                echo $dot;
            }
            echo "\n";
        }
    }
    
    public function acquireAnimal($animal)
    {
        $this->animals[] = $animal;
    }
    
    public function findAllMousesWithin($x, $y)
    {
        $previous = INF;
        $target   = array();
        foreach ($this->animals as $animal) {
            if (!($animal instanceof Mouse)) {
                continue;
            }
            $distance = abs($x - $animal->getCoordinateX()) + abs($y - $animal->getCoordinateY());
            if ($distance < $previous) {
                $target['x'] = $animal->getCoordinateX();
                $target['y'] = $animal->getCoordinateY();
                $previous    = $distance;
            }
            
            
        }
        
        return $target;
    }
    
    
    #Удалить в будущем эту хуйню:
    
    public function testTheKitty()
    {
        
        foreach ($this->animals as $animal) {
            if ($animal instanceof Cat) {
                $animal->makeMove($this->findAllMousesWithin($animal->getCoordinateX(), $animal->getCoordinateY()));
                
                $kittyX = $animal->getCoordinateX();
                $kittyY = $animal->getCoordinateY();
            }
            
            
        }
        for ($i = 0; $i < count($this->animals); $i++) {
            
            if ($this->animals[$i] instanceof Mouse && $this->animals[$i]->getCoordinateX() == $kittyX && $this->animals[$i]->getCoordinateY() == $kittyY) {
                unset($this->animals[$i]);
            }
        }
    }
    
    
    
    
}


$test   = new GameField(20, 20);
$mouse1 = new Mouse(3, 15, "1");
$mouse2 = new Mouse(5, 7, "2");
$kitty  = new Cat(19, 10, "@");

$test->acquireAnimal($mouse1);
$test->acquireAnimal($mouse2);
$test->acquireAnimal($kitty);
$test->printField();
echo "\n";
for ($i = 0; $i < 23; $i++) {
    $test->testTheKitty();
    $test->printField();
    echo "\n";
}