Created
April 15, 2011 06:17
-
-
Save goatslacker/921230 to your computer and use it in GitHub Desktop.
A tiles test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$tiles1 = array( | |
"11", // 1 | |
"23", | |
"", | |
"44", // 2 | |
"11", | |
"", | |
"16", // 3 | |
"36", | |
"", | |
"51", // 4 | |
"71", | |
"", | |
"46", // 5 | |
"26", | |
"", | |
"14", // 6 | |
"68", | |
0); | |
$tiles2 = array( | |
"12", // 1 | |
"34", | |
"", | |
"36", // 2 | |
"15", | |
"", | |
"56", // 3 | |
"78", | |
"", | |
"78", // 4 | |
"90", | |
"", | |
"46", // 5 | |
"26", | |
"", | |
"88", // 6 | |
"01", | |
"", | |
"93", // 7 | |
"54", | |
0); | |
$tiles3 = array( | |
"11", // 1 | |
"12", | |
"", | |
"12", // 2 | |
"93", | |
"", | |
"93", // 3 | |
"99", | |
"", | |
"39", // 4 | |
"98", | |
"", | |
"95", // 5 | |
"86", | |
"", | |
"57", // 6 | |
"66", | |
"", | |
"77", // 7 | |
"57", | |
"", | |
"13", // 8 | |
"24", | |
"", | |
"45", // 9 | |
"47", | |
"", | |
"24", // 10 | |
"39", | |
0); | |
function link_tiles (array $tile_list) { | |
// the virtual grid | |
$grid = new Tiles(); | |
// split the array into tiles | |
$tiles = array_chunk($tile_list, 3); | |
// the no of tiles | |
$tileNo = 1; | |
foreach ($tiles as $tile) { | |
echo "link " . $tileNo; | |
echo "\n"; | |
// drop the last element | |
$tile = new Tile($tile); | |
// Hack -- need to use a better way to detect if two quadrants match | |
// should've looked at example3 better! | |
$match = false; | |
// if the virtual grid is empty, add the item and move on | |
if ($grid->isEmpty()) { | |
// add the tile to the virtual grid | |
$grid->add($tile, array(0, 0)); | |
$match = true; | |
// we need to check the grid to find any possible matches | |
} else { | |
// first we get all available corners we're going to look through. | |
// Josh's definition of a corner is any item that's "hanging out there" the top, left, right or bottom must have 2 empty spots | |
// those 2 empty spots will be filled with my tile! (if it fits of course) | |
// we loop through each corner until we find a match | |
// we WILL find a match, they promised me we will! | |
for ($i = 0; $i < 360; $i = $i + 90) { | |
foreach ($grid->getCorners() as $xy) { | |
if ($grid->checkCorners(array($xy[0], $xy[1]), $tile) === false) { | |
continue; | |
} | |
$match = $xy; | |
} | |
if ($match) { | |
$grid->add($tile, array($match[0], $match[1])); | |
break; | |
} | |
$tile->rotate90(); | |
} | |
} | |
// add the link ct | |
$tileNo = $tileNo + 1; | |
// echo out the current progess | |
$grid->toString(); | |
// add a line break because it's pretty | |
echo "\n"; | |
// reset | |
$match = false; | |
} | |
} | |
class Tiles { | |
private $grid = array(); | |
public function getGrid () { | |
return $this->grid; | |
} | |
public function add (Tile $tile, $where) { | |
$top = $tile->getTop(); | |
$bottom = $tile->getBottom(); | |
$this->grid[$where[0]][$where[1]] = $top[0]; | |
$this->grid[$where[0]][$where[1] + 1] = $top[1]; | |
$this->grid[$where[0] + 1][$where[1]] = $bottom[0]; | |
$this->grid[$where[0] + 1][$where[1] + 1] = $bottom[1]; | |
//ksort($this->grid); | |
} | |
public function toString () { | |
$xy = $this->getSquareBlock(); | |
for ($x = $xy[0]; $x <= $xy[1]; $x = $x + 1) { | |
if (array_key_exists($x, $this->grid)) { | |
for ($y = $xy[0]; $y <= $xy[1]; $y = $y + 1) { | |
if (array_key_exists($y, $this->grid[$x])) { | |
echo $this->grid[$x][$y]; | |
} else { | |
echo " "; | |
} | |
} | |
} else { | |
echo " "; | |
} | |
echo "\n"; | |
} | |
} | |
public function checkCorners (array $point, Tile $tile) { | |
//tlXY stands for Top-Left XY - it's the top-left of the square's XY coordinates | |
// a tlXY of -2, 0 means that we'll have to check -3, 0; | |
$TLX = $point[0]; | |
$TLY = $point[1]; | |
$matches = 0; | |
// do topLeft | |
// top | |
if (array_key_exists($TLX - 1, $this->grid)) { | |
if (array_key_exists($TLY, $this->grid[$TLX - 1])) { | |
if ($tile->topLeftIsEqualTo($this->grid[$TLX - 1][$TLY])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
if (array_key_exists($TLX, $this->grid)) { | |
if (array_key_exists($TLY - 1, $this->grid[$TLX])) { | |
// left | |
if ($tile->topLeftIsEqualTo($this->grid[$TLX][$TLY - 1])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
// do topRight | |
if (array_key_exists($TLX - 1, $this->grid)) { | |
if (array_key_exists($TLY + 1, $this->grid[$TLX - 1])) { | |
// top | |
if ($tile->topRightIsEqualTo($this->grid[$TLX - 1][$TLY + 1])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
if (array_key_exists($TLX, $this->grid)) { | |
if (array_key_exists($TLY + 2, $this->grid[$TLX])) { | |
// right | |
if ($tile->topRightIsEqualTo($this->grid[$TLX][$TLY + 2])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
// do bottomLeft | |
if (array_key_exists($TLX + 2, $this->grid)) { | |
if (array_key_exists($TLY, $this->grid[$TLX + 2])) { | |
// bottom | |
if ($tile->bottomLeftIsEqualTo($this->grid[$TLX + 2][$TLY])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
if (array_key_exists($TLX + 1, $this->grid)) { | |
if (array_key_exists($TLY - 1, $this->grid[$TLX + 1])) { | |
// left | |
if ($tile->bottomLeftIsEqualTo($this->grid[$TLX + 1][$TLY - 1])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
// do bottomRight | |
if (array_key_exists($TLX + 2, $this->grid)) { | |
if (array_key_exists($TLY + 1, $this->grid[$TLX + 2])) { | |
// bottom | |
if ($tile->bottomRightIsEqualTo($this->grid[$TLX + 2][$TLY + 1])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
if (array_key_exists($TLX + 1, $this->grid)) { | |
if (array_key_exists($TLY + 2, $this->grid[$TLX + 1])) { | |
// right | |
if ($tile->bottomRightIsEqualTo($this->grid[$TLX + 1][$TLY + 2])) { | |
$matches = $matches + 1; | |
} else { | |
return false; | |
} | |
} | |
} | |
// if two match, we're golden... | |
return ($matches >= 2); | |
} | |
public function isEmpty () { | |
return (count($this->grid) === 0); | |
} | |
public function getSquareBlock () { | |
$top = $this->getTopMost(); | |
$left = $this->getLeftMost(); | |
$right = $this->getRightMost(); | |
$bottom = $this->getBottomMost(); | |
return array(($top < $left) ? $top : $left, ($right > $bottom) ? $right : $bottom); | |
} | |
private function getLeftMost () { | |
$tmp = $this->grid; | |
ksort($tmp); | |
$min = 0; | |
foreach ($tmp as $grid) { | |
ksort($grid); | |
$minChallenger = array_shift(array_keys($grid)); | |
$min = ($min > $minChallenger) ? $minChallenger : $min; | |
} | |
return $min; | |
} | |
private function getTopMost () { | |
$tmp = $this->grid; | |
ksort($tmp); | |
return array_shift(array_keys($tmp)); | |
} | |
private function getRightMost () { | |
$tmp = $this->grid; | |
ksort($tmp); | |
$min = 0; | |
foreach ($tmp as $grid) { | |
ksort($grid); | |
$minChallenger = array_pop(array_keys($grid)); | |
$min = ($min < $minChallenger) ? $minChallenger : $min; | |
} | |
return $min; | |
} | |
private function getBottomMost () { | |
$tmp = $this->grid; | |
ksort($tmp); | |
return array_pop(array_keys($tmp)); | |
} | |
public function getCorners () { | |
$xy = $this->getSquareBlock(); | |
$corners = array(); | |
for ($x = $xy[0]; $x <= $xy[1]; $x = $x + 1) { | |
if (array_key_exists($x, $this->grid)) { | |
for ($y = $xy[0]; $y <= $xy[1]; $y = $y + 1) { | |
// skip the ones that don't have any values | |
if (!array_key_exists($x, $this->grid) || !array_key_exists($y, $this->grid[$x])) { | |
continue; | |
} | |
// if top 2 are empty | |
if (array_key_exists($y + 1, $this->grid[$x])) { | |
if (!array_key_exists($x - 1, $this->grid) || | |
(!array_key_exists($y, $this->grid[$x - 1]) && !array_key_exists($y + 1, $this->grid[$x - 1])) | |
) { | |
array_push($corners, array($x - 2, $y)); | |
} | |
} | |
// if left 2 are empty | |
if (array_key_exists($x + 1, $this->grid)) { | |
if (!array_key_exists($y - 1, $this->grid[$x]) && !array_key_exists($y - 1, $this->grid[$x + 1])) { | |
array_push($corners, array($x, $y - 2)); | |
} | |
} | |
// if bottom 2 are empty | |
if (array_key_exists($y + 1, $this->grid[$x])) { | |
if (!array_key_exists($x + 1, $this->grid) || | |
(!array_key_exists($y, $this->grid[$x + 1]) && !array_key_exists($y + 1, $this->grid[$x + 1])) | |
) { | |
array_push($corners, array($x + 1, $y)); | |
} | |
} | |
// if right 2 are empty | |
if (array_key_exists($x + 1, $this->grid)) { | |
if (!array_key_exists($y + 1, $this->grid[$x]) && !array_key_exists($y + 1, $this->grid[$x + 1])) { | |
array_push($corners, array($x, $y + 1)); | |
} | |
} | |
} // end Y loop | |
} // endIf | |
} // end X for | |
return $corners; | |
} | |
} | |
class Tile { | |
private $tile; | |
public function __construct ($tile) { | |
if (count($tile) > 2) { | |
$tile = array_slice($tile, 0, 2); | |
} | |
$this->tile = array( | |
array( | |
substr($tile[0], 0, 1), | |
substr($tile[0], 1, 1) | |
), | |
array( | |
substr($tile[1], 0, 1), | |
substr($tile[1], 1, 1) | |
) | |
); | |
} | |
public function getTile () { | |
return $this->tile; | |
} | |
public function getTop () { | |
return array($this->tile[0][0], $this->tile[0][1]); | |
} | |
public function getRight () { | |
return array($this->tile[0][1], $this->tile[1][1]); | |
} | |
public function getBottom () { | |
return array($this->tile[1][0], $this->tile[1][1]); | |
} | |
public function getLeft () { | |
return array($this->tile[0][0], $this->tile[1][0]); | |
} | |
public function rotate90 () { | |
$this->tile = array( | |
array( | |
$this->tile[1][0], | |
$this->tile[0][0] | |
), | |
array( | |
$this->tile[1][1], | |
$this->tile[0][1] | |
) | |
); | |
return $this; | |
} | |
public function rotate180 () { | |
$this->tile = array( | |
array( | |
$this->tile[1][1], | |
$this->tile[1][0] | |
), | |
array( | |
$this->tile[0][1], | |
$this->tile[0][0] | |
) | |
); | |
return $this; | |
} | |
public function rotate270 () { | |
$this->tile = array( | |
array( | |
$this->tile[0][1], | |
$this->tile[1][1] | |
), | |
array( | |
$this->tile[0][0], | |
$this->tile[1][0] | |
) | |
); | |
return $this; | |
} | |
public function topLeftIsEqualTo ($grid) { | |
$topLeft = $this->getTop(); | |
return ($topLeft[0] === $grid); | |
} | |
public function topRightIsEqualTo ($grid) { | |
$topRight = $this->getTop(); | |
return ($topRight[1] === $grid); | |
} | |
public function bottomLeftIsEqualTo ($grid) { | |
$bottomLeft = $this->getBottom(); | |
return ($bottomLeft[0] === $grid); | |
} | |
public function bottomRightIsEqualTo ($grid) { | |
$bottomRight = $this->getBottom(); | |
return ($bottomRight[1] === $grid); | |
} | |
public function topIsEqualTo ($grid) { | |
return ($this->assertEquals($this->getTop(), $grid)); | |
} | |
public function leftIsEqualTo ($grid) { | |
return ($this->assertEquals($this->getLeft(), $grid)); | |
} | |
public function bottomIsEqualTo ($grid) { | |
return ($this->assertEquals($this->getBottom(), $grid)); | |
} | |
public function rightIsEqualTo ($grid) { | |
return ($this->assertEquals($this->getRight(), $grid)); | |
} | |
private function assertEquals ($grid1, $grid2) { | |
return ($grid1[0] === $grid2[0] && $grid1[1] === $grid2[1]); | |
} | |
} | |
link_tiles($tiles1); | |
echo "\n"; | |
link_tiles($tiles2); | |
echo "\n"; | |
link_tiles($tiles3); | |
echo "\n"; | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment