<?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
{
    protected $targets = array();
    protected $target = array();
    public function makeMove(array $field)
    {
        
        /*сохраним текущие координаты кошки*/
        $this->previousX = $this->x;
        $this->previousY = $this->y;
        /*Определяем мышей на карте*/
        $n               = 0;
        foreach ($field as $value) {
            $i = 0;
            foreach ($value as $dot) {
                if ($dot != " . " && $dot != $this->icon) {
                    $this->targets[] = array(
                        'x' => $n,
                        'y' => $i
                    );
                }
                $i++;
            }
            $n++;
        }
        /*Определяем координаты ближайшей мыши*/
        $previous = INF;
        for ($i = 0; $i < count($this->targets); $i++) {
            $distance = abs($this->x - $this->targets[$i]['x']) + abs($this->y - $this->targets[$i]['y']);
            if ($distance < $previous) {
                $this->target['x'] = $this->targets[$i]['x'];
                $this->target['y'] = $this->targets[$i]['y'];
            }
            $previous = $distance;
        }
        
        
        /*начинаем движение к ближайшей цели*/
        if ($this->target['x'] > $this->x) {
            $this->x = $this->x + 1;
        } elseif ($this->target['x'] < $this->x) {
            $this->x = $this->x - 1;
        }
        
        if ($this->target['y'] > $this->y) {
            $this->y = $this->y + 1;
        } elseif ($this->target['y'] < $this->y) {
            $this->y = $this->y - 1;
        }
        
        
    }
    
}


class GameField
{
    protected $field;
    
    public function __construct($height, $width)
    {
        $this->field = array_fill(0, $height, array_fill(0, $width, " . "));
    }
    public function printField()
    {
        foreach ($this->field as $value) {
            foreach ($value as $dot) {
                echo $dot;
            }
            echo "\n";
        }
    }
    public function aquireMouse(Mouse $mice)
    {
        $x                   = $mice->getCoordinateX();
        $y                   = $mice->getCoordinateY();
        $this->field[$x][$y] = $mice->getIcon();
    }
    
    public function aquireCat(Cat $kitten)
    {
        $x                   = $kitten->getCoordinateX();
        $y                   = $kitten->getCoordinateY();
        $previousX           = $kitten->getPreviousX();
        $previousY           = $kitten->getPreviousY();
        $this->field[$x][$y] = $kitten->getIcon();
        if ($x != $previousX || $y != $previousY) {
            $this->field[$previousX][$previousY] = " . ";
        }
        
    }
    public function shareField()
    {
        return $this->field;
    }
    
    
}



$test = new GameField(20, 20);

$mouse1 = new Mouse(3, 15, " 1 ");
$mouse2 = new Mouse(5, 7, " 2 ");
$kitty  = new Cat(19, 10, "@");
$test->aquireMouse($mouse1);
$test->aquireMouse($mouse2);
$test->aquireCat($kitty);
$test->printField();
echo "\n \n \n";
$kitty->makeMove($test->shareField());
$test->aquireCat($kitty);
$test->printField();

for ($i = 0; $i < 20; $i++) {
    echo "\n \n \n";
    $kitty->makeMove($test->shareField());
    $test->aquireCat($kitty);
    $test->printField();
}











?>