Maximum Density Still Life:LifeGrid

From CometPublic

Jump to: navigation, search

This is the model of a section of the Game of Life board used in Maximum Density Still Life. It uses the StillCell class.

include "StillCell";

/**
 * This class implements a rectangular section of the "Game of Life" board
 */
class LifeGrid
{
	LocalSolver _m;
	ConstraintSystem _S;
	int _h;
	int _w;
	range _Height;
	range _Width;
	int _numCells;
	
	var{int}[,] _alive;
	var{int} _numAlive;
	var{int} _numDead;

	/**
	 * Builds a new LifeGrid
	 * @param height The height the section to consider
	 * @param width The width of the section to consider
	 * @param initNull If set to true, the section will be initialized with dead (0) cells
	 *		else with live (1) cells.
	 */
	LifeGrid(int height, int width, bool initNull)
	{
		_m = new LocalSolver();
		_S = new ConstraintSystem(_m);
		_h = height;
		_w = width;
		_numCells = _w*_h;
		_Height = 1.._h;
		_Width = 1.._w;
		
		_alive = new var{int}[i in (-1.._h+2),j in (-1.._w+2)](_m, 0..1) := initNull ? 0 : (i <= 0 || j <= 0 || i >= _h+1 || j >= _w+1 ? 0 : 1);
		_numAlive = new var{int}(_m) <- sum(i in _Height) sum(j in _Width) _alive[i,j];
		_numDead = new var{int}(_m) <- _numCells - _numAlive;
		
		forall (i in 0.._h+1) {
			forall (j in 0.._w+1) {
				var{int} array[0..7](_m);
				int c = 0;
				forall (k in -1..1)
					forall (l in  -1..1)
						if (k != 0 || l != 0)
							array[c++] = _alive[i + k, j + l];
				StillCell sc(_alive[i, j], array);
				_S.post(sc);
			}
		}
	}
	
	/**
	 * @return The constraint system used to define the board constraints.
	 */
	ConstraintSystem getConstraintSystem()
	{
		return _S;
	}
	
	/**
	 * @return The local solver used to define the board variables
	 */
	LocalSolver getLocalSolver()
	{
		return _m;
	}
	
	/**
	 * @retun The whole grid of cells (including the boarder cells which allways value to 0
	 */
	var{int}[,] getGrid()
	{
		return _alive;
	}
	
	/**
	 * @return The number of cells in the grid
	 */
	int getNumCells()
	{
		return _numCells;
	}
	
	/**
	 * @return an incremental variable associated with the number of live cells
	 */
	var{int} getNumAlive()
	{
		return _numAlive;
	}
	
	/**
	 * @return an incremental variable associated with the number of dead cells
	 */
	var{int} getNumDead()
	{
		return _numDead;
	}
	
	/**
	 * @return an incremental variable associated with the number of violations of the constraints.
	 */
	var{int} violations()
	{
		return _S.violations();
	}
	
	/**
	 * Closes the model. This is mendatory before starting the search.
	 */
	void close()
	{
		_m.close();
	}
	
	/**
	 * Prints the state of the model in a human-readable form.
	 */
	void prettyPrint()
	{
		cout << "violations : " << violations() << "; num alive : " << getNumAlive() << endl;
		forall (i in _Height) {
			forall (j in _Width)
				cout << (_alive[i, j] == 1 ? "[]" : "  ");
			cout << endl;
		}
	}
}