-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMinesweeper.html
More file actions
314 lines (306 loc) · 19.4 KB
/
Minesweeper.html
File metadata and controls
314 lines (306 loc) · 19.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="theme-color" content="#0c1016">
<title>Minesweeper — Free Online Classic Mine Puzzle | Board Gaming Hub</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Play Minesweeper free online. Classic Beginner, Intermediate, and Expert grids. Right-click to flag, left-click to reveal. No signup, no downloads, mobile-friendly.">
<meta name="keywords" content="minesweeper, play minesweeper, free minesweeper online, classic minesweeper, mine puzzle">
<link rel="canonical" href="https://boardgaminghub.com/Minesweeper.html">
<meta property="og:type" content="website">
<meta property="og:url" content="https://boardgaminghub.com/Minesweeper.html">
<meta property="og:title" content="Minesweeper — Free Online Classic">
<meta property="og:description" content="The classic logic puzzle: clear the field without detonating any mines. Free, in-browser, single-file HTML.">
<meta name="twitter:card" content="summary">
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "VideoGame", "name": "Minesweeper",
"description": "Reveal cells without detonating any mines. Number clues show how many mines surround each cell.",
"url": "https://boardgaminghub.com/Minesweeper.html", "genre": "Puzzle",
"applicationCategory": "Game", "operatingSystem": "Any",
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" } }
</script>
<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Board Gaming Hub","item":"https://boardgaminghub.com/"},{"@type":"ListItem","position":2,"name":"Puzzles & Classics","item":"https://boardgaminghub.com/#puzzles"},{"@type":"ListItem","position":3,"name":"Minesweeper","item":"https://boardgaminghub.com/Minesweeper.html"}]}</script>
<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"What do the numbers in Minesweeper mean?","acceptedAnswer":{"@type":"Answer","text":"A number on a revealed cell shows how many mines lie among the 8 cells immediately surrounding it. A blank revealed cell has 0 adjacent mines (and the game auto-cascades, opening neighbors). A 1 means exactly one of the 8 neighbors is a mine; a 2 means exactly two; and so on up to 8 (rare)."}},{"@type":"Question","name":"What's the difference between Beginner, Intermediate, and Expert?","acceptedAnswer":{"@type":"Answer","text":"Beginner is 9×9 with 10 mines (~12% density). Intermediate is 16×16 with 40 mines (~16%). Expert is 30×16 with 99 mines (~21%). Higher density makes deductions harder and more likely to require a 50/50 guess."}},{"@type":"Question","name":"What is a chord click?","acceptedAnswer":{"@type":"Answer","text":"A chord (left+right click together, or middle-click) on a revealed numbered cell automatically opens all unflagged neighbors — but only if the number of flagged neighbors equals the number on the cell. Speeds up clearing significantly once you've flagged the obvious mines around a number."}},{"@type":"Question","name":"Can every Minesweeper game be solved without guessing?","acceptedAnswer":{"@type":"Answer","text":"No. Standard Minesweeper allows positions where the only safe cell can't be deduced from the visible numbers — a forced 50/50 guess. Some implementations (\"no-guess\" Minesweeper) use only solvable boards; the classic version does not. Approximately 20–30% of Expert games contain at least one unforced guess."}},{"@type":"Question","name":"What's the best Minesweeper strategy?","acceptedAnswer":{"@type":"Answer","text":"Open corners and edges first — they have fewer neighbors so numbers there are higher-information. Flag mines as you identify them so chord-click works. When stuck, look at numbers along the borders of unrevealed regions for forced deductions. Save guesses for when no logic remains, and prefer cells far from numbered constraints (lower local mine density)."}}]}</script>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2835365593874464" crossorigin="anonymous"></script>
<style>
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0;
background:
radial-gradient(ellipse at top, #1a1410 0%, #0a0604 70%) fixed;
color: #e8d8b8; font-family: Georgia, "Times New Roman", serif; }
#wrap { max-width: 760px; margin: 0 auto; padding: 28px 12px 60px; text-align: center; }
h1 { font-size: 2.2em; letter-spacing: 10px; margin: 0 0 6px;
background: linear-gradient(180deg, #ffe8a8 0%, #d4a050 50%, #905028 100%);
-webkit-background-clip: text; background-clip: text; color: transparent;
text-shadow: 0 2px 6px rgba(0,0,0,0.6); }
.tag { color: #a09078; letter-spacing: 4px; font-size: 0.82em; margin-bottom: 18px; font-style: italic; }
.controls { margin: 14px 0; display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
button { background: linear-gradient(180deg, #3a2818, #1f1408); color: #f0d89c; border: 1px solid #5a4028; border-radius: 4px; padding: 8px 14px; font-family: inherit; letter-spacing: 2px; font-size: 0.82em; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255,220,150,0.2), 0 2px 4px rgba(0,0,0,0.4); }
button:hover { background: linear-gradient(180deg, #4a3624, #2a1c10); border-color: #7a5838; }
button.active { background: linear-gradient(180deg, #f0d89c, #b08838); color: #1a1008; border-color: #b07810; }
.stats { display: flex; gap: 12px; justify-content: center; margin: 12px 0; }
.stat { background: linear-gradient(180deg, #2a1c10, #1a1008); border: 1px solid #4a3820; border-radius: 6px; padding: 6px 14px; min-width: 80px; box-shadow: inset 0 1px 0 rgba(255,220,150,0.15), 0 2px 4px rgba(0,0,0,0.4); }
.stat .lab { color: #8a7858; font-size: 0.7em; letter-spacing: 3px; }
.stat .val { color: #ffd896; font-size: 1.2em; font-weight: bold; text-shadow: 0 1px 0 #000;
font-family: "Courier New", monospace; }
#boardWrap { overflow: auto; padding: 12px; }
/* Brass-plate board */
#board { display: inline-grid; gap: 2px; padding: 8px;
background:
radial-gradient(ellipse at 25% 25%, rgba(255,220,150,0.18), transparent 60%),
linear-gradient(135deg, #5a3a18 0%, #3a2410 50%, #5a3a18 100%);
border: 2px solid;
border-image: linear-gradient(135deg, #f0d89c, #905028, #f0d89c) 1;
border-radius: 4px; user-select: none;
box-shadow: 0 0 0 1px #2a1808, 0 4px 14px rgba(0,0,0,0.7); }
/* Unrevealed: brass studs */
.cell { width: 26px; height: 26px;
background:
radial-gradient(circle at 30% 30%, rgba(255,220,150,0.5), transparent 60%),
linear-gradient(135deg, #b08038 0%, #6a4818 100%);
border: 1px solid #2a1808;
display: flex; align-items: center; justify-content: center;
font-weight: bold; cursor: pointer; font-size: 0.9em; color: #fff;
box-shadow: inset 0 1px 0 rgba(255,220,150,0.45), inset 0 -1px 0 rgba(0,0,0,0.4); }
/* Revealed: dark recessed copper */
.cell.r {
background: linear-gradient(180deg, #1a1208, #2a1c10);
border-color: #0a0604; cursor: default;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.6); color: #e8d8b8; }
.cell.r.m {
background: radial-gradient(circle at 35% 30%, #ff80a0, #c02038 50%, #600818);
color: #fff; box-shadow: inset 0 1px 0 rgba(255,180,180,0.5), 0 0 12px rgba(220,40,60,0.6); }
.cell.f {
background: radial-gradient(circle at 30% 30%, #ffd060, #d4801c 60%, #8a4810);
color: #fff; border-color: #4a2008;
box-shadow: inset 0 1px 0 rgba(255,220,120,0.5), 0 0 8px rgba(255,180,60,0.5); }
.n1 { color: #80b8ff; } .n2 { color: #80e0a0; } .n3 { color: #ff8090; }
.n4 { color: #d090ff; } .n5 { color: #ffa860; } .n6 { color: #60d8d8; }
.n7 { color: #e8e0c0; } .n8 { color: #a89878; }
#msg { margin-top: 14px; min-height: 1.2em; color: #f0d89c; letter-spacing: 3px; font-size: 0.95em; }
nav { margin-top: 22px; font-size: 0.82em; letter-spacing: 2px; }
nav a { color: #a09078; text-decoration: none; margin: 0 10px; }
nav a:hover { color: #f0d89c; }
.info { color: #8a7858; font-size: 0.82em; line-height: 1.6; margin-top: 30px; text-align: left; padding: 0 6px; }
.info h2 { color: #d4a050; font-size: 0.95em; letter-spacing: 4px; text-transform: uppercase; margin: 18px 0 8px; }
.info strong { color: #f0d89c; }
</style>
</head>
<body>
<div id="wrap">
<h1>MINESWEEPER</h1>
<div class="tag">FIND THE MINES</div>
<div class="controls">
<button data-d="b" class="active">BEGINNER 9×9</button>
<button data-d="i">INTERMEDIATE 16×16</button>
<button data-d="e">EXPERT 30×16</button>
<button id="newgame">NEW</button>
</div>
<div class="stats">
<div class="stat"><div class="lab">MINES</div><div class="val" id="mines">10</div></div>
<div class="stat"><div class="lab">TIME</div><div class="val" id="time">0</div></div>
<div class="stat"><div class="lab">BEST</div><div class="val" id="best">—</div></div>
</div>
<div id="boardWrap"><div id="board"></div></div>
<div id="msg"></div>
<nav><a href="index.html">All games</a> · <a href="Sudoku.html">Sudoku</a> · <a href="2048.html">2048</a></nav>
<div class="info">
<h2>How to play Minesweeper</h2>
<p><strong>Left-click</strong> a cell to reveal it. <strong>Right-click</strong> (or long-press on touch) to flag a suspected mine. Numbers show how many mines touch that cell, including diagonals. Reveal every safe cell to win — touch a mine and the field explodes.</p>
<h2>Tips</h2>
<p>The first click is always safe and opens an empty area. When the count of flags around a revealed number equals that number, you can <strong>chord-click</strong> (left+right or middle-click) to auto-reveal its remaining neighbors. Look for forced moves: a "1" with only one unrevealed neighbor means that neighbor is the mine.</p>
</div>
</div>
<script>
(() => {
const cfg = { b: {w:9,h:9,m:10}, i: {w:16,h:16,m:40}, e: {w:30,h:16,m:99} };
let diff = 'b', W=9, H=9, M=10, grid, revealed, flagged, started, dead, won, t0, timer, time;
const $ = id => document.getElementById(id);
function setDiff(d) {
diff = d; W = cfg[d].w; H = cfg[d].h; M = cfg[d].m;
document.querySelectorAll('[data-d]').forEach(b => b.classList.toggle('active', b.dataset.d === d));
newGame();
}
function newGame() {
grid = Array.from({length: H}, () => Array(W).fill(0));
revealed = Array.from({length: H}, () => Array(W).fill(false));
flagged = Array.from({length: H}, () => Array(W).fill(false));
started = false; dead = false; won = false; time = 0;
if (timer) clearInterval(timer);
$('mines').textContent = M; $('time').textContent = 0; $('msg').textContent = '';
$('best').textContent = (localStorage.getItem('msw_best_'+diff)) || '—';
render();
}
function placeMines(safeR, safeC) {
let placed = 0;
while (placed < M) {
const r = Math.floor(Math.random()*H), c = Math.floor(Math.random()*W);
if (grid[r][c] === -1) continue;
if (Math.abs(r-safeR) <= 1 && Math.abs(c-safeC) <= 1) continue;
grid[r][c] = -1; placed++;
}
for (let r=0;r<H;r++) for (let c=0;c<W;c++) {
if (grid[r][c] === -1) continue;
let n = 0;
for (let dr=-1;dr<=1;dr++) for (let dc=-1;dc<=1;dc++) {
const nr=r+dr,nc=c+dc; if (nr<0||nr>=H||nc<0||nc>=W) continue;
if (grid[nr][nc] === -1) n++;
}
grid[r][c] = n;
}
}
function reveal(r, c) {
if (r<0||r>=H||c<0||c>=W||revealed[r][c]||flagged[r][c]) return;
revealed[r][c] = true;
if (grid[r][c] === -1) { dead = true; return; }
if (grid[r][c] === 0) {
for (let dr=-1;dr<=1;dr++) for (let dc=-1;dc<=1;dc++) reveal(r+dr, c+dc);
}
}
function chord(r, c) {
if (!revealed[r][c] || grid[r][c] <= 0) return;
let f = 0;
for (let dr=-1;dr<=1;dr++) for (let dc=-1;dc<=1;dc++) {
const nr=r+dr,nc=c+dc; if (nr<0||nr>=H||nc<0||nc>=W) continue;
if (flagged[nr][nc]) f++;
}
if (f !== grid[r][c]) return;
for (let dr=-1;dr<=1;dr++) for (let dc=-1;dc<=1;dc++) reveal(r+dr, c+dc);
}
function checkWin() {
let safe = 0;
for (let r=0;r<H;r++) for (let c=0;c<W;c++) if (grid[r][c] !== -1 && revealed[r][c]) safe++;
if (safe === W*H - M) { won = true; clearInterval(timer); $('msg').textContent = 'CLEARED IN ' + time + 's';
const k = 'msw_best_'+diff; const cur = +(localStorage.getItem(k) || Infinity);
if (time < cur) { localStorage.setItem(k, time); $('best').textContent = time; }
}
}
function render() {
const b = $('board');
b.style.gridTemplateColumns = `repeat(${W}, 26px)`;
b.innerHTML = '';
let flags = 0;
for (let r=0;r<H;r++) for (let c=0;c<W;c++) {
const d = document.createElement('div');
d.className = 'cell';
if (flagged[r][c]) { d.classList.add('f'); d.textContent = '⚑'; flags++; }
else if (revealed[r][c]) {
d.classList.add('r');
if (grid[r][c] === -1) { d.classList.add('m'); d.textContent = '✱'; }
else if (grid[r][c] > 0) { d.textContent = grid[r][c]; d.classList.add('n'+grid[r][c]); }
}
d.addEventListener('mousedown', e => handle(e, r, c));
d.addEventListener('contextmenu', e => { e.preventDefault(); flag(r, c); });
let lpt, tsx, tsy;
d.addEventListener('touchstart', e => {
const tt = e.touches[0]; tsx = tt.clientX; tsy = tt.clientY;
lpt = setTimeout(() => { flag(r,c); lpt = null; }, 350);
}, {passive:true});
d.addEventListener('touchmove', e => {
if (!lpt) return;
const tt = e.touches[0];
if (Math.abs(tt.clientX - tsx) > 10 || Math.abs(tt.clientY - tsy) > 10) {
clearTimeout(lpt); lpt = null;
}
}, {passive:true});
d.addEventListener('touchend', e => {
if (lpt) { clearTimeout(lpt); lpt = null; reveal0(r,c); e.preventDefault(); }
});
b.appendChild(d);
}
$('mines').textContent = M - flags;
}
function handle(e, r, c) {
if (dead || won) return;
if (e.button === 2) return;
if (e.button === 1 || e.buttons === 3) { chord(r, c); after(); return; }
reveal0(r, c);
}
function reveal0(r, c) {
if (dead || won || flagged[r][c]) return;
if (!started) { started = true; placeMines(r, c); t0 = Date.now();
timer = setInterval(() => { time = Math.floor((Date.now()-t0)/1000); $('time').textContent = time; }, 250); }
reveal(r, c); after();
}
function flag(r, c) {
if (dead || won || revealed[r][c]) return;
flagged[r][c] = !flagged[r][c]; render();
}
function after() {
if (dead) { for (let r=0;r<H;r++) for (let c=0;c<W;c++) if (grid[r][c]===-1) revealed[r][c]=true;
clearInterval(timer); $('msg').textContent = 'BOOM — NEW GAME?'; }
else checkWin();
render();
}
document.querySelectorAll('[data-d]').forEach(b => b.onclick = () => setDiff(b.dataset.d));
$('newgame').onclick = newGame;
document.addEventListener('contextmenu', e => { if (e.target.closest('#board')) e.preventDefault(); });
newGame();
})();
</script>
<script src="/analytics.js"></script>
<section class="seo-content">
<h2>About Minesweeper</h2>
<p>Minesweeper is a single-player logic puzzle: uncover every safe cell on a grid without detonating any of the hidden mines. Numbers on revealed cells tell you exactly how many mines lie among the 8 surrounding cells. Originated as a 1980s mainframe game, popularized worldwide when Microsoft bundled it with Windows 3.1 in 1992.</p>
<h3>How to play</h3>
<p>Left-click to reveal a cell; right-click to flag a suspected mine. The first click is always safe — if it would otherwise hit a mine, the mine is moved. Revealing a 0-cell auto-cascades, opening all neighbors recursively (this is what produces the satisfying flood-open). Numbers 1–8 indicate exactly how many of the 8 neighboring cells contain mines.</p>
<h3>Number colors (classic Windows palette)</h3>
<table>
<thead><tr><th class="num">Number</th><th>Color</th><th>Adjacent mines</th></tr></thead>
<tbody>
<tr><td class="num">1</td><td>Blue</td><td>1</td></tr>
<tr><td class="num">2</td><td>Green</td><td>2</td></tr>
<tr><td class="num">3</td><td>Red</td><td>3</td></tr>
<tr><td class="num">4</td><td>Dark blue</td><td>4</td></tr>
<tr><td class="num">5</td><td>Maroon</td><td>5</td></tr>
<tr><td class="num">6</td><td>Cyan</td><td>6</td></tr>
<tr><td class="num">7</td><td>Black</td><td>7</td></tr>
<tr><td class="num">8</td><td>Gray</td><td>8 (rare)</td></tr>
</tbody>
</table>
<h3>Standard difficulty grids</h3>
<table>
<thead><tr><th>Difficulty</th><th>Grid</th><th class="num">Mines</th><th class="num">Density</th></tr></thead>
<tbody>
<tr><td>Beginner</td><td>9×9</td><td class="num">10</td><td class="num">12.3%</td></tr>
<tr><td>Intermediate</td><td>16×16</td><td class="num">40</td><td class="num">15.6%</td></tr>
<tr><td>Expert</td><td>30×16</td><td class="num">99</td><td class="num">20.6%</td></tr>
</tbody>
</table>
<h3>Frequently asked questions</h3>
<details><summary>What do the numbers mean?</summary><p>The number on a revealed cell is exactly how many of its 8 surrounding cells contain a mine. A 1 means exactly one neighbor is a mine; a 0 (blank) means none.</p></details>
<details><summary>Beginner / Intermediate / Expert sizes?</summary><p>Beginner 9×9 / 10 mines, Intermediate 16×16 / 40 mines, Expert 30×16 / 99 mines.</p></details>
<details><summary>What's a chord click?</summary><p>Left+right click together (or middle-click) on a numbered cell auto-opens all unflagged neighbors — but only if the flag count around it equals the number on the cell. Big speedup once you've flagged the obvious mines.</p></details>
<details><summary>Can every Minesweeper be solved without guessing?</summary><p>No. The classic version allows positions where the only safe cell can't be deduced from the visible numbers — a forced 50/50 guess. Some variants ("no-guess" Minesweeper) only generate solvable boards.</p></details>
<details><summary>Best strategy?</summary><p>Open corners and edges first (fewer neighbors → higher-information numbers). Flag mines as you identify them so chord-click works. Save guesses for when no logic remains, and prefer cells far from numbered constraints.</p></details>
<h3>Related games</h3>
<ul>
<li><a href="Sudoku.html">Sudoku</a> — pure-logic puzzle, also no luck if well-formed.</li>
<li><a href="2048.html">2048</a> — solo number puzzle.</li>
<li><a href="Solitaire.html">Solitaire</a> — solo card game.</li>
<li><a href="Chess.html">Chess</a> — two-player strategic logic.</li>
</ul>
</section>
<section style="max-width:900px;margin:60px auto 40px;padding:0 20px;font-family:Georgia,'Times New Roman',serif;color:#d8d0c0;">
<h2 style="color:#f0d89c;letter-spacing:4px;font-size:1.0em;text-transform:uppercase;border-bottom:1px solid #2a3540;padding-bottom:8px;margin-bottom:16px;">Discussion</h2>
<p style="color:#8098a8;font-size:0.9em;margin-bottom:18px;line-height:1.5;">Sign in with GitHub to share strategies, ask questions, or report a bug.</p>
<div class="giscus"></div>
</section>
<script src="https://giscus.app/client.js"
data-repo="mf4633/board-gaming"
data-repo-id="R_kgDOKyyThA"
data-category="Announcements"
data-category-id="DIC_kwDOKyyThM4C75Cz"
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="bottom"
data-theme="dark"
data-lang="en"
crossorigin="anonymous"
async></script>
<script src="/nav.js" defer></script>
</body>
</html>