Clearly I love writing these kinds of things:
Code: Select all
<?php
/*
$cities = new Map();
$cities->setObjectAtPos(array(1, 3, 8, 10), new SanFrancisco());
$currentCity = $cities->getByPos($x, $y);
*/
/**
* Assumes coords start at 0,0 in top left.
*/
interface Pos_Interface
{
function getX();
function getY();
}
class Pos_2d implements Pos_Interface
{
private $_x, $_y;
public function __construct($x, $y)
{
$this->_x = $x;
$this->_y = $y;
}
public function getX()
{
return $this->_x;
}
public function getY()
{
return $this->_y;
}
}
interface Space_Interface
{
function on(Pos_Interface $pos);
function within(Pos_Interface $pos);
}
class Space_2d implements Space_Interface
{
private $_left, $_top, $_right, $_bottom;
public function __construct($left, $top, $right, $bottom)
{
$this->_left = $left;
$this->_top = $top;
$this->_right = $right;
$this->_bottom = $bottom;
}
public function on(Pos_Interface $pos)
{
return $pos->getX() >= $this->_left
&& $pos->getX() <= $this->_right
&& $pos->getY() >= $this->_top
&& $pos->getY() <= $this->_bottom;
}
public function within(Pos_Interface $pos)
{
return $pos->getX() > $this->_left
&& $pos->getX() < $this->_right
&& $pos->getY() > $this->_top
&& $pos->getY() < $this->_bottom;
}
}
/**
* Should possibly refactor to make space a property of item
*/
interface Item_Interface
{
function __tostring();
}
class Item_FlatColour implements Item_Interface
{
private $_colour;
public function __construct($colour = 'white')
{
$this->_colour = $colour;
}
public function getColour()
{
return $this->_colour;
}
public function __tostring()
{
return '<span style="color:' . $this->getColour() . '">' . $this->getColour() . '</span>';
}
}
/**
* Refactor into separate abstract super and simple concrete as necessary
*/
class Map
{
/**
* Important that the keys of these 2 arrays match.
* They hold the positions of the items and the items
* themselves respectively
*
* @var array
*/
private $_space, $_item;
public function __construct(array $itemsInSpace = array())
{
foreach ($itemsInSpace as $itemInSpace) {
list($space, $item) = $itemInSpace;
$this->addToMap($space, $item);
}
}
public function addToMap(Space_Interface $space, Item_Interface $item)
{
$this->_space[] = $space;
$this->_item[] = $item;
return $this;
}
public function getItemAtPos(Pos_Interface $pos)
{
foreach ($this->_space as $key => $space) {
if ($space->on($pos)) {
return $this->_item[$key];
}
}
return null;
}
public function removeFromMapByItem(Item_Interface $itemToRemove)
{
foreach ($this->_item as $key => $item) {
if ($item === $toRemove) {
unset($this->_item[$key]);
unset($this->_space[$key]);
return true;
}
}
return false;
}
}
$map = new Map(array(
array(new Space_2d(0, 0, 1, 1), new Item_FlatColour('blue')),
array(new Space_2d(2, 2, 5, 5), new Item_FlatColour('red')),
));
echo '<table border="1">';
for ($y = 0; $y < 7; ++$y) {
echo '<tr>';
for ($x = 0; $x < 7; ++$x) {
echo '<td>';
$item = $map->getItemAtPos(new Pos_2d($x, $y));
if ($item) {
echo $item;
} else {
echo 'null';
}
echo '</td>';
}
echo '</tr>';
}
echo '</table>';
echo $map->getItemAtPos(new Pos_2d(0, 0))->getColour(), ' ', // blue
$map->getItemAtPos(new Pos_2d(1, 0))->getColour(), ' ', // blue
var_export($map->getItemAtPos(new Pos_2d(2, 0)), true), ' ', // NULL
$map->getItemAtPos(new Pos_2d(2, 2))->getColour(), ' ', // red
$map->getItemAtPos(new Pos_2d(5, 4))->getColour(), ' ', // red
var_export($map->getItemAtPos(new Pos_2d(5, 6)), true); // NULL