Github Classroom Link
Your final project is to write a command-line solver for a two-player game of perfect information. The game cannot contain randomness (via dice or card draws), or information that that is known to only one player. You may not use games of severely bounded depth, such as Tic-Tac-Toe. You may consider generalizations of those games, such as Connect 4. The following list contains examples. Game not from this list must be approved, to make sure they are suitable.
k-Hands Chopsticks
Deterministic Qwirkle
The project is divided into three sprints, each of which will have feedback and evaluation. Objectives for the project include:
Functionality: your code should work and satisfy the specification for each sprint.
Communicating computation: working in a group requires that you be able to communicate computational concepts. You should ensure everyone in the group understands the code well enough to work on it.
Design - abstraction and decomposition: you must decide how to decompose your problem, how to represent your data, what functions to define, and what types to give those functions. “It works” is a poor justification for such a decision. You should divide your types and functions on logical lines that naturally fit the structure of the problem you are solving. Towards the second sprint you should divide the project into separate modules.
For this sprint, you will need to be able to represent the board game in Haskell, make moves on the board game, and tell if a player has won the board game. You should have a variable defined that represents the initial game state. I should be able to play the game by loading your code in GHCI and calling functions you have defined.
This sprint should implement the following stories, each of which should be implemented on one or more branches. In total, you will add 6 stories (pieces of functionality) to your list of tasks to be finished by the sprint, called the backlog. I have included an Estimate of the relative difficulty of each story, selected from the range 1,2,3,5,8. The Estimate considers the amount of work required, the logical difficulty of the story, and how much the story will effect the rest of the code base. The difficulty of stories 2, 3, and 4 stories can vary significantly from game to game.
Story 1: Define data types or type aliases for a player, game state, move, and winner. I suggest data types (or possibly type aliases) to represent:
The state of the board Game, including both tangible and intangible components.
Tangible componentdris includes pieces and their locations.
Intangible components may include whose turn it is, what the current bet in, or any other information not represented on the game board, but critical to game play.
A Move on the game board.
The Winner of a game.
You may have subtypes for these types as well. Be careful of using strings or integers where enumerated types would have more fidelity.
Estimate: 8.
Story 2: Check who has won the game state, if anyone, with a function of type Game -> Winner.
Estimate: 5 requires story 1.
Story 3: Compute the result of making a legal move in a game state, with a function of type Game -> Move -> Game.
Estimate: 2 requires story 1.
Story 4: Compute the legal moves from a game state, with a function of type Game -> [Move].
Estimate: 3 requires story 1.
Story 5: Pretty-print a game into a string, with a function of type Game -> String. You should not override the Show typeclass. This is primarily for debugging purposes.
Estimate: 2, requires story 1, lower priority.
Story 6: All of these functions should consider possible errors or edge cases: what if there no winner, what if the move is not legal for the current game, etc. Use Maybe's or Either's appropriately.
Estimate: 2, requires stories 1-4, for full credit.