/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://fgcs.sketchpad.cc/sp/pad/view/ro.3uzMYA0YFMm/rev.3915
*
* authors:
* Markus Roberts
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
int grid_size = 4;
int [][] grid = new int[grid_size][grid_size];
int [][] shine = new int[grid_size][grid_size];
boolean game_over = false;
void setup() {
size(400, 400);
frameRate(30);
grid[1][1] = 1;
}
String debug;
void draw() {
background(255,255,200);
int cell_width = round(width/grid_size);
int cell_height = round(height/grid_size);
int margin = 5;
for (int i = 0; i<grid_size; i++) {
for (int j = 0; j<grid_size; j++) {
fill(255-(17*grid[i][j] % 100),255-(23*grid[i][j] % 100),255-shine[i][j]);
shine[i][j] = (shine[i][j]*98)/100;
noStroke();
rect(i*cell_width+margin,j*cell_height+margin,cell_width-2*margin,cell_height-2*margin);
textSize(30);
if (grid[i][j] > 0) {
fill(0);
text(""+grid[i][j],i*cell_width+(cell_width-textWidth(""+grid[i][j]))/2,j*cell_height+margin+cell_height/2);
}
}
}
fill(0,0,0,30);
textSize(50);
text(debug,width/2-textWidth(debug)/2,height/2);
if (game_over) {
fill(255,255,255,50);
rect(0,0,width,height);
fill(0);
textSize(50);
text("Game Over",width/2-textWidth("Game Over")/2,height/2);
}
}
void keyPressed() {
if (key == 'z') shift_grid( 0,-1);
else if (key == 'w') shift_grid( 0, 1);
else if (key == 'a') shift_grid( 1, 0);
else if (key == 's') shift_grid(-1, 0);
}
void shift_grid(int delta_x, int delta_y) {
int [][] rotation = new int [][] {
{1-abs(delta_x),delta_x,(delta_x < 0 ? grid_size-1 : 0)},
{1-abs(delta_y),delta_y,(delta_y < 0 ? grid_size-1 : 0)}
};
int zeros = 0, changes = 0;
for (int row = 0; row<grid_size; row++) {
int r = 0, w = 0;
while (r<grid_size) {
int
rx = row*rotation[0][0]+r*rotation[0][1]+rotation[0][2],
ry = row*rotation[1][0]+r*rotation[1][1]+rotation[1][2],
wx = row*rotation[0][0]+w*rotation[0][1]+rotation[0][2],
wy = row*rotation[1][0]+w*rotation[1][1]+rotation[1][2];
if (grid[rx][ry] == 0) {
zeros++;
r++;
} else if (r == w) {
r++;
} else if (grid[wx][wy] == 0) {
grid[wx][wy] = grid[rx][ry];
shine[wx][wy] = shine[rx][ry];
grid[rx][ry] = 0;
shine[rx][ry] = 0;
changes++;
r++;
} else if (addable(grid[rx][ry],grid[wx][wy])) {
grid[wx][wy] += grid[rx][ry];
shine[wx][wy] = 128;
grid[rx][ry] = 0;
shine[rx][ry] = 0;
changes++;
zeros++;
r++;
w++;
} else {
w++
if (w>=r) r++;
}
}
}
if (zeros > 0 && changes > 0) {
int new_x,new_y;
boolean found = false;
while (!found) {
new_x = round(random(grid_size-1));
new_y = round(random(grid_size-1));
found = grid[new_x][new_y] == 0;
}
grid[new_x][new_y] = 1;
shine[new_x][new_y] = 128;
}
if (zeros == 0) game_over = true;
}
boolean addable(int a, int b) {
return (a == 1 && (b == 1 || b == 2)) || (a > b && addable(b,a)) || (max(0,b-a) < a && a < b && addable(b-a,a));
}