| | | 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 | | |