Course:CPSC312-2023-Minesweeper JJ
Authors: Joy, Jonathan
What is the problem?
We will be creating a harder version of Minesweeper. More information can be found in our README.
What is the something extra?
We will be using the hspec package to write unit tests.
What did we learn from doing this?
Higher order functions, functions that can be passed into other functions as arguments/returns functions, enabled us to more easy write generic code which can be reused in different parts of our program.
For example, `src/GameBoard.hs`'s `updateSquares` method came from our realization that iterating through the board to increment bomb counts (for board initialization) has an end result extremely similar to iterating through the board to reveal the marking whenever a player inputs a (row col) pair. The two functions `revealMarking` and `incrementBombCount` allowed us to do both these using the generic function `updateSquares`. Similar idea to out Board visualizers
Haskell's functional programming and our insistance to be as functional as possible my limiting the amount of `do/where/let` keywords had allowed us to discover the benefits of modularity. By writing small digestable functions out of necessaity, we avoided the common pitfall of many procedural programming with long functions. Our pure functions were as small we could make them so each non-generic function did a singular task.
Using Haskell's `HSpec` library was an easy experience because of functional programming encourages zero side effect functions. We were able to mock up individual components, such as `Squares`, `Locations`, and `Boards` and test them without having to worry about our function modifying some global object like you might have when testing classes in object oriented programming.
We wish we could tell you using Haskell was all sunshine and rainbows, but we can't...
In the spirit of Haskell, everything we used, including the data structure is immuteable. Unfortunately, for Minesweeper, this means that every time a user reveals a single new square, a completely new board must be created. For a small board size such as `n = 5` the performance hit is negligible, but as n increases the downsides will become apparent. While it may be true developers can optimize this problem by caching uneffected rows, the workarounds will never be as easy as reassignment in non-functional programming languages.
Links to code etc
https://github.com/JonAndYu/MineSweeper