Project Idea: How to Code a Hangman-style game in Logo
You can open this project in the web-based IDE environment by following this link: https://turtlespaces.org/weblogo/?pub=122
Due to Logo’s enhanced string-handling capabilities and built-in dictionary, making Hangman-style games in turtleSpaces is easy-peasy!
The mechanics of a Hangman game are simple: the computer chooses a word, and then the player chooses letters. If the letters they choose are in the chosen word, then those letters are revealed. If they aren’t in the chosen word, the ‘hanged man’ is built — although these days we probably shouldn’t do that due to nasty historical context, and choose something else.
In our example, we’ve decided to reconstitute the Egyptian god Konshu (aka Khonsu) as a shameless reference to the Marvel TV show Moon Knight. Once Konshu is fully-reconstituted then he will block out the sun forever — we don’t want that! Another potential conceit could be a space portal being built by aliens which once complete will deliver an invading armada.
Whichever way you choose to present it, the mechanic is the same — once you run out of ‘misses’ the game is over.
- Computer chooses a word
- The number of ‘misses’ is specified
- We prompt the user for a selection
- We check to see if the letter is valid (hasn’t been picked before)
- We search through the target word looking for the letter
- If we find it, we reveal it by placing it into the ‘solution’
- We show the player if they’ve uncovered any letters or not
- If not, we add more on to Konshu (or the space portal, or what-have-you)
- We repeat until the target word is entirely revealed, or Konshu is built
Here are the ways in which Logo makes building this program simple:
- We can use the pick and english primitives to choose a word from the built-in dictionary
- We can use forever to repeat our game loop… forever!
- We can use question and answer to prompt for and receive input from the user
- We can queue the user’s selection into the list that logs the user’s choices
- We can use the boolean containsp to determine if the user’s choice has already been chosen, by passing it the user’s current choice and the list containing the users previous choices
- We can use count to ensure the user only provides a single letter as input
- We can use dountil to repeat the question until we get a valid answer
- We can use foreach to cycle through each letter of the selected word and check for matches.
- We can use a combination of setitem and loopcount to set the appropriate space in the ‘solution’ container to the guess, should it match. If we initially set the solution container to be a series of dashes, we can then check for dashes using containsp later, to see if we’ve completed the solution
- We can call another procedure to build our ‘hangman’, passing it the number of tries remaining, so we know which part of the hangman to build. We can use switch and case to build the relevant part of our hangman
- We can use decrement to decrease a counter by one, and use if to check to see if we are out of tries.
Because we have all of these tools at our disposal in Logo, the game logic does not occupy very many lines of code, and is nearly english-readable:
TO game reset hideturtle (print |You must determine the magic word required to banish Konshu back to the netherrealm.|) (print |If Konshu is able to reconstitute himself in this realm and awaken, he will banish the sun!|) ;instructions (in brackets for display purposes) make "attempts 10 ;this could be made more, or less make "target pick english 6 ;similarly, we could pick a different target word length make "solve "------ ;this container reflects correct player choices ;if we change the word length, we will need to change ;the number of dashes make "picks [] ;this holds the players choices so we can discount ;duplicate picks forever [ dountil (and not containsp answer :picks 1 = count answer ) [question |Pick letter:|] ;repeatedly ask which letter until the player enters only ;one letter, and it has not already been picked queue answer "picks ;add the selection to the :picks list make "hit false ;set the :hit boolean to false foreach "i :target [ ;for each letter in the :target word: if :i = answer [ ;if the letter matches the users choice setitem loopcount "solve answer ;update the appropriate character in the :solve ;container to reveal the matching letter make "hit true ;set the :hit boolean to true, so we don't ;advance the building of Konshu ] ] show :solve ;show the current state of the :solve container if not :hit [ ;if our selection wasn't in the answer: dec "attempts ;decrease the :attempts container by one konshu :attempts ;execute the konshu procedure, passing the ;number of remaining attempts to it (print |Attempts remaining:| :attempts) ;placing round brackets around a statement allows more ;parameters to be passed to it than its default ] if not containsp "- :solve [ ;if there are no dashes left in the :solve container: print |You have banished Konshu!| finish ] if :attempts = 0 [ ;if we've no attempts left: (print |The word was:| :target) print |Darkness descends.... forever!| finish ] ] END
See? That was pretty easy — it only took an hour to write that code! Then comes the building of our ‘hangman’ model:
TO konshu :attempts ;this procedure builds the relevant part of the Konshu ;model. switch "attempts ;switch takes a literal container name ;and then subsequent case statements execute ;based on the contents of that container: case 9 [ ;this is what we build if there are 9 tries remaining ] case 8 [ ;... ] ;etc... END
You simply put the code to create each stage of construction inside each case block. This could make a great project to tie language / string manipulation to game coding, with a bit of 3D artistry (putting the A in STEAM) in the mix.
Logo is such a powerful, easy-to-use language it can be hard to decide what makes the best introduction for your students. But you know them best, and we hope that one of our examples will work for them, and you!
Thanks for checking out this project!