import ddf.minim.*; import ddf.minim.signals.*; Minim minim; AudioOutput out; SoundSample []wale_sounds; color background_color; Grid board; ArrayList list_big_fish; ArrayList list_small_fish; ArrayList deleted_list_big_fish; ArrayList deleted_list_small_fish; int x_grid_size; int y_grid_size; int fish_types; int small_fish_median_life; int small_fish_variance_life; int big_fish_median_breeding_age; int big_fish_variance_breeding_age; int big_fish_median_dying_age; int big_fish_variance_dying_age; float initial_population; int big_fish_median_need_to_eat; int big_fish_variance_need_to_eat; int []fish_count; int fish_colors; Buttons magnifying_button; Buttons pause_button; Histogram histogram; final int NORTH = 1; final int SOUTH = 2; final int EAST = 3; final int WEST = 4; boolean [][]fish_image; boolean [][]fish_image_head; boolean [][]fish_image_tail; int cycles; void setup() { /* Set the size of the area */ size(600, 650); /* Set the speed of animation */ frameRate(30); /* create GUI items */ pause_button = new Buttons(0, 600, 199, 50, color(0,100,0), color(255,255,255), "Pause Simulation", "Run Simulation"); magnifying_button = new Buttons(200, 600, 199, 50, color(0,0,100), color(255,255,255), "Turn Magnify Off", "Turn Magnify On"); histogram = new Histogram(400, 600, 200, 50, color(255), "Histogram"); /* initialize the game data structures */ init_game_ds(); /* initial draw */ board.update_draw(); pause_button.button_draw(); magnifying_button.button_draw(); histogram.partial_draw(); cycles = 0; minim = new Minim(this); // get a line out from Minim, default bufferSize is 1024, default sample rate is 44100, bit depth is 16 out = minim.getLineOut(Minim.STEREO, 2048); wale_sounds = new SoundSample[18]; wale_sounds[0] = new SoundSample("wale0.mp3"); wale_sounds[1] = new SoundSample("wale1.mp3"); wale_sounds[2] = new SoundSample("wale3.mp3"); wale_sounds[3] = new SoundSample("wale4.mp3"); wale_sounds[4] = new SoundSample("wale5.mp3"); wale_sounds[5] = new SoundSample("wale6.mp3"); wale_sounds[6] = new SoundSample("wale7.mp3"); wale_sounds[7] = new SoundSample("wale8.mp3"); wale_sounds[8] = new SoundSample("wale9.mp3"); wale_sounds[9] = new SoundSample("wale10.mp3"); wale_sounds[10] = new SoundSample("wale11.mp3"); wale_sounds[11] = new SoundSample("wale12.mp3"); wale_sounds[12] = new SoundSample("wale13.mp3"); wale_sounds[13] = new SoundSample("wale14.mp3"); wale_sounds[14] = new SoundSample("wale15.mp3"); wale_sounds[15] = new SoundSample("wale16.mp3"); wale_sounds[16] = new SoundSample("wale17.mp3"); wale_sounds[17] = new SoundSample("wale2.mp3"); } void draw() { if (pause_button.is_button_on() == true) { small_fish_move(); big_fish_move(); for (int i = 0; i < fish_types; i++) { fish_count[i] = 0; } update_small_fish(); update_big_fish(); board.update_draw(); histogram.update_draw(); pause_button.button_draw(); magnifying_button.button_draw(); cycles ++; } } void stop() { out.close(); for (int i = 0; i < 18; i++) { wale_sounds[i].sound.close(); } minim.stop(); super.stop(); } void mouseClicked() { pause_button.update_clicked(); magnifying_button.update_clicked(); if (magnifying_button.is_over() == true) { board.toggle_magnify(); /* draw magnifying on off */ if (pause_button.is_button_on() == false) { board.update_draw(); } } } void init_game_ds() { x_grid_size = 300; y_grid_size = 300; fish_types = 2; initial_population = .99; // the bigger the less population... big_fish_median_need_to_eat = 0; big_fish_variance_need_to_eat = 0; small_fish_median_life = 10; small_fish_variance_life = 20; big_fish_median_breeding_age = 0; big_fish_variance_breeding_age = 10; big_fish_median_dying_age = 30; big_fish_variance_dying_age = 50; /* initialize the fish count */ fish_count = new int[fish_types]; fish_colors = 245/(fish_types/7+1); /* create fish lists */ list_big_fish = new ArrayList(); list_small_fish = new ArrayList(); deleted_list_big_fish = new ArrayList(); deleted_list_small_fish = new ArrayList(); /* initialize the seed */ randomSeed(mouseX + mouseY); /* initialize the board */ board = new Grid(x_grid_size, y_grid_size); /* create all the allocations ahead of time */ for (int i = 0; i < x_grid_size * y_grid_size; i++) { if (i % 2 == 0) { BigFish big_fish = new BigFish(0, 0, 0, 0, 0, 0, 0, 0); deleted_list_big_fish.add(big_fish); } SmallFish small_fish = new SmallFish(0, 0, 0, 0); deleted_list_small_fish.add(small_fish); } /* create the fish in each of the grid spots */ for (int i = 0; i < x_grid_size; i++) { for (int j = 0; j < x_grid_size; j++) { int next_fish_type = int(random(fish_types)); if (random(1) > initial_population) { /* make a small fish in this grid spot but allow for spaces */ SmallFish fish = (SmallFish)deleted_list_small_fish.get(0); deleted_list_small_fish.remove(0); fish.renit(i, j, next_fish_type, small_fish_median_life + int(random(small_fish_variance_life))); /* add to the list */ list_small_fish.add(fish); /* add to the grid */ board.add_small_fish(i, j, fish); } } } fish_image = new boolean[8][8]; fish_image_head = new boolean[8][8]; fish_image_tail = new boolean[8][8]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { fish_image[i][j] = false; fish_image_head[i][j] = false; fish_image_tail[i][j] = false; } } fish_image[1][1] = true; fish_image[1][2] = true; fish_image[1][3] = true; fish_image[1][4] = true; fish_image[1][5] = true; fish_image[1][6] = true; fish_image[2][2] = true; fish_image[2][5] = true; fish_image[3][3] = true; fish_image[3][4] = true; fish_image[4][2] = true; fish_image[4][3] = true; fish_image[4][4] = true; fish_image[4][5] = true; fish_image[5][1] = true; fish_image[5][6] = true; fish_image[6][2] = true; fish_image[7][3] = true; fish_image[7][4] = true; fish_image[6][5] = true; fish_image_head[0][0] = true; fish_image_head[0][7] = true; fish_image_head[1][0] = true; fish_image_head[1][7] = true; fish_image_head[2][1] = true; fish_image_head[2][6] = true; fish_image_head[3][2] = true; fish_image_head[3][5] = true; fish_image_head[4][3] = true; fish_image_head[4][4] = true; fish_image_tail[2][0] = true; fish_image_tail[2][1] = true; fish_image_tail[2][2] = true; fish_image_tail[2][3] = true; fish_image_tail[2][4] = true; fish_image_tail[2][5] = true; fish_image_tail[2][6] = true; fish_image_tail[2][7] = true; fish_image_tail[3][1] = true; fish_image_tail[3][6] = true; fish_image_tail[4][2] = true; fish_image_tail[4][5] = true; fish_image_tail[5][2] = true; fish_image_tail[5][5] = true; fish_image_tail[6][2] = true; fish_image_tail[6][5] = true; fish_image_tail[7][1] = true; fish_image_tail[7][6] = true; } void small_fish_move() { int max_index = list_small_fish.size(); int index = int(random(max_index)); // start at different spot in list SmallFish current_fish; for (int i = 0; i < max_index; i++) { current_fish = (SmallFish) list_small_fish.get(index); /* call the grid function to move a small fish */ board.move_small_fish (current_fish); if (index == max_index - 1) { index = 0; } else { index ++; } } } void update_small_fish() { int max_index = list_small_fish.size(); SmallFish current_fish; for (int index = max_index-1; index >= 0; index--) { current_fish = (SmallFish) list_small_fish.get(index); /* dead fish eliminate */ if (current_fish.is_dead()) { board.small_fish_dead(current_fish); /* don't need to update grid since a big fish ate me */ list_small_fish.remove(index); deleted_list_small_fish.add(current_fish); continue; } /* update how long alive */ current_fish.update_fish(); if (current_fish.is_growing()) { if (board.grow_small_fish (current_fish)) { /* delete the existing fish */ list_small_fish.remove(index); deleted_list_small_fish.add(current_fish); } } /* keep count of the fish of certain types */ fish_count[current_fish.type]++; } } void big_fish_move() { int max_index = list_big_fish.size(); int index = int(random(max_index)); // start at different spot in list BigFish current_fish; for (int i = 0; i < max_index; i++) { current_fish = (BigFish) list_big_fish.get(index); /* call the grid function to move a big fish */ board.move_big_fish (current_fish); board.big_fish_breed (current_fish); if (index == max_index - 1) { index = 0; } else { index ++; } } } void update_big_fish() { int max_index = list_big_fish.size(); BigFish current_fish; for (int index = max_index-1; index >= 0; index--) { current_fish = (BigFish) list_big_fish.get(index); /* update how long alive */ current_fish.update_fish(); /* dead fish eliminate */ if (current_fish.is_dead()) { list_big_fish.remove(index); deleted_list_big_fish.add(current_fish); board.big_fish_dead(current_fish); continue; } if(current_fish.is_spawning()) { list_big_fish.remove(index); deleted_list_big_fish.add(current_fish); int fish_type_1; int fish_type_2; /* add two small fish */ /* make a small fish in this grid spot but allow for spaces */ if (random(1) > 0.5) { fish_type_1 = current_fish.type; } else { fish_type_1 = current_fish.mate_type; } SmallFish fish = (SmallFish) deleted_list_small_fish.get(0); deleted_list_small_fish.remove(0); fish.renit(current_fish.x, current_fish.y, fish_type_1, small_fish_median_life + int(random(small_fish_variance_life))); fish.direction = current_fish.direction; /* add to the list */ list_small_fish.add(fish); /* add to the grid */ board.add_small_fish(current_fish.x, current_fish.y, fish); if (random(1) > 0.5) { fish_type_2 = current_fish.type; } else { fish_type_2 = current_fish.mate_type; } SmallFish fish2 = (SmallFish)deleted_list_small_fish.get(0); deleted_list_small_fish.remove(0); fish2.renit(current_fish.tail_x, current_fish.tail_y, fish_type_2, small_fish_median_life + int(random(small_fish_variance_life))); fish2.direction = current_fish.direction; /* add to the list */ list_small_fish.add(fish2); board.add_small_fish(current_fish.tail_x, current_fish.tail_y, fish2); /* keep count of the fish of certain types */ fish_count[fish.type]++; fish_count[fish2.type]++; } else { /* keep count of the fish of certain types */ fish_count[current_fish.type]++; } } } class Buttons { int x_top, y_top; int x_size, y_size; color button_color; color font_color; String button_text_on; String button_text_off; boolean button_on; boolean over; Buttons(int x_top, int y_top, int x_size, int y_size, color button_color, color font_color, String button_text_on, String button_text_off) { this.x_top = x_top; this.y_top = y_top; this.x_size = x_size; this.y_size = y_size; this.button_color = button_color; this.font_color = font_color; this.button_text_on = button_text_on; this.button_text_off = button_text_off; this.button_on = false; } boolean is_button_on() { return button_on; } boolean update_clicked() { if(is_over()) { over = true; } else { over = false; } if(over) { if (this.button_on == true) { button_on = false; } else { button_on = true; } } button_draw(); return button_on; } void button_draw() { /* create the rectangle button */ fill(button_color); stroke(color(255)); rect(x_top, y_top, x_size, y_size); /* put the writing on */ fill(font_color); if (button_on) { text(button_text_on, x_top+3, y_top+3, x_size, y_size); } else { text(button_text_off, x_top+3, y_top+3, x_size, y_size); } } boolean is_over() { if(mouseX > x_top && mouseX < x_top+x_size && mouseY > y_top && mouseY < y_top+y_size) { return true; } else { return false; } } } class Histogram { int x_top, y_top; int x_size, y_size; color font_color; String text; Histogram(int x_top, int y_top, int x_size, int y_size, color font_color, String text) { this.x_top = x_top; this.y_top = y_top; this.x_size = x_size; this.y_size = y_size; this.font_color = font_color; this.text= text; } void partial_draw() { /* create the rectangle */ fill(color(0)); stroke(color(255)); rect(x_top, y_top, x_size, y_size); fill(font_color); text(text, x_top+3, y_top+3, x_size, y_size); } void update_draw() { float total_fish = (float)(list_big_fish.size() + list_small_fish.size()) + 0.01; int max_y = y_size - 4; partial_draw(); for (int i = 0; i < fish_types; i++) { int colour_level = (i/7+1) * fish_colors; color this_color = color((((i%7+1) & 4) >> 2) * colour_level, (((i%7+1) & 2) >> 1) * colour_level, ((i%7+1) & 1) * colour_level); fill(this_color); stroke(color(255)); int y_height = int((((float)fish_count[i])/total_fish)*((float)max_y)); rect(x_top + 10 + i*10, y_top + 2 + (max_y-y_height), 7, y_height); } } } class Grid { GridSpot[][] grid_point; int x_size, y_size; boolean magnifying_on; int magnifying_glass_size; int magnifying_glass_grid_size; float [][]blur_kernel2 = {{0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067}, {0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292}, {0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117}, {0.00038771, 0.01330373, 0.11098164, 0.22508352, 0.11098164, 0.01330373, 0.00038771}, {0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117}, {0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292}, {0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067}}; Grid(int x_size, int y_size) { this.x_size = x_size; this.y_size = y_size; this.magnifying_on = false; this.magnifying_glass_size = 160; this.magnifying_glass_grid_size = 8; grid_point = new GridSpot[x_size][y_size]; for (int i=0; i < x_size; i++) { for (int j=0; j < y_size; j++) { grid_point[i][j] = new GridSpot(i, j); } } } void toggle_magnify() { if (magnifying_on == true) { magnifying_on = false; } else { magnifying_on = true; } } void update_draw() { int x_val, y_val; blur_draw(7); for (int i=0; i < x_size; i++) { for (int j=0; j < y_size; j++) { grid_point[i][j].update_draw(); } } if (magnifying_on) { if (mouseX < magnifying_glass_size/2) { x_val = magnifying_glass_size/2; } else if (mouseX > (width - magnifying_glass_size/2)) { x_val = width - magnifying_glass_size/2; } else { x_val = mouseX; } if (mouseY < magnifying_glass_size/2) { y_val = magnifying_glass_size/2; } else if (mouseY > width - magnifying_glass_size/2) { y_val = width - magnifying_glass_size/2; } else { y_val = mouseY; } this.draw_magnifying(x_val, y_val); } } void blur_draw(int size) { color point_color, blur_color; int midpoint = size / 2; for (int x = 0; x < x_size; x++) { for (int y = 0; y < y_size; y++) { float sum_r = 0; float sum_g = 0; float sum_b = 0; for (int cx = -midpoint; cx < midpoint; cx ++) { for (int cy = -midpoint; cy < midpoint; cy ++) { int point_x = x+cx; int point_y = y+cy; if (point_x < 0 || point_y < 0 || point_x > x_size - 1 || point_y > y_size - 1) continue; point_color = grid_point[point_x][point_y].get_grid_color(); sum_r += blur_kernel2[cx + midpoint][cy + midpoint] * red(point_color); sum_b += blur_kernel2[cx + midpoint][cy + midpoint] * blue(point_color); sum_g += blur_kernel2[cx + midpoint][cy + midpoint] * green(point_color); } } blur_color = color(sum_r, sum_b, sum_g); grid_point[x][y].set_grid_color(blur_color); } } } void draw_magnifying(int x_val, int y_val) { int i_cent = x_val / 2; int j_cent = y_val / 2; int i_top = i_cent - 10; int j_top = j_cent - 10; int x_top = x_val - magnifying_glass_size/2; int y_top = y_val - magnifying_glass_size/2; for (int i=0; i < 20; i++) { for (int j=0; j < 20; j++) { grid_point[i_top+i][j_top+j].update_big_draw(x_top+i*magnifying_glass_grid_size, y_top+j*magnifying_glass_grid_size, magnifying_glass_grid_size); grid_point[i_top+i][j_top+j].potentially_play_sound(); } } } void remove_big_fish(int tail_x, int tail_y) { /* remove the tail since the tail will move into the head spot */ grid_point[tail_x][tail_y].grid_empty(); } void add_big_fish(int x, int y, int tail_x, int tail_y, BigFish fish) { grid_point[x][y].update_big_fish_here(fish); grid_point[tail_x][tail_y].update_big_fish_tail(fish); } void remove_small_fish(int x, int y) { grid_point[x][y].grid_empty(); } void add_small_fish(int x, int y, SmallFish fish) { grid_point[x][y].update_small_fish_here(fish); } void move_big_fish (BigFish fish) { int i; int j; int pref = int(random(4)); int new_i; int new_j; boolean moved_to_eat = false; boolean moved = false; i = fish.x; j = fish.y; new_i = i; new_j = j; for (int x = 0; x < 4; x++) { if (i != 0 && pref == 0) { if (grid_point[i-1][j].is_small_fish_of_not_my_type(fish.type)) { new_i = i - 1; new_j = j; fish.direction = WEST; moved_to_eat = true; break; } } else if (i != x_size-1 && pref == 1) { if (grid_point[i+1][j].is_small_fish_of_not_my_type(fish.type)) { new_i = i + 1; new_j = j; moved_to_eat = true; fish.direction = EAST; break; } } else if (j != 0 && pref == 2) { if (grid_point[i][j-1].is_small_fish_of_not_my_type(fish.type)) { new_i = i; new_j = j - 1; moved_to_eat = true; fish.direction = NORTH; break; } } else if (j != y_size-1 && pref == 3) { if (grid_point[i][j+1].is_small_fish_of_not_my_type(fish.type)) { new_i = i; new_j = j + 1; moved_to_eat = true; fish.direction = SOUTH; break; } } pref = (pref + 1) % 4; } if (moved_to_eat == true) { /* update that a fish was eaten */ fish.fish_eaten(); /* update the small_fish that it's dead */ grid_point[new_i][new_j].small_fish_index.fish_dead(); } else //if (moved_to_eat == false) { for (int x = 0; x < 4; x++) { if (i != 0 && pref == 0) { if (grid_point[i-1][j].is_grid_empty()) { new_i = i - 1; new_j = j; moved = true; fish.direction = WEST; break; } } else if (i != x_size-1 && pref == 1) { if (grid_point[i+1][j].is_grid_empty()) { new_i = i + 1; new_j = j; moved = true; fish.direction = EAST; break; } } else if (j != 0 && pref == 2) { if (grid_point[i][j-1].is_grid_empty()) { new_i = i; new_j = j - 1; moved = true; fish.direction = NORTH; break; } } else if (j != y_size-1 && pref == 3) { if (grid_point[i][j+1].is_grid_empty()) { new_i = i; new_j = j + 1; moved = true; fish.direction = SOUTH; break; } } pref = (pref + 1) % 4; } } if (moved == true || moved_to_eat == true) { /* remove from old spot */ grid_point[fish.tail_x][fish.tail_y].grid_empty(); // tail empties /* add to new spot */ grid_point[new_i][new_j].update_big_fish_here(fish); grid_point[i][j].update_big_fish_tail(fish); /* update fish */ fish.update_x(new_i); fish.update_y(new_j); fish.update_tail_x(i); fish.update_tail_y(j); } else { fish.alive_counter = fish.dying_age; } } void big_fish_breed(BigFish fish) { int i; int j; int pref = int(random(4)); i = fish.x; j = fish.y; if (fish.breeding_age == false) return; for (int x = 0; x < 4; x++) { int mate_type = -1; if (i != 0 && pref == 0) { mate_type = grid_point[i-1][j].is_big_fish_of_breeding(fish.type); } else if (i != x_size-1 && pref == 1) { mate_type = grid_point[i+1][j].is_big_fish_of_breeding(fish.type); } else if (j != 0 && pref == 2) { mate_type = grid_point[i][j-1].is_big_fish_of_breeding(fish.type); } else if (j != y_size-1 && pref == 3) { mate_type = grid_point[i][j+1].is_big_fish_of_breeding(fish.type); } if (mate_type != -1) { grid_point[i][j].is_big_fish_of_breeding(mate_type); break; } pref = (pref + 1) % 4; } } void small_fish_dead(SmallFish fish) { if (grid_point[fish.x][fish.y].is_small_fish_here()) grid_point[fish.x][fish.y].grid_empty(); } void big_fish_dead(BigFish fish) { grid_point[fish.tail_x][fish.tail_y].grid_empty(); // tail empties grid_point[fish.x][fish.y].grid_empty(); // head empties } void move_small_fish (SmallFish fish) { int i; int j; int pref = int(random(4)); int new_i; int new_j; boolean moved = false; i = fish.x; j = fish.y; new_i = i; new_j = j; for (int x = 0; x < 4; x++) { if (i != 0 && pref == 0) { if (grid_point[i-1][j].is_grid_empty()) { new_i = i - 1; new_j = j; moved = true; fish.direction = WEST; break; } } else if (i != x_size-1 && pref == 1) { if (grid_point[i+1][j].is_grid_empty()) { new_i = i + 1; new_j = j; moved = true; fish.direction = EAST; break; } } else if (j != 0 && pref == 2) { if (grid_point[i][j-1].is_grid_empty()) { new_i = i; new_j = j - 1; moved = true; fish.direction = NORTH; break; } } else if (j != y_size-1 && pref == 3) { if (grid_point[i][j+1].is_grid_empty()) { new_i = i; new_j = j + 1; moved = true; fish.direction = SOUTH; break; } } pref = (pref + 1) % 4; } if (moved == true) { /* remove from old spot */ grid_point[i][j].grid_empty(); /* add to new spot */ grid_point[new_i][new_j].update_small_fish_here(fish); /* update fish */ fish.update_y(new_j); fish.update_x(new_i); } else { fish.fish_dead(); } } boolean grow_small_fish(SmallFish current_fish) { /* check if space to grow */ int i; int j; int pref = int(random(4)); int new_i; int new_j; boolean space = false; int direction = NORTH; i = current_fish.x; j = current_fish.y; new_i = i; new_j = j; for (int x = 0; x < 4; x++) { if (i != 0 && pref == 0) { if (grid_point[i-1][j].is_grid_empty()) { new_i = i - 1; new_j = j; space = true; direction = EAST; break; } } else if (i != x_size-1 && pref == 1) { if (grid_point[i+1][j].is_grid_empty()) { new_i = i + 1; new_j = j; space = true; direction = WEST; break; } } else if (j != 0 && pref == 2) { if (grid_point[i][j-1].is_grid_empty()) { new_i = i; new_j = j - 1; space = true; direction = SOUTH; break; } } else if (j != y_size-1 && pref == 3) { if (grid_point[i][j+1].is_grid_empty()) { new_i = i; new_j = j + 1; space = true; direction = NORTH; break; } } pref = (pref + 1) % 4; } if (space == true) { BigFish fish = (BigFish)deleted_list_big_fish.get(0); deleted_list_big_fish.remove(0); fish.renit(i, j, current_fish.type, new_i, new_j, big_fish_median_breeding_age + int(random(big_fish_variance_breeding_age)), big_fish_median_dying_age + int(random(big_fish_variance_dying_age)), big_fish_median_need_to_eat + int(random(big_fish_variance_need_to_eat))); fish.direction = direction; /* add to the list */ list_big_fish.add(fish); /* add to the grid */ board.add_big_fish(i, j, new_i, new_j, fish); } return space; } } class GridSpot { int x; int y; int i; int j; BigFish big_fish_index; BigFish tail_index; SmallFish small_fish_index; color grid_color; GridSpot(int x, int y) { this.i = x; this.j = y; this.x = 2*x; this.y = 2*y; grid_empty(); } void update_big_fish_here(BigFish big_fish_index) { grid_empty(); this.big_fish_index = big_fish_index; set_initial_grid_color(); } void update_big_fish_tail(BigFish big_fish_index) { grid_empty(); this.tail_index = big_fish_index; set_initial_grid_color(); } void update_small_fish_here(SmallFish small_fish_index) { grid_empty(); this.small_fish_index = small_fish_index; set_initial_grid_color(); } boolean is_small_fish_here() { if (this.small_fish_index != null) return true; else return false; } void grid_empty() { this.big_fish_index = null; this.tail_index = null; this.small_fish_index = null; set_grid_color(color(0)); } boolean is_small_fish_of_not_my_type(int my_type) { if (this.small_fish_index != null) { if (this.small_fish_index.type != my_type) { return true; } else { return false; } } else { return false; } } int is_big_fish_of_breeding(int my_type) { if (this.big_fish_index != null) { // inbreeding if (this.big_fish_index.breeding_age == true && this.big_fish_index.type != my_type) if (this.big_fish_index.breeding_age == true && cycles < 200) { this.big_fish_index.breeding = true; this.big_fish_index.mate_type = my_type; return this.big_fish_index.type; } else if (this.big_fish_index.breeding_age == true && this.big_fish_index.type != my_type && cycles < 400) { this.big_fish_index.breeding = true; this.big_fish_index.mate_type = my_type; return this.big_fish_index.type; } else if (cycles == 400) { cycles = 0; return -1; } else { return -1; } } else { return -1; } } boolean is_grid_empty() { if (this.big_fish_index == null && this.tail_index == null && this.small_fish_index == null) { return true; } else { return false; } } void set_initial_grid_color() { color grid_color; int colour_level; if (big_fish_index != null) { colour_level = (big_fish_index.type / 7+1) * fish_colors; this.grid_color = color((((big_fish_index.type%7+1) & 4) >> 2) * colour_level, (((big_fish_index.type%7+1) & 2) >> 1) * colour_level, ((big_fish_index.type%7+1) & 1) * colour_level); } else if (tail_index != null) { colour_level = (tail_index.type / 7+1) * fish_colors; this.grid_color = color((((tail_index.type%7+1) & 4) >> 2) * colour_level, (((tail_index.type%7+1) & 2) >> 1) * colour_level, ((tail_index.type%7+1) & 1) * colour_level); } else if (small_fish_index != null) { colour_level = (small_fish_index.type / 7+1) * fish_colors; this.grid_color = color((((small_fish_index.type%7+1) & 4) >> 2) * colour_level, (((small_fish_index.type%7+1) & 2) >> 1) * colour_level, ((small_fish_index.type%7+1) & 1) * colour_level); } else { this.grid_color = background_color; } } color get_grid_color() { return grid_color; } void set_grid_color(color current_color) { grid_color = current_color; } void update_draw() { color grid_color = get_grid_color(); stroke(grid_color); fill(grid_color); rect(x, y, 1, 1); } void update_big_draw(int x_top, int y_top, int size) { color grid_color; int colour_level; boolean [][]image; int direction; if (big_fish_index != null) { direction = big_fish_index.direction; image = fish_image_head; colour_level = (big_fish_index.type / 7+1) * fish_colors; grid_color = color((((big_fish_index.type%7+1) & 4) >> 2) * colour_level, (((big_fish_index.type%7+1) & 2) >> 1) * colour_level, ((big_fish_index.type%7+1) & 1) * colour_level); } else if (tail_index != null) { direction = tail_index.direction; image = fish_image_tail; colour_level = (tail_index.type / 7+1) * fish_colors; grid_color = color((((tail_index.type%7+1) & 4) >> 2) * colour_level, (((tail_index.type%7+1) & 2) >> 1) * colour_level, ((tail_index.type%7+1) & 1) * colour_level); } else if (small_fish_index != null) { direction = small_fish_index.direction; image = fish_image; colour_level = (small_fish_index.type / 7+1) * fish_colors; grid_color = color((((small_fish_index.type%7+1) & 4) >> 2) * colour_level, (((small_fish_index.type%7+1) & 2) >> 1) * colour_level, ((small_fish_index.type%7+1) & 1) * colour_level); } else { grid_color = background_color; stroke(grid_color); fill(grid_color); rect(x_top, y_top, size, size); return; } stroke(color(0)); fill(color(0)); rect(x_top, y_top, size, size); stroke(grid_color); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { if (image[i][j] == true) { if (direction == EAST) { point(x_top+i, y_top+j); } else if (direction == WEST) { point(x_top+(size-1-i), y_top+j); } else if (direction == NORTH) { point(x_top+j, y_top+((size-1-i)%size)); } else if (direction == SOUTH) { point(x_top+((size-1-j)%size), y_top+i); } } } } } void potentially_play_sound() { if (big_fish_index != null) { if (random(1) > 0.9) { int index = int(random(17)); wale_sounds[index].play_sound(cycles); } } } } class BigFish extends Fish { int tail_x; // where your tail is int tail_y; int alive_counter; // how many more turns are you alive for boolean breeding_age; boolean breeding; int mate_type; int breeding_age_value; int dying_age; int fish_eaten; // how many fish have you eaten int need_to_eat_x_fish; // how many fish to eat to become two new fish BigFish(int x, int y, int type, int tail_x, int tail_y, int breeding_age, int dying_age, int need_to_eat_x_fish) { super(x,y,type); this.tail_x = tail_x; this.tail_y = tail_y; this.breeding_age_value = breeding_age; this.dying_age = dying_age; this.alive_counter = 0; this.breeding_age = false; this.breeding = false; this.fish_eaten = 0; this.need_to_eat_x_fish = need_to_eat_x_fish; } void renit(int x, int y, int type, int tail_x, int tail_y, int breeding_age, int dying_age, int need_to_eat_x_fish) { this.reinit(x,y,type); this.tail_x = tail_x; this.tail_y = tail_y; this.breeding_age_value = breeding_age; this.dying_age = dying_age; this.alive_counter = 0; this.breeding_age = false; this.breeding = false; this.fish_eaten = 0; this.need_to_eat_x_fish = need_to_eat_x_fish; } void fish_eaten() // updates if a fish is eaten { /* add another time step */ fish_eaten ++; this.breeding_age_value = 0; this.dying_age += 10; } boolean is_dead() { if (alive_counter >= dying_age) return true; else return false; } boolean is_spawning() { if (breeding == true) return true; else return false; } void update_fish() // returns if fish spawns { /* add another time step */ if (alive_counter >= breeding_age_value && fish_eaten >= need_to_eat_x_fish) { breeding_age = true; } alive_counter ++; } int get_tail_x() { return tail_x; } int get_tail_y() { return tail_y; } void update_tail_x(int tail_x) { this.tail_x = tail_x; } void update_tail_y(int tail_y) { this.tail_y = tail_y; } } class SmallFish extends Fish { int alive_for; // how many turns small fish alive for int need_to_stay_alive; // how many turns until you become a big fish SmallFish(int x, int y, int type, int need_to_stay_alive) { super(x,y,type); this.alive_for = 0; this.need_to_stay_alive = need_to_stay_alive; } void renit(int x, int y, int type, int need_to_stay_alive) { this.reinit(x,y,type); this.alive_for = 0; this.need_to_stay_alive = need_to_stay_alive; } boolean is_growing() { if (alive_for >= need_to_stay_alive) return true; else return false; } void update_fish() // returns if fish spawns { /* add another time step */ alive_for ++; } boolean is_dead() { return this.dead; } } class Fish { int x, y; int type; // tells you what type of fish you are... boolean dead; int direction; Fish (int x, int y, int type) { this.x = x; this.y = y; this.type = type; this.dead = false; this.direction = NORTH; } void reinit (int x, int y, int type) { this.x = x; this.y = y; this.type = type; this.dead = false; this.direction = NORTH; } int get_x() { return x; } int get_y() { return y; } void update_x(int x) { this.x = x; } void update_y(int y) { this.y = y; } int get_type() { return type; } void fish_dead() { dead = true; } } class SoundSample { int played_at_cycle; AudioPlayer sound; SoundSample(String sound_file) { this.sound = minim.loadFile(sound_file); this.played_at_cycle = -200; } void play_sound(int cycle) { if (cycle + 200 + int(random(200)) > played_at_cycle) { for (int i = 0; i < 18; i++) { if (wale_sounds[i].sound.isPlaying()) { return; } } this.played_at_cycle = cycle; sound.play(); } } }