RosettaCodeData/Task/Minesweeper-game/Mathematica/minesweeper-game.math

47 lines
1.9 KiB
Plaintext

DynamicModule[{m = 6, n = 4, minecount, grid, win, reset, clear,
checkwin},
reset[] :=
Module[{minesdata, adjacentmines},
minecount = RandomInteger[Round[{.1, .2} m*n]];
minesdata =
Normal@SparseArray[# -> 1 & /@
RandomSample[Tuples[Range /@ {m, n}], minecount], {m, n}];
adjacentmines =
ArrayPad[
Total[RotateLeft[
ArrayPad[minesdata,
1], #] & /@ {{-1, -1}, {0, -1}, {1, -1}, {-1, 0}, {1,
0}, {-1, 1}, {0, 1}, {1, 1}}], -1];
grid = Array[{If[minesdata[[#1, #2]] == 1, "*",
adjacentmines[[#1, #2]]], ".", 1} &, {m, n}]; win = ""];
clear[i_, j_] :=
If[grid[[i, j, 1]] == "*", win = "You lost.";
grid = grid /. {{n_Integer, "?", _} :> {n, "x", 0}, {"*",
".", _} :> {"*", "*", 0}},
grid[[i, j]] = {grid[[i, j, 1]], grid[[i, j, 1]], 0};
If[grid[[i, j, 2]] == 0, grid[[i, j, 2]] = "";
clear[i + #[[1]],
j + #[[2]]] & /@ {{-1, -1}, {0, -1}, {1, -1}, {-1, 0}, {1,
0}, {-1, 1}, {0, 1}, {1, 1}}]] /;
1 <= i <= m && 1 <= j <= n && grid[[i, j, 2]] == ".";
checkwin[] :=
If[FreeQ[grid, {_Integer, "?", _} | {_, "*", _} | {_Integer,
".", _}], win = "You win.";
grid = grid /. {{"*", ".", _} :> {"*", "?", 1}}];
reset[];
Panel@Column@{Row@{Dynamic@minecount, "\t",
Button["Reset", reset[]]},
Grid[Table[
With[{i = i, j = j},
EventHandler[
Button[Dynamic[grid[[i, j, 2]]], Null, ImageSize -> {17, 17},
Appearance ->
Dynamic[If[grid[[i, j, 3]] == 0, "Pressed",
"DialogBox"]]], {{"MouseClicked", 1} :>
If[win == "", clear[i, j]; checkwin[]], {"MouseClicked",
2} :> If[win == "",
Switch[grid[[i, j, 2]], ".", grid[[i, j, 2]] = "?";
minecount--, "?", grid[[i, j, 2]] = "."; minecount++];
checkwin[]]}]], {i, 1, m}, {j, 1, n}], Spacings -> {0, 0}],
Dynamic[win]}]