Course:CPSC312-2023-Hangman
Hangman
Authors: Carmen, Christine, Gloria
What is the problem?
Our project implements the game Hangman in Haskell. The game involves the computer choosing a word from a word bank for the player to guess. If the player chooses a letter that is not in the chosen word, a body part will be added to a stick figure drawing. The stick figure comprises of 6 body parts, so the player has 6 guesses available. If the player is unable to guess the word before the stick figure is completed, the player loses.
Rules can be found here: https://gambiter.com/paper-pencil/Hangman_game.html
What is the something extra?
Our game includes a feature in which the player can ask the computer to give three hints for word that is being guessed. The first hint will return how many times a vowels appears in the word, while the second and third hint will give the player the next missing letter in the word. We also print out a small ASCII-styled hangman for players to see their progress visually.
What did we learn from doing this?
We started from using the code files Play.hs and MagicSum.hs to adapt the structure of the game to suit our needs from Hangman. Through this process we learnt a lot more about:
- Managing and customizing the specific requirements of the state and internal state of a game. Since MagicSum had more simple requirements of just a number, we needed to do work to figure out what other aspects needed to be tracked and how it would affect the game state. This also affected how we implemented Play.hs, as we not only need to allow the player to guess a letter, we also needed to implement the hint feature.
- Randomizers and their tie to the IO monad. We had tried to implement a randomizing element in the word selection process but found it tricky to work with an IO String within the game's internal state due to the target word being passed around in a lot of functions and would be used in different ways. Due to the time constraints of the project, we ended up having the player enter a number to access our word bank that is pre-shuffled to not be in alphabetic order, but a future goal or and potential extension would have been to figure out how to use System.Random best to work in conjunction with our code. As well, learning the basics of reading and writing to a file to integrate into our game is also a feature that can be added to our game in the future.
- Monads and the do-expression was use quite extensively as we often needed to execute many steps due to the higher level of complexity of managing the game state.
- The Maybe type was also used extensively as we needed to check user input into the game and be on the lookout if we got an input that was unexpected. This proved to be very helpful for us in these cases.
We think that the simplicity of functional programming is suitable for creating simple games as there are abstractions that can be used that apply to many games and the code can be in general more readable. Overall, this project strengthened our understanding of how Haskell could be used to build potentially more complex games, but also showed us how different the approach in building something like this would be compared to our typical usage of imperative languages.