Holy grail hangman
A hangman that involves testing your Monty python Holy grail movie dialog skills
Context
When the time came to choose a programming language, I chose Python because the name was inspired by the inimitable Monty Python. As a Pythonist, I also used Monty Python as an inspiration when I wanted to learn the Python programming language. I started working on the (now paused) RPG based on the Monty Python holy grail movie project. I learned to play around with the pygame
module as well as a bit about the objected-oriented aspects of Python.
I had noted down a long time back that I wanted to use the contents from the remarkable website MontyPython.net in some application or the other. So when I saw a hangman game implementation in Python on the Kite Youtube channel, I immediately thought that I should build a hangman, but with a Monty Python theme.
This blog entry is the story of how that came about.
I wanted to say a Python Thesaurus, the word list that provides a pool for the game to pick words from. But, given that it would be silly to prepare a world list, I decided that it should be a quote list. The MontyPython.Net had the scripts, so all I needed now were web scraping tools. I chose BeautifulSoup
because I liked the name (you need to decide based on some condition).
I quickly realized that making sense of the quotes from the entire Monty Python content (several movies and several seasons of the show) would be daunting. So I decided to stick to the Holy Grail movie script. Another reason tied my hands too. I found it difficult to narrow down on the popular quotes (to avoid using every dialogue or description). This is when I noticed that the website admin had done something awesome: add audio clips to famous quotes, but only for the Holy Grail movie. So I decided to focus only on those quotes that have been given an audio file. I later added a few more quotes manually into the list generated, but, web scraping using BeautifulSoup did a great job. To make sure everything went smooth, I had to circumvent problems through some quirks, but overall, I got a nice set of quotes.
The sources used are as follows
sources = [requests.get('https://montypython.net/grailmm1.php').text,
requests.get('https://montypython.net/grailmm2.php').text,
requests.get('https://montypython.net/grailmm3.php').text]
The following code gets the quotes into a list.
monty_python_quotes = []
quote = None
for source in sources:
soup = BeautifulSoup(source, 'lxml')
for aa in soup.find_all('a'):
if 'href' in aa.attrs: #looking for only those which are hyperlinks
if '.wav' in aa.attrs['href']: # We are only looking for those quotes which have an associated sound file
if len(aa.contents) > 1:
quote = aa.contents[0]
else:
quote = aa.contents
if quote is None:
pass
else:
if isinstance(quote, list):
if isinstance(quote[0], bs4.element.NavigableString): # It was observed that all the valid quotes were of this type
if len(quote[0].split(' ')) > 1 : # To avoid single word quotes that were mostly useless.
monty_python_quotes.append(quote[0])
# There were several quotes that were duplicated.
# The following trick of converting the list into dictionary and back helped to remove them
monty_python_quotes = list(dict.fromkeys(monty_python_quotes))
So I created a series of black knight terminal avatar in the same way he loses limbs in the movie. One arm, then the next arm, one leg and then both legs.
def display_black_knight(state):
knight = [
"""
"You lost. I'm off to cross the bridge"
O
|
""",
"""
"You loose both your legs. I won't call it a draw"
_
| |
O
|
""",
"""
"A single-legged knight?"
_
| |
O
|
|
/
""",
"""
"Now you got no hands"
_
| |
O
|
|
/ \\
""",
"""
"Ouch! You lose your sword hand"
_
| |
O
|\\
|
/ \\
""",
"""
"You are the Black knight"
_
| |
O
\\/|\\
|
/ \\
"""
]
return knight[state]
Awesome, isn't it? Well, at least I feel so. And I also added quotes on top.
The game provides the player with 5 guesses (if one feels an expert, they can go for the expert model with 3 chances). You can get the rest of the code here in the github repository.
And below is the case when I go through all stages of the black knight state and lose:
And here I win.
Final Remarks
I took some time to write this blog entry because I hoped to finish an ipython-widget-based version of the game (hence everyone can play the game using binder). But it got stuck in some technicalities (and I still have to figure out if everything I want to do will work well with the widgets). So until I get that up and running, you have no other choice but to download the code from the repository and play the game.
Have fun.