⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cellspace.java

📁 Sugarscape模型仿真
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package GameOfLife;

import java.awt.*;
import java.util.*;

public class CellSpace extends Canvas
{
	//constants ->growthTYPE->growCellSugar()
	static int SEED = 0, RENEW = 1;
	//constants ->detailLevel->showStatus()
	static int DETAIL = 0, ALL = 1, SUMMARY = 2;

	public int generations = 0;
	public int population;
	public int sugarCount;
	static int destinationI = -1, destinationJ = -1;
	private int cellSize;
	private int cellRows;
	private int cellCols;
	private boolean cellUnderMouse;
	private boolean cells[][];
	private int cellsBuffer[][];
	private double cellsSugar[][];
	private Image offScreenImage = null;
	private Graphics offScreenGraphics;
	private Citizen citizen[][];

	//datastream - collects data from multiple methods
	private String bigDataStream;

	public CellSpace( int cellSize, int cellCols, int cellRows )
	{
		cells = new boolean[cellCols][cellRows];
		cellsBuffer = new int[cellCols][cellRows];
		cellsSugar 	= new double[cellCols][cellRows];

		//array of citizen - not all elements actually contain citizens
		citizen = new Citizen[cellCols][cellRows];
		for (int i=0;i<cellCols;i++)
			for (int j=0;j<cellRows;j++)
				citizen[i][j]= new Citizen();

		this.cellSize = cellSize;
		this.cellCols = cellCols;
		this.cellRows = cellRows;

		//generate a sugar distribution in CellSpace
		growCellSugar( SEED );
		//display sugar distribution
		if( GoLconst.DEBUG || GoLconst.DEBUG_CELLSCAPE_SUGAR )
		{	bigDataStream += showSugarscapeStats(0,0,cellCols,cellRows);	} //display sugar distribution

		reshape(0, 0, cellSize*cellCols-1, cellSize*cellRows-1);
		//Initialize grid & list of citizens
		clear();
	}

	public int getCellRows()
	{	return cellRows;	}

	public int getCellCols()
	{	return cellCols;	}

	public int getCellSugar(int col, int row)
	{	return (int) cellsSugar[col][row];	}

	public void setCellSugar(int col, int row)
	{	//**The decimal portion of sugar is currently discarded
		cellsSugar[col][row] = 0.0;
	}

	/***Generate initial/periodic distribution of sugar in Cellspace***/
	public void growCellSugar(int growthType)
	{	sugarCount = 0;
		for(int i = 0; i<cellCols; i++)
			for(int j = 0; j < cellRows; j++)
			{	if( growthType == RENEW )
				{	//renew available sugar up to max cell capacity
					if( GoLconst.LIMIT_CELL_SUGAR )
						cellsSugar[i][j] += cellsSugar[i][j] < GoLconst.SUGAR_MAX_CELL ?
												GoLconst.SUGAR_RENEW : 0;
					else
						cellsSugar[i][j] += GoLconst.SUGAR_RENEW;
				} else
				{	if( Math.random() > GoLconst.GRID_FERTILITY )
						cellsSugar[i][j] = 0.0;
					else
						cellsSugar[i][j] = ( (int)(Math.random() *
												GoLconst.SUGAR_MAX_CELL) );
				}
				sugarCount += cellsSugar[i][j];
			}
	}

	public synchronized boolean mouseUp(java.awt.Event evt, int x, int y) {
		toggleCellUnderMouse( x,y );
		return true;
	}

	public synchronized boolean mouseDown(java.awt.Event evt, int x, int y)
	{	try { cellUnderMouse = cells[x/cellSize][y/cellSize];
		} catch ( java.lang.ArrayIndexOutOfBoundsException e ) {}
		return true;
	}

	public synchronized boolean mouseDrag(java.awt.Event evt, int x, int y)
	{	toggleCellUnderMouse( x,y );
		return true;
	}

