Minesweeper game: Difference between revisions

m
 
(38 intermediate revisions by 10 users not shown)
Line 25:
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
 
Line 392:
Put (The_Grid);
end;
end Minesweeper;</langsyntaxhighlight>
 
=={{header|AutoHotkey}}==
Gui clone w/o graphic files but with cheats.
<langsyntaxhighlight lang="autohotkey">; Minesweeper.ahk - v1.0.6
; (c) Dec 28, 2008 by derRaphael
; Licensed under the Terms of EUPL 1.0
Line 951:
- Add middle-button shortcut
- Re-license as GPL 1.3
*/</langsyntaxhighlight>
 
=={{header|BASIC256BASIC}}==
=== Mouse version {{header|BASIC256}}===
==== Mouse version ====
[[File:Minesweeper game BASIC-256 won.png|thumb|right|Game won]]
[[File:Minesweeper game BASIC-256 lost.png|thumb|right|Game lost (green mines are those that were flagged before explosion)]]
<langsyntaxhighlight lang="basic256">N = 6 : M = 5 : H = 25 : P = 0.2
 
fastgraphics
Line 1,066 ⟶ 1,067:
end if
if f[ai,aj]&2 then over = -1
return</langsyntaxhighlight>
 
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
 
static $( randstate = 0 $)
 
manifest $(
nummask = #XF
flagmask = #X10
bombmask = #X20
revealed = #X40
MAXINT = (~0)>>1
MININT = ~MAXINT
$)
 
let min(x,y) = x<y -> x, y
and max(x,y) = x>y -> x, y
 
let rand() = valof
$( randstate := random(randstate)
resultis randstate >> 7
$)
 
let randto(x) = valof
$( let r, mask = ?, 1
while mask<x do mask := (mask << 1) | 1
r := rand() & mask repeatuntil r < x
resultis r
$)
 
// Place a bomb on the field (if not already a bomb)
let placebomb(field, xsize, ysize, x, y) =
(field!(y*xsize+x) & bombmask) ~= 0 -> false,
valof
$( for xa = max(x-1, 0) to min(x+1, xsize-1)
for ya = max(y-1, 0) to min(y+1, ysize-1)
$( let loc = ya*xsize+xa
let n = field!loc & nummask
field!loc := (field!loc & ~nummask) | (n + 1)
$)
field!(y*xsize+x) := field!(y*xsize+x) | bombmask
resultis true
$)
 
// Populate the field with N bombs
let populate(field, xsize, ysize, nbombs) be
$( for i=0 to xsize*ysize-1 do field!i := 0
while nbombs > 0
$( let x, y = randto(xsize), randto(ysize)
if placebomb(field, xsize, ysize, x, y) then
nbombs := nbombs - 1
$)
$)
 
// Reveal field (X,Y) - returns true if stepped on a bomb
let reveal(field, xsize, ysize, x, y) =
(field!(y*xsize+x) & bombmask) ~= 0 -> true,
valof
$( let loc = y*xsize+x
field!loc := field!loc | revealed
if (field!loc & nummask) = 0 then
for xa = max(x-1, 0) to min(x+1, xsize-1)
for ya = max(y-1, 0) to min(y+1, ysize-1)
if (field!(ya*xsize+xa) &
(bombmask | flagmask | revealed)) = 0 do
reveal(field, xsize, ysize, xa, ya)
resultis false
$)
// Toggle flag
let toggleflag(field, xsize, ysize, x, y) be
$( let loc = y*xsize+x
field!loc := field!loc neqv flagmask
$)
 
// Show the field. Returns true if won.
let showfield(field, xsize, ysize, kaboom) = valof
$( let bombs, flags, hidden, found = 0, 0, 0, 0
for i=0 to xsize*ysize-1
$( if (field!i & revealed) = 0 do hidden := hidden + 1
unless (field!i & bombmask) = 0 do bombs := bombs + 1
unless (field!i & flagmask) = 0 do flags := flags + 1
if (field!i & bombmask) ~= 0 & (field!i & flagmask) ~= 0
do found := found + 1
$)
writef("Bombs: %N - Flagged: %N - Hidden: %N*N", bombs, flags, hidden)
wrch('+')
for x=0 to xsize-1 do wrch('-')
writes("+*N")
for y=0 to ysize-1
$( wrch('|')
for x=0 to xsize-1
$( let loc = y*xsize+x
test kaboom & (field!loc & bombmask) ~= 0 do
wrch('**')
or test (field!loc & (flagmask | revealed)) = flagmask do
wrch('?')
or test (field!loc & revealed) = 0 do
wrch('.')
or test (field!loc & nummask) = 0 do
wrch(' ')
or
wrch('0' + (field!loc & nummask))
$)
writes("|*N")
$)
wrch('+')
for x=0 to xsize-1 do wrch('-')
writes("+*N")
resultis found = bombs
$)
 
// Ask a question, get number
let ask(q, min, max) = valof
$( let n = ?
$( writes(q)
n := readn()
$) repeatuntil min <= n <= max
resultis n
$)
 
// Read string
let reads(v) = valof
$( let ch = ?
v%0 := 0
$( ch := rdch()
if ch = endstreamch then resultis false
v%0 := v%0 + 1
v%(v%0) := ch
$) repeatuntil ch = '*N'
resultis true
$)
 
// Play game given field
let play(field, xsize, ysize) be
$( let x = ?
let y = ?
let ans = vec 80
if showfield(field, xsize, ysize, false)
$( writes("*NYou win!*N")
finish
$)
$( writes("*NR)eveal, F)lag, Q)uit? ")
unless reads(ans) finish
unless ans%0 = 2 & ans%2='*N' loop
ans%1 := ans%1 | 32
if ans%1 = 'q' then finish
$) repeatuntil ans%1='r' | ans%1='f'
y := ask("Row? ", 1, ysize)-1
x := ask("Column? ", 1, xsize)-1
switchon ans%1 into
$( case 'r':
unless (field!(y*xsize+x) & flagmask) = 0
$( writes("*NError: that field is flagged, unflag it first.*N")
endcase
$)
unless (field!(y*xsize+x) & revealed) = 0
$( writes("*NError: that field is already revealed.*N")
endcase
$)
if reveal(field, xsize, ysize, x, y)
$( writes("*N K A B O O M *N*N")
showfield(field, xsize, ysize, true)
finish
$)
endcase
case 'f':
test (field!(y*xsize+x) & revealed) = 0
do toggleflag(field, xsize, ysize, x, y)
or writes("*NError: that field is already revealed.*N")
endcase
$)
wrch('*N')
$) repeat
 
let start() be
$( let field, xsize, ysize, bombs = ?, ?, ?, ?
 
writes("Minesweeper*N-----------*N*N")
randstate := ask("Random seed? ", MININT, MAXINT)
xsize := ask("Width (4-64)? ", 4, 64)
ysize := ask("Height (4-22)? ", 4, 22)
// 10 to 20% bombs
bombs := muldiv(xsize,ysize,10) + randto(muldiv(xsize,ysize,10)+1)
field := getvec(xsize*ysize)
populate(field, xsize, ysize, bombs)
play(field, xsize, ysize)
$)</syntaxhighlight>
{{out}}
<pre style='height:70ex;'>Minesweeper
-----------
 
Random seed? 50
Width (4-64)? 6
Height (4-22)? 4
Bombs: 4 - Flagged: 0 - Hidden: 24
+------+
|......|
|......|
|......|
|......|
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 1
Column? 1
 
Bombs: 4 - Flagged: 0 - Hidden: 16
+------+
| 1....|
| 2....|
| 2....|
| 1....|
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 4
Column? 6
 
