PageSourceSearch

https://oussbenk.github.io/minesweeper/examples/minesweeper.js

js oussbenk.github.io collected 2026-10-03 09:43:51 UTC 6,783 bytes, 197 lines download raw bytes

1/**
2***	Author : Oussama Ben Khiroun
3***	Contact : https://oussamabenkhiroun.com/
4*** Version 1.0
5**/
6
7// create board
8const numberOfBombs = 10;
9const matrixSize = 9;
10const boardSize="9x9";
11const theme="url('images/minesweeper.png') "	// theme could be changed with another sprite (cells dimension=16px)
12
13var b = jsboard.board({attach:"game", size:boardSize});
14b.style({borderSpacing: "0px", border:"1px solid #CCC"});
15b.cell("each").style({textIndent:"-9999px", background:theme+"-80px -16px no-repeat", width:"16px", height:"16px", margin:"0", padding:"0"});
16
17// setup pieces
18var zero = jsboard.piece({text:"ZR", textIndent:"-9999px", background:theme+"0 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
19var one = jsboard.piece({text:"ON", textIndent:"-9999px", background:theme+"-16px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
20var two = jsboard.piece({text:"TW", textIndent:"-9999px", background:theme+"-32px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
21var three = jsboard.piece({text:"TH", textIndent:"-9999px", background:theme+"-48px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
22var four = jsboard.piece({text:"FO", textIndent:"-9999px", background:theme+"-64px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
23var five = jsboard.piece({text:"FI", textIndent:"-9999px", background:theme+"-80px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
24var six = jsboard.piece({text:"SX", textIndent:"-9999px", background:theme+"-96px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
25var seven = jsboard.piece({text:"SV", textIndent:"-9999px", background:theme+"-112px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
26var eight = jsboard.piece({text:"EI", textIndent:"-9999px", background:theme+"-128px 0 no-repeat", width:"16px", height:"16px", margin:"0 auto" });
27
28var flag = jsboard.piece({text:"FL", textIndent:"-9999px", background:theme+"-64px -16px no-repeat", width:"16px", height:"16px", margin:"0 auto" });
29
30// setup bombs
31var bomb = jsboard.piece({text:"BM", textIndent:"-9999px", background:theme+"0 -16px no-repeat", width:"16px", height:"16px", margin:"0 auto" });
32var bombRed = jsboard.piece({text:"BR", textIndent:"-9999px", background:theme+"-32px -16px no-repeat", width:"16px", height:"16px", margin:"0 auto" });
33
34// array regrouping numbered pieces
35var arrayNumbers = [zero, one, two, three, four, five, six, seven, eight];
36
37var gameIsOver = false;
38
39// handle bombs in 2d array
40var bombMatrix;
41
42// initializing game array with random placed bombs
43initGame();
44
45// game click handler (left mouse click)
46b.cell("each").on("click", function() {
47	if(!gameIsOver){
48		if (b.cell(this).get()===null) {
49			// getting current cell indices
50			var loc = b.cell(this).where();
51			var i = loc[0];
52			var j = loc[1];
53			
54			if(bombMatrix[i][j]==1){
55				// game over
56				finishGame(i,j);
57				// show "Game Over" in HTML
58				document.getElementById("game-result").innerText = "Game Over";
59				document.getElementById("game-result").className = "game-over";
60			}else{
61			
62				var nearBombs = numberOfNearBombs(i,j); 
63				
64				if(nearBombs==0){
65					// when zero bombs are placed near the current cell
66					exploreRecursively(i,j);
67				}else{
68					b.cell(this).place(arrayNumbers[nearBombs].clone());
69				}
70				
71				// test if all cells not containing bombs are explored
72				if(isAllCellExplored()){
73					finishGame(-1,-1);
74					// show winning message
75					document.getElementById("game-result").innerText = "You won!";
76					document.getElementById("game-result").className = "game-win";				
77				}
78			}
79		}
80	}
81});
82
83// placing flags (right mouse click)
84b.cell("each").on("contextmenu", function(ev) {
85	// avoid showing context menu
86    ev.preventDefault();
87	// for updating remaining mines
88	var x = eval(document.getElementById("remaining-mines").innerText);
89	if (b.cell(this).get()===null) {
90		b.cell(this).place(flag.clone());	// place a flag
91		document.getElementById("remaining-mines").innerText = x - 1;
92	}else if(b.cell(this).get()=="FL"){
93		b.cell(this).rid();
94		document.getElementById("remaining-mines").innerText = x + 1;
95	}
96    return false;
97}, false);
98
99function initGame(){
100	var i, j;
101	bombMatrix = [];
102	for (i=0; i<matrixSize; i++){
103		bombMatrix[i] = [];
104		for (j=0; j<matrixSize; j++){
105			bombMatrix[i][j] = 0;
106		}
107	}
108	
109	// place bombs randomly
110	var placedBombs = 0;
111	while(placedBombs<numberOfBombs){
112		i = Math.floor(Math.random() * matrixSize);
113		j = Math.floor(Math.random() * matrixSize);
114		if(bombMatrix[i][j]==0){
115			bombMatrix[i][j]=1;
116			placedBombs++;
117		}
118	}
119	// set number of remaining mines in HTML
120	document.getElementById("remaining-mines").innerText = numberOfBombs;
121}
122
123function numberOfNearBombs(i,j){
124	var nearBombs = 0;
125	if(i>0){
126		nearBombs = nearBombs + bombMatrix[i-1][j];
127	}
128	if(j>0){
129		nearBombs = nearBombs + bombMatrix[i][j-1];
130	}
131	if(i<matrixSize-1){
132		nearBombs = nearBombs + bombMatrix[i+1][j];
133	}
134	if(j<matrixSize-1){
135		nearBombs = nearBombs + bombMatrix[i][j+1];
136	}
137	if((i-1>=0)&&(j-1>=0)){
138		nearBombs = nearBombs + bombMatrix[i-1][j-1];
139	}
140	if((i+1<matrixSize)&&(j+1<matrixSize)){
141		nearBombs = nearBombs + bombMatrix[i+1][j+1];
142	}
143	if((i-1>=0)&&(j+1<matrixSize)){
144		nearBombs = nearBombs + bombMatrix[i-1][j+1];
145	}	
146	if((i+1<matrixSize)&&(j-1>=0)){
147		nearBombs = nearBombs + bombMatrix[i+1][j-1];
148	}
149	return nearBombs; 
150}
151
152// this function is called when zero cell is clicked
153function exploreRecursively(i,j){
154	if((i>=0)&&(i<matrixSize)&&(j>=0)&&(j<matrixSize)&&(b.cell([i,j]).get()===null)){
155		var nearBombs = numberOfNearBombs(i,j);
156		b.cell([i,j]).place(arrayNumbers[nearBombs].clone());
157		if((nearBombs==0)){		
158			exploreRecursively(i+1,j) + exploreRecursively(i-1,j) + exploreRecursively(i,j+1) + exploreRecursively(i,j-1)
159			+ exploreRecursively(i-1,j-1) + exploreRecursively(i-1,j+1) + exploreRecursively(i+1,j-1) + exploreRecursively(i+1,j+1);
160		}			
161	}
162}
163
164/* show all hidden cells:
165	- when a bombs is clicked, (k,l) represent the cell indices (a red bomb is shown)
166	- to resolve the grid, this function can be called by passing (-1,-1) arguments
167*/
168function finishGame(k,l){
169	var aux; 
170	for (var i=0; i<matrixSize; i++){
171		for (var j=0; j<matrixSize; j++){
172			if(bombMatrix[i][j]==1){
173				if((i==k)&&(j==l)){
174					b.cell([i,j]).place(bombRed.clone());
175				}else{
176					b.cell([i,j]).place(bomb.clone());
177				}				
178			}else{
179				aux = numberOfNearBombs(i,j);
180				b.cell([i,j]).place(arrayNumbers[aux].clone());
181			}
182		}	
183	}
184	gameIsOver = true;
185}
186
187// verify if all cells are exlored (win scenario)
188function isAllCellExplored(){
189	for (var i=0; i<matrixSize; i++){
190		for (var j=0; j<matrixSize; j++){
191			if((bombMatrix[i][j]==0)&&(b.cell([i,j]).get()===null)){
192				return false;
193			}
194		}	
195	}
196	return true;
197}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.