<?php
error_reporting(-1);
class Field
{
    public $size;
    public $mapOfField;
    public $numberAnimals;
    public $animals;
    public $cats;
    public function Field($size)
    {
        $this->animals       = array();
        $this->size          = $size;
        $this->cats          = array();
        $this->numberAnimals = 0;
        $string              = array();
        $this->mapOfField    = array();
        for ($a = 0; $a <= $size; $a++) {
            $string[$a] = null;
        }
        for ($i = 0; $i <= $size; $i++) {
            $this->mapOfField[$i] = $string;
        }
    }
    public function add($animal)
    {
        $this->animals[$this->numberAnimals] = $animal;
        $animal->number                      = $this->numberAnimals;
        $this->numberAnimals++;
        $this->mapOfField[$animal->x][$animal->y] = $animal;
        if ($animal->name == 'C') {
            $this->cats[] = $animal;
        }
    }
    public function remove($animal)
    {
        $this->animals[$animal->number]           = null;
        $this->mapOfField[$animal->x][$animal->y] = null;
    }
    public function updateCoordinates($animal, $x, $y)
    {
        $this->mapOfField[$animal->x][$animal->y] = null;
        $this->mapOfField[$x][$y]                 = $animal;
        $this->animals[$animal->number]->x        = $x;
        $this->animals[$animal->number]->y        = $y;
    }
    public function canMoveTo($x, $y)
    {
        if ($x < 0 || $x > $this->size || $y < 0 || $y > $this->size) {
            return false;
        } elseif ($this->mapOfField[$x][$y] == null || $this->mapOfField[$x][$y]->name == 'M') {
            return true;
        }
    }
}

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

class Cats extends Animals
{
    public $hungry = 1;
    function __construct($name, $x, $y)
    {
        parent::__construct($name, $x, $y);
    }
    public function move($field)
    {
        $x = $this->x;
        $y = $this->y;
        if ($this->hungry != 0) {
            $min = $field->size;
            for ($i = 0; $i <= $field->numberAnimals; $i++) {
                if ($field->animals[$i]->name == 'M') {
                    $b = sqrt(pow($field->animals[$i]->x - $x, 2) + pow($field->animals[$i]->y - $y, 2));
                    if ($b < $min) {
                        $min       = $b;
                        $aimAnimal = $field->animals[$i];
                        $xm        = $field->animals[$i]->x;
                        $ym        = $field->animals[$i]->y;
                    }
                }
            }
            
            if ($x < $xm) {
                $x++;
            } elseif ($x > $xm) {
                $x--;
            } else {
                if ($y == $ym) {
                    $this->hungry = 0;
                    $field->remove($aimAnimal);
                }
            }
            if ($y < $ym) {
                $y++;
            } elseif ($y > $ym) {
                $y--;
            } else {
                if ($x == $xm) {
                    $this->hungry = 0;
                    $field->remove($aimAnimal);
                }
            }
            $can = $field->canMoveTo($x, $y);
            if ($can) {
                $field->updateCoordinates($this, $x, $y);
            }
        }
        $this->hungry = 1;
    }
}

class Mauses extends Animals
{
    public $overview = 5;
    function __construct($name, $x, $y)
    {
        parent::__construct($name, $x, $y);
    }
    public function move($field)
    {
        $cats       = $field->cats;
        $numberCats = count($cats);
        $vectorX    = 0;
        $vectorY    = 0;
        for ($i = 0; $i < $numberCats; $i++) {
            $xR = abs($this->x - $field->cats[$i]->x);
            $yR = abs($this->y - $field->cats[$i]->y);
            if ($xR <= $this->overview && $yR <= $this->overview) {
                $vectorX = $vectorX + ($field->cats[$i]->x - $this->x);
                $vectorY = $vectorY + ($field->cats[$i]->y - $this->y);
            }
        }
        $x = $this->x;
        $y = $this->y;
        if ($x < $vectorX * (-1)) {
            $x++;
        } elseif ($x > $vectorX * (-1)) {
            $x--;
        }
        if ($y < $vectorY * (-1)) {
            $y++;
        } elseif ($y > $vectorY * (-1)) {
            $y--;
        }
        $can = $field->canMoveTo($x, $y);
        if ($can) {
            $field->updateCoordinates($this, $x, $y);
        }
    }
}

function printField($array)
{
    foreach ($array as &$value) {
        foreach ($value as &$value) {
            if ($value == null) {
                echo '.';
            } else {
                echo "$value->name";
            }
        }
        echo "\n";
    }
}

$field  = new Field(7);
$mause  = new Mauses('M', 4, 4);
$cat    = new Cats('C', 6, 6);
$cat1   = new Cats('C', 6, 2);
$mause1 = new Mauses('M', 7, 3);

$field->add($cat);
$field->add($mause);
$field->add($cat1);
$field->add($mause1);

printField($field->mapOfField);
echo "\n";
for ($i = 1; $i < 18; $i++) {
    $mause->move($field);
    $mause1->move($field);
    $cat->move($field);
    $cat1->move($field);
    printField($field->mapOfField);
    echo "\n";
}