// CellWar // // The screen is divided into a grid of cells. Each row of each cell is an // instruction, and each cell has many instructions. There are several types of // instructions: // // Null - Do nothing. This is instruction 0 and shows up as black on the screen // Move (left,right,up,down) - Copies the entire cell to the adjacent cell // using Binary-OR, and sets the new cell as the current location // Kill (left,right,up,down) - Fill the adjacent cell with Nulls // Clone (left,right,up,down) - Binary OR on top of the adjacent cell without // changing the location // Mutate - mutates a random instruction in the current cell // // Each of these are represented in binary with 4 bits, from 0-15. Mutation is // instruction 15, so when cells Binary-OR on top of each other enough it // generally leads to mutation. // // Each set of instructions also has it's own shape, so you can easily see when // a specific set of instructions (a "species" if you will) is spreading. int sx = 200; int sy = 200; int x_inner_zoom_out = 2; // draw every nth pixel x-wise int y_inner_zoom_out = 10; // draw every nth pixel y-wise int x_outer_zoom_out = 1; // draw every nth cell x-wise int y_outer_zoom_out = 1; // draw every nth cell y-wise int instrs = 32; int[][][] world; boolean wrap_x = false; boolean wrap_y = false; boolean use_color = true; boolean start_randomly = false; int refresh_rate = sx*sy; // try sx*sy/10 or just 100 int mutation_rate = sx*sy/2; // Higher is actually less mutation void setup() { size(4*sx/x_inner_zoom_out/x_outer_zoom_out,instrs*sy/y_inner_zoom_out/y_outer_zoom_out,P2D); stroke(255); world = new int[sx][sy][instrs]; if(start_randomly) { for(int x = 0; x < sx; x++) { for(int y = 0; y < sy; y++) { for(int r = 0; r < instrs; r++) { world[x][y][r] = (int)random(16); } } } } } void draw() { background(0); for (int x = 0; x < sx; x=x+x_outer_zoom_out) { for (int y = 0; y < sy; y=y+y_outer_zoom_out) { color cmdcolor; if(use_color) { int avgcmd = 0; int sumcmd = 0; for(int r = 0; r < instrs; r++) { avgcmd += world[x][y][r]; } sumcmd = avgcmd; avgcmd = avgcmd / instrs; cmdcolor = color( //world[x][y][0]*16 sumcmd*(256/instrs/16), //world[x][y][instrs/2-1]*16, // maybe use average instead? avgcmd*16, world[x][y][instrs-1]*16 ); } else { cmdcolor = color(255,255,255); } for (int r = 0; r < instrs; r=r+1) { int x_base = x*4/x_outer_zoom_out; int y_base = y*instrs/y_outer_zoom_out; if((world[x][y][r] & 8) > 0) { set(x_base/x_inner_zoom_out,(y_base+r)/y_inner_zoom_out, cmdcolor); } if((world[x][y][r] & 4) > 0) { set((x_base+1)/x_inner_zoom_out,(y_base+r)/y_inner_zoom_out,cmdcolor); } if((world[x][y][r] & 2) > 0) { set((x_base+2)/x_inner_zoom_out,(y_base+r)/y_inner_zoom_out,cmdcolor); } if((world[x][y][r] & 1) > 0) { set((x_base+3)/x_inner_zoom_out,(y_base+r)/y_inner_zoom_out,cmdcolor); } } } } //for(int i = 0; i < sx*sy; i=i+1) { for(int i = 0; i < refresh_rate; i=i+1) { int x = (int)random(sx); int y = (int)random(sy); int x_right = x + 1; if(x_right == sx) { x_right = 0; } int y_right = y; for(int r = 0; r < instrs; r=r+1) { int cmd = world[x][y][r]; if(cmd == 1) { int[] new_pos = move_right(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 2) { int[] new_pos = move_down(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 3) { int[] new_pos = kill_left(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 4) { int[] new_pos = kill_up(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 5) { int[] new_pos = clone_right(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 6) { int[] new_pos = clone_down(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } /*if(cmd == 7) { int[] new_pos = kill_left(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 8) { int[] new_pos = kill_down(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); }*/ if(cmd == 9) { int[] new_pos = clone_left(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 10) { int[] new_pos = clone_up(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 11) { int[] new_pos = kill_right(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 12) { int[] new_pos = kill_down(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 13) { int[] new_pos = move_left(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } if(cmd == 14) { int[] new_pos = move_up(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } //if(cmd == 13) { // int[] new_pos = self_destruct(x,y); // x = normalize_x(new_pos[0]); // y = normalize_y(new_pos[1]); //} if(cmd == 15) { int[] new_pos = mutate(x,y); x = normalize_x(new_pos[0]); y = normalize_y(new_pos[1]); } } if((int)random(mutation_rate) == 0) { int[] trash = mutate((int)random(sx),(int)random(sy)); } } } int normalize_x(int x) { if(x >= sx) { return wrap_x ? 0 : sx - 1; } if(x < 0) { return wrap_x ? sx - 1 : 0; } return x; } int normalize_y(int y) { if(y >= sy) { return wrap_y ? 0 : sy - 1; } if(y < 0) { return wrap_y ? sy - 1 : 0; } return y; } int[] move_right(int x, int y) { int x_right = normalize_x(x + 1); int y_right = normalize_y(y); for(int s = 0; s < instrs; s=s+1) { world[x_right][y_right][s] |= world[x][y][s]; world[x][y][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x_right; new_pos[1] = y_right; return new_pos; } int[] move_left(int x, int y) { int x_left = normalize_x(x - 1); int y_left = normalize_y(y); for(int s = 0; s < instrs; s=s+1) { world[x_left][y_left][s] |= world[x][y][s]; world[x][y][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x_left; new_pos[1] = y_left; return new_pos; } int[] move_up(int x, int y) { int x_up = normalize_x(x); int y_up = normalize_y(y - 1); for(int s = 0; s < instrs; s=s+1) { world[x_up][y_up][s] |= world[x][y][s]; world[x][y][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x_up; new_pos[1] = y_up; return new_pos; } int[] move_down(int x, int y) { int x_down = normalize_x(x); int y_down = normalize_y(y + 1); for(int s = 0; s < instrs; s=s+1) { world[x_down][y_down][s] |= world[x][y][s]; world[x][y][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x_down; new_pos[1] = y_down; return new_pos; } int[] kill_right(int x, int y) { int x_right = normalize_x(x + 1); int y_right = normalize_y(y); for(int s = 0; s < instrs; s=s+1) { world[x_right][y_right][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] kill_left(int x, int y) { int x_left = normalize_x(x - 1); int y_left = normalize_y(y); for(int s = 0; s < instrs; s=s+1) { world[x_left][y_left][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] kill_up(int x, int y) { int x_up = normalize_x(x); int y_up = normalize_y(y - 1); for(int s = 0; s < instrs; s=s+1) { world[x_up][y_up][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] kill_down(int x, int y) { int x_down = normalize_x(x); int y_down = normalize_y(y + 1); for(int s = 0; s < instrs; s=s+1) { world[x_down][y_down][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] clone_right(int x, int y) { int x_right = normalize_x(x + 1); int y_right = normalize_y(y); for(int s = 0; s < instrs; s=s+1) { world[x_right][y_right][s] |= world[x][y][s]; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] clone_left(int x, int y) { int x_left = normalize_x(x - 1); int y_left = normalize_y(y); for(int s = 0; s < instrs; s=s+1) { world[x_left][y_left][s] |= world[x][y][s]; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] clone_up(int x, int y) { int x_up = normalize_x(x); int y_up = normalize_y(y - 1); for(int s = 0; s < instrs; s=s+1) { world[x_up][y_up][s] |= world[x][y][s]; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] clone_down(int x, int y) { int x_down = normalize_x(x); int y_down = normalize_y(y + 1); for(int s = 0; s < instrs; s=s+1) { world[x_down][y_down][s] |= world[x][y][s]; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] mutate(int x, int y) { world[x][y][(int)random(instrs)] = (int)random(16); int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; } int[] self_destruct(int x, int y) { int x_down = normalize_x(x); int y_down = normalize_y(y + 1); int x_up = normalize_x(x); int y_up = normalize_y(y - 1); int x_right = normalize_x(x + 1); int y_right = normalize_y(y); int x_left = normalize_x(x - 1); int y_left = normalize_y(y); for(int s = 0; s < instrs; s=s+1) { world[x][y][s] = 0; world[x_down][y_down][s] = 0; world[x_up][y_up][s] = 0; world[x_left][y_left][s] = 0; world[x_right][y_right][s] = 0; } int[] new_pos = new int[2]; new_pos[0] = x; new_pos[1] = y; return new_pos; }