📄 cellspace.java
字号:
{ 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 + -