	public synchronized boolean toggleCellUnderMouse(int x, int y)
	{	//Determine Col from pixel position on grid
		int col = x/cellSize, row = y/cellSize;

		// toggle cell
		try { cells[col][row] = !cellUnderMouse; }
		catch ( java.lang.ArrayIndexOutOfBoundsException e ) {}

		//Cell toggled ON - create new citizen
		if( cells[col][row] )
		{	int RANDOM = -1;
			citizen[col][row].setVision(RANDOM);
			citizen[col][row].setMetabolism(RANDOM);
			citizen[col][row].sugar = citizen[col][row].setSugar(RANDOM)
										+ getCellSugar(col,row);
			setCellSugar(col,row);		//cell sugar content set to zero
			population++;

			if( GoLconst.DEBUG || GoLconst.DEBUG_CREATE_CITIZEN )
			{	bigDataStream += showCitizenStats("Born! Citizen", col, row);	}
		} else	//Cell toggled OFF - so kill citizen
		{
			citizen[col][row].setVision(0);
			citizen[col][row].setMetabolism(0);
			citizen[col][row].setSugar(0);
			population--;

			if( GoLconst.DEBUG || GoLconst.DEBUG_CREATE_CITIZEN )
			{	bigDataStream += showCitizenStats("Died! Citizen", col, row);	}
		}
		repaint();
		return true;
	}

	public synchronized void update( Graphics theG )
	{
		Dimension d = size();
		if((offScreenImage == null) ) {
			offScreenImage = createImage( d.width, d.height );
			offScreenGraphics = offScreenImage.getGraphics();
		}
		paint(offScreenGraphics);
		theG.drawImage( offScreenImage, 0, 0, null );
	}

	public void paint(Graphics g)
	{	int colorVal;
		// draw background (MSIE doesn't do that)
		g.setColor( Color.lightGray );	//sets/resets window background -  new Color(0,0,240)
		//font setting for grid coordinates
		g.setFont( new java.awt.Font("Verdana",Font.PLAIN,(int)(cellSize/2.5)) );
		//draws the window background for the grid
		g.fillRect( 0, 0, cellSize*cellCols-1, cellSize*cellRows-1 );
		// draw grid
		g.setColor( getBackground() );

		//draw the vertical lines on the grid
		for( int x=1; x<cellCols; x++ )
		{	g.drawLine( x*cellSize-1, 0, x*cellSize-1, cellSize*cellRows-1 );	}
		//draw the horizontal lines on the grid
		for( int y=1; y<cellRows; y++ )
		{	g.drawLine( 0, y*cellSize-1, cellSize*cellCols-1, y*cellSize-1 );	}

		// draw populated cells
		g.setColor( Color.gray );
		for( int x=0; x<cellCols; x++ ) {
			for( int y=0; y<cellRows; y++ )
			{	//**All Menu Selections Other Than Sugarscape
				if( !GoLconst.flagSugarscape )
				{	if ( cells[x][y] )
					{	g.setColor( Color.yellow );	}
					else g.setColor( Color.gray );

					g.fillRect( x*cellSize, y*cellSize, cellSize-1, cellSize-1 );
					continue;
				}

				//**If Cell Occupied, Draw Citizen
				if ( cells[x][y] )
				{	int currVision 			= citizen[x][y].getVision();
					int currMetabolism 		= citizen[x][y].getMetabolism();
					int currSugar 			= citizen[x][y].getSugar();
					int currSugarReserve 	= currSugar / currMetabolism;

					//Determine color of citizen object//
					if( currSugarReserve < 10 )
					//Color.red - gets darker with increasing sugar reserve
					{	g.setColor( new Color(255-(currSugarReserve*10),0,0) );	}
					else if( currSugarReserve > 100 )
					//Color.green - gets darker with increasing sugar reserve
					{	g.setColor( new Color(0,
							255-( currSugarReserve>200?200:currSugarReserve ),0) ); }
					else
					//Color.orange changes to yellow as sugar reserve increases
					{	g.setColor( new Color(254,155+currSugarReserve,0) );}

					/**Determine shape of citizen object**/
					// if HIGH vision & HIGH metabolism draw filled CIRCLE
					if( (currVision >= (0.5 * GoLconst.VISION_MAX)) &&
						(currMetabolism >= (0.5 * GoLconst.METABOLISM_MAX)) )
					{	g.fillOval( x*cellSize, y*cellSize, cellSize-1, cellSize-1 );	}

					// if LOW vision & HIGH metabolism draw filled RECTANGLE
					else if( (currVision < (0.5 * GoLconst.VISION_MAX)) &&
						(currMetabolism >= (0.5 * GoLconst.METABOLISM_MAX)) )
					{	g.fillRect( x*cellSize, y*cellSize, cellSize-1, cellSize-1 );	}

					// if HIGH vision & LOW metabolism draw filled PLUS sign
					else if( (currVision >= (0.5 * GoLconst.VISION_MAX)) &&
							(currMetabolism < (0.5 * GoLconst.METABOLISM_MAX)) )
					{	g.fillRect( (x*cellSize)+(cellSize/3), y*cellSize, (cellSize-1)/3, cellSize-1 );
						g.fillRect( x*cellSize, y*cellSize+(cellSize/3), cellSize-1, (cellSize-1)/3 );
					}

					// if LOW vision & LOW metabolism draw filled INVERTED ARC's
					else if( (currVision < (0.5 * GoLconst.VISION_MAX)) &&
							(currMetabolism < (0.5 * GoLconst.METABOLISM_MAX)) )
					{	g.fillArc( x*cellSize, y*cellSize, cellSize, cellSize,30,120 );
						g.fillArc( x*cellSize, y*cellSize, cellSize, cellSize,210,120 );
					}
				}
				else	//Empty Cell, Determine Color Based on Available Sugar
				{	int currCellSugar = getCellSugar(x,y);
					g.setColor( Color.lightGray );

					if( currCellSugar >= GoLconst.SUGAR_MAX_CELL )
					{	g.setColor( Color.darkGray );	}
					else if( currCellSugar > 0 && currCellSugar < GoLconst.SUGAR_MAX_CELL  )
					{	colorVal = (int)( (( (double)currCellSugar / (double)GoLconst.SUGAR_MAX_CELL )
											* 100) * 1.28 );
						g.setColor( new Color(	192 - colorVal,	192 - colorVal,	192 - colorVal) );	}
					//Fill Based on Determined Color
					g.fillRect( x*cellSize, y*cellSize, cellSize-1, cellSize-1 );

					//Write cell coordinates
					if( GoLconst.GRID_COORD_SHOW )
					{
						if(  GoLconst.GRID_COORD_DETAIL==0 ||
							(GoLconst.GRID_COORD_DETAIL==1 && (x == cellCols-1 || y == cellRows-1)) ||
							(GoLconst.GRID_COORD_DETAIL==2 && x == cellCols-1) ||
							(GoLconst.GRID_COORD_DETAIL==3 && y == cellRows-1) ||
							(GoLconst.GRID_COORD_DETAIL==4 && x == cellCols-1 && y == cellRows-1)	)
						{
							if( GoLconst.GRID_COORD_COLOR == "blue" )
								g.setColor( Color.blue);
							else if( GoLconst.GRID_COORD_COLOR == "red" )
								g.setColor( Color.red );
							else if( GoLconst.GRID_COORD_COLOR == "green" )
								g.setColor( Color.green );
							else g.setColor( Color.black );

							g.drawString(x+","+y, x*cellSize, (y+1)*cellSize-1);
						}
					}
				}
			}
		}
	}

