Grid Class
PHP Code Examples
[Download]
<?php
// Represents a grid of dots.  Send it the size and zero or more points
// to mark in the grid.
class point_grid {
	private $width, $height;		// Size of the grid
	private $points;			// List of points.

	// This function takes a first argument which
	// is a value to set positions the grid array.  The rest of the
	// arguments are points or arrays of points.  The array structure is
	// recursively flattened to give an array of points, which are then
	// all set to the value.  The list items are taken in pairs to
	// indicate the points.  If the number of points coordinates is odd,
	// the last one is ignored.  Points outside the area of the grid are
	// also ignored.
	private function set_items($setto) {
		// Get the array of arguments, and extract the value to
		// set from the front.
		$args = func_get_args();
		$setto = array_shift($args);

		// Get a flat array of all the coordinates.
		$coords = array();
		while(count($args) > 0) {
			// Get the next arg, which may be a coord or an array.
			$arg = array_shift($args);

			if(is_array($arg)) 
				// If head is an array, flatten.
				$args = array_merge($arg, $args);
			else
				// Not an array, just add to our list.
				$coords[] = $arg;
		}

		// Set the points.
		$ct = 2*(int)(count($coords)/2);
		for($i = 0; $i < $ct; $i += 2) {
			$x = $coords[$i];
			$y = $coords[$i + 1];
			if(0 <= $x && $x < $this->width && 
					0 <= $y && $y < $this->height)
				$this->points["$x,$y"] = $setto;
		}
	}

	// Set a list of points.
	function set() {
		$pts = func_get_args();
		$this->set_items(1, $pts);
	}

	// Clear a list of points.
	function clear() {
		$pts = func_get_args();
		$this->set_items(0, $pts);
	}

	// Construct of a given size, with optional extra points.
	function __construct($x, $y) {
		// Set up internal variables.
		$this->width = $x;
		$this->height = $y;
		$this->points = array();

		// Apply any additional points.
		$pts = func_get_args();
		array_shift($pts);
		array_shift($pts);
		$this->set_items(1, $pts);
	}

	// Generate the grid as a table.
	function gen($tab = "", $td = "") {
		$dot = '<img style="width: 6px; height: 6px;" ' .
				'src="/~bennet/icons/bluedot.gif">';
		$blank = '<img style="width: 6px; height: 6px;" ' .
				'src="/~bennet/icons/blank.gif">';
		echo "<table $tab>\n";
		for($r = 0; $r < $this->height; ++$r) {
			print "<tr>";
			for($c = 0; $c < $this->width; ++$c)
				if($this->points["$c,$r"] == 1)
					echo "<td $td>$dot</td>";
				else
					echo "<td $td>$blank</td>";
			print "</tr>\n";
		}
		print "</table>";

	}

	// Append another grid to the right of this one.  The height of
	// the result will be the maximum of the two input heights.
	function append($og) {
		// Fix up the dimensions.
		$oldwidth = $this->width;
		$this->width += $og->width;
		if($this->height < $og->height)
			$this->height = $og->height;

		// Add the points.
		foreach(array_keys($og->points) as $pt) {
			if($og->points[$pt] != 1) continue;
			list($x, $y) = explode(',', $pt);
			$this->set($x + $oldwidth, $y);
		}
	}
}

// Classes to represent the digits in dot grids.
class zero_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			    1,0, 2,0, 3,0,
			0,1,              4,1,
			0,2,              4,2,
			0,3,              4,3,
			0,4,              4,4,
			    1,5, 2,5, 3,5);
	}
}

class one_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			     1,0, 2,0,
			          2,1,
			          2,2,
			          2,3,
			     	  2,4,
		 	     1,5, 2,5, 3,5);
	}
}

class two_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			    1,0, 2,0, 3,0,
			0,1,              4,1,
		 	             3,2,
			         2,3,
			     1,4,
			0,5, 1,5, 2,5, 3,5, 4,5);
	}
}

class three_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			    1,0, 2,0, 3,0,
			0,1,               4,1,
		 	         2,2,  3,2,
				           4,3,
			0,4,		   4,4,
			    1,5, 2,5, 3,5);
	}
}

class four_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			0,0,                4,0,
			0,1,                4,1,
			0,2,                4,2,
			0,3, 1,3, 2,3, 3,3, 4,3,
				            4,3,
				            4,4,
				            4,5);

	}
}

class five_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			0,0, 1,0, 2,0, 3,0, 4,0,
			0,1,                
			0,2, 1,2, 2,2, 3,2, 
					    4,3,
			0,4,	            4,4,
			     1,5, 2,5, 3,5);

	}
}

class six_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			    1,0, 2,0, 3,0,
			0,1,               
		 	0,2, 1,2, 2,2, 3,2,
			0,3,	           4,3,
			0,4,		   4,4,
			    1,5, 2,5, 3,5);
	}
}

class seven_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			0,0, 1,0, 2,0, 3,0, 4,0,
			                    4,1,
				            4,2,
				       3,3,
				  2,4,
			          2,5);

	}
}

class eight_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			    1,0, 2,0, 3,0,
			0,1,               4,1,
		 	    1,2, 2,2, 3,2,
			0,3,	           4,3,
			0,4,		   4,4,
			    1,5, 2,5, 3,5);
	}
}

class nine_grid extends point_grid {
	function __construct() {
		parent::__construct(5, 6,
			    1,0, 2,0, 3,0,
			0,1,               4,1,
		 	    1,2, 2,2, 3,2, 4,2,
				           4,3,
					   4,4,
			    1,5, 2,5, 3,5);
	}
}

// A grid to represent a number
class grid_number extends point_grid {
	// Returns the grid for the digit.
	function dig_grid($digit) {
		switch($digit) {
		case '0':
			return new zero_grid();
		case '1':
			return new one_grid();
		case '2':
			return new two_grid();
		case '3':
			return new three_grid();
		case '4':
			return new four_grid();
		case '5':
			return new five_grid();
		case '6':
			return new six_grid();
		case '7':
			return new seven_grid();
		case '8':
			return new eight_grid();
		case '9':
			return new nine_grid();
		default:
			// Bad digit --- blanks.
			return new point_grid(5, 6);
		}
	}

	// Construct the grid showing the number.
	function __construct($num) {
		// Separator.
		$sep = new point_grid(1, 1);

		// First digit.
		parent::__construct(0,0);
		$this->append($this->dig_grid($num[0]));

		// Other digits (with separator).
		$len = strlen($num);
		for($i = 1; $i < $len; ++$i) {
			$this->append($sep);
			$this->append($this->dig_grid($num[$i]));
		}
	}
}

?>