<?php

error_reporting(-1);

class Field {
    private $size;
	public $mapOfField = array();
	private $numberOfCats = 0;
	private $cats = array();
	private $numberOfMouses = 0;
	private $mouses = array();
	public function __construct ($size)
	{
		$this->size = $size;
		$string = array();
		for ($a = 0; $a <= $size; $a++) {
            $string[$a] = null;
        }
        for ($i = 0; $i <= $size; $i++) {
            $this->mapOfField[$i] = $string;
        }
	}
	public function add ($animal)
	{
		$type = $animal->getType();
		if ($type == 'mouse') {
			$this->mouses[$this->numberOfMouses] = $animal;
			$animal->setNumber($this->numberOfMouses);
			$this->numberOfMouses++;
		} elseif ($type == 'cat') {
			$this->cats[$this->numberOfCats] = $animal;
			$animal->setNumber($this->numberOfCats);
			$this->numberOfCats++;
		}
		$x = $animal->getCoordinate('x');
		$y = $animal->getCoordinate('y');
		$this->mapOfField[$x][$y] = $animal;
	}
	public function delete ($animal)
	{
		$number = $animal->getNumber();
		$this->mouses[$number] = array_pop($this->mouses);
	}
	public function getMouses ()
	{
		return $this->mouses;
	}
	public function getSize ()
	{
		return $this->size;
	}
	public function updateCoordinates ($animal, $x, $y)
	{
		$type = $animal->getType();
		if (($x <= $this->size && $x >= 0) && ($y <= $this->size && $y >= 0)) {
			if ($type == 'cat') {
				$cell = $this->mapOfField[$x][$y];
				if (($cell == null) || (($aimType = $cell->getType) == 'mouse')) {
					$startX = $animal->getCoordinate('x');
					$startY = $animal->getCoordinate('y');
					$this->mapOfField[$startX][$startY] = null;
					$animal->setCoordinate ('x',$x);
					$animal->setCoordinate ('y',$y);
					$this->mapOfField[$x][$y] = $animal;
				}
			} elseif ($type == 'mouse') {
				$cell = $this->mapOfField[$x][$y];
				if ($cell == null) {
					$startX = $animal->getCoordinate('x');
					$startY = $animal->getCoordinate('y');
					$this->mapOfField[$startX][$startY] = null;
					$animal->setCoordinate ('x',$x);
					$animal->setCoordinate ('y',$y);
					$this->mapOfField[$x][$y] = $animal;
				}
			}
		}
	}
}

class Animals {
	protected $type;
	protected $number;
	protected $x;
	protected $y;
	public function __construct ($type, $x, $y)
	{
		$this->type = $type;
		$this->x = $x;
		$this->y = $y;
	}
	public function getCoordinate ($orXY)
	{
		if ($orXY == 'x') {
			return $this->x;
		} elseif ($orXY == 'y') {
			return $this->y;
		}
	}
	public function setCoordinate ($orXY, $coordinate)
	{
		if ($orXY == 'x') {
			$this->x = $coordinate;
		} elseif ($orXY == 'y') {
			$this->y = $coordinate;
		}
	}
	public function setNumber ($number)
	{
		$this->number = $number;
	}
	public function getType ()
	{
		return $this->type;
	}
}

class Cats extends Animals {
	private $hungry = 1;
	public function __construct ($type, $x, $y)
	{
		parent::__construct($type, $x, $y);
	}
	public function move ($field)
	{
		$x = $this->x;
		$y = $this->y;
		$min = $field->getSize();
		if ($this->hungry == 1) {
			$mouses = $field->getMouses();
			foreach ($mouses as &$value) {
				$mouseX = $value->getCoordinate('x');
				$mouseY = $value->getCoordinate('y');
				$distance = sqrt(pow($mouseX - $x, 2) + pow($mouseY - $y, 2));
				if ($distance <= $min) {
					$aimAnimal = $value;
					$aimX = $mouseX;
					$aimY = $mouseY;
				}
			}
			if ($x < $aimX) {
                $x++;
            } elseif ($x > $aimX) {
                $x--;
            } else {
                if ($y == $aimY) {
                    $this->hungry = 0;
                    $field->delete($aimAnimal);
                }
            }
            if ($y < $aimY) {
                $y++;
            } elseif ($y > $aimY) {
                $y--;
            } else {
                if ($x == $aimX) {
                    $this->hungry = 0;
                    $field->delete($aimAnimal);
                }
            }
			$field->updateCoordinates($this, $x, $y);
		} elseif ($this->hungry ==0) {
			$this->hungry = 1;
		}
	}
}

function printField($array)
{
    foreach ($array as &$value) {
        foreach ($value as &$value) {
            if ($value == null) {
                echo '.';
            } else {
                $type = $value->getType();
				if ($type == 'mouse') {
					echo 'M';
				} elseif($type == 'cat') {
					echo 'C';
				}
            }
        }
        echo "\n";
    }
}

class Mouses extends Animals
{
    public $overview = 5;
    function __construct($name, $x, $y)
    {
        parent::__construct($name, $x, $y);
    }
}

$field  = new Field(7);
$cat = new Cats ('cat', 0, 0);
$mouse = new Mouses ('mouse', 2, 2);

$field->add($cat);
$field->add($mouse);

printField($field->mapOfField);
echo "\n";

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