Bombs: 4 - Flagged: 0 - Hidden: 10
+------+
| 1....|
| 2....|
| 2.311|
| 1.1 |
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 1
Column? 3
 
Bombs: 4 - Flagged: 0 - Hidden: 9
+------+
| 11...|
| 2....|
| 2.311|
| 1.1 |
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 4
Column? 3
 
Bombs: 4 - Flagged: 0 - Hidden: 8
+------+
| 11...|
| 2....|
| 2.311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? f
Row? 2
Column? 3
 
Bombs: 4 - Flagged: 1 - Hidden: 8
+------+
| 11...|
| 2?...|
| 2.311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? f
Row? 3
Column? 3
 
Bombs: 4 - Flagged: 2 - Hidden: 8
+------+
| 11...|
| 2?...|
| 2?311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 1
Column? 4
 
Bombs: 4 - Flagged: 2 - Hidden: 7
+------+
| 112..|
| 2?...|
| 2?311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 2
Column? 4
 
Bombs: 4 - Flagged: 2 - Hidden: 6
+------+
| 112..|
| 2?3..|
| 2?311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? f
Row? 2
Column? 5
 
Bombs: 4 - Flagged: 3 - Hidden: 6
+------+
| 112..|
| 2?3?.|
| 2?311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 2
Column? 6
 
Bombs: 4 - Flagged: 3 - Hidden: 5
+------+
| 112..|
| 2?3?2|
| 2?311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? r
Row? 1
Column? 5
 
Bombs: 4 - Flagged: 3 - Hidden: 4
+------+
| 1122.|
| 2?3?2|
| 2?311|
| 111 |
+------+
 
R)eveal, F)lag, Q)uit? f
Row? 1
Column? 6
 
Bombs: 4 - Flagged: 4 - Hidden: 4
+------+
| 1122?|
| 2?3?2|
| 2?311|
| 111 |
+------+
 
You win!</pre>
 
=={{header|C}}==
Line 1,073 ⟶ 1,426:
 
{{libheader|curses}}
<langsyntaxhighlight lang="c">#if 0
 
Unix build:
Line 1,488 ⟶ 1,841:
# endif
return 0;
}</langsyntaxhighlight>
 
===Mouse version===
Using ncurses and mouse input. Compiled with <code>gcc -lncurses -Wall -std=c99</code>. Run as <code>a.out [height] [width]</code>; your terminal needs to support mouse input, and at least 2*width + 2 columns wide. Left button clears a cell, right button toggles mine mark, middle button on a cleared cell clears all neighboring cells (or blow up if there are unmarked mines). When mine count drops to zero, click "claim victory" to win the game or blow up.
<langsyntaxhighlight Clang="c">#include <ncurses.h>
#include <locale.h>
#include <stdlib.h>
Line 1,675 ⟶ 2,028:
endwin();
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
The following solution implements the required task providing GUI (Windows Forms).
 
<langsyntaxhighlight lang="csharp">using System;
using System.Drawing;
using System.Windows.Forms;
Line 1,945 ⟶ 2,298:
Application.Run(new MineSweepForm());
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
This solution implements the required task and one more command: unknown. It is represented by a '?' that's why the flag in this solution is represented as a '!'
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <string>
Line 2,173 ⟶ 2,526:
return system( "pause" );
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,221 ⟶ 2,574:
=={{header|Ceylon}}==
Be sure to import ceylon.random in your module.ceylon file.
<langsyntaxhighlight lang="ceylon">import ceylon.random {
 
DefaultRandom
Line 2,354 ⟶ 2,707:
}
}
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight Clojurelang="clojure">(defn take-random [n coll]
(->> (repeatedly #(rand-nth coll))
distinct
Line 2,434 ⟶ 2,787:
(let [[cmd & xy] (.split #" " (read-line))
[x y] (map #(Integer. %) xy)]
(recur ((if (= cmd "mark") mark open) board x y)))))))</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defclass minefield ()
((mines :initform (make-hash-table :test #'equal))
(width :initarg :width)
Line 2,523 ⟶ 2,876:
(return-from play-game T))))))
 
(play-game)</langsyntaxhighlight>
 
=={{header|D}}==
Line 2,529 ⟶ 2,882:
 
=={{header|EasyLang}}==
 