	//Clears Grid & Citizen List
	public synchronized void clear() {
		generations = 0;
		population = 0;
		for( int x=0; x<cellCols; x++ ) {
			for( int y=0; y<cellRows; y++ ) {
				cells[x][y] = false;

				//If Sugarscape, Clear Citizen List as well
				if( GoLconst.flagSugarscape )
				{
					citizen[x][y].setVision(0);
					citizen[x][y].setMetabolism(0);
					citizen[x][y].setSugar(0);
				}
			}
		}
	}

	// create next generation of shape
	public synchronized void next()
	{	int x;
		int y;
		generations++;
		// clear the buffer
		for( x=0; x<cellCols; x++ )
			for( y=0; y<cellRows; y++ )
			{	cellsBuffer[x][y] = 0;	}

		// count neighbors of off-edge cells
		for( x=1; x<cellCols-1; x++ )
			for( y=1; y<cellRows-1; y++ )
				if ( cells[x][y] )
				{	cellsBuffer[x-1][y-1]++;		cellsBuffer[x][y-1]++;
					cellsBuffer[x+1][y-1]++;		cellsBuffer[x-1][y]++;
					cellsBuffer[x+1][y]++;			cellsBuffer[x-1][y+1]++;
					cellsBuffer[x][y+1]++;			cellsBuffer[x+1][y+1]++;
				}

		// count neighbors of edge cells
		x=1; // start at (1,0)
		y=0;
		int dx=1;		int dy=0;
		while( true )
		{	if ( cells[x][y] )
			{	if ( x > 0 )
				{	if ( y > 0 )			{	cellsBuffer[x-1][y-1]++;	}
					if ( y < cellRows-1 )	{	cellsBuffer[x-1][y+1]++;	}
					cellsBuffer[x-1][y]++;
				}
				if ( x < cellCols-1 )
				{	if ( y < cellRows-1 )	{	cellsBuffer[x+1][y+1]++;	}
					if ( y > 0 )			{	cellsBuffer[x+1][y-1]++;	}
					cellsBuffer[x+1][y]++;
				}
				if ( y > 0 )				{	cellsBuffer[x][y-1]++;		}
				if ( y < cellRows-1 )		{	cellsBuffer[x][y+1]++;		}
			}

			// turn clockwise at collision with edge
			if ( x==cellCols-1 && y==0 )
			{	dx = 0;		dy = 1;		}
			else if ( x==cellCols-1 && y==cellRows-1 )
			{	dx = -1;	dy = 0;		}
			else if ( x==0 && y==cellRows-1 )
			{	dx = 0;		dy = -1;	}
			else if ( x==0 && y==0 ) // all edge cells done
			{	break;	}
			x += dx;
			y += dy;
		}

		// here is the life algorithm
		// simple, isn't it?
		for( x=0; x<cellCols; x++ )
			for( y=0; y<cellRows; y++ )
				switch( cellsBuffer[x][y] )
				{	case 2:		// no change
						break;
					case 3:
						cells[x][y] = true;
						break;
					default:
						cells[x][y] = false;
						break;
				}
	}

