#46 Simple Mine-Sweeper
(Won, Playing, Lost)
Code
int a = 10; //width and height of grid
int grid[][] = new int[a][a];
int scl = 600/a, m = 10;
boolean show[][] = new boolean[a][a];
boolean flagged[][] = new boolean[a][a];
int RESULT = 0; //-1: lost 0: undecided 1: won
void setup() {
size(600, 600);
grid = newGrid(a, m);
textAlign(3, 3);
textSize(scl*0.6);
}
void draw() {
background(0);
stroke(255, 50);
for (int i = 1; i < a; i++) {
line( i*scl, 0, i*scl, height);
line( 0, i*scl, width, i*scl);
}
for (int i = 0; i < a; i++) for (int j = 0; j < a; j++) {
if (show[i][j]||RESULT==1) {
fill(100);
square(i*scl, j*scl, scl);
fill(255);
if (grid[i][j] > 0) text(grid[i][j], (i+0.5)*scl, (j+0.5)*scl);
else if(grid[i][j]==-1) drawMine(i,j);
} else {
if (mouseX>i*scl&&mouseY>j*scl&&mouseX<(i+1)*scl&&mouseY<(j+1)*scl) {
fill(200);
} else fill(0);
square(i*scl, j*scl, scl);
if (flagged[i][j]) {
fill(0, 0, 255, 50);
square(i*scl, j*scl, scl);
}
}
if(RESULT==-1 && grid[i][j]==-1) drawMine(i,j);
}
if(RESULT!=0) {
textSize(100+sin(frameCount*0.05)*scl*0.25);
if(RESULT==1) {
//sin -1 1
//+1= 0 2
// *0.5 = 0 1
fill(20,255,20,map( sin(frameCount*0.05), -1,1, 100,255));
text("YOU WIN!!",width*0.5,height*0.5);
} else if(RESULT==-1) {
fill(255,20,20,map( sin(frameCount*0.05), -1,1, 100,255));
text("YOU LOSE!!",width*0.5,height*0.5);
}
textSize(scl*0.6);
}
}
void drawMine(int x, int y) {
fill(255,0,0,150);
circle((x+0.5)*scl,(y+0.5)*scl,scl*0.5);
}
void mousePressed() {
int mx = mouseX/scl, my = mouseY/scl;
if (mouseButton==LEFT) {
if (flagged[mx][my]==false) checkSlot(mx, my);
} else if (mouseButton==RIGHT && RESULT==0) flagged[mx][my] = !flagged[mx][my];
}
void keyPressed() {
if(key==' ') println(checkWin());
}
void checkSlot(int x, int y) {
if (grid[x][y]==-1) {
println("GAME OVER");
RESULT=-1;
} else if (RESULT==0) {
show[x][y]=true;
while (spreadVisible(x, y)>0);
if (checkWin()) {
RESULT=1;
println("YOU WIN!");
}
}
}
int spreadVisible(int x, int y) {
int num = 0;
for (int i = 0; i < a; i++) for (int j = 0; j < a; j++) {
if (grid[i][j]==0||i==x&&j==y) {
for (int k = -1; k < 2; k++) for (int l = -1; l < 2; l++) if (inBounds(i, j, k, l, a)) {
if (grid[i+k][j+l]!=-1) show[i+k][j+l]=true;
}
}
}
return num;
}
int[][] newGrid (int na, int nm) {
int ngrid[][] = new int[na][na];
if (nm>=na*na) nm = na*na-1; //to prevent infinite loops, the higher the mine:area ratio the longer it takes
for (int i = 0, rx = (int)random(na), ry = (int)random(na); i < nm; i++, rx = (int)random(na), ry =(int)random(na)) {
while (!canPlace(ngrid, rx, ry, 0)) {
rx = (int)random(na);
ry = (int)random(na);
}
ngrid[rx][ry]=-1;
}
for (int i = 0; i < na; i++) for (int j = 0; j < na; j++) if (ngrid[i][j]!=-1) {
int num = 0;
for (int k = -1; k < 2; k++) for (int l = -1; l < 2; l++) if (!(k==0&&l==0) && inBounds(i, j, k, l, a)) {
if (ngrid[i+k][j+l]==-1) num ++;
}
ngrid[i][j] = num;
}
a = na;
m = nm;
return ngrid;
}
boolean inBounds(int x, int y, int px, int py, int w) {
return(x+px<w&&y+py<w&&x+px>=0&&y+py>=0);
}
boolean canPlace(int mgrid[][], int x, int y, int desired) {
return(mgrid[x][y]==desired);
}
boolean checkWin() {
boolean won = true; //first set it to true
for (int i = 0; i < a; i++) for (int j = 0; j < a; j++) {
if (!(show[i][j]==true&&grid[i][j]>=0 || show[i][j]==false&&grid[i][j]==-1)) won = false;
}
return won;
}
Notable features:
- flexible grid size and amount of mines
- flag slots to mark potential mines (cannot uncover unless you unflag)
A game I completed with 20x20 grid & 40 mines.