[https://easylang.online/apps/mine-sweeper.html Run it]
[https://easylang.dev/apps/mine-sweeper.html Run it]
<lang>len cell[] 56
 
<syntaxhighlight>
len cell[] 56
len cnt[] 56
len flag[] 56
#
subr initvars
state = 0
ticks = 0
indx = -1
no_time = 0
.
func getind r c . ind .
ind = -1
if r >= 0 and r <= 6 and c >= 0 and c <= 7
ind = r * 8 + c + 1
.
return ind
.
funcproc draw_cell ind h . .
r = ind /-= 81
c r = ind moddiv 8
x# = c *= 12ind +mod 2.58
y# x = rc * 12 + 142.5
y = r * 12 + 2.5
move x# y#
rect 11move 11x y
if hrect >11 011
if #h count> 0
move x# + 3 y# + 2count
move x + 3 y + 3
color 000
text h color 000
elif h = -3 text h
elif #h flag= -3
x# += 4# flag
color 000 x += 4
linewidth 0.8 color 000
move x# y#linewidth + 30.8
line move x# y# + 83
color 600 line x y + 8
linewidth 2 color 600
move x# +linewidth 0.5 y# + 42
line move x# + 20.5 y# + 47
line x + 2 y + 7
elif h <> 0
elif #h mine<> 0
color 333 # mine
if h =color -2333
colorif 800h = -2
. color 800
move x# + 5 y# + 6
circle 3
line x# + 8 y# + 2
.
.
func open ind . .
if ind <> -1 and cell[ind] = 0
cell[ind] = 2
flag[ind] = 0
color 686
call draw_cell ind cnt[ind]
if cnt[ind] = 0
r0 = ind / 8
c0 = ind mod 8
for r = r0 - 1 to r0 + 1
for c = c0 - 1 to c0 + 1
if r <> r0 or c <> c0
call getind r c ind
call open ind
.
.
.
move x + 5 y + 5
.
circle 3
.
line x + 8 y + 9
.
.
funcproc show_minesopen mind . .
if ind <> -1 and cell[ind] = 0
for ind range 56
if cell[ind] = 12
flag[ind] = 0
color 686
ifdraw_cell mind = -1cnt[ind]
if cnt[ind] color= 3530
ind -= 1
r0 = ind div 8
c0 = ind mod 8
for r = r0 - 1 to r0 + 1
for c = c0 - 1 to c0 + 1
if r <> r0 or c <> c0
open getind r c
.
.
.
.
.
call draw_cell ind m
.
.
.
funcproc outpshow_mines col s$m . .
for ind to 56
move 2.5 2
if cell[ind] = 1
color col
color 686
rect 59 11
if m = -1
color 000
color 353
move 5 4.5
text s$ .
draw_cell ind m
.
.
.
funcproc upd_infooutp col s$ . .
nm =move 02.5 87
nc =color 0col
for irect range59 5611
color 000
nm += flag[i]
move if5 cell[i] < 290
text nc += 1s$
.
.
if nc = 8
call outp 484 "Well done"
call show_mines -1
state = 1
else
call outp 464 8 - nm & " mines left"
.
.
funcproc test indupd_info . .
for i to 56
if cell[ind] < 2 and flag[ind] = 0
if cell[ind] nm += 1flag[i]
callif show_minescell[i] -1< 2
color 686 nc += 1
call draw_cell ind -2.
.
call outp 844 "B O O M !"
if nc = 8
outp 484 "Well done"
show_mines -1
state = 1
else
calloutp open464 ind8 - nm & " mines left"
.
call upd_info
.
.
.
funcproc starttest ind . .
if cell[ind] < 2 and flag[ind] = 0
color 676
if cell[ind] = 1
move 0 0
show_mines -1
rect 100 100
color 353686
draw_cell ind -2
for ind range 56
outp 844 "B O O M !"
cnt[ind] = 0
cell[ind] state = 01
flag[ind] = 0else
call draw_cell ind 0 open ind
upd_info
.
n = 8
while n > 0
c = random 8
r = random 7
ind = r * 8 + c
if cell[ind] = 0
n -= 1
cell[ind] = 1
for rx = r - 1 to r + 1
for cx = c - 1 to c + 1
call getind rx cx ind
if ind > -1
cnt[ind] += 1
.
.
.
.
.
background 676
call initvars
proc start . .
call outp 464 ""
clear
textsize 4
move 5color 3353
for ind to 56
text "Minesweeper - 8 mines"
cnt[ind] = 0
move 5 7.8
cell[ind] = 0
text "Long-press for flagging"
flag[ind] = 0
textsize 6
draw_cell ind 0
timer 0
.
n = 8
while n > 0
c = randint 8 - 1
r = randint 7 - 1
ind = r * 8 + c + 1
if cell[ind] = 0
n -= 1
cell[ind] = 1
for rx = r - 1 to r + 1
for cx = c - 1 to c + 1
ind = getind rx cx
if ind > -1
cnt[ind] += 1
.
.
.
.
.
initvars
outp 464 ""
textsize 4
move 5 93
text "Minesweeper - 8 mines"
move 5 88.2
text "Long-press for flagging"
textsize 6
timer 0
.
on mouse_down
if state = 0
call getind floorif ((mouse_y -> 14)86 /and 12) floor ((mouse_x - 2) / 12)> indx60
ticks0 no_time = ticks1
move 64.5 87
elif state = 3
call start color 464
rect 33 11
.
.
indx = getind ((mouse_y - 2) div 12) ((mouse_x - 2) div 12)
ticks0 = ticks
elif state = 3
start
.
.
on mouse_up
if state = 0 and indx <> -1
call test indx
.
indx = -1
.
on timer
if state = 1
state = 2
timer 1
elif state = 2
state = 3
elif no_time = 0 and ticks > 3000
call outp 844 "B O O M !"
call show_mines -2
state = 2
timer 1
else
if indx > -10 and ticks = ticks0 + 52
if cell[indx] < 2
color 353
flag[indx] = 1 - flag[indx]
opt = 0
if flag[indx] = 1
opt = -3
.
call draw_cell indx opt
call upd_info
.
indx = -1
.
indxif no_time = 0 and ticks mod 10 = -10
move 64.5 87
if ticks mod 10 = 0color 464
move 64.5 2 if ticks >= 2500
color 464844
if ticks >= 2500.
color 844rect 33 11
color 000
move 66 90
text "Time:" & 300 - ticks / 10
.
rectticks 33+= 111
colortimer 0000.1
move 66 4.5
text "Time:" & 300 - ticks / 10
.
ticks += 1
timer 0.1
.
.
call start</lang>
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
===Mouse version===
Based On BeBeliOuS's original code (www.bebelious.fr)
<syntaxhighlight lang="vb">'--- Declaration of global variables ---
Type mina
Dim mina As Byte
Dim flag As Byte
Dim ok As Byte
Dim numero As Byte
End Type
 
Dim Shared As Integer size = 16, NX = 20, NY = 20
Dim Shared As Double mina = 0.10
 
Dim Shared tablero(NX+1,NY+1) As mina
Dim Shared As Integer GameOver, ddx, ddy, kolor, nbDESCANSO
Dim Shared As Double temps
Dim As String tecla
 
'--- SUBroutines and FUNCtions ---
Sub VerTodo
Dim As Integer x, y
For x = 1 To NX
For y = 1 To NY
With tablero(x,y)
If .mina = 1 Or .flag > 0 Then .ok = 1
End With
Next y
Next x
End Sub
 
Sub ShowGrid
Dim As Integer x, y
Line(ddx-1,ddy-1)-(1+ddx+size*NX,1+ddy+size*NY),&hFF0000,B
For x = 1 To NX
For y = 1 To NY
With tablero(x,y)
'Si la casilla no se hace click
If .ok = 0 Then
Line(ddx+x*size,ddy+y*size)-(ddx+(x-1)*size,ddy+(y-1)*size),&h888888,BF
Line(ddx+x*size,ddy+y*size)-(ddx+(x-1)*size,ddy+(y-1)*size),&h444444,B
'bandera verde
If .flag = 1 Then
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h00FF00,,,,F
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h0
End If
'bandera azul
If .flag = 2 Then
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h0000FF,,,,F
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h0
End If
'Si se hace clic
Else
If .mina = 0 Then
If .numero > 0 Then
Select Case .numero
Case 1: kolor = &h3333FF
Case 2: kolor = &h33FF33
Case 3: kolor = &hFF3333
Case 4: kolor = &hFFFF33
Case 5: kolor = &h33FFFF
Case 6: kolor = &hFF33FF
Case 7: kolor = &h999999
Case 8: kolor = &hFFFFFF
End Select
Draw String(ddx+x*size-size/1.5,ddy+y*size-size/1.5),Str(.numero),kolor
End If
If GameOver = 1 Then
'Si no hay Mina y una bandera verde >> rojo completo
If .flag = 1 Then
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h330000,,,,F
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h555555
End If
'Si no hay Mina y una bandera azul >> azul oscuro
If .flag = 2 Then
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h000033,,,,F
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h555555
End If
End If
Else
'Si hay una Mina sin bandera >> rojo
If .flag = 0 Then
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&hFF0000,,,,F
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&hFFFF00
Else
'Si hay una Mina con bandera verde >>> verde
If .flag = 1 Then
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h00FF00,,,,F
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&hFFFF00
End If
If .flag = 2 Then
'Si hay una Mina con bandera azul >>>> verde oscuro
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&h003300,,,,F
Circle (ddx+x*size-size/2,ddy+y*size-size/2),size/4,&hFFFF00
End If
End If
End If
End If
End With
Next y
Next x
End Sub
 
Sub Calcul
Dim As Integer x, y
For x = 1 To NX
For y = 1 To NY
tablero(x,y).numero = _
Iif(tablero(x+1,y).mina=1,1,0) + Iif(tablero(x-1,y).mina=1,1,0) + _
Iif(tablero(x,y+1).mina=1,1,0) + Iif(tablero(x,y-1).mina=1,1,0) + _
Iif(tablero(x+1,y-1).mina=1,1,0) + Iif(tablero(x+1,y+1).mina=1,1,0) + _
Iif(tablero(x-1,y-1).mina=1,1,0) + Iif(tablero(x-1,y+1).mina=1,1,0)
Next y
Next x
End Sub
 
Sub Inicio
size = 20
If NX > 720/size Then size = 720/NX
If NY > 520/size Then size = 520/NY
Redim tablero(NX+1,NY+1) As mina
Dim As Integer x, y
For x = 1 To NX
For y = 1 To NY
With tablero(x,y)
.mina = Iif(Rnd > (1-mina), 1, 0)
.ok = 0
.flag = 0
.numero = 0
End With
Next y
Next x
ddx = (((800/size)-NX)/2)*size
ddy = (((600/size)-NY)/2)*size
Calcul
End Sub
 
Function isGameOver As Integer
Dim As Integer x, y, nbMINA, nbOK, nbAZUL, nbVERT
For x = 1 To NX
For y = 1 To NY
If tablero(x,y).ok = 1 And tablero(X,y).mina = 1 Then
Return -1
End If
If tablero(x,y).ok = 0 And tablero(x,y).flag = 1 And tablero(X,y).mina = 1 Then
nbOK += 1
End If
If tablero(X,y).mina = 1 Then
nbMINA + =1
End If
If tablero(X,y).flag = 2 Then
nbAZUL += 1
'End If
Elseif tablero(X,y).flag = 1 Then
nbVERT += 1
End If
Next y
Next x
If nbMINA = nbOK And nbAZUL = 0 Then Return 1
nbDESCANSO = nbMINA - nbVERT
End Function
 
Sub ClicRecursivo(ZX As Integer, ZY As Integer)
If tablero(ZX,ZY).ok = 1 Then Exit Sub
If tablero(ZX,ZY).flag > 0 Then Exit Sub
'CLICK
tablero(ZX,ZY).ok = 1
If tablero(ZX,ZY).mina = 1 Then Exit Sub
If tablero(ZX,ZY).numero > 0 Then Exit Sub
If ZX > 0 And ZX <= NX And ZY > 0 And ZY <= NY Then
ClicRecursivo(ZX+1,ZY)
ClicRecursivo(ZX-1,ZY)
ClicRecursivo(ZX,ZY+1)
ClicRecursivo(ZX,ZY-1)
ClicRecursivo(ZX+1,ZY+1)
ClicRecursivo(ZX+1,ZY-1)
ClicRecursivo(ZX-1,ZY+1)
ClicRecursivo(ZX-1,ZY-1)
End If
End Sub
 
 
'--- Main Program ---
Screenres 800,600,24
Windowtitle"Minesweeper game"
Randomize Timer
Cls
Dim As Integer mx, my, mb, fmb, ZX, ZY, r, tt
Dim As Double t
Inicio
GameOver = 1
Do
tecla = Inkey
If GameOver = 1 Then
Select Case Ucase(tecla)
Case Chr(Asc("X"))
NX += 5
If NX > 80 Then NX = 10
Inicio
Case Chr(Asc("Y"))
NY += 5
If NY > 60 Then NY = 10
Inicio
Case Chr(Asc("M"))
mina += 0.01
If mina > 0.26 Then mina = 0.05
Inicio
Case Chr(Asc("S"))
Inicio
GameOver = 0
temps = Timer
End Select
End If
Getmouse mx,my,,mb
mx -= ddx-size
my -= ddy-size
ZX = (MX-size/2)/size
ZY = (MY-size/2)/size
If GameOver = 0 And zx > 0 And zx <= nx And zy > 0 And zy <= ny Then
If MB=1 And fmb=0 Then ClicRecursivo(ZX,ZY)
If MB=2 And fmb=0 Then
tablero(ZX,ZY).flag += 1
If tablero(ZX,ZY).flag > 2 Then tablero(ZX,ZY).flag = 0
End If
fmb = mb
End If
r = isGameOver
If r = -1 And GameOver = 0 Then
VerTodo
GameOver = 1
End If
If r = 1 And GameOver = 0 Then GameOver = 1
If GameOver = 0 Then tt = Timer-temps
Screenlock
Cls
ShowGrid
If GameOver = 0 Then
Draw String (210,4), "X:" & NX & " Y:" & NY & " MINA:" & Int(mina*100) & "% TIMER : " & Int(TT) & " S REMAINING:" & nbDESCANSO,&hFFFF00
Else
Draw String (260,4), "PRESS: 'S' TO START X,Y,M TO SIZE" ,&hFFFF00
Draw String (330,17), "X:" & NX & " Y:" & NY & " MINA:" & Int(mina*100) & "%" ,&hFFFF00
If r = 1 Then
t += 0.01
If t > 1000 Then t = 0
Draw String (320,280+Cos(t)*100),"!! CONGRATULATION !!",&hFFFF00
End If
End If
Screenunlock
Loop Until tecla = Chr(27)
Bsave "Minesweeper.bmp",0
End</syntaxhighlight>
{{out}}
[https://www.dropbox.com/s/vj7cjdz7dp3wtk3/MinesweeperFB.bmp?dl=0 Minesweeper FreeBasic image]
 
=={{header|Go}}==
{{trans|PureBasic}}
... though altered somewhat.
<langsyntaxhighlight lang="go">package main
 
import (
Line 2,999 ⟶ 3,624:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 3,112 ⟶ 3,737:
=={{header|Icon}} and {{header|Unicon}}==
The following solution implements the required task and additionally error checking, and several additional commands.
<langsyntaxhighlight Iconlang="icon">global DEFARGS,MF
 
record minefield(mask,grid,rows,cols,mines,density,marked)
Line 3,292 ⟶ 3,917:
MF.mask := m
write(tag) & showgrid()
end</langsyntaxhighlight>
 
Sample output:
Line 3,324 ⟶ 3,949:
6 : ....
0 marked mines and 9 mines left to be marked.</pre>
=={{header|Haskell}}==
Game Module
 
<syntaxhighlight lang="haskell">{-# LANGUAGE TemplateHaskell #-}
 
module MineSweeper
( Board
, Cell(..)
, CellState(..)
, Pos
-- lenses / prisms
, pos
, coveredLens
, coveredFlaggedLens
, coveredMinedLens
, xCoordLens
, yCoordLens
-- Functions
, emptyBoard
, groupedByRows
, displayCell
, isLoss
, isWin
, exposeMines
, openCell
, flagCell
, mineBoard
, totalRows
, totalCols )
where
 
import Control.Lens ((%~), (&), (.~), (^.), (^?), Lens', Traversal', _1, _2,
anyOf, filtered, folded, lengthOf, makeLenses, makePrisms,
preview, to, view)
import Data.List (find, groupBy, nub, delete, sortBy)
import Data.Maybe (isJust)
import System.Random (getStdGen, getStdRandom, randomR, randomRs)
 
type Pos = (Int, Int)
type Board = [Cell]
 
data CellState = Covered { _mined :: Bool, _flagged :: Bool }
| UnCovered { _mined :: Bool }
deriving (Show, Eq)
 
data Cell = Cell
{ _pos :: Pos
, _state :: CellState
, _cellId :: Int
, _adjacentMines :: Int }
deriving (Show, Eq)
 
makePrisms ''CellState
makeLenses ''CellState
makeLenses ''Cell
 
-- Re-useable lens.
coveredLens :: Traversal' Cell (Bool, Bool) --'
coveredLens = state . _Covered
 
coveredMinedLens, coveredFlaggedLens, unCoveredLens :: Traversal' Cell Bool --'
coveredMinedLens = coveredLens . _1
coveredFlaggedLens = coveredLens . _2
unCoveredLens = state . _UnCovered
 
xCoordLens, yCoordLens :: Lens' Cell Int --'
xCoordLens = pos . _1
yCoordLens = pos . _2
 
-- Adjust row and column size to your preference.
totalRows, totalCols :: Int
totalRows = 4
totalCols = 6
 
emptyBoard :: Board
emptyBoard = (\(n, p) -> Cell { _pos = p
, _state = Covered False False
, _adjacentMines = 0
, _cellId = n }) <$> zip [1..] positions
where
positions = (,) <$> [1..totalCols] <*> [1..totalRows]
 
updateCell :: Cell -> Board -> Board
updateCell cell = fmap (\c -> if cell ^. cellId == c ^. cellId then cell else c)
 
updateBoard :: Board -> [Cell] -> Board
updateBoard = foldr updateCell
 
okToOpen :: [Cell] -> [Cell]
okToOpen = filter (\c -> c ^? coveredLens == Just (False, False))
 
openUnMined :: Cell -> Cell
openUnMined = state .~ UnCovered False
 
openCell :: Pos -> Board -> Board
openCell p b = f $ find (\c -> c ^. pos == p) b
where
f (Just c)
| c ^? coveredFlaggedLens == Just True = b
| c ^? coveredMinedLens == Just True = updateCell
(c & state .~ UnCovered True)
b
| isCovered c = if c ^. adjacentMines == 0 && not (isFirstMove b)
then updateCell (openUnMined c) $ expandEmptyCells b c
else updateCell (openUnMined c) b
| otherwise = b
f Nothing = b
isCovered = isJust . preview coveredLens
 
expandEmptyCells :: Board -> Cell -> Board
expandEmptyCells board cell
| null openedCells = board
| otherwise = foldr (flip expandEmptyCells) updatedBoard (zeroAdjacent openedCells)
where
findMore _ [] = []
findMore exclude (c : xs)
| c `elem` exclude = findMore exclude xs
| c ^. adjacentMines == 0 = c : adjacent c <>
findMore (c : exclude <> adjacent c) xs
| otherwise = c : findMore (c : exclude) xs
adjacent = okToOpen . flip adjacentCells board
openedCells = openUnMined <$> nub (findMore [cell] (adjacent cell))
zeroAdjacent = filter (view (adjacentMines . to (== 0)))
updatedBoard = updateBoard board openedCells
 
flagCell :: Pos -> Board -> Board
flagCell p board = case find ((== p) . view pos) board of
Just c -> updateCell (c & state . flagged %~ not) board
Nothing -> board
 
adjacentCells :: Cell -> Board -> [Cell]
adjacentCells Cell {_pos = c@(x1, y1)} = filter (\c -> c ^. pos `elem` positions)
where
f n = [pred n, n, succ n]
positions = delete c $ [(x, y) | x <- f x1, x > 0, y <- f y1, y > 0]
 
isLoss, isWin, allUnMinedOpen, allMinesFlagged, isFirstMove :: Board -> Bool
isLoss = anyOf (traverse . unCoveredLens) (== True)
isWin b = allUnMinedOpen b || allMinesFlagged b
 
allUnMinedOpen = (== 0) . lengthOf (traverse . coveredMinedLens . filtered (== False))
allMinesFlagged b = minedCount b == flaggedMineCount b
where
minedCount = lengthOf (traverse . coveredMinedLens . filtered (== True))
flaggedMineCount = lengthOf (traverse . coveredLens . filtered (== (True, True)))
 
isFirstMove = (== totalCols * totalRows) . lengthOf (folded . coveredFlaggedLens . filtered (== False))
 
groupedByRows :: Board -> [Board]
groupedByRows = groupBy (\c1 c2 -> yAxis c1 == yAxis c2)
. sortBy (\c1 c2 -> yAxis c1 `compare` yAxis c2)
where
yAxis = view yCoordLens
 
displayCell :: Cell -> String
displayCell c
| c ^? unCoveredLens == Just True = "X"
| c ^? coveredFlaggedLens == Just True = "?"
| c ^? (unCoveredLens . to not) == Just True =
if c ^. adjacentMines > 0 then show $ c ^. adjacentMines else "▢"
| otherwise = "."
 
exposeMines :: Board -> Board
exposeMines = fmap (\c -> c & state . filtered (\s -> s ^? _Covered . _1 == Just True) .~ UnCovered True)
 
updateMineCount :: Board -> Board
updateMineCount b = go b
where
go [] = []
go (x : xs) = (x & adjacentMines .~ totalAdjacentMines b) : go xs
where
totalAdjacentMines =
foldr (\c acc -> if c ^. (state . mined) then succ acc else acc) 0 . adjacentCells x
 
-- IO
mineBoard :: Pos -> Board -> IO Board
mineBoard p board = do
totalMines <- randomMinedCount
minedBoard totalMines >>= \mb -> pure $ updateMineCount mb
where
mines n = take n <$> randomCellIds
minedBoard n = (\m ->
fmap (\c -> if c ^. cellId `elem` m then c & state . mined .~ True else c)
board) . filter (\c -> openedCell ^. cellId /= c)
<$> mines n
openedCell = head $ filter (\c -> c ^. pos == p) board
 
randomCellIds :: IO [Int]
randomCellIds = randomRs (1, totalCols * totalRows) <$> getStdGen
 
randomMinedCount :: IO Int
randomMinedCount = getStdRandom $ randomR (minMinedCells, maxMinedCells)
where
maxMinedCells = floor $ realToFrac (totalCols * totalRows) * 0.2
minMinedCells = floor $ realToFrac (totalCols * totalRows) * 0.1</syntaxhighlight>
 
Text Play
<syntaxhighlight lang="haskell">module Main
 
where
 
import MineSweeper (Board, Cell (..), Pos, coveredLens, coveredMinedLens,
coveredFlaggedLens, xCoordLens, yCoordLens, pos, emptyBoard,
groupedByRows, displayCell, isLoss, isWin, exposeMines,
openCell, flagCell, mineBoard, totalRows, totalCols)
import Text.Printf (printf)
import Text.Read (readMaybe)
import System.IO (hSetBuffering, stdout, BufferMode(..))
import Control.Monad (join, guard)
import Control.Lens (lengthOf, filtered, view, preview)
 
data Command = Open Pos | Flag Pos | Invalid
 
parseInput :: String -> Command
parseInput s | length input /= 3 = Invalid
| otherwise = maybe Invalid command parsedPos
where
input = words s
parsedPos = do
x <- readMaybe (input !! 1)
y <- readMaybe (input !! 2)
guard (x <= totalCols && y <= totalRows)
pure (x, y)
command p = case head input of
"o" -> Open p
"f" -> Flag p
_ -> Invalid
 
cheat :: Board -> String
cheat = show . fmap (view pos) . filter ((== Just True) . preview coveredMinedLens)
 
totalMines, totalFlagged, totalCovered :: Board -> Int
totalMines = lengthOf (traverse . coveredMinedLens . filtered (==True))
totalFlagged = lengthOf (traverse . coveredFlaggedLens . filtered (==True))
totalCovered = lengthOf (traverse . coveredLens)
 
-- IO
drawBoard :: Board -> IO ()
drawBoard b = do
-- printf "Cheat: %s\n" $ cheat b
printf " Mines: %d Covered: %d Flagged: %d\n\n"
(totalMines b) (totalCovered b) (totalFlagged b)
printf "%3s" ""
mapM_ (printf "%3d") $ view xCoordLens <$> head rows
printf "\n"
mapM_ (\row -> do
printf "%3d" $ yCoord row
mapM_ (printf "%3s" . displayCell) row
printf "\n" ) rows
where
rows = groupedByRows b
yCoord = view yCoordLens . head
 
gameLoop :: Board -> IO ()
gameLoop b
| isLoss b = drawBoard (exposeMines b) >> printf "\nYou Lose.\n"
| isWin b = drawBoard b >> printf "\nYou Win.\n"
| otherwise = do
drawBoard b
putStr "\nPick a cell: "
c <- getLine
case parseInput c of
Open p -> gameLoop $ openCell p b
Flag p -> gameLoop $ flagCell p b
Invalid -> gameLoop b
 
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
drawBoard emptyBoard
putStr "\nPick a cell: "
c <- getLine
case parseInput c of
Open p -> join $ startGame p emptyBoard
_ -> main
where
startGame p b = gameLoop . openCell p <$> mineBoard p b</syntaxhighlight>
{{out}}
<pre> Mines: 0 Covered: 24 Flagged: 0
 
1 2 3 4 5 6
1 . . . . . .
2 . . . . . .
3 . . . . . .
4 . . . . . .
 
Pick a cell: o 1 1
Mines: 2 Covered: 23 Flagged: 0
 
1 2 3 4 5 6
1 ▢ . . . . .
2 . . . . . .
3 . . . . . .
4 . . . . . .
 
Pick a cell: f 1 2
Mines: 2 Covered: 23 Flagged: 1
 
1 2 3 4 5 6
1 ▢ . . . . .
2 ? . . . . .
3 . . . . . .
4 . . . . . .
 
Pick a cell: f 6 6
Mines: 2 Covered: 23 Flagged: 1
 
1 2 3 4 5 6
1 ▢ . . . . .
2 ? . . . . .
3 . . . . . .
4 . . . . . .
 
Pick a cell: f 6 4
Mines: 2 Covered: 23 Flagged: 2
 
1 2 3 4 5 6
1 ▢ . . . . .
2 ? . . . . .
3 . . . . . .
4 . . . . . ?
 
Pick a cell: f 1 2
Mines: 2 Covered: 23 Flagged: 1
 
1 2 3 4 5 6
1 ▢ . . . . .
2 . . . . . .
3 . . . . . .
4 . . . . . ?
 
Pick a cell: o 1 2
Mines: 2 Covered: 14 Flagged: 1
 
1 2 3 4 5 6
1 ▢ 1 . . . .
2 ▢ 1 . . . .
3 ▢ 1 2 . . .
4 ▢ ▢ 1 . . ?
 
Pick a cell: o 6 1
Mines: 2 Covered: 4 Flagged: 1
 
1 2 3 4 5 6
1 ▢ 1 . 1 ▢ ▢
2 ▢ 1 . 1 ▢ ▢
3 ▢ 1 2 2 1 ▢
4 ▢ ▢ 1 . 1 ?
 
Pick a cell: f 4 4
Mines: 2 Covered: 4 Flagged: 2
 
1 2 3 4 5 6
1 ▢ 1 . 1 ▢ ▢
2 ▢ 1 . 1 ▢ ▢
3 ▢ 1 2 2 1 ▢
4 ▢ ▢ 1 ? 1 ?
 
Pick a cell: o 3 2
Mines: 0 Covered: 2 Flagged: 1
 
1 2 3 4 5 6
1 ▢ 1 . 1 ▢ ▢
2 ▢ 1 X 1 ▢ ▢
3 ▢ 1 2 2 1 ▢
4 ▢ ▢ 1 X 1 ?
 
You Lose.</pre>
 
=={{header|J}}==
'''Solution'''
<langsyntaxhighlight lang="j">NB. minefield.ijs script
NB. =========================================================
NB. Game engine
Line 3,429 ⟶ 4,422:
- start a new game using the command:
fld=: MineSweeper <num columns> <num rows>
)</langsyntaxhighlight>
 
'''Example Usage'''
<langsyntaxhighlight lang="j"> load 'minefield.ijs'
fld=: Minesweeper 6 4
=== MineSweeper ===
Line 3,530 ⟶ 4,523:
│***1 1*12*312*1 1*1│
└────────────────────┘
You won! Try again?</langsyntaxhighlight>
 
=={{header|Java}}==
 
<langsyntaxhighlight lang="java">
 
--------------------------------- START of Main.java ---------------------------------
Line 3,557 ⟶ 4,550:
int input;
boolean loopEnd;
String wordcheck;
do {
Line 3,594 ⟶ 4,586:
{
loopEnd = false;
wordcheck = userInput.next();
System.out.println("Input is invalid.");
return 0;
Line 3,626 ⟶ 4,618:
 
 
public class Cell
{
public class Cell{ //This entire class is quite self-explanatory. All we're really doing is setting booleans.
Line 3,886 ⟶ 4,876:
mine.select(x, y);
}
 
//Middle click
if (e.getButton() == 2) {
int mineCount = 0;
int flagCount = 0;
}
//Right click - marks mine
if (e.getButton() == 3)
Line 4,181 ⟶ 5,163:
 
 
</syntaxhighlight>
</lang>
 
=={{header|Julia}}==
Save the following code to a file (for example "minesweeper.jl") and include it in the Julia REPL to play the game.
<syntaxhighlight lang="julia">
<lang Julia>
# Minesweeper:
 
Line 4,304 ⟶ 5,286:
 
play()
</syntaxhighlight>
</lang>
typical game:
<syntaxhighlight lang="julia">
<lang Julia>
julia> include("minesweeper.jl")
 
Line 4,391 ⟶ 5,373:
ERROR: You closed the game.
 
</syntaxhighlight>
</lang>
 
=={{header|Locomotive Basic}}==
 
<langsyntaxhighlight lang="locobasic">10 mode 1:randomize time
20 defint a-z
30 boardx=6:boardy=4
Line 4,508 ⟶ 5,490:
1120 next
1130 if mm=nmines then locate 5,22:print "Congratulations, you've won!":end
1140 return</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
Line 4,522 ⟶ 5,504:
 
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Minesweeper {
Font "Arial Black"
Line 4,790 ⟶ 5,772:
}
Minesweeper
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
===Mouse version===
<langsyntaxhighlight lang="mathematica">DynamicModule[{m = 6, n = 4, minecount, grid, win, reset, clear,
checkwin},
reset[] :=
Line 4,839 ⟶ 5,821:
minecount--, "?", grid[[i, j, 2]] = "."; minecount++];
checkwin[]]}]], {i, 1, m}, {j, 1, n}], Spacings -> {0, 0}],
Dynamic[win]}]</langsyntaxhighlight>
 
=={{header|MATLAB}}==
Line 4,845 ⟶ 5,827:
===Built-In Graphical Version===
 
<syntaxhighlight lang MATLAB="matlab">xpbombs</langsyntaxhighlight>
 
===Original Graphical Version===
Line 4,861 ⟶ 5,843:
*Code uses <code>gca</code> and <code>gcf</code> frequently, which could possibly cause problems if user is working with multiple figure windows at once.
 
<langsyntaxhighlight MATLABlang="matlab">function Minesweeper
 
% Game parameters (should be modified by user)
Line 5,103 ⟶ 6,085:
delete(stopwatch)
delete(obj)
end</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|Go}}
<syntaxhighlight lang="nim">import random, sequtils, strformat, strscans, strutils
 
const LMargin = 4
 
type
 
Cell = object
isMine: bool
display: char
 
Grid = seq[seq[Cell]]
 
Game = object
grid: Grid
mineCount: Natural
minesMarked: Natural
isOver: bool
 
 
proc initGame(m, n: Positive): Game =
result.grid = newSeqWith(m, repeat(Cell(isMine: false, display: '.'), n))
let min = (float(m * n) * 0.1).toInt
let max = (float(m * n) * 0.2).toInt
result.mineCount = min + rand(max - min)
var rm = result.mineCount
while rm > 0:
let x = rand(m - 1)
let y = rand(n - 1)
if not result.grid[x][y].isMine:
dec rm
result.grid[x][y].isMine = true
result.minesMarked = 0
 
 
template `[]`(grid: Grid; x, y: int): Cell = grid[x][y]
 
 
iterator cells(grid: var Grid): var Cell =
for y in 0..grid[0].high:
for x in 0..grid.high:
yield grid[x, y]
 
 
proc display(game: Game; endOfGame: bool) =
if not endOfGame:
echo &"Grid has {game.mineCount} mine(s), {game.minesMarked} mine(s) marked."
let margin = repeat(' ', LMargin)
echo margin, toSeq(1..game.grid.len).join()
echo margin, repeat('-', game.grid.len)
for y in 0..game.grid[0].high:
stdout.write align($(y + 1), LMargin)
for x in 0..game.grid.high:
stdout.write game.grid[x][y].display
stdout.write '\n'
 
 
proc terminate(game: var Game; msg: string) =
game.isOver = true
echo msg
var answer = ""
while answer notin ["y", "n"]:
stdout.write "Another game (y/n)? "
answer = try: stdin.readLine().toLowerAscii
except EOFError: "n"
if answer == "y":
game = initGame(6, 4)
game.display(false)
 
 
proc resign(game: var Game) =
var found = 0
for cell in game.grid.cells:
if cell.isMine:
if cell.display == '?':
cell.display = 'Y'
inc found
elif cell.display == 'x':
cell.display = 'N'
game.display(true)
let msg = &"You found {found} out of {game.mineCount} mine(s)."
game.terminate(msg)
 
 
proc markCell(game: var Game; x, y: int) =
if game.grid[x, y].display == '?':
dec game.minesMarked
game.grid[x, y].display = '.'
elif game.grid[x, y].display == '.':
inc game.minesMarked
game.grid[x, y].display = '?'
 
 
proc countAdjMines(game: Game; x, y: Natural): int =
for j in (y - 1)..(y + 1):
if j in 0..game.grid[0].high:
for i in (x - 1)..(x + 1):
if i in 0..game.grid.high:
if game.grid[i, j].isMine:
inc result
 
 
proc clearCell(game: var Game; x, y: int): bool =
 
if x in 0..game.grid.high and y in 0..game.grid[0].high:
if game.grid[x, y].display == '.':
 
if game.grid[x, y].isMine:
game.grid[x][y].display = 'x'
echo "Kaboom! You lost!"
return false
 
let count = game.countAdjMines(x, y)
if count > 0:
game.grid[x][y].display = chr(ord('0') + count)
else:
game.grid[x][y].display = ' '
for dx in -1..1:
for dy in -1..1:
if dx != 0 or dy != 0:
discard game.clearCell(x + dx, y + dy)
 
result = true
 
 
proc testForWin(game: var Game): bool =
if game.minesMarked != game.mineCount: return false
for cell in game.grid.cells:
if cell.display == '.': return false
result = true
echo "You won!"
 
 
proc splitAction(game: Game; action: string): tuple[x, y: int; ok: bool] =
var command: string
if not action.scanf("$w $s$i $s$i$s$.", command, result.x, result.y): return
if command.len != 1: return
if result.x notin 1..game.grid.len or result.y notin 1..game.grid.len: return
result.ok = true
 
 
proc printUsage() =
echo "h or ? - this help,"
echo "c x y - clear cell (x,y),"
echo "m x y - marks (toggles) cell (x,y),"
echo "n - start a new game,"
echo "q - quit/resign the game,"
echo "where 'x' is the (horizontal) column number and 'y' is the (vertical) row number.\n"
 
 
randomize()
printUsage()
var game = initGame(6, 4)
game.display(false)
 
while not game.isOver:
stdout.write "\n>"
let action = try: stdin.readLine().toLowerAscii
except EOFError: "q"
case action[0]
 
of 'h', '?':
printUsage()
 
of 'n':
game = initGame(6, 4)
game.display(false)
 
of 'c':
let (x, y, ok) = game.splitAction(action)
if not ok: continue
if game.clearCell(x - 1, y - 1):
game.display(false)
if game.testForwin(): game.resign()
else:
game.resign()
 
of 'm':
let (x, y, ok) = game.splitAction(action)
if not ok: continue
game.markCell(x - 1, y - 1)
game.display(false)
if game.testForWin(): game.resign()
 
of 'q':
game.resign()
 
else:
continue</syntaxhighlight>
 
{{out}}
Session example.
<pre>h or ? - this help,
c x y - clear cell (x,y),
m x y - marks (toggles) cell (x,y),
n - start a new game,
q - quit/resign the game,
where 'x' is the (horizontal) column number and 'y' is the (vertical) row number.
 
Grid has 2 mine(s), 0 mine(s) marked.
123456
------
1......
2......
3......
4......
 
>c 3 3
Grid has 2 mine(s), 0 mine(s) marked.
123456
------
1.1 1..
211 111
3
4
 
>m 1 1
Grid has 2 mine(s), 1 mine(s) marked.
123456
------
1?1 1..
211 111
3
4
 
