This project is powered by p5.js and originates from this Minesweeper tutorial.
class Cell {
constructor(x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.rect = {
'topLeft': createVector((this.x * this.size), (this.y * this.size)),
'bottomRight': createVector(((this.x + 1) * this.size), ((this.y + 1) * this.size))
};
this.neighbors = [];
this.neighbor_bees = 0;
this.revealed = false;
this.bee = false;
}
countNeighbors() {
if(this.bee) {
return;
}
let lower_x = (this.x - 1);
let upper_x = (this.x + 1);
let lower_y = (this.y - 1);
let upper_y = (this.y + 1);
// row above
for(let yy = (this.y - 1); yy <= (this.y + 1); yy++) {
if((yy < 0) || (yy >= grid.length)) {
continue;
}
for(let xx = (this.x - 1); xx <= (this.x + 1); xx++) {
if((xx < 0) || (xx >= grid[ yy ].length)) {
continue;
}
this.neighbors.push(createVector(xx, yy));
if(grid[ yy ][ xx ].bee) {
this.neighbor_bees++;
}
}
}
}
contains(px, py) {
return ((this.rect.topLeft.x < px) && (this.rect.topLeft.y < py) && (this.rect.bottomRight.x >= px) && (this.rect.bottomRight.y >= py));
}
reveal() {
if(this.revealed) {
return;
}
this.revealed = true;
if(!this.neighbor_bees) {
for(let i = 0; i < this.neighbors.length; i++) {
let vec = this.neighbors[ i ];
grid[ vec.y ][ vec.x ].reveal();
}
}
}
draw() {
push();
translate(this.rect.topLeft.x, this.rect.topLeft.y);
if(this.revealed) {
if(this.bee) {
fill(255);
} else {
fill(200);
}
} else {
fill(255);
rect(0, 0, this.size, this.size);
}
stroke(0);
rect(0, 0, this.size, this.size);
if(this.revealed) {
let rect_half = (this.size / 2);
if(this.bee) {
// draw bee
push();
translate(rect_half, rect_half);
ellipseMode(CENTER);
strokeWeight(3);
stroke(0);
fill("#fff01f");
ellipse(0, 0, rect_half);
pop();
} else if(this.neighbor_bees > 0) {
// draw neighbor tally
push();
//textAlign(LEFT);
let text_height = (this.size * 0.66);
textSize(text_height);//textSize(text_height);
let text_width = textWidth(this.neighbor_bees);
fill(0);
text(this.neighbor_bees, (rect_half - (text_width / 2)), (rect_half + (text_height * 0.4)));
pop();
}
}
pop();
}
setBee() {
if(this.bee) {
return false;
}
this.bee = true;
return true;
}
}
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<title>p5.js - Minesweeper</title>
<script src="lib/p5.min.js"></script>
<!-- <script src="lib/p5.dom.min.js"></script> -->
<!-- <script src="lib/p5.sound.min.js"></script> -->
<script src="cell.js"></script>
<script src="sketch.js"></script>
</head>
<body>
</body>
</html>
let grid = [];
function setup() {
let num_cols = 10;
let num_rows = 12;
let cell_size = 32;
let game_width = ((num_cols * cell_size) + 1);
let game_height = ((num_rows * cell_size) + 1);
createCanvas(game_width, game_height);
for(let y = 0; y < num_rows; y++) {
grid[ y ] = [];
for(let x = 0; x < num_cols; x++) {
grid[ y ][ x ] = new Cell(x, y, cell_size);
}
}
// add bees
let num_bees = floor(random(ceil((num_cols / 2)), num_cols));
let num_bees_added = 0;
while(num_bees_added < num_bees) {
let randX = floor(random(0, (num_cols - 1)));
let randY = floor(random(0, (num_rows - 1)));
if(grid[ randY ][ randX ].setBee()) {
num_bees_added += 1;
}
}
// count neighbors
for(let y = 0; y < num_rows; y++) {
for(let x = 0; x < num_cols; x++) {
grid[ y ][ x ].countNeighbors();
}
}
}
function gameLost() {
for(let cell_row in grid) {
for(let cell_col in grid[ cell_row ]) {
let cell = grid[ cell_row ][ cell_col ];
cell.revealed = true;
}
}
alert("Sorry, you lost!");
}
function gameWon() {
for(let cell_row in grid) {
for(let cell_col in grid[ cell_row ]) {
let cell = grid[ cell_row ][ cell_col ];
cell.revealed = true;
}
}
alert("You won!");
}
function checkGameWon() {
let num_remaining = 0;
for(let cell_row in grid) {
for(let cell_col in grid[ cell_row ]) {
let cell = grid[ cell_row ][ cell_col ];
if(!cell.bee && !cell.revealed) {
num_remaining++;
}
}
}
if(num_remaining == 0) {
gameWon();
}
}
function draw() {
background(255);
for(let cell_row in grid) {
for(let cell_col in grid[ cell_row ]) {
let cell = grid[ cell_row ][ cell_col ];
cell.draw();
}
}
}
function mousePressed() {
for(let cell_row in grid) {
for(let cell_col in grid[ cell_row ]) {
let cell = grid[ cell_row ][ cell_col ];
if(cell.contains(mouseX, mouseY)) {
cell.reveal();
if(cell.bee) {
gameLost();
} else {
checkGameWon();
}
}
}
}
}