 # ChrisPritchard's solution

## to Minesweeper in the F# Track

Published at Aug 26 2018 · 0 comments
Instructions
Test suite
Solution

Add the numbers to a minesweeper board.

Minesweeper is a popular game where the user has to find the mines using numeric hints that indicate how many mines are directly adjacent (horizontally, vertically, diagonally) to a square.

In this exercise you have to create some code that counts the number of mines adjacent to a square and transforms boards like this (where `*` indicates a mine):

``````+-----+
| * * |
|  *  |
|  *  |
|     |
+-----+
``````

into this:

``````+-----+
|1*3*1|
|13*31|
| 2*2 |
| 111 |
+-----+
``````

## Running the tests

To run the tests, run the command `dotnet test` from within the exercise directory.

## Further information

For more detailed information about the F# track, including how to get help if you're having trouble, please visit the exercism.io F# language page.

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### MinesweeperTest.fs

``````// This file was auto-generated based on version 1.1.0 of the canonical data.

module MinesweeperTest

open FsUnit.Xunit
open Xunit

open Minesweeper

[<Fact>]
let ``No rows`` () =
let minefield: string list = []
let expected: string list = []
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``No columns`` () =
let minefield = [""]
let expected = [""]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``No mines`` () =
let minefield =
[ "   ";
"   ";
"   " ]
let expected =
[ "   ";
"   ";
"   " ]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Minefield with only mines`` () =
let minefield =
[ "***";
"***";
"***" ]
let expected =
[ "***";
"***";
"***" ]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Mine surrounded by spaces`` () =
let minefield =
[ "   ";
" * ";
"   " ]
let expected =
[ "111";
"1*1";
"111" ]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Space surrounded by mines`` () =
let minefield =
[ "***";
"* *";
"***" ]
let expected =
[ "***";
"*8*";
"***" ]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Horizontal line`` () =
let minefield = [" * * "]
let expected = ["1*2*1"]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Horizontal line, mines at edges`` () =
let minefield = ["*   *"]
let expected = ["*1 1*"]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Vertical line`` () =
let minefield =
[ " ";
"*";
" ";
"*";
" " ]
let expected =
[ "1";
"*";
"2";
"*";
"1" ]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Vertical line, mines at edges`` () =
let minefield =
[ "*";
" ";
" ";
" ";
"*" ]
let expected =
[ "*";
"1";
" ";
"1";
"*" ]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Cross`` () =
let minefield =
[ "  *  ";
"  *  ";
"*****";
"  *  ";
"  *  " ]
let expected =
[ " 2*2 ";
"25*52";
"*****";
"25*52";
" 2*2 " ]
annotate minefield |> should equal expected

[<Fact(Skip = "Remove to run test")>]
let ``Large minefield`` () =
let minefield =
[ " *  * ";
"  *   ";
"    * ";
"   * *";
" *  * ";
"      " ]
let expected =
[ "1*22*1";
"12*322";
" 123*2";
"112*4*";
"1*22*2";
"111111" ]
annotate minefield |> should equal expected``````
``````module Minesweeper
open System

let annotate (input: string list) =
[-1..1] |> List.collect (fun y -> [-1..1] |> List.map (fun x -> (fst point + y, snd point + x)))
|> List.except [point]
let forPoint y x c = if c = '*' then ((y,x), adjacencies (y,x) |> Some) else (((y,x)), None)
input
|> List.mapi (fun y line -> line |> Seq.toList |> List.mapi (fun x c -> forPoint y x c))
|> List.concat |> List.filter (fun (_,a) -> a.IsSome) |> List.map (fun (p,a) -> (p,a.Value))
let plotter y x c =
if c = '*' then '*' else
let count = List.filter (fun (_,a) -> List.contains (y,x) a) minesAndAdjancies |> List.length
if count = 0 then ' ' else count |> string |> char
input
|> List.mapi (fun y line -> line |> Seq.toList |> List.mapi (fun x c -> plotter y x c) |> String.Concat)``````