	// draws shape in cells
	// returns false if shape doesn't fit
	public synchronized boolean drawShape( int shapeWidth, int shapeHeight, int shape[] )
	{	int xOffset;
		int yOffset;

		if ( shapeWidth>cellCols || shapeHeight>cellRows )
			return false; // shape doesn't fit on canvas

		// center the shape
		xOffset = (cellCols-shapeWidth)/2;
		yOffset = (cellRows-shapeHeight)/2;
		clear();
		for ( int i=0; i < shape.length; i+=2 )
			cells[xOffset+shape[i]][yOffset+shape[i+1]] = true;
		return true;
	}

	public synchronized boolean drawRandomShape( )
	{	clear();
		for ( int i=0; i < cellCols; i++ )
			for ( int j=0; j < cellRows; j++ )
				if( ( (float)(Math.random()) ) < GoLconst.DENSITY_FACTOR)
					cells[i][j] = true;
		return true;
	}

	public synchronized String drawSugarscape( )
	{
		String dataStream = "";
		int RANDOM = -1;

		//initialize cells, population, generations & reseed Sugarscape
		clear();
		growCellSugar( SEED );

		//initialize cells, population & generations
		if( GoLconst.DEBUG_PROGRAM_FLOW )
		{	bigDataStream += "drawSugarscape(" + ")\n";		}
		if( GoLconst.DEBUG || GoLconst.DEBUG_CREATE_CITIZEN )
		{	dataStream += "Randomly populating the grid...\n";	}
		for(int i=0; i<cellCols; i++)
			for(int j=0; j<cellRows; j++)
				if( (float)(Math.random()) < GoLconst.DENSITY_FACTOR)
				{	cells[i][j] = true;

					citizen[i][j].vision = citizen[i][j].setVision(RANDOM);
					citizen[i][j].metabolism = citizen[i][j].setMetabolism(RANDOM);
					/*Initialize citizen sugar lvl & add curr cell sugar to it*/
					citizen[i][j].sugar = citizen[i][j].setSugar(RANDOM) + this.getCellSugar(i,j);
					setCellSugar(i,j);	//initialize cell sugar to zero
					population++;
					if( GoLconst.DEBUG || GoLconst.DEBUG_CREATE_CITIZEN )
					{	dataStream += showCitizenStats("Citizen", i,j);	}
				}
			//no closing brace FOR j
		//no closing brace FOR i
		if( GoLconst.DEBUG || GoLconst.DEBUG_CREATE_CITIZEN )
		{	dataStream += "Finished populating.., curr. population : " + population + "\n";	}

		return dataStream;
	}

	// Create next generation for Sugarscape
	public synchronized String nextScape(int detailLevel)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -