boolean gameover = false; int kRED = 0; int kGREEN = 1; int kBLUE = 2; int kCOLORS = 3; int initialMouseX; int initialMouseY; Grid mike = new Grid(); void setup() { size(180, 200); stroke(255); smooth(); frameRate(60); mike.Setup(); } class Circle { int mR, mG, mB, mRow, mCol, mRadius; int mColor; Circle( int iColor, int row, int col ) { mR = mG = mB = 0; if( iColor == kRED ) { mColor = kRED; mR = 255; } else if( iColor == kGREEN ){ mColor = kGREEN; mG = 255; } else { mColor = kBLUE; mB = 255; } mRow = row; mCol = col; mRadius = 30; } void render(int xoffset, int yoffset) { fill(mR, mG, mB, 255); ellipse((mCol * mRadius)+xoffset, (mRow*mRadius)+yoffset, mRadius, mRadius); } void setPos(int row, int col ) { mRow = row; mCol = col; } } class Grid { int rows = 5; int cols = 4; int rad = 30; int offset = 40; int hlRow = -1; int hlCol = -1; int xhlOffset = 0; int yhlOffset = 0; ArrayList circles; int [] circleCount; int [] goalCount; int [][] goalArea; void Setup() { circles = new ArrayList(); goalArea = new int[rows][cols]; circleCount = new int [kCOLORS]; goalCount = new int[kCOLORS]; for(int r = 0; r < rows; ++r) { for( int c = 0; c < cols; ++c ) { int randColor = (int)random(kCOLORS); circles.add(new Circle(randColor, r, c)); circleCount[randColor] += 1; goalArea[r][c] = -1; } } } void CreateNewGoal() { //Clear out previous goals /*for(int r = 0; r < rows; ++r) { for( int c = 0; c < cols; ++c ) { goalArea[r][c] = -1; } }*/ int col = (int)random(kCOLORS); int boxes = 0; do { boxes = (int)random(5); } while( boxes == 0 || goalCount[col] + boxes > circleCount[col]); goalCount[col] += boxes; int sR, sC; do{ sR = (int)random(rows); sC = (int)random(cols); } while( sR < 0 || sR >= rows || sC < 0 || sC >= cols ); for(int i = 0; i < boxes; ++i ) { if( goalArea[sR][sC] == -1 ) { goalArea[sR][sC] = col; } else { --i; } int move = 0; if( (int) random(2) == 0 ) { do { move = (int)random(3) - 1; sR = sR + move; } while( sR < 0 || sR >= rows); } else{ do { move = (int)random(3) - 1; sC = sC + move; } while( sC < 0 || sC >= cols); } } } void render() { //Render our circles; stroke(255); for(int r = 0; r < circles.size(); ++r) { Circle temp = (Circle)circles.get(r); if(temp.mRow == hlRow || temp.mCol == hlCol) { temp.render( offset+xhlOffset, offset+yhlOffset); } else { temp.render( offset, offset); } } //Render our goal area; strokeWeight(3); drawGoalArea(); } void drawGoalArea() { for( int r = 0; r < rows; ++r ) { for( int c = 0; c < cols; ++c ) { if( goalArea[r][c] != -1 ) { if( goalArea[r][c] == kRED ) { stroke(255, 0, 0); } else if( goalArea[r][c] == kGREEN ) { stroke(0, 255, 0); } else { stroke(0,0,255); } drawBox(c, r); } } } } void drawBox( int r, int c ) { line( (r*rad) + offset - (rad/2), (c*rad) + offset - (rad/2), (r*rad)+offset - (rad/2), (c*rad) + offset + (rad/2)); line( (r*rad) + offset - (rad/2), (c*rad) + offset - (rad/2), (r*rad)+offset + (rad/2), (c*rad) + offset - (rad/2)); line( (r*rad) + offset + (rad/2), (c*rad) + offset + (rad/2), (r*rad)+offset - (rad/2), (c*rad) + offset + (rad/2)); line( (r*rad) + offset + (rad/2), (c*rad) + offset + (rad/2), (r*rad)+offset + (rad/2), (c*rad) + offset - (rad/2)); } void processClick(int x, int y) { for( int c = 0; c < cols; ++c) { if( (c*rad) + offset - (rad/2) <= x && (c*rad) + offset + (rad/2) >= x) { hlCol = c; break; } } for( int r = 0; r < rows; ++r) { if( (r*rad) + offset - (rad/2) <= y && (r*rad) + offset + (rad/2) >= y) { hlRow = r; break; } } boolean fail = false; for( int r = 0; r < rows; ++r ) { for( int c = 0; c < cols; ++c ) { if( goalArea[r][c] != -1 ) { for(int i = 0; i < circles.size(); ++i) { Circle temp = (Circle)circles.get(i); if( temp.mRow == r && temp.mCol == c && temp.mColor != goalArea[r][c] ) { //println( "ROW: " + r + " COL: " + c + " CC: " + temp.mColor + " GC: " + goalArea[r][c]); fail = true; break; } } } } } if( fail == false ) { CreateNewGoal(); } } void unhighLight(){ hlCol = hlRow = -1; xhlOffset = 0; yhlOffset = 0; } void setOffset(int x, int y ) { if(abs(x) > abs(y) && abs(x) > (rad/4) && hlRow != -1) { xhlOffset = (x%rad); yhlOffset = 0; hlCol = -1; } else if( abs(y) > abs(x) && abs(y) > (rad/4) && hlCol != -1) { xhlOffset = 0; yhlOffset = (y%rad); hlRow = -1; } if( abs(x) > (rad/2) || abs(y) > (rad/2) ) { //Loop around if need be. for( int i = 0; i < circles.size(); ++i ) { Circle temp = (Circle)circles.get(i); if( temp.mRow == hlRow && xhlOffset == 0) { if( x > 0 ) { temp.mCol = temp.mCol + 1; } else { temp.mCol = temp.mCol - 1; } if( temp.mCol >= cols ) { temp.mCol = 0; } else if( temp.mCol < 0 ) { temp.mCol = cols -1; } } if( temp.mCol == hlCol && yhlOffset == 0) { if( y > 0 ) { temp.mRow = temp.mRow + 1; } else { temp.mRow = temp.mRow - 1; } if( temp.mRow >= rows ) { temp.mRow = 0; } else if( temp.mRow < 0 ) { temp.mRow = rows -1; } } } } } } void draw() { background(255); mike.render(); } void mouseDragged() { mike.setOffset( mouseX - initialMouseX, mouseY - initialMouseY); } void mousePressed() { initialMouseX = mouseX; initialMouseY = mouseY; mike.processClick( initialMouseX, initialMouseY ); } void mouseReleased() { mike.unhighLight(); } /**//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////