import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Font; import java.awt.FontMetrics; import java.awt.*; import java.util.Date; import java.lang.Math; import java.lang.*; import java.*; // This is a cellular automata simulation of a predator prey ecology // where the two species ( green fish & red sharks ) play out survival. // The domain, as displayed on the top left grid, supports a surface // where each cellular animal can wrap its movement, ie if they move // too far left they appear on the right -- same wrap happens for // top to bottom movement. This surface is topologically eqivalent // to a torus -- ie. the doughnut. The chart on the bottom // displays the population of both species on the verticle axis // and time across the bottom axis // // scott stensland -- april 1 1999 // public class erin extends java.applet.Applet implements Runnable { // introduced from doughnut program eve.java static final int X = 0, Y = 1, Z = 2, num_slices = 16, num_spokes = 40, max_num_generations_pop_counted = 10000; int num_point_of_circle, num_point_doughnut, test_mod = 50, test_next_point = 3, loop_index; double vx = 80.0, vy = 60.0, vz = 70.0, xhome = 200.0, yhome = 200.0, theta = -.5, PI = Math.PI, omega = 1.3, alpha = -0.9, radius_cross_section = 50.0 /* radius of cross section of doughnut's surface */, radius_doughnut = 150, // distance between center of doughnut // and center of it's outer ring x_offset_from_origin = 300.0, y_offset_from_origin = 300.0, z_offset_from_origin = 00.0, z_multiplier_factor = 0.550, junk = 4.0; double box[][] = new double[8][3]; double doughnut[][] = new double[num_slices * num_spokes][3]; // MUST FIX - 5000 with correct num pts in doughnut int x_y_map[][] = new int[num_slices * num_spokes][2]; // for each point on doughnut - this stores X and Y value on grid Image image1=null; int x_y_displayed_integers[][][] = new int[num_spokes][num_slices][2]; // for given x and y returns projected display x & y as integers boolean initial_display_of_Doughnut; int xPoints[] = new int[4], yPoints[] = new int[4], nPoints = 4; int pop_history[][] = new int[2][max_num_generations_pop_counted], cur_num_generations_pop_counted = 0; double pop_chart_height = 100.0, pop_chart_width = 200.0, x_offset_chart = 350.0, y_offset_chart = 450.0, max_pop = 0.0, min_pop = 99999.0; // terri follows below: int Ix, Iy; // Thread runner; Thread runner; public static final int max_random_dir = 100, // max_random_dir MUST be multiple of 4 (ie. 16 24 256) left = 0, right = 1, up = 2, down = 3; int random_dir[] = new int[max_random_dir]; int current_generation = 0; // 0=left 1=right 2=up 3=down as per above constants int cur_random_index = 0; /* legend for array pop 0 x 1 y 2 species 0 fish 1 shark 999 vacant 3 age 4 hunger 0 --> infinite - pertains to shark only - fish remain 0 legend for array grid <--- MUST check value of species FIRST - species = vacant nullifies values of vitality/number (x) (y) (0 vitality 0 alive 1 dead 1 number whichAnimal 2 species 0 fish 1 shark 999 vacant */ static final int vacant = 999, x = 0, y = 1, species = 2, age = 3, hunger = 4, fish = 0, shark = 1, vitality = 0, alive = 0, dead = 0, number=1, undefined = -1; int curAnimal = 0, cur_fish = 0, cur_shark = 0, curDead = 0, sharkStarveAge = 6, fishSexMaturity = 2, sharkSexMaturity = 8, oceanx = num_spokes, oceany = num_slices, // init_fish = 480, init_shark = 122, MaxAnimals = oceanx * oceany, init_fish = 8, init_shark = 5, MaxAnimals = oceanx * oceany, animalSize = 5; boolean debugMode = false , continue_looping = true; static final boolean no = false, yes = true; int pop[][] = new int [oceanx * oceany][5]; // 0=x 1=y 2=species 3=age 4=hunger int grid[][][] = new int [oceanx][oceany][3]; // 0=vitality (0 alive 1 dead) // 1=number(whichAnimal) 2=species(0/1/999) int cur_pop[] = new int [2]; // 0=fish 1=shark int birthAge[] = new int [2]; // age respective species gives birth int deathRow[] = new int [oceanx * oceany]; // list of dead animals as index into pop curAnimals int locx[] = new int [oceanx]; int locy[] = new int [oceany]; Color animalColor[] = new Color[2]; // .... private boolean doubleBuffer=true; // or false of course private Image buf; // bitmap for double buffering private Graphics gBuf; // gc to draw on bitmap // -------------------------------- public void init() // -------------------------------- { double xoff = 0.0, yoff = 0.0, zoff = 0.0, xfactor = 80.5, yfactor = 80.5, zfactor = 80.5; // eve follows double x,y,z,circle_increment, spoke_increment, theta, sin_theta, cos_theta, phi, sin_phi, cos_phi; current_generation = 0; cur_num_generations_pop_counted = 0; // image1 = getImage(getDocumentBase(), "/ms/user/s/stens/gif/kidney_pie.gif"); image1 = getImage(getDocumentBase(), "kidney_pie.gif"); // .... birthAge[fish] = fishSexMaturity; birthAge[shark] = sharkSexMaturity; animalColor[fish] = Color.green; animalColor[shark] = Color.red; box[0][0] = (-1.0 + xoff) * xfactor; box[0][1] = (-1.0 + yoff) * yfactor; box[0][2] = (-1.0 + zoff) * zfactor; box[1][0] = (-1.0 + xoff) * xfactor; box[1][1] = (1.0 + yoff) * yfactor; box[1][2] = (-1.0 + zoff) * zfactor; box[2][0] = (1.0 + xoff) * xfactor; box[2][1] = (1.0 + yoff) * yfactor; box[2][2] = (-1.0 + zoff) * zfactor; box[3][0] = (1.0 + xoff) * xfactor; box[3][1] = (-1.0 + yoff) * yfactor; box[3][2] = (-1.0 + zoff) * zfactor; box[4][0] = (-1.0 + xoff) * xfactor; box[4][1] = (-1.0 + yoff) * yfactor; box[4][2] = (1.0 + zoff) * zfactor; box[5][0] = (-1.0 + xoff) * xfactor; box[5][1] = (1.0 + yoff) * yfactor; box[5][2] = (1.0 + zoff) * zfactor; box[6][0] = (1.0 + xoff) * xfactor; box[6][1] = (1.0 + yoff) * yfactor; box[6][2] = (1.0 + zoff) * zfactor; box[7][0] = (1.0 + xoff) * xfactor; box[7][1] = (-1.0 + yoff) * yfactor; box[7][2] = (1.0 + zoff) * zfactor; // initialize pop of animals int tempc = 0; for (int i = 0; i < oceanx; i++) { locx[i] = i * animalSize; for (int ii = 0; ii < oceany; ii++) { // initialize to blank grid/pop locy[ii] = ii * animalSize; grid[i][ii][vitality] = vacant; grid[i][ii][number] = undefined; grid[i][ii][species] = vacant; pop[tempc][species] = vacant; tempc++; } } int possx, possy; curAnimal = 0; cur_pop[fish] = 0; for (int i = 0; i < init_fish;) { possx = Randomize(oceanx); possy = Randomize(oceany); if (grid[possx][possy][species] == vacant) { birthAnimal(possx, possy, fish); i++; } } if (debugMode) { System.out.println("init_fish = " + init_fish + " and cur_pop[fish] = " + cur_pop[fish]); } cur_pop[shark] = 0; for (int i = 0; i < init_shark;) { possx = Randomize(oceanx); possy = Randomize(oceany); if (grid[possx][possy][species] == vacant) { birthAnimal(possx, possy, shark); i++; } } if (debugMode) { System.out.println("init_shark = " + init_shark + " and cur_pop[shark] = " + cur_pop[shark]); System.out.println("curAnimal = " + curAnimal); } // initializes array with random sequence of the 4 directions 0 -> 3 storeRandom(); // buffer image for smooth animation if (doubleBuffer) { Dimension d = getSize(); buf = createImage(d.width, d.height); gBuf = buf.getGraphics(); } // eve follows: init_doughnut(); } // init // -------------------------------- public void init_doughnut() { // -------------------------------- int index, which_x, which_y; double xoff = 0.0, yoff = 0.0, zoff = 0.0, xfactor = 80.5, yfactor = 80.5, zfactor = 80.5, x,y,z,circle_increment, spoke_increment, theta, sin_theta, cos_theta, phi, sin_phi, cos_phi; initial_display_of_Doughnut = yes; /* init a circle which defines a single cross section of a doughnut's ring. This will be used as a base to construct the entire doughnut. The doughnut will be used to display the fish/shark */ circle_increment = (2.0 * PI) / num_slices; // System.out.println("circle_increment = " + circle_increment ); theta = 0.0; // angle in radians as we revolve around the initial circle x = 0.0; y = radius_cross_section; z = 0.0; num_point_doughnut = 0; which_x = 0; which_y = 0; doughnut[num_point_doughnut][X] = x + radius_doughnut; doughnut[num_point_doughnut][Y] = y; doughnut[num_point_doughnut][Z] = z; x_y_map[num_point_doughnut][X] = which_x; x_y_map[num_point_doughnut][Y] = which_y; // System.out.println("init_doughnut " + num_point_doughnut + " x_y_map[" + num_point_doughnut + "][X] = " + x_y_map[num_point_doughnut][X] + " x_y_map[" + num_point_doughnut + "][Y] = " + x_y_map[num_point_doughnut][Y] ); num_point_doughnut++; which_y++; for ( index = 1; index < num_slices; index++) { theta += circle_increment; sin_theta = Math.sin(theta); cos_theta = Math.cos(theta); // generate initial circle of points by spinning a single point about the Z axis doughnut[num_point_doughnut][X] = (x * cos_theta) - (y * sin_theta) + radius_doughnut; doughnut[num_point_doughnut][Y] = (x * sin_theta) + (y * cos_theta); doughnut[num_point_doughnut][Z] = 0.0; x_y_map[num_point_doughnut][X] = which_x; x_y_map[num_point_doughnut][Y] = which_y; // System.out.println("init_doughnut " + index + "x_y_map[num_point_doughnut][X] = " + x_y_map[num_point_doughnut][X] + " x_y_map[num_point_doughnut][Y] = " + x_y_map[num_point_doughnut][Y]); // System.out.println("init_doughnut " + num_point_doughnut + " x_y_map[" + num_point_doughnut + "][X] = " + x_y_map[num_point_doughnut][X] + " x_y_map[" + num_point_doughnut + "][Y] = " + x_y_map[num_point_doughnut][Y] ); num_point_doughnut++; which_y++; } // for num_slices // dump contents of doughnut for ( index = 0; index < num_slices; index++) { // System.out.println("dump of initial circle x = " + doughnut[index][X] + " y = " + doughnut[index][Y] + " z = " + doughnut[index][Z] ); } // generate doughnut surface points by spinning initial circle, // generated in the above algorthim, about the Y axis // this above generated initial circle actually consists of // the first num_slices of array doughnut // ( NOTE1 ) - NEED to create a means to assure size of each polygon on doughnut's surface // has equal width and height. Given above variable num_slices - which determines // number of points in initial circle, use this along with radius_cross_section // to calculate the number of times to split the 360 degrees as we spin the // above circle around the center of the doughnut spoke_increment = (2.0 * PI) / num_spokes; phi = 0.0; // angle in radians as we spin then completed initial circle of points // around the vertical Y axis // System.out.println("num_spokes = " + num_spokes); for ( index = 1; index < num_spokes; index++) { // spin about the Y axis // System.out.println("phi = " + phi ); phi += spoke_increment; sin_phi = Math.sin(phi); cos_phi = Math.cos(phi); // take initial circle of points and rotate all of them phi radians // to populate the doughnut array which stores X Y Z locations of all // points defined on surface of doughnut which_x++; which_y = 0; for ( num_point_of_circle = 0; num_point_of_circle < num_slices; num_point_of_circle++) { x = doughnut[num_point_of_circle][X]; y = doughnut[num_point_of_circle][Y]; z = doughnut[num_point_of_circle][Z]; doughnut[num_point_doughnut][X] = (x * cos_phi) + (z * sin_phi); doughnut[num_point_doughnut][Y] = y; doughnut[num_point_doughnut][Z] = ( -1.0 * x * sin_phi) + (z * cos_phi); x_y_map[num_point_doughnut][X] = which_x; x_y_map[num_point_doughnut][Y] = which_y; // System.out.println("init_doughnut num_point_doughnut = " + num_point_doughnut + " x = " + doughnut[num_point_doughnut][X] + " y = " + doughnut[num_point_doughnut][Y] + " z = " + doughnut[num_point_doughnut][Z] ); // System.out.println("init_doughnut " + num_point_doughnut + " x_y_map[" + num_point_doughnut + "][X] = " + x_y_map[num_point_doughnut][X] + " x_y_map[" + num_point_doughnut + "][Y] = " + x_y_map[num_point_doughnut][Y] ); num_point_doughnut++; which_y++; } // for num_point_of_circle } // for num_spokes for ( index = 0; index < num_point_doughnut; index++) { // System.out.println("Dump doughnut " + index + " x = " + doughnut[index][X] + " y = " + doughnut[index][Y] + " z = " + doughnut[index][Z] + " x_y_map[" + index + "][X] = " + x_y_map[index][X] + " x_y_map[" + index + "][Y] = " + x_y_map[index][Y] ); // System.out.println("Dump doughnut " + index + " x_y_map[" + index + "][X] = " + x_y_map[index][X] + " x_y_map[" + index + "][Y] = " + x_y_map[index][Y] ); } } // init_doughnut // -------------------------------- public void birthAnimal(int newx, int newy, int whichSpecies) { // -------------------------------- pop[curAnimal][x] = newx; pop[curAnimal][y] = newy; pop[curAnimal][species] = whichSpecies; pop[curAnimal][age] = 0; pop[curAnimal][hunger] = 0; grid[newx][newy][vitality] = alive; grid[newx][newy][number] = curAnimal; grid[newx][newy][species] = whichSpecies; curAnimal++; cur_pop[whichSpecies] += 1; if (curAnimal >= MaxAnimals) { System.out.println("Error - attempt to birth too many animals. "); System.out.println("Reduce init animal count if this has happened during init"); System.exit(103); } } // -------------------------------- public void storeRandom() { // -------------------------------- int i; if (max_random_dir < 50) { System.out.println("Increase size of max_random_dir"); System.exit(104); } random_dir[0] = 0; random_dir[1] = 3; random_dir[2] = 1; random_dir[3] = 2; for (i = 7; i < max_random_dir; i += 4) { random_dir[i] = Randomize(4); random_dir[i - 1] = Randomize(4); while (random_dir[i - 1] == random_dir[i]) { random_dir[i - 1] = Randomize(4); } random_dir[i - 2] = Randomize(4); while (random_dir[i - 2] == random_dir[i] || random_dir[i - 2] == random_dir[i - 1]) { random_dir[i - 2] = Randomize(4); } random_dir[i - 3] = Randomize(4); while (random_dir[i - 3] == random_dir[i] || random_dir[i - 3] == random_dir[i - 1] || random_dir[i - 3] == random_dir[i - 2]) { random_dir[i - 3] = Randomize(4); } } if (i - 3 != max_random_dir) { System.out.println("max_random_dir must be Multiple of 4"); System.exit(105); } } // -------------------------------- public int getNextx(int now_animal, int dir) { // -------------------------------- /* IMPROVEMENT need to determine poss dir without mindlessly trying successive list of random directions - repeating past directions */ int tempx = pop[now_animal][x]; if (dir == left) { tempx -= 1; if (tempx < 0) tempx = oceanx - 1; } else if (dir == right) { tempx += 1; if (tempx == oceanx) tempx = 0; } return tempx; } // -------------------------------- public int getNexty(int now_animal, int dir) { // -------------------------------- int tempy = pop[now_animal][y]; if (dir == up) { tempy -= 1; if (tempy < 0) tempy = oceany - 1; } else if (dir == down) { tempy += 1; if (tempy == oceany) tempy = 0; } return tempy; } // -------------------------------- public boolean isStarved(int whichAnimal) { // -------------------------------- if (pop[whichAnimal][species] == fish) return no; if (pop[whichAnimal][hunger] > sharkStarveAge) { if (debugMode) { System.out.println(" --------> Shark starved."); } return yes; } return no; } // -------------------------------- public void doMate(int whichAnimal) { // -------------------------------- } // -------------------------------- public void chronos() { // -------------------------------- int tempf=0, temps=0 ; // System.out.println("chronos begins anew"); if (debugMode) { System.out.println("chronos begins anew"); referentialIntegrity("chronos begins anew"); System.out.print("fish = " + cur_pop[fish] + " shark = " + cur_pop[shark] + " curAnimal = " + curAnimal); for (int i = 0; i < curAnimal; i++) { if (pop[i][species] == fish) tempf++; if (pop[i][species] == shark) temps++; } System.out.println(" countfish= " + tempf + " countshark= " + temps); System.out.println(" generation= " + current_generation ); if ((cur_pop[fish] != tempf) || (cur_pop[shark] != temps)) { System.out.println("Error - top of chronos athena"); System.exit(100); continue_looping = false; } } boolean sharkEatsFish, found_good_dir = false, triedDir [] = new boolean [4]; int cur_dir, possx, possy, origCurAnimal = curAnimal, xcanDoDir, ycanDoDir, indeterminant = -1; // showGridText(); if (debugMode) { System.out.println("Total Animal Count = " + curAnimal); showGridText(); System.out.println(" -------- " ); } for (int i = 0; i < origCurAnimal; i++) { sharkEatsFish = false; if (pop[i][species] == vacant) continue; // found dead fish - bypass this index i if (grid[pop[i][x]][pop[i][y]][species] == vacant) { continue_looping = false; System.out.println("Error in Chronos - dead according to grid, but pop says alive for species = " + pop[i][species]); System.out.println("dump of pop --> animal=" + i + " x=" + pop[i][x] + " y=" + pop[i][y] + " species=" + pop[i][species] + " age=" + pop[i][age] + " hunger=" + pop[i][hunger]); System.out.println("dump of grid -> vitality=" + grid[pop[i][x]][pop[i][y]][vitality] + " number=" + grid[pop[i][x]][pop[i][y]][number] + " species=" + grid[pop[i][x]][pop[i][y]][species]); System.exit(101); } if (debugMode) { System.out.println(" "); System.out.print("chronos of animal " + i + " is at xy of " + pop[i][x] + ", " + pop[i][y]); System.out.print(" species = " + pop[i][species] + " age = " + pop[i][age] + " hunger=" + pop[i][hunger]); } pop[i][age] += 1; if (pop[i][species] == shark) pop[i][hunger]++; if (isStarved(i)) { if (debugMode) { System.out.print(" pre-burying animal " + i); showGridText(); } killAnimal(i); if (debugMode) { System.out.print(" post burial animal " + i); showGridText(); System.out.print(" done burying animal " + i); } } else { triedDir[up] = triedDir[down] = triedDir[left] = triedDir[right] = false; found_good_dir = false; xcanDoDir = ycanDoDir = indeterminant; do { // move animal cur_dir = getRandomDir(); // above randomly directs animal to any direction, parameter for // intelligence should alter above to be non-random possx = getNextx(i, cur_dir); possy = getNexty(i, cur_dir); if (debugMode) { System.out.println("possible xy are " + possx + ", " + possy); } if ((pop[i][species] == shark) && (grid[possx][possy][species] == fish)) { found_good_dir = true; xcanDoDir = ycanDoDir = indeterminant; if (debugMode) { System.out.println("animal " + i + " is shark eating FISH " + grid[possx][possy][number] + " at location xy of " + possx + ", " + possy); } killAnimal(grid[possx][possy][number]); // shark eats fish moveAnimal(i, possx, possy); pop[i][hunger] = 0; } else { if (grid[possx][possy][species] == vacant) { xcanDoDir = possx; ycanDoDir = possy; if (pop[i][species] == fish) { found_good_dir = true; moveAnimal(i, possx, possy); } } } triedDir[cur_dir] = true; if (debugMode) { System.out.println("just tried dir of " + cur_dir); } } while ((found_good_dir != true) && (triedDir[up]==false || triedDir[down]==false || triedDir[left]==false || triedDir[right]==false)) ; if ((found_good_dir != true) && (xcanDoDir != indeterminant)) { moveAnimal(i, xcanDoDir, ycanDoDir); } } if (debugMode) { System.out.println(" "); } } buryDead(); if (debugMode) { referentialIntegrity("end of chronos"); } // System.out.println("leaving chronos - currently with current_generation of " + current_generation); // System.out.println("current_generation = " + current_generation + " cur_pop[fish] = " + cur_pop[fish] + " pop_history[fish] [current_generation] = " + pop_history[fish] [current_generation]); // ----- below moved out of showPop ------ if (cur_pop[fish] > max_pop) max_pop = cur_pop[fish]; if (cur_pop[fish] < min_pop) min_pop = cur_pop[fish]; if (cur_pop[shark] > max_pop) max_pop = cur_pop[shark]; if (cur_pop[shark] < min_pop) min_pop = cur_pop[shark]; // System.out.println("current_generation = " + current_generation + " cur_pop[fish] = " + cur_pop[fish]); // store current populations into array for chart of both species pop_history[fish] [current_generation] = cur_pop[fish]; pop_history[shark][current_generation] = cur_pop[shark]; // System.out.println("current_generation = " + current_generation + " cur_pop[fish] = " + cur_pop[fish] + " pop_history[fish] [current_generation] = " + pop_history[fish] [current_generation]); // System.out.println("just set --- line 1100 gen = " + current_generation + " cur pop fish = " + pop_history[fish] [current_generation] + " cur_pop[fish] = " + cur_pop[fish]); // ----- above moved out of showPop ------ current_generation++ ; cur_num_generations_pop_counted++; // need to identify when this becomes too large to display in pop history chart // System.out.println("leaving chronos - just incremented current_generation NOW with " + current_generation); } // chronos // -------------------------------- public void referentialIntegrity(String called_from_here) { // -------------------------------- int totalFishp = 0, totalSharkp = 0, totalFishg = 0, totalSharkg = 0; for (int xx = 0; xx < oceanx; xx++) { for (int yy = 0; yy < oceany; yy++) { if (grid[xx][yy][species] == fish) { totalFishg++; } else if (grid[xx][yy][species] == shark) { totalSharkg++; } } } for (int i = 0; i < curAnimal; i++) { if (pop[i][species] == fish) totalFishp++; else if (pop[i][species] == shark) totalSharkp++; } System.out.println("inside - ref integ fault - " + called_from_here); System.out.println("totalfish pop= " + totalFishp + " totalShark pop = " + totalSharkp); System.out.println("totalfish grid= " + totalFishg + " totalShark grid = " + totalSharkg); if ((totalFishp != totalFishg) || (totalSharkp != totalSharkg)) { System.out.println("Error - ref integ fault - " + called_from_here); showGridText(); System.exit(102); continue_looping = false; } } // -------------------------------- public void showGridText() { // -------------------------------- int whichAnimal = 0; boolean foundAnimal = false; System.out.println("show grid with total fish=" + cur_pop[fish] + " and shark=" +cur_pop[shark]); for (int i = 0; i < curAnimal; i++) { System.out.print("animal = " + i + " x= " + pop[i][x] + " y= " + pop[i][y]); System.out.println(" species= " + pop[i][species] + " age= " + pop[i][age] + " hunger=" + pop[i][hunger]); } for (int xx = 0; xx < oceanx; xx++) { System.out.println(" "); for (int yy = 0; yy < oceany; yy++) { if (grid[xx][yy][species] == vacant) { System.out.print("_"); } else { System.out.print(grid[xx][yy][species]); } } } System.out.println("\nNow displaying grid[x][y][number]"); for (int xx = 0; xx < oceanx; xx++) { System.out.println(" "); for (int yy = 0; yy < oceany; yy++) { if (grid[xx][yy][species] == vacant) { System.out.print("_"); } else { System.out.print(grid[xx][yy][number]); } } } System.out.println("Now Displaying grid of whichAnimal"); for (int xx = 0; xx < oceanx; xx++) { System.out.println(" "); for (int yy = 0; yy < oceany; yy++) { if (grid[xx][yy][species] == vacant) { System.out.print("_"); } else { foundAnimal = false; whichAnimal = 0; do { if ((pop[whichAnimal][x] == xx) && (pop[whichAnimal][y] == yy)) { System.out.print(whichAnimal); foundAnimal = true; } whichAnimal++; } while ((whichAnimal < curAnimal) && (foundAnimal == false)); } } } } // -------------------------------- public void storeDeathRow(int killThisAnimal) { // -------------------------------- int index = curDead, tempSlot; boolean stillSearchingPosition = true; deathRow[curDead] = killThisAnimal; curDead++; while (index - 1 >= 0 && stillSearchingPosition == true) { stillSearchingPosition = false; if (deathRow[index - 1] > killThisAnimal) { stillSearchingPosition = true; tempSlot = deathRow[index - 1]; deathRow[index - 1] = killThisAnimal; deathRow[index] = tempSlot; } index--; } } // puss // -------------------------------- public void killAnimal(int killThisAnimal) { // -------------------------------- int xx = pop[killThisAnimal][x], yy = pop[killThisAnimal][y];; if (debugMode) { System.out.println("inside killAnimal with death of " + killThisAnimal + " x=" + xx + " y=" + yy + " species=" + pop[killThisAnimal][species] + " at age=" + pop[killThisAnimal][age] + " cur_pop=" + cur_pop[fish] + ", " + cur_pop[shark]); } if (grid[xx][yy][species] == vacant) { continue_looping = false; System.out.println("Error in killAnimal - attempting to kill dead animal"); } storeDeathRow(killThisAnimal); // deathRow[curDead] = killThisAnimal; // curDead++; cur_pop[pop[killThisAnimal][species]] -= 1; grid[xx][yy][vitality] = dead; grid[xx][yy][number] = undefined; grid[xx][yy][species] = vacant; pop[killThisAnimal][species] = vacant; // able to use pop[][species] == vacant to mean dead } public boolean mateSuccess(int whichAnimal) { if ((curAnimal + 1) < (oceanx * oceany) && pop[whichAnimal] [age] >= birthAge[pop[whichAnimal][species]]) { return true; } return false; } // -------------------------------- public void moveAnimal(int now_animal, int newx, int newy) { // -------------------------------- if (debugMode) { System.out.println("inside moveAnimal moving animal " + now_animal + " to xy of " + newx + ", " + newy); referentialIntegrity("calling referential Integrity at TOP of moveAnimal"); } if (grid[newx][newy][species] != vacant) { // throw exception } else { if (mateSuccess(now_animal)) { pop[now_animal][age] = 0; if ((pop[now_animal][species] != fish) && (pop[now_animal][species] != shark)) { continue_looping = false; System.out.println("Error in moveAnimal - birthing unknown species = " + pop[now_animal][species]); } birthAnimal(newx, newy, pop[now_animal][species]); } else { grid[newx][newy][vitality] = alive; grid[newx][newy][number] = now_animal; grid[newx][newy][species] = pop[now_animal][species]; grid[pop[now_animal][x]][pop[now_animal][y]][vitality] = vacant; grid[pop[now_animal][x]][pop[now_animal][y]][number] = undefined; grid[pop[now_animal][x]][pop[now_animal][y]][species] = vacant; pop[now_animal][x] = newx; pop[now_animal][y] = newy; } } if (debugMode) { referentialIntegrity("calling referential Integrity at BOTTOM of moveAnimal"); } } // -------------------------------- public int getRandomDir() { // -------------------------------- int next_dir; next_dir = random_dir[cur_random_index++]; if (cur_random_index >= max_random_dir) { cur_random_index = 0; // storeRandom(); } return next_dir; } // -------------------------------- public int Randomize( int range ) // -------------------------------- { double rawResult; rawResult = Math.random(); return (int) (rawResult * range); } // -------------------------------- public void destroy() // -------------------------------- { // .... if (doubleBuffer) gBuf.dispose(); } // oct 98 public boolean mouseDrag(Event evt, int x, int y) // -------------------------------- public boolean processMouseMotionEvent(Event evt, int x, int y) // -------------------------------- { Ix = x; Iy = y; repaint(); System.out.println(x + " and " + y); return true; } // -------------------------------- public void showPop(Graphics g) { // -------------------------------- double cur_x, prev_x = 0.0, cur_y_fish, cur_y_shark, prev_y_fish = 0.0, prev_y_shark = 0.0, increment_x = 0.0; g.setColor(Color.gray); Dimension d = getSize(); g.fillRect(0,0,d.width, d.height); g.setColor(Color.blue); g.drawString ("generation = " + Integer.toString(current_generation), 410, 10) ; g.drawString ("curDead = " + Integer.toString(curDead), 410, 20) ; g.drawString ("fish coun t = " + Integer.toString(cur_pop[fish]), 410, 30) ; g.drawString ("shark count = " + Integer.toString(cur_pop[shark]), 410, 40) ; g.drawString ("getSize width= " + Integer.toString(d.width), 270, 30) ; g.drawString ("getSize height= " + Integer.toString(d.height), 270, 40) ; // System.out.println(" just refreshed appletviewer of cur_pop stats"); if(image1 != null) g.drawImage(image1, 320, 45, this); /* for (int i = 0; i < curDead; i++) { g.fillRect(locx[pop[deathRow[i]][x]], locy[pop[deathRow[i]][y]], animalSize - 1, animalSize - 1); if (debugMode) { System.out.println("paintover dead animal " + deathRow[i] + " at position " + pop[deathRow[i]][x] + ", " + pop[deathRow[i]][y]); } } */ for (int i = 0; i < curAnimal; i++) { if (pop[i][species] != vacant) { g.setColor(animalColor[pop[i][species]]); g.fillRect(locx[pop[i][x]], locy[pop[i][y]], animalSize, animalSize); // System.out.println("animal " + i + " is at xy of " + pop[i][x] + ", " + pop[i][y]); // display fish and sharks as polygons on surface of doughnut !!! draw_animal_on_doughnut_surface(g, i); } } // display chart of history of populations of both fish and shark // g.drawString ("fish coun t = " + Integer.toString(cur_pop[fish]), 410, 30) ; // g.drawString ("shark count = " + Integer.toString(cur_pop[shark]), 410, 40) ; if (cur_num_generations_pop_counted < 2) { increment_x = pop_chart_width; } else { increment_x = ((double) pop_chart_width) / (double) (cur_num_generations_pop_counted - 1); } // System.out.println("current_generation = " + current_generation + " cur_pop[fish] = " + cur_pop[fish] + " pop_history[fish] [current_generation] = " + pop_history[fish] [current_generation]); // System.out.println("just set --- line 1100 gen = " + current_generation + " cur pop fish = " + pop_history[fish] [current_generation] + " cur_pop[fish] = " + cur_pop[fish]); cur_x = x_offset_chart; g.setColor(Color.blue); // draw frame about real-time population chart g.drawLine((int) x_offset_chart, (int) y_offset_chart, (int) x_offset_chart + (int) pop_chart_width, (int) y_offset_chart); g.drawLine((int) x_offset_chart + (int) pop_chart_width, (int) y_offset_chart, (int) x_offset_chart + (int) pop_chart_width, (int) y_offset_chart + (int) pop_chart_height); g.drawLine((int) x_offset_chart + (int) pop_chart_width, (int) y_offset_chart + (int) pop_chart_height, (int) x_offset_chart, (int) y_offset_chart + (int) pop_chart_height); g.drawLine((int) x_offset_chart, (int) y_offset_chart + (int) pop_chart_height, (int) x_offset_chart, (int) y_offset_chart); prev_y_fish = ((((pop_history[fish][0]) - min_pop) * pop_chart_height) / (max_pop - min_pop)); prev_x = 0.0; cur_x = increment_x; for (loop_index=1; loop_index < current_generation; loop_index++) { cur_y_fish = ((((pop_history[fish][loop_index]) - min_pop) * pop_chart_height) / (max_pop - min_pop)); cur_y_shark = ((((pop_history[shark][loop_index]) - min_pop) * pop_chart_height) / (max_pop - min_pop)); // people complained about the fish graph being blue g.setColor(Color.blue); g.setColor(Color.green); g.drawLine( (int) (prev_x + x_offset_chart), (int) (y_offset_chart + pop_chart_height - prev_y_fish), (int) (cur_x + x_offset_chart), (int) (y_offset_chart + pop_chart_height - cur_y_fish)); // System.out.println(prev_x + ", " + prev_y_fish + " " + cur_x + ", " + cur_y_fish + " fish pop = " + pop_history[fish][loop_index] + " generation = " + loop_index + " line 1130 cur_pop[fish] = " + cur_pop[fish]); // people complained about the shark being black g.setColor(Color.black); g.setColor(Color.red); g.drawLine( (int) (prev_x + x_offset_chart), (int) (y_offset_chart + pop_chart_height - prev_y_shark), (int) (cur_x + x_offset_chart), (int) (y_offset_chart + pop_chart_height - cur_y_shark)); prev_x = cur_x; cur_x += increment_x; prev_y_fish = cur_y_fish; prev_y_shark = cur_y_shark; // ---- DEBUG ---- if ( pop_history[fish][loop_index] == 0 ) { System.out.println("exiting .... " + cur_pop[fish] ); continue_looping = false; } // ---- DEBUG ---- } } // showPop // -------------------------------- public void draw_animal_on_doughnut_surface(Graphics g, int cur_animal) { // -------------------------------- /* this function draws a given animal as a polygon on the surface of the doughnut ------------------> X axis limit of Y axis is determined by value of num_spokes | | 0 ----- 3 | | | | | | | | | | 1-------2 | \/ Y axis - limit of Y axis is determined by value of num_slices, NOT num_spokes input point cur_animal is 0 and points 1,2 & 3 are the neighbor points which define the bounds of the polygon to represent one animal on the surface of the doughnut */ int point_0[] = new int [2], point_1[] = new int [2], point_2[] = new int [2], point_3[] = new int [2]; point_0[X] = pop[cur_animal][X]; point_0[Y] = pop[cur_animal][Y]; point_1[X] = point_0[X]; point_1[Y] = ( (point_0[Y] + 1) >= num_slices) ? 0 : point_0[Y] + 1; point_2[X] = ( (point_0[X] + 1) >= num_spokes) ? 0 : point_0[X] + 1; point_2[Y] = point_1[Y]; point_3[X] = point_2[X]; point_3[Y] = point_0[Y]; // System.out.println("draw surf dough point " + cur_animal + " 0 xy= " + point_0[X] + "," + point_0[Y] + " 1 xy= " + point_1[X] + "," + point_1[Y] +" 2 xy= " + point_2[X] + "," + point_2[Y] + " 3 xy= " + point_3[X] + "," + point_3[Y] ); xPoints[0] = x_y_displayed_integers [point_0[X]] [point_0[Y]] [X]; xPoints[1] = x_y_displayed_integers [point_1[X]] [point_1[Y]] [X]; xPoints[2] = x_y_displayed_integers [point_2[X]] [point_2[Y]] [X]; xPoints[3] = x_y_displayed_integers [point_3[X]] [point_3[Y]] [X]; yPoints[0] = x_y_displayed_integers [point_0[X]] [point_0[Y]] [Y]; yPoints[1] = x_y_displayed_integers [point_1[X]] [point_1[Y]] [Y]; yPoints[2] = x_y_displayed_integers [point_2[X]] [point_2[Y]] [Y]; yPoints[3] = x_y_displayed_integers [point_3[X]] [point_3[Y]] [Y]; g.fillPolygon(xPoints, yPoints, nPoints); } // draw_animal_on_doughnut_surface // -------------------------------- public int getTopAliveAnimal() { // -------------------------------- for (int i = (curAnimal - 1); i >= 0; i--) { if (pop[i][species] != vacant) return i; } return 0; } // -------------------------------- public int getNextDead() { // -------------------------------- int highestDead = deathRow[0], indexHighestDead = 0; /* for (int i = 1; i < curDead; i++) { if (highestDead < deathRow[i] && deathRow[i] != undefined) { highestDead = deathRow[i]; indexHighestDead = i; } System.out.println("highest Dead is " + highestDead + " viewing cur deathRow of " + deathRow[i]); } System.out.println("Found highest Dead which is " + highestDead); deathRow[indexHighestDead] = undefined; */ curDead--; return deathRow[curDead]; } // -------------------------------- public void buryDead() { // -------------------------------- if (debugMode) { referentialIntegrity("top of buryDead"); showGridText(); for (int i = 0; i < curDead; i++) System.out.println("displaying deathRow = " + deathRow[i]); } int origDead = curDead - 1, whichDead, topAliveAnimal; if (curDead == 0) return; for (int i = origDead; i >= 0; i--) { // whichDead = deathRow[i]; whichDead = getNextDead(); if (debugMode) { System.out.println("inside buryDead - burying animal " + whichDead + " pop x=" + pop[whichDead][x] + " y=" + pop[whichDead][y] + " species=" + pop[whichDead][species]); } topAliveAnimal = getTopAliveAnimal(); // was topAliveAnimal = curAnimal - 1; if (debugMode) { System.out.println("top animal number is " + topAliveAnimal); } if (whichDead < topAliveAnimal) { if (debugMode) { System.out.println("Moving top animal of " + topAliveAnimal + " into dead slot of " + whichDead); } pop[whichDead][x] = pop[topAliveAnimal][x]; pop[whichDead][y] = pop[topAliveAnimal][y]; pop[whichDead][species] = pop[topAliveAnimal][species]; pop[whichDead][age] = pop[topAliveAnimal][age]; pop[whichDead][hunger] = pop[topAliveAnimal][hunger]; grid[pop[topAliveAnimal][x]] [pop[topAliveAnimal][y]] [number] = whichDead; } else { if (debugMode) { System.out.println("dead NOT moved - just buried in spot for animal " + whichDead); } pop[whichDead][species] = vacant; // grid[pop[whichDead][x]][pop[whichDead][y]][vitality] = vacant; // grid[pop[whichDead][x]][pop[whichDead][y]][number] = undefined; // grid[pop[whichDead][x]][pop[whichDead][y]][species] = vacant; } curAnimal -= 1; } if (curAnimal == 0 || cur_pop[shark] == 0 || cur_pop[fish] == 0) { System.out.println("Game Over"); // continue_looping = false; init(); } if (debugMode) { referentialIntegrity("bottom of buryDead"); } curDead = 0; } // -------------------------------- protected void paintApplet(Graphics g) // -------------------------------- { double rx, ry, rz, tx, ty, tz, zcos, zsin, ysin, ycos, xsin, xcos; // pre-clear the bitmap or the applet // remove this if you paint the entire area anyway Dimension d = getSize(); g.setColor(getBackground()); g.fillRect(0, 0, d.width, d.height); // ....code that was originally in paint()... // if(image1 != null) g.drawImage(image1, Ix, Iy, this); if(image1 != null) g.drawImage(image1, 320, 45, this); showPop(g); if ( initial_display_of_Doughnut ) { showDoughnut(g); // initial_display_of_Doughnut = no; } // show population of fish & sharks /* xPoints[0] = 100; yPoints[0] = 150; xPoints[1] = 300; yPoints[1] = 100; xPoints[2] = 320; yPoints[2] = 450; xPoints[3] = 100; yPoints[3] = 480; g.fillPolygon(xPoints, yPoints, nPoints); */ } // -------------------------------- public void showDoughnut(Graphics g) { // -------------------------------- int prev_x, prev_y, cur_x, cur_y, temp_test_next_point; double rx, ry, rz, tx, ty, tz, zcos, zsin, ysin, ycos, xsin, xcos; // pre-clear the bitmap or the applet // remove this if you paint the entire area anyway // Dimension d = getSize(); // g.setColor(getBackground()); // g.fillRect(0, 0, d.width, d.height); // ....code that was originally in paint()... g.setColor(Color.blue); g.drawString (Integer.toString(Ix), 210, 50) ; g.drawString (Integer.toString(Iy), 240, 50) ; zsin = Math.sin(theta); zcos = Math.cos(theta); ysin = Math.sin(omega); ycos = Math.cos(omega); xsin = Math.sin(alpha); xcos = Math.cos(alpha); for (int i = 0; i < box.length; i++) { // twist object about z axis tx = box[i][0] * zcos - box[i][1] * zsin; ty = box[i][0] * zsin + box[i][1] * zcos; tz = box[i][2]; // twist object about y axis rx = tx * ycos + tz * ysin; ry = ty; rz = -1.0 * tx * ysin + tz * ycos; // twist object about x axis tx = rx; ty = ry * xcos - rz * xsin; tz = ry * xsin + rz * xcos; g.fillRect((int) (tx + xhome), (int) (ty + yhome), 15, 15); } alpha -= 0.04; if (alpha <= 0.0) { alpha += (2.0 * PI); } theta -= 0.03; if (theta <= 0.0) { theta += (2.0 * PI); } omega += 0.107; if (omega >= (2.0 * PI)) { omega -= (2.0 * PI); } prev_x = (int) (doughnut[0][X] + x_offset_from_origin); prev_y = (int) ((doughnut[0][Y] - (z_multiplier_factor * doughnut[0][Z])) + y_offset_from_origin); for ( int i = 0; i < num_point_doughnut; i++) { // g.fillRect((int) (doughnut[i][X] + 280), (int) (doughnut[i][Y] - (z_multiplier_factor * doughnut[i][Z])) + 280, 3, 3); tx = doughnut[i][X]; ty = doughnut[i][Y]; tz = doughnut[i][Z]; // twist object about y axis rx = tx * ycos + tz * ysin; ry = ty; rz = -1.0 * tx * ysin + tz * ycos; /* */ // twist object about z axis tx = rx * zcos - ry * zsin; ty = rx * zsin + ry * zcos; tz = rz; // twist object about y axis rx = tx * ycos + tz * ysin; ry = ty; rz = -1.0 * tx * ysin + tz * ycos; // twist object about x axis tx = rx; ty = ry * xcos - rz * xsin; tz = ry * xsin + rz * xcos; cur_x = (int) (tx + x_offset_from_origin); cur_y = (int) (ty - (z_multiplier_factor * tz) + y_offset_from_origin); /* */ cur_x = (int) (rx + x_offset_from_origin); cur_y = (int) (ry - (z_multiplier_factor * rz) + y_offset_from_origin); g.drawLine(prev_x, prev_y, cur_x, cur_y); // System.out.println("At drawLine point " + i + " curx = " + cur_x + " cur_y = " + cur_y); // System.out.println("At drawLine point " + i + " x_y_map[i][X] = " + x_y_map[i][X] + " x_y_map[i][Y] = " + x_y_map[i][Y]); x_y_displayed_integers[x_y_map[i][X]] [x_y_map[i][Y]] [X] = cur_x; x_y_displayed_integers[x_y_map[i][X]] [x_y_map[i][Y]] [Y] = cur_y; // System.out.println("At drawLine point " + i + " curx = " + cur_x + " cur_y = " + cur_y); prev_x = cur_x; prev_y = cur_y; } } // showDoughnut // -------------------------------- public void paint(Graphics g) // -------------------------------- { if (doubleBuffer) { paintApplet(gBuf); g.drawImage(buf, 0, 0, this); } else { paintApplet(g); } } // -------------------------------- public void update(Graphics g) // -------------------------------- { // override this because the default implementation always // calls clearRect first, causing unwanted flicker paint(g); } // -------------------------------- public void run () { // -------------------------------- while (continue_looping) { repaint(); chronos(); // current_generation++ ; // cur_num_generations_pop_counted++; // need to identify when this becomes too large to display in pop history chart // added march 28 1999 : // Thread.currentThread().setPriority(Thread.NORM_PRIORITY-2); try { Thread.sleep(75); } catch (InterruptedException e) { } // to repaint new frames as fast as the machine can handle it: // Thread.yield(); } } // -------------------------------- public void start () { // -------------------------------- if (runner == null) ; { runner = new Thread (this) ; runner.start() ; } } // -------------------------------- public void stop () { // // -------------------------------- // if (runner != null) { runner = null ; continue_looping = false; } } }