Then we'll start writing the program so we'll start the game you'll validate your guesses to make sure users have typed incorrect sensible letters and then see whether the guesses are actually correct or not by marking them whether they exist in the hangman word we'll show a progress message on screen so the user can see how far they've gone and how far they have still to go and how many guesses they have left too and then we'll test for whether the game's actually been won or lost each time around the loop and finally we'll test the final program so i'll show you a bit about debugging.
Classes in the in this particular stage now at any point in your screen on most versions of this tutorial anyway an icon should appear at the top right and you should be able to click on that to see any files or exercises to do with this tutorial but i think that's enough for listening to me i'm going to hand over to sven now and he will guide you through the rest of this tutorial as always so let's get started.
You can't write a game of hangman until you understand the rules what i've got here is a file called hangmancomplete.py you can download this from our the webpage for this tutorial on our website and it gives you the complete code which we're going to work towards building over the course of this tutorial embedded within it on line 201 as it happens is instruction to begin a game of hangman the word i'm going to ask you to guess is ladder and i'll give you just five guesses there's no attempt to draw a scaffold we'll come to that point in a second and.
Also i'm not going to use code runner and again i'll explain why in a second but for the moment let's just run that so if i press ctrl f5 it tells me what i need to do i need to guess a six letter word and i can have up to five wrong guesses and it wishes me good luck so my first guess guess next letter is going to be a d and when i press return it's good news the letter d does appear it fills it in my word for me and maintains a list of all the letters i've guessed correctly so far and tells.
Me i've still got five of five guesses left i'm not feeling so lucky now i'm gonna go for a w i don't think there is one of those and if i press return you can see it tells me i've only got four or five guesses left going to continue to guess badly with a q and it's maintaining a list of all the guess letters i've guessed incorrectly as well and i can continue along this let's try an l there is one of those that fills it in for me.
I'll guess an r there's one of those and at this point it looks like i'm going to guess the letter guess a word rather but actually i'm not so i'm guessing loads of wrong letters here and when i eventually finish it tells me i've used up all my guesses and tells me what the word was and tells me commiserations in the title finally it gives me a message and this is an important point about the whole tutorial you can write classes in many different ways the code you're going to learn now is by.
No means the optimal way of writing hangman it's possibly a good optimal way to do it if you're teaching people through a tutorial on how to play hangman using classes in python but there's many different ways to skin a cat as they say in an old english expression and what you're about to see is just one of them so just before we begin thinking about classes i need to just set the scene there's three things i want to briefly.
Consider the user interface we're going to use which i think you'll probably agree was quite primitive we'll look at how you can display message boxes to make it a bit livelier and we'll look at why i'm not using code runner so to do that let's start with the first one the user interface i've included on our website the file tkin to example dot py and what i'm going to do is just run that program without further ado and when you do that what you'll see is it comes up with a dating agency form and you can type in your name so you.
Could type in sven about myself i am swedish and then i can choose ok and what it will do is display a quick summary of it now the point of showing you this is that if i was going to write a proper hangman game i would probably use a gui graphic user interface program like tkinter the reason i'm not doing that and i'm relying on doing everything at the command command prompt is because a i don't like tkinter i find it very cumbersome to use.
And b if we did this i would spend a lot a lot of time explaining how to draw the screen and what i want to do is concentrate on the classes so that's why i'm not using a glossy user interface now to make it slightly more interesting we're going to use message boxes so what i'm going to start by doing is copying lines 8 to 15. to a new file called hangman.py let's get rid of that and what this does is imports an external or.
Posts Related:
- What happened to OneNote
- How to Create Setup.exe in Visual Studio 2019 using VS Installer Projects
- A To Z Alphabet Logo Free Download In CDR Files Sheri Sk Corel Draw Tutorial Office
Internal rather modular built-in module called c-types and uses it to display a message if you want to find more about the message box - ID Card Make
Command in python you can go to the stack overflow article so to show you how this works what i could now do is display a message so i could type in show message and there's two arguments which are the text to be displayed so i think i'll say hello and the title which will be wise owl and if i run this very modest little program you can see it comes up and says hello owl hello brother.That will make it slightly more interesting i can keep having pop-up messages rather relying on using the terminal window all the time the third thing i was going to show is why i'm relying on not code runner but running using control f5 if i go back to my program here and try running it with control with code runner by pressing alt control n what he would do is take me to the output window and i wouldn't be able to type anything in there the input prompt so you can assume whenever i'm running this hangman program that i'm pressing ctrl f5 the equivalent to run python file.
I think you can see that when you choose run from the menu up here you can see there's two options i'm going to choose run without debugging all the time so it's important to remember to do that otherwise you won't be able to type things in in the terminal window so with all that preamble out the way let's look in more detail at our program i've chosen in my program to use an enumeration to make it clear what the possible choices are for a status of a guess and there are five choices i can think of you can guess correctly wrongly.
You can already guess something so you choose a letter which you've already previously guessed it could be an invalid guess so you either don't type anything in or you type in the string which is too long or perhaps it's not even a letter and it could not be set yet now to make it clearer to work with these possible values what i've done is created an enumeration so what i'm going to do is copy lines 17 to 25 from the complete example into my code i'll just get rid of that previous message and then to show you briefly how this.
Works i think you can possibly guess already i'm going to create a variable called status which i'll get rid of in a moment and i'll set it equal to guess status dot correct so what i can then do is test out the value of the status and say if it equals let's say if it's wrong then what i'll do is print out that that's wrong otherwise i'll print out that it's correct and you won't be surprised to know that.
When i run this program what it would do is display the word correct and that's because i set it to correct so it doesn't equal wrong to prove this works let's just change that to wrong with one w and if i run this this time it will give me the words wrong so the benefit of this is when you have a discrete finite set of possible values for a particular status for example an enumeration makes your coding much easier to clearer to read so i could have put status equals two.
For wrong and checked if that equals two but then i would have been forever trying to work out what i meant by this number two so that's enumerations the next stage in our programming process is to create an algorithm and in any program this is the most important thing what you need to be able to do is to understand the task you've been given to do and to be able to turn it into a set of instructions which aren't quite english but aren't quite python either.
Now how you do this is up to you some people do it all in their head some people have a sheet of paper which is my preference and they write down very messy instructions on what they're going to do the more experienced a programmer you are the less you'll need to use the sheet of paper because the more you kind of know where you're going to go anyway this is my algorithm for solving the problem and what i want you to do is think carefully as we go through whether you agree with it whether you buy into it and if so we'll try turning this into python so the first thing you'll do is to start.
A new game specifying the word to be guessed and how many let guesses you're allowed and then maybe show some instructions on how to proceed what we'll then do is keep asking for guesses until the game is won or lost so all of this code here all of that is going to be executed once for each guess that you make and it's only when you break out of that code you'll run the final bit of information or the final instruction to display a final message.
So within that loop what we're going to do is get the next letter to guess so that's where we'll display an input box
Or an input prompt and you're typing a letter you'll check if it's a valid guess i.e a single letter and if it's not just show an error message otherwise so by the time we get to this point here we know we've got a letter which we need to determine whether it's in the existing word or not and whether actually we've guessed it previously so what we'll do is try to guess out and get its status and there are three.Possibilities it's either correct or it's wrong or you've already guessed it previously if you haven't already guessed it what we'll do is display a message whether you've won or lost we need to test whether you've completed the word or whether you've just run out of guesses and you'll execute that each time around the loop if you've either won or lost the important thing is to break out of the loop without that instruction you'll just carry on leaping forever and finally by the time we get to this point we know we haven't won and we.
Haven't lost so we'll despair an update and the update has to be quite detailed it has to tell you what your last guess was whether it was correct or not it has to fill in though how many letters you've got in the current word with underscores or blanks for the missing letters it has to display the letters you've guessed correctly and the letters you've guessed incorrectly so far and how many guesses remain to you so that's my algorithm now please don't think that i wrote that down from scratch i didn't.
I started writing the code i realized many things it took me quite a long time to realize that a guess has actually got three status so it can be correct it can be wrong or it can be previously guessed that took me a while and basically i went down a lot of wrong turnings but i did start with a basic outline like this which i tried to implement okay to have flaws in the logic but i did start with it so what we're going to do now is to see if we can turn this pseudo code as it's.
Sometimes called into python now that we've got our algorithm and we know what we're trying to do the next stage is to identify which classes we can create before we begin can i just stress that there's no right answer to this there's lots of different ways of approaching this some answers are more elegant than others i'm not that satisfied with the one i've got but i never am i always think there could be a better way to achieve things with classes so the first obvious class to identify.
In our pro problem is again you'll start a game you'll stop again when it's won or when it's lost and each time in the game you'll offer up a different letter for consideration the second obvious class is a guess each time you have a guess it will consist of one or more letters hopefully just one letter and a status whether that was correct whether it was wrong whether it didn't actually exist as a letter in the alphabet and the third obvious class which we won't be considering is a scaffold so if we had a user interface we'd have to.
Find some way of maintaining the drawing of the scaffold which would involve adding shapes and seeing whether it was finished at any stage so we're going to focus on the first two classes and what i want to do now is to look at the attributes or properties of them so i'll divide this into two i'll show the ones i actually thought of when i was first designing the classes and then i'll talk about the ones i suddenly realized i needed as i was writing the program and that's always the way these things tend to go so for the game i began by thinking well we're definitely going to need the word to be guest which in our case was ladder.
And you also need to know how many guesses you're allowed and there are a couple of other properties i guessed from if you'll excuse the pump from the very beginning i realized you'd need a property saying whether the game had been won which you could get by uh looping over the number of letters which are unfulfilled seeing there are any left and also properties seeing whether the game has been lost which you could do by seeing if the number of wrong guesses equaled or exceeded the total number of guesses allowed and then i started programming and as i.
Was writing this program i realized we needed a few more so we needed to maintain a list of the correct guesses and a list of the wrong guesses actually it took me a very long time to realize this because initially i just had a list of all the guesses with the status for each and it took me a long time to realize it would be much much easier to program if i kept them in two separate lists we also need what the current guesses we're looking at we need how many guesses there are left at any point which will be what's called.
Sometimes called a derived property which we can calculate and i also found it useful to have a property giving the progress message to display so that's what comes up in the message box each time you make a guess turning our attention now to the guest itself this was easier it was fairly obvious that you need the letter being guest and you also need the status now that wasn't what i thought you needed when i first began i just had a boolean property saying whether the guess was correct or not.
But it turned out to be useful to determine whether the guest was a valid guess at all whether it had been set or not to be correct or incorrect so it turned out to be useful to store the status as an enumeration as we've seen so let's have a look in a bit more detail about the guest class let's suppose you guessed d first that is correct because it's in ladder and you get a q which isn't an x which isn't an e which is and a c which isn't each of those five things is an object based on the guest class.
So it has two things it has a letter you guessed and the status of it at the end so the guest class comprises two things the letter and the status you could then divide those into wrong and right guesses so you can take the first guess d which was correct and the second guess e which is correct and then create two or maintain two lists one is a list of the wrong guesses and the other is a list of the correct guesses and those are the two properties of the.
Game class which i mentioned much earlier on in this presentation and it turned out as i say to be useful to keep those two lists separate finally let's have a look at some methods so for the game class it turned out to be useful to have two methods one to actually make a guess and the second one to show or display on screen the current status message that's what appears once for each guest as a message box popping up on screen and for the.
Guest class what i had initially assumed is it would be useful to have a method to set the current status it turned out that it was more useful to have the status of a guess as a read write property so when you read it you determine if it's a valid guess and when you write it you just set a hidden argument or hidden attribute within the class itself that is such an important principle when.
Designing classes it's so often the case that you can do something by either applying a method to an object or by reading or writing a property and again i would stress there's no right answer to this in the end i went for a property because i felt it was more elegant solution it's time now to start playing our game i'm not going to attempt to type in the code i think this tutorial will go on way too long if i did that what i'll do is just copy the chunks in explaining each as i go along.
So the first thing we need to do start the game is to go to line 196 to 207 in the complete code and what i'm going to do is copy those in and paste them into my hangman example so this is a code to start playing a game what it would do is create a new object in the game class and define the word and the number of guesses allowed and it will create a variable called hangman to refer to that game so to get this to work i now need to.
Create that game class to do that i can click on the word press f12 to go to the definition of it and what i'm going to do is copy down not just the comment at the top and the document string but also the instantiation routine as well so if you're keeping track with the line numbers that's from 984 to 110. so i'll copy that in and i need to put that above because i can't refer to a class if i haven't yet defined it so let's have a look at this class and see what it's actually doing.
You need to pass in the self object as you always do with an initial instantiation or initialization routine the star there is saying a standard way of saying for any function that all the arguments which follow it have to be declared by name rather than just by position and that means when i'm creating the class or creating an object based on the class i need to specify the name of the argument as word and then number of guesses allowed and the reason i've done that is because i think it makes it clearer when i create a new hangman game if i actually name the arguments.
I then specify the two arguments the first one is the word to be guest and the second one is the number of guesses allowed what i then immediately have to do is to store those two bits of information within the class so that i can refer to them again so i re create two variables with coincidentally the same names to make it easier to read i guess and i do one more thing when i'm storing the word to be guest i take the opportunity to convert it to uppercase i don't really want to force my user to.
Type everything in an up or lowercase so this makes sure that everything i'm testing is always in capitals i then create three additional variables the first one for the game is a list of the correct guesses there aren't any the second one is a list of the incorrect guesses again there aren't any yet and finally i say which my current guess is so this is going to be a reference to a guess object it's going to say which guest i'm currently on and at the beginning i set that to none so what i should be able to do now is to.
Run this program so let's give it a go if i run that program it comes up with a message and then when i choose okay what will actually happen is the variable referring to the class will be no longer needed and at some stage something called the garbage collector will come along and free up the variable and release the memory it's taking up so it's time now to start guessing letters and so what i'm going to do is copy lines 208 218 copy them to the clipboard and paste them in after my i've started my game.
And what we're going to do now is to keep trying letters to do that we'll display an input box or an input problem saying guess the next letter and i've actually converted that into uppercase i think i might be doing this several times unnecessarily and then i create a new guess object based on this letter so we need to create the guest class in a second what i then do is have a look at the status of that new object and if it's an invalid guess then i'll display a message saying it must be a single letter i'm a bit worried when i test this i'll.
Create an infinite loop so what i'm going to do is put a break statement in to just make sure that when i test this it doesn't leap indefinitely i'll get rid of that at the end so now i need to create my guess class and again i'm going to go back to my original program click on the word guess and press f12 to go to the definition and what i can now do is to copy down the comments at the beginning the document string and the initialization routine i'll come back and get the property in a second.
So this needs to go above the game class i think and that's because the game class is going to refer to the guess so it's important to put things in the correct order because python's an interpreted language it basically just reads the instructions down from the top you can't refer to something until it's been declared so here's my guest class as always it takes in the self the current object to the first argument and the second is the letter being guessed letter is actually possibly a poor name.
For that variable because you might end up typing in a whole string of text it wouldn't it wouldn't work it wouldn't be passed as valid but it would be able to be validated at this stage what it then does is stores the letter being validated it converts that uppercase again i think i'm overdoing this and then it sets a hidden attribute a managed attribute called underscore guest status so this is something which is considered to be private to the class.
And in order to be able to set or get its value read or write its value we'll need to write some property a property decorator so let's do that now so going back to my class i'll select from lines 46 down all the way to 76. and i'll paste that in after my initialization routine for my class here and this will be what happens when i try to find out if a letter is valid or not so.
When i type in a letter in my code down here what it does is say is the status invalid or not that's reading the value of this property so what that will do if i press f12 in it is go to the get clause which i've created and it will run this code so what this code does is have a look at the managed attribute the hidden attribute called underscore guest status which don't forget initially will be set to not yet because that's what i.
Determined it should be initialized as and if it's not not set yet it just returns the current status the reason i put this in is because in subsequent calls to this property i'll already have determined what the status is of this particular guess so i don't really want to run through the code again so it just returns the current value so from this point onwards you can assume that you haven't yet determined whether it's a valid guess or not and this again is a very common uh code pattern you have a hidden attribute a managed.
Attribute which you initially set to none and then you check when you read the value the property whether you've actually previously set the value of that attribute and if you have you just return its value without further processing so what i can now do is say um if the letter or letters that the user typed into the cursor is none it means they just press return so it's definitely an invalid guess so i'll set that and just return that as the current status.