| | 1 | | namespace Minesweeper |
| | 2 | |
|
| | 3 | | open System.Text |
| | 4 | | open FSharpPlus |
| | 5 | | open Cell |
| | 6 | |
|
| | 7 | |
|
| | 8 | | type Width = int |
| | 9 | | type Height = int |
| | 10 | | type Cells = Map<(int*int), Cell> |
| | 11 | | type BombsPos = seq<(int*int)> |
| | 12 | |
|
| | 13 | | type Minefield = |
| | 14 | | | Setup of Width * Height |
| | 15 | | | SetupWithBombs of Width * Height * BombsPos |
| | 16 | | | Playing of Width * Height * Cells |
| | 17 | |
|
| | 18 | | module Minefield = |
| | 19 | | let rec start v = |
| 4 | 20 | | match v with |
| | 21 | | | SetupWithBombs (w, h, z) -> |
| 4 | 22 | | let nearBombsPos (y, x) = seq { |
| 4 | 23 | | (y - 1, x - 1) ; |
| 4 | 24 | | (y - 1, x); |
| 4 | 25 | | (y - 1, x + 1); |
| 4 | 26 | | (y , x - 1) ; |
| 4 | 27 | | (y , x + 1); |
| 4 | 28 | | (y + 1, x - 1) ; |
| 4 | 29 | | (y + 1, x); |
| 4 | 30 | | (y + 1, x + 1); |
| 4 | 31 | | } |
| 3 | 32 | | let cells = Map.ofSeq <| seq { |
| 15 | 33 | | for y in {0..h - 1} do |
| 63 | 34 | | for x in {0..w - 1} do |
| 36 | 35 | | yield ((y, x), init) |
| 3 | 36 | | } |
| | 37 | | let cellsWithBombs = |
| 9 | 38 | | (cells, z) ||> Seq.fold (fun s p -> |
| 19 | 39 | | s |> Map.change p (Option.map (fun _ -> Bomb |> Covered))) |
| | 40 | | let cellsWithBombsAndNumber = |
| 9 | 41 | | (cellsWithBombs, z) ||> Seq.fold (fun s p -> |
| 12 | 42 | | (s, nearBombsPos(p)) ||> Seq.fold(fun s1 p1 -> |
| 71 | 43 | | s1 |> Map.change p1 (Option.map add))) |
| 3 | 44 | | Playing (w, h, cellsWithBombsAndNumber) |
| 2 | 45 | | | Setup (w, h) -> SetupWithBombs (w, h, Seq.empty) |> start |
| 0 | 46 | | | _ -> v |
| | 47 | | let string v (f : Cell -> char) = |
| 2 | 48 | | match v with |
| | 49 | | | Playing (w, h, z) -> |
| 10 | 50 | | (StringBuilder(), z |> Map.toSeq) ||> fold (fun s ((y, x), c) -> |
| 72 | 51 | | let _1 = s.Append (c |> f) |
| 24 | 52 | | match x with |
| 30 | 53 | | | _ when x = w - 1 -> _1.Append '\n' |
| 22 | 54 | | | _ -> _1.Append ' ') |> string |
| 0 | 55 | | | _ -> "" |
| | 56 | | let cells = function |
| 1 | 57 | | | Playing (w, h, z) -> z |
| 0 | 58 | | | _ -> Map.empty |
| | 59 | |
|
| | 60 | |
|
| | 61 | |
|