color[] durrett_colors = {color(200, 0, 0), color(200, 200, 0), color( 0, 200, 0), color( 0, 200, 200)}; float d2_alph = 2.0/3.0; float d2_beta = 2; // why the hell is this 2? it is only ever used as (d2_beta - 1), // which makes sense since it's a probability, from 0-1. int[][] durrett3_grid = new int[grid_width][grid_height]; int[][] durrett3_grid_new = new int[grid_width][grid_height]; float[] d3_alph = {0, d2_alph, d2_alph, d2_alph}; float[] d3_beta = {0, d2_beta, d2_beta, d2_beta}; boolean[] d3_s_live = {true, true, true, true}; // zero reference doesn't matter void d3_occupy_vacancies(){ for(int j = 0; j < grid_height; j++){ for(int i = 0; i < grid_width; i++){ if(durrett3_grid[i][j] == 0){ float[] f_n = new float[4]; float f_total = 0; // with different sized neighborhoods, this can go above 1. // without a cleaner idea of how to handle this, lets just scale it to one. for(int s = 1; s < d3_n_x.length; s++){ if(d3_s_live[s]){ for(int n = 0; n < d3_n_x[s].length; n++){ int n_i = (i + d3_n_x[s][n] + grid_width) % grid_width; int n_j = (j + d3_n_y[s][n] + grid_height) % grid_height; if(durrett3_grid[n_i][n_j] == s){ float f_w = 1f/(float)(d3_n_x[s].length); f_n[durrett3_grid[n_i][n_j]] += f_w; } } } } float dice_roll = random((f_total <= 1) ? 1f : f_total); float p_sum = 0; int contender = 0; int winner = 0; while(dice_roll > p_sum && contender < f_n.length){ p_sum += f_n[contender]; if( dice_roll > p_sum) { contender++; } else { winner = contender; } } if(d3_s_live[winner]){ durrett3_grid_new[i][j] = winner; } } } } } void d3_spread(){ for(int j = 0; j < grid_height; j++){ for(int i = 0; i < grid_width; i++){ if(durrett3_grid[i][j] != 0){ int s = durrett3_grid[i][j]; // choose a neighbor float n_dice_roll = random(1f); int n = (int)(floor(n_dice_roll * (float)(d3_n_x[s].length))); // decide whether or not to colonize (or attack) float c_dice_roll = random(1f); if(c_dice_roll < (d3_beta[s]-1)){ int n_i = (i + d3_n_x[s][n] + grid_width) % grid_width; int n_j = (j + d3_n_y[s][n] + grid_height) % grid_height; int n_s = durrett3_grid[n_i][n_j]; if(d3_s_live[s] && d3_s_live[n_s]){ //is it occupied by a type this one dominates? if(n_s != 0 && s == n_s+1 || (s == 1 && n_s == 3)){ // then kill it or replace it float k_dice_roll = random(1f); if(k_dice_roll > (1 - d3_alph[s])/(d3_beta[3] - 1)){ durrett3_grid_new[n_i][n_j] = 0; } else { durrett3_grid_new[n_i][n_j] = s; } } } } } } } } int d3_population_count(int s){ int count = 0; for(int j = 0; j < grid_height; j++){ for(int i = 0; i < grid_width; i++){ if(durrett3_grid[i][j] == s) count++; } } return count; } void initD3AllThree(){ for(int j = 0; j < grid_height; j++){ for(int i = 0; i < grid_width; i++){ durrett3_grid[i][j] = 0; durrett3_grid_new[i][j] = 0; } } for(int i = 0; i < grid_width; i++){ durrett3_grid[i][0] = 1; durrett3_grid_new[i][0] = 1; durrett3_grid[i][grid_height/3] = 2; durrett3_grid_new[i][grid_height/3] = 2; durrett3_grid[i][2*grid_height/3] = 3; durrett3_grid_new[i][2*grid_height/3] = 3; } }