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

📄 cellspace.java

📁 Sugarscape模型仿真
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	{	bigDataStream = "";
		generations++;		//increment the generation count
		destinationI = -1;
		destinationJ = -1;

		if( GoLconst.DEBUG_PROGRAM_FLOW )
		{	bigDataStream += "nextScape(" + detailLevel + ")\n";	}

		//replenish sugar
		growCellSugar( RENEW );
		//Display Sugar Distribution
		if( GoLconst.DEBUG || GoLconst.DEBUG_CELLSCAPE_SUGAR )
		{	bigDataStream += showSugarscapeStats(0,0,cellCols,cellRows);	}

		for (int i=0; i<cellCols; i++)
			for (int j=0; j<cellRows; j++)
				if( cells[i][j] )	//cell contains a living citizen
				{	if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
					{	bigDataStream += "+-------------------------------------\n";
						bigDataStream += "Eating sugar [" +i+"][" +j+"]\t"
									+ citizen[i][j].getSugar() + "\n" ;
					}
					//eatSugar returns false if insufficient food
					if( !(citizen[i][j].eatSugar()) )
					{
						if( GoLconst.DEBUG || GoLconst.DEBUG_CREATE_CITIZEN
							|| GoLconst.DEBUG_CITIZEN_DEATH)
						{	bigDataStream += "\t";
							bigDataStream += showCitizenStats("Died! Citizen", i, j);
						}

						cells[i][j] = false;	//not enough food, citizen dies.
						citizen[i][j].setVision(0);
						citizen[i][j].setMetabolism(0);
						citizen[i][j].setSugar(0);
						population--;
						continue;				//interrupt & continue next loop
					}

					if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
					{	bigDataStream += "...balance " + citizen[i][j].getSugar() + "\n";	}

					/*Look Around for the most plentiful supply of sugar*/
					if( searchCellspace(i,j,'S') )	//search for sugar
					{
						if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
						{	bigDataStream += "Found sugar "
								+ getCellSugar(destinationI,destinationJ)
								+ ", moving from " + "[" +i+"]["+j+"]" + " to " + "["
								+ destinationI + "][" + destinationJ+"]\n";
						}
						if( GoLconst.DEBUG || GoLconst.DEBUG_CRITICAL_ERROR )
						{	if(	citizen[destinationI][destinationJ].getVision() > 0)
							//another citizen exists at current citizen's destination
								bigDataStream += showCitizenStats(
											"ERROR:Another citizen at destination ", i, j);
						}
						moveCellspaceCitizen(i, j, destinationI, destinationJ);
					}
					else
					{	if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
						{	bigDataStream += "***No sugar around cell[" +i+"]["+j+"]"
												+ ", moving random\n";
						}
						moveCellspaceRandom(i,j);
					}
				} //ENDIf cells[i][j]

		/*All cells should be false - chk cells containing citizens & activate them
		//by setting them to true*/
		population = 0;
		for (int i=0; i<cellCols; i++)
			for (int j=0; j<cellRows; j++)
			{	if( GoLconst.DEBUG || GoLconst.DEBUG_CRITICAL_ERROR )
				{	if( cells[i][j] )	//a cell marked living is found
						bigDataStream += showCitizenStats(
									"ERROR:Active Cell found unexpectedly ", i, j);
				}
				//Chk cells containing citizens & activate them
				if( citizen[i][j].getVision() > 0 )
				{	cells[i][j] = true;
					population++;
				}
			}

		if( GoLconst.DEBUG || GoLconst.DEBUG_CITIZEN_DETAIL)
		{	bigDataStream += showPopulationStats( detailLevel );	}

		return bigDataStream;
	}


	private boolean moveCellspaceCitizen(int fromI, int fromJ, int toI, int toJ)
	{	if( GoLconst.DEBUG_PROGRAM_FLOW )
		{	bigDataStream += "moveCellspaceCitizen(" + fromI + "," + fromJ
								+ "," + toI + "," + toJ + ")\n";
		}
		if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
		{		if( (fromI == toI) && (fromJ == toJ) )	//THIS DOES NOT MAKE SENSE
					bigDataStream += "moveCellspaceCitizen: Found random cell, moving from "
							+ "[" +fromI+"]["+fromJ+"]" + " to " + "[" +toI+"]["+toJ+"]\n";
		}
		if( cells[toI][toJ] )
		{	if( GoLconst.DEBUG || GoLconst.DEBUG_CRITICAL_ERROR )
			{	bigDataStream += showCitizenStats("ERROR:Attempted move to occupied cell! From ", fromI, fromJ);
				bigDataStream += showCitizenStats("\t\t\t...To ", toI, toJ);
				bigDataStream += "\n";
			}
			return false;
		}

		/* copy Citizen parameters to new Citizen */
		citizen[toI][toJ].setVision( citizen[fromI][fromJ].getVision() );
		citizen[toI][toJ].setMetabolism( citizen[fromI][fromJ].getMetabolism() );
		citizen[toI][toJ].setSugar( citizen[fromI][fromJ].getSugar() + this.getCellSugar(toI,toJ) );

		setCellSugar(toI,toJ);	//All sugar in new cell consumed, now set to zero

		/* Activate new cells only after entire grid completes current generation */
		cells[fromI][fromJ] = false;		//citizen has moved to new cell

		citizen[fromI][fromJ].setVision(0);
		citizen[fromI][fromJ].setMetabolism(0);
		citizen[fromI][fromJ].setSugar(0);
		return true;
	}

	private boolean moveCellspaceRandom(int col, int row)
	{	if( GoLconst.DEBUG_PROGRAM_FLOW )
		{	bigDataStream += "moveCellspaceRandom(" + col + "," + row + ")\n";	}

		if( searchCellspace(col,row,'D') )
		{	if( moveCellspaceCitizen(col, row, destinationI, destinationJ) )
			{	if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
				{	bigDataStream += "Found random cell, moving from " + "[" +col+"]["+row+"]"
						+ " to " + "[" +destinationI+"]["+destinationJ+"]\n";
				}
				return true;
			}
		}
		cells[col][row] = false;
		//Else - all cells occupied, citizen stays in current cell
		if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
			{	bigDataStream += "NO food, NO empty cells, staying put at "
									+ "[" +col+"]["+row+"]\n";	}
		return false;
	}

	private boolean searchCellspace( int col, int row, char searchType )
	{	int i0, j0, ix, jx;		//diagonal corners of vision grid
		destinationI = -1;
		destinationJ = -1;
		int currCitizenVision = 0;

		/*determine current citizen's vision grid*/
		currCitizenVision = citizen[col][row].getVision();
		i0 = col - currCitizenVision;
		j0 = row - currCitizenVision;
		ix = col + currCitizenVision;
		jx = row + currCitizenVision;
		/*ensure vision grid does not extend beyond Cellspace*/
		if(i0 < 0)	{i0 = 0;}
		if(j0 < 0)	{j0 = 0;}
		if(ix >= cellCols)	{	ix = cellCols - 1;	}
		if(jx >= cellRows)	{	jx = cellRows - 1;	}

		if( GoLconst.DEBUG_PROGRAM_FLOW )
		{	bigDataStream += "searchCellspace(" +col + "," +row + "," +searchType +")\n";	}

		//**Find Cell(s) at Greatest Distance - Randomly Select One Destination**
		if(searchType == 'D')
		{	int[][] distance = new int[cellCols][cellRows];
			int distanceVal = 0;
			int destinations = 0;

			/*Initialize Distance Array*/
			for(int i=0; i<cellCols; i++)
				for(int j=0; j<cellRows; j++)
					distance[i][j] = 0;

			/*Calculate Distance of Each Cell Within Scope of Vision*/
			for(int i=i0; i<=ix; i++)
				for(int j=j0; j<=jx; j++)
					if( !cells[i][j] && citizen[i][j].getVision() < 1 )
					{	//Calculate Distance to This Unoccupied Cell
						distance[i][j] = Math.abs(col-i) + Math.abs(row-j);
						//if this cell is more distant than current greatest distance
						if(distance[i][j] > distanceVal)
						{	distanceVal  = distance[i][j];
							//Initialize with discovery of greater distance
							destinations = 1;

							if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
							{	bigDataStream += "New Destination = " + destinations
									+ "\t Distance  of cell["+i+"]["+j+"] = "
									+ distance[i][j] + "\n";
							}
						}
						// another destination found, equal to current greatest distance
						else if( distance[i][j] == distanceVal  && distanceVal > 0)
						{	destinations++;
							if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
							{	bigDataStream += "Destination = " + destinations
									+ "\t Distance  of cell["+i+"]["+j+"] = "
									+ distance[i][j] + "\n";
							}
						}
					}
					else
						distance[i][j] = 0;	//cell occupied, distance irrelevant

			if( distanceVal == 0 )
			{	if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
				{	bigDataStream += "NO food, NO empty cells, staying put at "
									+ "[" +col+"]["+row+"]\n";
				}
				return false;	//No available cell within scope of vision
			}
			if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
			{	bigDataStream += "Greatest distance = " + distanceVal
								+ "\tTotal destinations = " + destinations + "\n";
				bigDataStream += "---NO food around cell " + "[" +col+"]["+row+"]\n";
				bigDataStream += "Greatest distance = " + distanceVal
										+ "\tTotal destinations = " + destinations + "\n";
			}
			/*Randomly set one of most distant cells as destination*/
			int randomDest = (int)(Math.random()* destinations) + 1;
			boolean foundDestination = false;

			if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
			{	bigDataStream += "Random Destination = " + randomDest + "\n";	}

			for(int i=i0; i<=ix; i++)
			{	if( foundDestination )
				{	break;	}

				for(int j=j0; j<=jx; j++)
				{	if( distance[i][j] == distanceVal )
					{	if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
						{	bigDataStream += "RandomDest = " + randomDest
							+ "\t Distance from cell["+col+"]["+row+"] = "
							+ distance[i][j] + "\n";
						}
						if( randomDest == 1)
						{	foundDestination = true;	//get out of the 2 For loops
							destinationI = i;
							destinationJ = j;
							if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR)
							{	bigDataStream += "***Destination found!!"
									+ "\t Distance to cell["+i+"]["+j+"] = "
									+ distance[i][j] + "\n";
							}
							break;
						}
						else
						{	randomDest--;
							if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
							{	bigDataStream += "Search next destination\n";	}
						}
			}	}	}	//END for i, for j & if
		}
		/*Seek best supply of sugar*/
		else if (searchType == 'S')
		{	int currCellSugar = 0;
			int destinationSugar = 0;
			int destinations = 0;

			if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
			{	bigDataStream += "Vision = " + citizen[col][row].getSugar() + "\n";
				bigDataStream += "Search grid for curr citizen ->i0 = " +i0+"  j0 = "
								+ j0 + "\tix = " + ix + "  jx = " + jx + "\n";
			}
			/*Find highest qty of sugar in any one cell*/
			for(int i=i0; i<=ix; i++)
				for(int j=j0; j<=jx; j++)
				{	currCellSugar = getCellSugar(i,j);
					//If Current Cell Sugar more Than Highest Sugar Amt Found
					if( currCellSugar > destinationSugar )
					{	destinationSugar = currCellSugar;
						destinations = 1;
						if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
						{	bigDataStream += "Cell["+i+"]["+j+"] contains"
												+ currCellSugar + " sugar\n";
						}
					}
					//If Current Cell Sugar Equals Highest Sugar Amt Found
					else if( currCellSugar == destinationSugar && destinationSugar > 0 )
					{	destinations++;
						if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
						{	bigDataStream += "Cell["+i+"]["+j+"] contains"
												+ currCellSugar + " sugar\n";
						}
					}
				}
				if( destinationSugar == 0 )		//if no sugar found
					return false;
				if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
				{	bigDataStream += "Highest sugar = " + destinationSugar
							+ "\tCells w/highest sugar = " + destinations + "\n";
				}

			/*randomly pick one out of the many cells that have the highest qty of sugar*/
			int randomDest = (int)(Math.random()* destinations) + 1;
			boolean foundDestination = false;
			if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
			{	bigDataStream += "Random Destination = " + randomDest + "\n";	}

			for(int i=i0; i<=ix; i++)
			{	if( foundDestination ) 		{	break;	}

				for(int j=j0; j<=jx; j++)
				{	currCellSugar = getCellSugar(i,j);
					if( currCellSugar == destinationSugar )
					{	if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
						{	bigDataStream += "RandomDest = " + randomDest
							+ "\t Sugar found in cell["+i+"]["+j+"]\n";
						}
						if( randomDest == 1)
						{	foundDestination = true;	//get out of the two For loops
							destinationI = i;
							destinationJ = j;
							break;
						} else		//Skip This Destination
						{	randomDest--;
							if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
							{	bigDataStream += "Search next destination\n";	}
						}
			}	}	}	//END for i, for j & if

			if( GoLconst.DEBUG || GoLconst.DEBUG_SEARCH_SUGAR )
			{	bigDataStream += "***Search over, RandomDest = " + randomDest
						+ "\tHighest sugar in cell["+destinationI+"]["+destinationJ+"]"
						+ "\tActual sugar " + getCellSugar(destinationI,destinationJ) + "\n";
				if( destinationSugar == 0 )
				{	bigDataStream += showCitizenStats( "No sugar found.", col, row);	}
			}
		}
		if(destinationI < 0)		//all cells occupied OR
			return false;			//no sugar available within area of vision
		else return true;
	}

	//**Display Basic/Detailed Stats on Cellspace Population
	public String showPopulationStats(int detailLevel)
	{
		String dataStream = "";
		if(detailLevel <= 1)	//Detail for each citizen
		{	for(int i=0; i<cellCols; i++)
				for(int j=0; j<cellRows; j++)
					if( cells[i][j] ) {	dataStream += showCitizenStats("Citizen",i,j);	}
			dataStream += "\n\n";
		} //ENDIf detailLevel <= 1

		//Aggregate & Per Capita detail for Sugarscape
		if(detailLevel >= 1)
		{	float visionTotal = 0;
			float metabolismTotal = 0;
			float sugarCitizens = 0;
			float sugarCellspace = 0;

			for(int i=0; i<cellCols; i++)
				for(int j=0; j<cellRows; j++)
					if( cells[i][j] )	//cell contains living citizen
					{	visionTotal 	+= citizen[i][j].getVision();
						metabolismTotal += citizen[i][j].getMetabolism();
						sugarCitizens	+= citizen[i][j].getSugar();
					}

			dataStream += "+--------------------------------+\n";
			dataStream += "|Grid size\t: "  	+ cellCols + "x" + cellRows + "\n";
			dataStream += "|Grid sugar\t: " 	+ sugarCount + "\n";
			dataStream += "|Population\t: " 	+ population + "\n";
			dataStream += "|Cells/Citizen\t: "	+ ((float)population/(cellCols*cellRows)) * 100.00
															+ "\n";
			dataStream += "|Sugar density\t: " + (float)sugarCount/(cellCols*cellRows) + "\n";
			dataStream += "|Avg vision\t: " 	+ (population/visionTotal) + "\n";
			dataStream += "|Avg metabolism\t: "+ (population/metabolismTotal) + "\n";
			dataStream += "|Sugar/citizen\t: " + (population/sugarCitizens) + "\n";
			dataStream += "+--------------------------------+\n";
		}
		return dataStream;
	}

	//**Display Basic Stats for a Given Citizen
	public String showCitizenStats(String message, int col, int row)
	{	String dataStream;
		String spacer = "";
		if( col < 10) {	spacer += " ";	}
		if( row < 10) {	spacer += " ";	}
		dataStream = message + spacer + " [" + col + "][" + row + "]\t"
							+ citizen[col][row].getVision() + "V\t"
							+ citizen[col][row].getMetabolism() + "M\t"
							+ citizen[col][row].getSugar() + "S\n";
		return dataStream;
	}

	//**Display Sugar Distribution on the Sugarscape
	public String showSugarscapeStats(int startCol, int startRow, int endCol, int endRow)
	{	String dataStream;
		dataStream = "\n    ";

		for(int i=startCol; i<endCol; i++)
			if(i<10)	{	dataStream  +=  " " + i + " ";	}
			else dataStream +=  i + " ";
		dataStream += "\n";

		for(int i=startCol; i<=endCol; i++)
			dataStream += "---";
		dataStream += "\n";

		for (int i=startRow;i<endRow;i++)
		{	if(i<10) dataStream += "  " + i + "|";
			else dataStream += " " + i + "|";

			for (int j=startCol;j<endCol;j++)
				dataStream += " " + (int)cellsSugar[j][i] + " ";
			dataStream += "\n";
		}
		return dataStream;
	}
}

⌨️ 快捷键说明

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