Skip to content
This repository has been archived by the owner on May 30, 2023. It is now read-only.

Commit

Permalink
Add minesweeper exercise (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom authored May 7, 2023
1 parent 4a39a21 commit 2413f7f
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 0 deletions.
12 changes: 12 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,18 @@
],
"difficulty": 2
},
{
"slug": "minesweeper",
"name": "Minesweeper",
"uuid": "1d8dc367-3f00-4b99-a6bd-e5895a0bdb4c",
"practices": [],
"prerequisites": [
"vectors",
"conditionals",
"strings"
],
"difficulty": 7
},
{
"slug": "wordy",
"name": "Wordy",
Expand Down
32 changes: 32 additions & 0 deletions exercises/practice/minesweeper/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Instructions

Add the mine counts to a completed 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 given empty square and replaces that square with the count.

The board is a rectangle composed of blank space (' ') characters.
A mine is represented by an asterisk (`*`) character.

If a given space has no adjacent mines at all, leave that square blank.

## Examples

For example you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen):

```text
·*·*·
··*··
··*··
·····
```

And your code will transform it into this:

```text
1*3*1
13*31
·2*2·
·111·
```
17 changes: 17 additions & 0 deletions exercises/practice/minesweeper/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"authors": [
"ErikSchierboom"
],
"files": {
"solution": [
"src/minesweeper.cljs"
],
"test": [
"test/minesweeper_test.cljs"
],
"example": [
".meta/src/example.cljs"
]
},
"blurb": "Add the numbers to a minesweeper board."
}
27 changes: 27 additions & 0 deletions exercises/practice/minesweeper/.meta/src/example.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
(ns minesweeper
(:require [clojure.pprint :refer [cl-format]]
[clojure.string :refer [split-lines]]))

(defn- windows [field]
(->> field
(map #(partition 3 1 `(nil ~@% nil)))
(apply map #(partition 3 1 `(nil ~@%& nil)))
(apply map vector)))

(defn- count-mines-around [[[a b c]
[d e f]
[g h i]]]
(if-let [mines-count (and (= \space e)
(count (filter #{\*} [a b c d f g h i])))]
(if (zero? mines-count)
\space
mines-count)
e))

(defn draw [field]
(if (empty? field) ""
(->> field
split-lines
windows
(map (fn [line] (map count-mines-around line)))
(cl-format nil "~{~{~a~}~^~%~}"))))
39 changes: 39 additions & 0 deletions exercises/practice/minesweeper/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.

[0c5ec4bd-dea7-4138-8651-1203e1cb9f44]
description = "no rows"

[650ac4c0-ad6b-4b41-acde-e4ea5852c3b8]
description = "no columns"

[6fbf8f6d-a03b-42c9-9a58-b489e9235478]
description = "no mines"

[61aff1c4-fb31-4078-acad-cd5f1e635655]
description = "minefield with only mines"

[84167147-c504-4896-85d7-246b01dea7c5]
description = "mine surrounded by spaces"

[cb878f35-43e3-4c9d-93d9-139012cccc4a]
description = "space surrounded by mines"

[7037f483-ddb4-4b35-b005-0d0f4ef4606f]
description = "horizontal line"

[e359820f-bb8b-4eda-8762-47b64dba30a6]
description = "horizontal line, mines at edges"

[c5198b50-804f-47e9-ae02-c3b42f7ce3ab]
description = "vertical line"

[0c79a64d-703d-4660-9e90-5adfa5408939]
description = "vertical line, mines at edges"

[4b098563-b7f3-401c-97c6-79dd1b708f34]
description = "cross"

[04a260f1-b40a-4e89-839e-8dd8525abe0e]
description = "large minefield"
10 changes: 10 additions & 0 deletions exercises/practice/minesweeper/deps.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{:deps
{org.clojure/clojure {:mvn/version "1.10.1"}
org.clojure/clojurescript {:mvn/version "1.10.773"}}

:aliases
{:test
{:extra-paths ["test"]
:extra-deps
{olical/cljs-test-runner {:mvn/version "3.8.0"}}
:main-opts ["-m" "cljs-test-runner.main"]}}}
5 changes: 5 additions & 0 deletions exercises/practice/minesweeper/src/minesweeper.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(ns minesweeper)

(defn draw [] ;; <- arglist goes here
;; your code goes here
)
62 changes: 62 additions & 0 deletions exercises/practice/minesweeper/test/minesweeper_test.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
(ns minesweeper-test
(:require [clojure.test :refer [deftest is]]
[clojure.string :refer [join]]
[minesweeper :refer [draw]]))

(def line-separator "\n")

(deftest zero-size-board
(is (= (draw "") "")))

(deftest empty-board
(is (= (draw (join line-separator [" "
" "
" "]))
(join line-separator [" "
" "
" "]))))

(deftest surrounded
(is (= (draw (join line-separator ["***"
"* *"
"***"]))
(join line-separator ["***"
"*8*"
"***"]))))

(deftest board-full-of-mines
(is (= (draw (join line-separator ["***"
"***"
"***"]))
(join line-separator ["***"
"***"
"***"]))))

(deftest horizontal-line
(is (= (draw " * * ")
"1*2*1")))

(deftest vertical-line
(is (= (draw (join line-separator [" "
"*"
" "
"*"
" "]))
(join line-separator ["1"
"*"
"2"
"*"
"1"]))))

(deftest cross
(is (= (draw (join line-separator [" * "
" * "
"*****"
" * "
" * "]))
(join line-separator [" 2*2 "
"25*52"
"*****"
"25*52"
" 2*2 "]))))

0 comments on commit 2413f7f

Please sign in to comment.