// Color Beads static final int pw = 10; static final int ph = 10; int tw, th; static final int kMaxColors = 4; int[][] cgrid = new int[pw][ph]; // int[] colors = {0xA41F62, 0xFFA300, 0x5F9F00, 0x001FA2}; boolean specularOK = true; int[] colors = {0x14bff0, 0xf5c809, 0xc72626, 0x31aa42}; int nbrCells; boolean gameOver = false; // Init void setup() { size(220,200); tw = width/pw; th = height/ph; smooth(); noLoop(); PFont myFont = loadFont("ComicSansMS-24.vlw"); textFont(myFont, 24); newGame(); } void newGame() { gameOver = false; for (int y = 0; y < ph; ++y) { for (int x = 0; x < pw; ++x) { cgrid[y][x] = int(random(kMaxColors)+1); } } nbrCells = pw*ph; } void draw() { background(0); // 0xf4,0xf1,0xce); noStroke(); ellipseMode(CORNER); int x1,y1,x2,y2,x3,y3,x4,y4,x5,y5; for (int y = 0; y < ph; ++y) { for (int x = 0; x < pw; ++x) { if (cgrid[y][x] == 0) continue; int clr = colors[cgrid[y][x]-1]; int r = clr >> 16; int g = (clr >> 8) & 0xFF; int b = clr & 0xFF; fill(r,g,b); ellipse(x*tw+1,y*th+1,tw-2,th-2); if (x < pw-1 && cgrid[y][x] == cgrid[y][x+1]) { if (y < ph-1 && cgrid[y][x] == cgrid[y+1][x] && cgrid[y][x] == cgrid[y+1][x+1]) { // corner junction rect(x*tw+th/4,y*th+th/4,tw,th); } else { // horizontal junction rect(x*tw+th/4,y*th+th/4,tw,th/2); } } if (y < ph-1 && cgrid[y][x] == cgrid[y+1][x]) { // vertical function rect(x*tw+th/4,y*th+th/4,tw/2,th); } if (specularOK) { fill(255); ellipse(x*tw+tw*.6,y*th+th*.2,2,2); } } } if (gameOver) { fill(255); textAlign(CENTER); if (nbrCells == 0) { text("WINNER!",width/2,height/2); } else { text("GAME OVER",width/2,height/2); } smooth(); } } void mousePressed() { int gx = mouseX/tw; int gy = mouseY/th; if (gx < 0 || gx >= pw || gy < 0 || gy >= ph) return; if (gameOver) { newGame(); redraw(); return; } int c = cgrid[gy][gx]; if (c == 0) return; if ((gx == 0 || cgrid[gy][gx-1] != c) && (gy == 0 || cgrid[gy-1][gx] != c) && (gx >= pw-1 || cgrid[gy][gx+1] != c) && (gy >= ph-1 || cgrid[gy+1][gx] != c)) return; // println("Got one"); // remove all connected dots by flood fill FloodRemove(gx,gy,c); if (nbrCells == 0) { // Winner!! println("WINNER!"); gameOver = true; redraw(); } boolean lastX = false; for (int x = pw-1; x >= 0; --x) { boolean lastY = false; for (int y = 0; y < ph; ++y) { if (cgrid[y][x] == 0) { if (lastY) ScrollDownInto(x,y); } else { lastY = true; } } if (cgrid[ph-1][x] == 0) { if (lastX) ScrollLeftInto(x); } else { lastX = true; } } // detect loser here... // println ("CC"); boolean connectsDetected = false; for (int y = 0; y < ph && !connectsDetected; ++y) { for (int x = 0; x < pw-1; ++x) { if (cgrid[y][x] != 0 && ( cgrid[y][x+1] == cgrid[y][x] || (y < ph-1 && cgrid[y+1][x] == cgrid[y][x]) ) ) { connectsDetected = true; break; } } } if (!connectsDetected) { gameOver = true; println("GAME OVER " + nbrCells + " cells remaining"); } redraw(); } void ScrollDownInto(int x, int dy) { // println("V " + x + " x " + dy); for (int y = dy; y > 0; --y) { cgrid[y][x] = cgrid[y-1][x]; } cgrid[0][x]= 0; } void ScrollLeftInto(int dx) { // println("< " + dx); for (int y = 0; y < ph; ++y) { for (int x = dx; x < pw-1; ++x) { cgrid[y][x] = cgrid[y][x+1]; } cgrid[y][pw-1] = 0; } } void FloodRemove(int x, int y, int c) { if (cgrid[y][x] == 0) return; cgrid[y][x] = 0; --nbrCells; if (x > 0 && cgrid[y][x-1] == c) FloodRemove(x-1,y,c); if (y > 0 && cgrid[y-1][x] == c) FloodRemove(x,y-1,c); if (x < pw-1 && cgrid[y][x+1] == c) FloodRemove(x+1,y,c); if (y < ph-1 && cgrid[y+1][x] == c) FloodRemove(x,y+1,c); } void keyPressed() { if (key == 'n' || key == 'N') { newGame(); redraw(); } else println("Key: " + keyCode); }