>m 5 1
Grid has 2 mine(s), 2 mine(s) marked.
123456
------
1?1 1?.
211 111
3
4
 
>c 6 1
Grid has 2 mine(s), 2 mine(s) marked.
123456
------
1?1 1?1
211 111
3
4
You won!
123456
------
1Y1 1Y1
211 111
3
4
You found 2 out of 2 mine(s).
Another game (y/n)? n</pre>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">exception Lost
exception Won
 
Line 5,251 ⟶ 6,486:
in
minesweeper n m percent;
;;</langsyntaxhighlight>
 
Sample output:
Line 5,294 ⟶ 6,529:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 5,460 ⟶ 6,695:
}
print "You won!\n";
</syntaxhighlight>
</lang>
 
=={{header|Phix}}==
Simple text-based console version
<langsyntaxhighlight Phixlang="phix">constant help = """
 
Minesweeper
Line 5,635 ⟶ 6,870:
disclose()
puts(1,board&"game over\n\n")
{} = wait_key()</langsyntaxhighlight>
{{out}}
<pre>
Line 5,667 ⟶ 6,902:
=={{header|PHP}}==
This example generates webpage. It also uses JavaScript to have right-click events. Use it as CGI script.
<langsyntaxhighlight PHPlang="php"><?php
define('MINEGRID_WIDTH', 6);
define('MINEGRID_HEIGHT', 4);
Line 5,920 ⟶ 7,155:
unset($_SESSION['minesweeper']);
echo '<p>Congratulations. You won :).';
}</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp"># NIL Hidden: Empty field
# T Hidden: Mine
# 0-8 Marked: Empty field
Line 5,978 ⟶ 7,213:
(showMines)
(unless (fish =T *Field)
"Congratulations! You won!!" ) )</langsyntaxhighlight>
Output:
<pre>: (minesweeper 6 4)
Line 6,025 ⟶ 7,260:
Works with SWI-Prolog
 
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(clpfd)).
 
% Play - run the minesweeper game with a specified width and height
Line 6,231 ⟶ 7,466:
grid_set_xy(G, H, cell(0,0), Ng1),
expose_grid(H, Ng1, Ng2),
expose_grid_(T, Ng2, Ng).</langsyntaxhighlight>
 
<pre>
Line 6,247 ⟶ 7,482:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">Structure cell
isMine.i
display.c ;character to displays for cell, one of these {'.', '?', ' ', #)
Line 6,424 ⟶ 7,659:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Sample output:
<pre>h or ? - this help,
Line 6,475 ⟶ 7,710:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">
'''
Minesweeper game.
Line 6,611 ⟶ 7,846:
% (len(mines.intersection(markedmines)),
len(markedmines.difference(mines)),
len(mines)) )</langsyntaxhighlight>
 
'''Sample output'''
Line 6,691 ⟶ 7,926:
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
(require math/array)
Line 6,836 ⟶ 8,071:
;parse failed
(run))))))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2015-09-23}}
<syntaxhighlight lang="raku" perl6line>enum Tile-Type <Empty Mine>;
class Tile {
Line 6,951 ⟶ 8,186:
}
say ~$f;</langsyntaxhighlight>
 
=={{header|Ruby}}==
<langsyntaxhighlight Rubylang="ruby">puts <<EOS
Minesweeper game.
 
Line 7,118 ⟶ 8,353:
show_grid
end
end</langsyntaxhighlight>
 
=={{header|Rust}}==
<langsyntaxhighlight Rustlang="rust">extern crate rand;
 
use std::io;
Line 7,436 ⟶ 8,671:
}
}
}</langsyntaxhighlight>
 
'''Sample output'''
Line 7,483 ⟶ 8,718:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
fconfigure stdout -buffering none
 
Line 7,632 ⟶ 8,867:
}
 
play 6 4</langsyntaxhighlight>
Sample output:
<pre>
Line 7,688 ⟶ 8,923:
- 1 Class Module (Name it cMinesweeper)</pre>
===Code Module : ===
<syntaxhighlight lang="vb">
<lang vb>
Option Explicit
 
Line 7,701 ⟶ 8,936:
Userf.Show 0, True
End Sub
</syntaxhighlight>
</lang>
 
===Code Class Module===
Line 7,710 ⟶ 8,945:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!</pre>
 
<syntaxhighlight lang="vb">
<lang vb>
Option Explicit
Line 7,952 ⟶ 9,187:
End If
End Sub
</syntaxhighlight>
</lang>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-dynamic}}
{{libheader|Wren-fmt}}
{{libheader|Wren-ioutil}}
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "./dynamic" for Struct
import "./fmt" for Fmt
import "random" for Random
import "./ioutil" for Input
import "./str" for Str
 
var Cell = Struct.create("Cell", ["isMine", "display"])
 
var lMargin = 4
var grid = []
var mineCount = 0
var minesMarked = 0
var isGameOver = false
var rand = Random.new()
 
var makeGrid = Fn.new { |n, m|
if ( n <= 0 || m <= 0) Fiber.abort("Grid dimensions must be positive.")
grid = List.filled(n, null)
for (i in 0...n) {
grid[i] = List.filled(m, null)
for (j in 0...m) grid[i][j] = Cell.new(false, ".")
}
var min = (n * m * 0.1).round // 10% of tiles
var max = (n * m * 0.2).round // 20% of tiles
mineCount = min + rand.int(max - min + 1)
var rm = mineCount
while (rm > 0) {
var x = rand.int(n)
var y = rand.int(m)
if (!grid[x][y].isMine) {
rm = rm - 1
grid[x][y].isMine = true
}
}
minesMarked = 0
isGameOver = false
}
 
var displayGrid = Fn.new { |isEndOfGame|
if (!isEndOfGame) {
System.print("Grid has %(mineCount) mine(s), %(minesMarked) mine(s) marked.")
}
var margin = " " * lMargin
System.write("%(margin) ")
for (i in 1..grid.count) System.write(i)
System.print()
System.print("%(margin) %("-" * grid.count)")
for (y in 0...grid[0].count) {
Fmt.write("$*d:", lMargin, y+1)
for (x in 0...grid.count) System.write(grid[x][y].display)
System.print()
}
}
 
var endGame = Fn.new { |msg|
isGameOver = true
System.print(msg)
var ans = Input.option("Another game (y/n)? : ", "ynYN")
if (ans == "n" || ans == "N") return
makeGrid.call(6, 4)
displayGrid.call(false)
}
 
var resign = Fn.new {
var found = 0
for (y in 0...grid[0].count) {
for (x in 0...grid.count) {
if (grid[x][y].isMine) {
if (grid[x][y].display == "?") {
grid[x][y].display = "Y"
found = found + 1
} else if (grid[x][y].display != "x") {
grid[x][y].display = "N"
}
}
}
}
displayGrid.call(true)
var msg = "You found %(found), out of %(mineCount) mine(s)."
endGame.call(msg)
}
 
var usage = Fn.new {
System.print("h or ? - this help,")
System.print("c x y - clear cell (x,y),")
System.print("m x y - marks (toggles) cell (x,y),")
System.print("n - start a new game,")
System.print("q - quit/resign the game,")
System.print("where x is the (horizontal) column number and y is the (vertical) row number.\n")
}
 
var markCell = Fn.new { |x, y|
if (grid[x][y].display == "?") {
minesMarked = minesMarked - 1
grid[x][y].display = "."
} else if (grid[x][y].display == ".") {
minesMarked = minesMarked + 1
grid[x][y].display = "?"
}
}
 
var countAdjMines = Fn.new { |x, y|
var count = 0
for (j in y-1..y+1) {
if (j >= 0 && j < grid[0].count) {
for (i in x-1..x+1) {
if (i >= 0 && i < grid.count) {
if (grid[i][j].isMine) count = count + 1
}
}
}
}
return count
}
 
var clearCell // recursive function
clearCell = Fn.new { |x, y|
if (x >= 0 && x < grid.count && y >= 0 && y < grid[0].count) {
if (grid[x][y].display == ".") {
if (!grid[x][y].isMine) {
var count = countAdjMines.call(x, y)
if (count > 0) {
grid[x][y].display = String.fromByte(48 + count)
} else {
grid[x][y].display = " "
clearCell.call(x+1, y)
clearCell.call(x+1, y+1)
clearCell.call(x, y+1)
clearCell.call(x-1, y+1)
clearCell.call(x-1, y)
clearCell.call(x-1, y-1)
clearCell.call(x, y-1)
clearCell.call(x+1, y-1)
}
} else {
grid[x][y].display = "x"
System.print("Kaboom! You lost!")
return false
}
}
}
return true
}
 
var testForWin = Fn.new {
var isCleared = false
if (minesMarked == mineCount) {
isCleared = true
for (x in 0...grid.count) {
for (y in 0...grid[0].count) {
if (grid[x][y].display == ".") isCleared = false
}
}
}
if (isCleared) System.print("You won!")
return isCleared
}
 
var splitAction = Fn.new { |action|
var fields = action.split(" ").where{ |s| s != "" }.toList
if (fields.count != 3) return [0, 0, false]
var x = Num.fromString(fields[1])
if (x < 1 || x > grid.count) return [0, 0, false]
var y = Num.fromString(fields[2])
if (y < 1 || y > grid[0].count) return [0, 0, false]
return [x, y, true]
}
 
usage.call()
makeGrid.call(6, 4)
displayGrid.call(false)
while (!isGameOver) {
var action = Str.lower(Input.text("\n>", 1))
var first = action[0]
if (first == "h" || first == "?") {
usage.call()
} else if (first == "n") {
makeGrid.call(6, 4)
displayGrid.call(false)
} else if (first == "c") {
var res = splitAction.call(action)
if (!res[2]) continue
var x = res[0]
var y = res[1]
if (clearCell.call(x-1, y-1)) {
displayGrid.call(false)
if (testForWin.call()) resign.call()
} else {
resign.call()
}
} else if (first == "m") {
var res = splitAction.call(action)
if (!res[2]) continue
var x = res[0]
var y = res[1]
markCell.call(x-1, y-1)
displayGrid.call(false)
if (testForWin.call()) resign.call()
} else if (first == "q") {
resign.call()
} else {
System.print("Invalid option, try again")
}
}</syntaxhighlight>
 
{{out}}
Sample game:
<pre>
h or ? - this help,
c x y - clear cell (x,y),
m x y - marks (toggles) cell (x,y),
n - start a new game,
q - quit/resign the game,
where x is the (horizontal) column number and y is the (vertical) row number.
 
Grid has 2 mine(s), 0 mine(s) marked.
123456
------
1:......
2:......
3:......
4:......
 
>c 1 1
Grid has 2 mine(s), 0 mine(s) marked.
123456
------
1: 1....
2: 11211
3:
4:
 
>m 3 1
Grid has 2 mine(s), 1 mine(s) marked.
123456
------
1: 1?...
2: 11211
3:
4:
 
>c 6 1
Grid has 2 mine(s), 1 mine(s) marked.
123456
------
1: 1?..1
2: 11211
3:
4:
 
>m 5 1
Grid has 2 mine(s), 2 mine(s) marked.
123456
------
1: 1?.?1
2: 11211
3:
4:
 
>c 4 1
Grid has 2 mine(s), 2 mine(s) marked.
123456
------
1: 1?2?1
2: 11211
3:
4:
You won!
123456
------
1: 1Y2Y1
2: 11211
3:
4:
You found 2, out of 2 mine(s).
Another game (y/n)? : n
</pre>
1,983

edits