WEBVTT 1 00:00:01.580 --> 00:00:05.100 so just before we start a challenge there's one little bugs that I want to fix 2 00:00:05.100 --> 00:00:08.490 and I just want to run it again and show you what the bug was and you probably picked this up 3 00:00:08.490 --> 00:00:15.030 in the last video so when we first start the dealer 4 00:00:15.030 --> 00:00:19.990 score is showing 0 obviously the player scores working and the reason that's doing that 5 00:00:19.990 --> 00:00:25.330 if you closes this down and on the code on the bottom we've got the deal player 6 00:00:25.330 --> 00:00:30.410 we call the deal_player function and we actually add the card to the 7 00:00:30.410 --> 00:00:35.010 dealer hand and notice we are not calling a function to print it to display anything 8 00:00:35.010 --> 00:00:40.410 or anything along those lines whereas the deal_player function is sort of 9 00:00:40.410 --> 00:00:43.230 self-contained and also outputs the actual 10 00:00:43.230 --> 00:00:47.360 scores as well on the screen so what we want to do is make quick changes there 11 00:00:47.360 --> 00:00:58.750 to actually show this score so its gonna be dealer..... 12 00:00:58.750 --> 00:01:06.010 ...so basically we are just going to display that's score so we've drawn a 13 00:01:06.010 --> 00:01:09.500 card and we are going to show that on the screen once and then obviously 14 00:01:09.500 --> 00:01:13.090 subsequent times its going to work automatically when we click the dealer 15 00:01:13.090 --> 00:01:17.130 button so if we run again now that should fix that so we got an 16 00:01:17.130 --> 00:01:23.560 initial score and you can see its better now we got it working even 17 00:01:23.560 --> 00:01:27.820 though the functions still work in that once we pressed deal it is still going 18 00:01:27.820 --> 00:01:31.880 to calculate this is a better way of actually showing and obviously I got 19 00:01:31.880 --> 00:01:39.100 slaughtered by dealer ok so that's working so talking a little bit about the challenge 20 00:01:39.100 --> 00:01:44.240 its is going to be quite simple because just looking at where we're at with the game now it 21 00:01:44.240 --> 00:01:48.340 plays a reasonably good game of blackjack and all the dealing is now taking 22 00:01:48.340 --> 00:01:54.190 care of by the computer so we only need to click on dealer once we are finish with our turn and the 23 00:01:54.190 --> 00:01:56.550 rest of the game finishes and the deal 24 00:01:56.550 --> 00:02:01.200 function deal_dealer function sort of handles that functionality to play the 25 00:02:01.200 --> 00:02:03.560 game as far as a computer the is concern 26 00:02:03.560 --> 00:02:06.710 their is a bit of annoying though which you see me to do having to close the window and run the 27 00:02:06.710 --> 00:02:10.580 program again for a new game and I mentioned in the last video it's time 28 00:02:10.580 --> 00:02:12.360 for a challenge so 29 00:02:12.360 --> 00:02:16.300 just before I do that one final comment about global variables you probably sick about 30 00:02:16.300 --> 00:02:19.450 it now but we are harping on about it because it's really important that you 31 00:02:19.450 --> 00:02:26.050 understand this and get it to the right mind set about how to use them so you are aware of the 32 00:02:26.050 --> 00:02:30.530 limitations you might be wondering why the variables player_hand 33 00:02:30.530 --> 00:02:34.990 and dealer_hand are not triggering warnings about a local variable shadowing 34 00:02:34.990 --> 00:02:38.720 the global ones because both the deal_player function if we go back and 35 00:02:38.720 --> 00:02:45.700 have a look at that as you can see the deal_player function on line 78 and 36 00:02:45.700 --> 00:02:50.170 the deal_dealer function on line 64 they are both appending new 37 00:02:50.170 --> 00:02:54.459 cards to the corresponding list so wouldn't that count as modifying the 38 00:02:54.459 --> 00:02:57.940 global variable in which make them local because we talked about that in previous 39 00:02:57.940 --> 00:02:59.260 videos 40 00:02:59.260 --> 00:03:05.020 well the answer is that neither variable is modified their initialized as lists 41 00:03:05.020 --> 00:03:08.130 if you go down and have a look 42 00:03:08.130 --> 00:03:15.010 we got player_hand and dealer_hand is initialization as you can see here in 43 00:03:15.010 --> 00:03:22.049 line 152 and 153 and continue to reference the same lists as long as the program 44 00:03:22.049 --> 00:03:26.830 runs so adding items to list or removing items from it is not modifying the list 45 00:03:26.830 --> 00:03:31.150 variable it always has the same value which is a list and the contents of a list 46 00:03:31.150 --> 00:03:36.340 can change now adding items to a global list is still a side effect but its not 47 00:03:36.340 --> 00:03:41.049 considered as dangerous as changing the list of the variable holds for example 48 00:03:41.049 --> 00:03:46.360 lists exists to have items added and removed and so consequently this is 49 00:03:46.360 --> 00:03:49.470 acceptable behavior and that's why IntelliJ is not actually warning of us 50 00:03:49.470 --> 00:03:53.890 of that so it would still probably better to pass the lists arguments to the 51 00:03:53.890 --> 00:03:58.700 functions but as we can't provide parameters to functions that are used as button 52 00:03:58.700 --> 00:04:02.410 commands we really don't have any choice here but to use global list so that of 53 00:04:02.410 --> 00:04:07.890 course why we went ahead and did that ok so moving on now the challenge and its going to be 54 00:04:07.890 --> 00:04:11.989 quite a simple one the challenges is to add a new button to the program with the 55 00:04:11.989 --> 00:04:16.930 text new game now the button should call a function that clears the cards from the 56 00:04:16.930 --> 00:04:22.590 screen it resets the players and dealers hands and then starts a new game now the 57 00:04:22.590 --> 00:04:24.360 easiest way to clear the contents of a 58 00:04:24.360 --> 00:04:29.270 frame is to destroy the frame and create a new one with the same name and in fact 59 00:04:29.270 --> 00:04:34.210 that's why the program has a player_card_frame and dealer_card_frame 60 00:04:34.210 --> 00:04:40.199 inside the card frame itself so that's it go away and create a 61 00:04:40.199 --> 00:04:44.990 new button with the text new game and again the functionality clear the cards 62 00:04:44.990 --> 00:04:48.629 from the Screen reset the player and dealers hands and then start a new game so 63 00:04:48.629 --> 00:04:54.939 pause the video go away and see if you can come up with a solution and when you're ready to see 64 00:04:54.939 --> 00:04:58.529 our version of it come back and and I'll go through that with you pause the video now..... 65 00:05:03.080 --> 00:05:04.480 ...ok so hopefully you 66 00:05:04.480 --> 00:05:09.240 managed to figure it out and have a pretty good going getting it working so let's go through 67 00:05:09.240 --> 00:05:14.360 what our solution is to implement this and what we're going to do is create a new 68 00:05:14.360 --> 00:05:20.470 function called new_game now the thing to remember here is the most of the initialization code in 69 00:05:20.470 --> 00:05:24.540 the main program concern setting up the GUI and so consequently we don't need to 70 00:05:24.540 --> 00:05:29.130 repeat all of that every time a new game started but the deal_card_frame 71 00:05:29.130 --> 00:05:34.930 and player_card_frame will need to be cleared so 72 00:05:34.930 --> 00:05:38.870 calling the destroy method will do that and once that is done the list holding 73 00:05:38.870 --> 00:05:44.330 the hands rather will need to be cleared and the first 3 cards dealt and we can also make 74 00:05:44.330 --> 00:05:47.160 a start on that now so let's do that so I'm going to come down here after 75 00:05:47.160 --> 00:05:58.240 deal_player lets add the method so....and so 76 00:05:58.240 --> 00:06:02.950 we need to reference those global variables.... 77 00:06:02.950 --> 00:06:21.810 .... 78 00:06:21.810 --> 00:06:28.710 ....ok so 79 00:06:28.710 --> 00:06:35.340 first thing we want to do is.... 80 00:06:36.170 --> 00:06:50.350 ..... 81 00:06:51.010 --> 00:06:59.140 .... 82 00:06:59.870 --> 00:07:26.900 .... 83 00:07:26.900 --> 00:07:35.870 .....and what I could have done just scrolling down 84 00:07:35.870 --> 00:07:55.150 is just grab this code again....because its an identical code and obviously I could have done it as well for the dealer frame next we 85 00:07:55.150 --> 00:08:00.350 clear the status of the game at the top wether dealer wins or the player wins so.... 86 00:08:00.350 --> 00:08:07.050 ..need to recreate the lists 87 00:08:07.050 --> 00:08:15.430 and what we can do their I can come down here and just copy this code 88 00:08:15.430 --> 00:08:24.600 copy that and come back up here and paste it in.... 89 00:08:27.800 --> 00:08:41.880 ...ok so obviously we've cleared the player hands and dealer hands now and we 90 00:08:41.880 --> 00:08:47.709 deal a new card and we will see also deal a new card for the dealer and another 91 00:08:47.709 --> 00:08:52.420 card for the player again as we've done previously and obviously because looking 92 00:08:52.420 --> 00:08:56.810 at the code we also need to declare that we want to use the global objects rather 93 00:08:56.810 --> 00:09:02.560 than creating local variables and that's why we used to global key word on line 94 00:09:02.560 --> 00:09:08.160 88 to 91 now on Python 3 the 2 lists holding the hands could be cleared 95 00:09:08.160 --> 00:09:13.040 using their .clear method and that just removes all the items for them but it doesn't create 96 00:09:13.040 --> 00:09:16.680 a new list so we could access to global variables without declaring them in the 97 00:09:16.680 --> 00:09:21.240 function however we've also written blackjack to work with Python 2 so instead 98 00:09:21.240 --> 00:09:25.610 of that approach what we've done is we assigned empty lists to the two variables you can see on 99 00:09:25.610 --> 00:09:30.290 line 103 and 104 and that means they do have to be declared s global and the function 100 00:09:30.290 --> 00:09:35.200 for that to actually work now creating the button itself is pretty easy we 101 00:09:35.200 --> 00:09:39.120 already have a frame in place so let's add that down below the initial 102 00:09:39.120 --> 00:09:57.470 initialization code so.... 103 00:09:57.470 --> 00:10:00.540 ... 104 00:10:03.660 --> 00:10:08.480 ....making sure we don't use the brackets because we don't want 105 00:10:08.480 --> 00:10:13.220 to execute that we just saying this is the function to call anytime the buttons clicked we are 106 00:10:13.220 --> 00:10:24.640 just gonna call that functionality then need to add it to the grid so..... 107 00:10:24.640 --> 00:10:28.420 .... 108 00:10:28.420 --> 00:10:32.790 so that has added the button and just the other thing we can take because you've notice we've got a lot 109 00:10:32.790 --> 00:10:39.750 of code their that's being used so we can actually call this new_game function if I 110 00:10:39.750 --> 00:10:45.100 just scroll down I neet to put some of this back so I'm going to copy 111 00:10:45.100 --> 00:10:55.460 this bit of code here so we need to create those variables initially down here and once 112 00:10:55.460 --> 00:11:04.920 you've done that we can actually call the new game functions so I'm gonna do that so.... 113 00:11:04.920 --> 00:11:07.870 and what we're trying to do is avoid duplication of code because we had the 114 00:11:07.870 --> 00:11:12.520 code here that we have originally placed in there and so basically at the start 115 00:11:12.520 --> 00:11:16.170 of the game we can go through and just actually run this and we have got 116 00:11:16.170 --> 00:11:20.270 a frame we are actually technically destroying a frame and created it 117 00:11:20.270 --> 00:11:24.540 creating it again but have what we are doing is we are avoiding this duplication 118 00:11:24.540 --> 00:11:29.690 of the code and not running it I should say sort of in two places so the Idea is to put the 119 00:11:29.690 --> 00:11:39.400 code and only executed it only once so lets try running that and see whether it works... 120 00:11:39.400 --> 00:11:45.230 ....and so far so good we've now got another button for a 121 00:11:45.230 --> 00:11:50.180 new game and players 14 so I'm going to click on play another 122 00:11:50.180 --> 00:11:55.720 card I should say so hit me and I busted the dealer wins and now I click 123 00:11:55.720 --> 00:12:01.550 new game starting again thats work and strait away I obviously got blackjack which 124 00:12:01.550 --> 00:12:07.420 is a good thing so I'm going to click on dealer and I win because the player the dealer 125 00:12:07.420 --> 00:12:08.520 busted 126 00:12:08.520 --> 00:12:11.630 click on new game and click on play 127 00:12:12.590 --> 00:12:14.800 and I got 21 again I'm having a great run here 128 00:12:14.800 --> 00:12:21.560 and the dealer busts so click on new game again I've got 18 so I'm gonna just gonna hold 129 00:12:21.560 --> 00:12:27.800 that and I win again and lets just see whether we get the dealer to win so click on 130 00:12:27.800 --> 00:12:29.260 dealer 131 00:12:29.260 --> 00:12:33.459 the dealer is having a bad run their new game 132 00:12:33.459 --> 00:12:39.350 dealer again we got a draw this time so I talked about that in the previous video wanting 133 00:12:39.350 --> 00:12:44.579 to get it draw so we got that work new game I'm going to click on dealer again and 134 00:12:44.579 --> 00:12:49.260 lets see if we can get the dealer to win the dealer has a bad run with cards new game I'm 135 00:12:49.260 --> 00:12:54.899 going to click on dealer again and finally we get the dealer to win so that's working well 136 00:12:54.899 --> 00:12:58.470 but we are gonna have a problem with this and if we keep playing you should 137 00:12:58.470 --> 00:13:02.880 eventually get an error so I will see if I can do a few more games and you think what I'm doing this what 138 00:13:02.880 --> 00:13:12.029 that error will be It might take a few more games for us to see it their we go we got it to actually crash so why 139 00:13:12.029 --> 00:13:17.130 is it crashed well the reason it crashed is that we ran out of cards their is no 140 00:13:17.130 --> 00:13:22.060 more cards remember we have we created the deck of cards initially and we're not 141 00:13:22.060 --> 00:13:26.770 refreshing those and we're not you know once we reach the end the deck we are not 142 00:13:26.770 --> 00:13:30.480 reinitializing that again and that is why it crashed now theirs 143 00:13:30.480 --> 00:13:34.970 many ways to solve this but the obvious one would be to create a new deck 144 00:13:34.970 --> 00:13:41.180 list every time a new game has started by just copying the two lines and 145 00:13:41.180 --> 00:13:48.839 in other words if I just shut this down so the two lines and actually that turn out to be in the 146 00:13:48.839 --> 00:13:53.740 wrong place so the shuttle should bee in strait after the deck when we 147 00:13:53.740 --> 00:13:57.100 created it for the first time so what that actually meant was that we didn't 148 00:13:57.100 --> 00:14:02.410 execute the very first time the game is played the shuffling of the decks so that was 149 00:14:02.410 --> 00:14:06.730 my mistake putting that in the wrong place but what we could do the obvious approach 150 00:14:06.730 --> 00:14:12.699 would be to every time we create a new game we basically execute these two 151 00:14:12.699 --> 00:14:16.529 lines of code create a new deck of cards and shuffle them so that each game 152 00:14:16.529 --> 00:14:22.500 literally like a standard game of blackjack with a new deck so that would be one way we can 153 00:14:22.500 --> 00:14:26.940 actually put that code in the new_game function but we're gonna take 154 00:14:26.940 --> 00:14:27.910 a slightly different approach here 155 00:14:27.910 --> 00:14:32.220 so what we gonna do is every time a new card is dealt it is going to be put back 156 00:14:32.220 --> 00:14:36.130 at the bottom of the deck in other words you just reusing the same deck 157 00:14:36.130 --> 00:14:40.520 continually so in Python terms the object is going to be appended back to the list so 158 00:14:40.520 --> 00:14:49.700 we want to do that in the deal_card frame and come back and have a look and you can see on line 159 00:14:49.700 --> 00:14:57.980 35 were actually popping that so what we now need to do is before we display it.... 160 00:14:57.980 --> 00:15:06.160 ...so we added it back again so..... 161 00:15:06.160 --> 00:15:10.930 .....so that should be all 162 00:15:10.930 --> 00:15:15.510 we need to do so this is actually more realistic because it's like a real 163 00:15:15.510 --> 00:15:19.070 game and that's because when normally play a game of blackjack you don't 164 00:15:19.070 --> 00:15:22.960 start with the a brand new deck for every single game do you just sort of just 165 00:15:22.960 --> 00:15:27.360 keep using the same deck and that is what we are doing here essentially now there's many 166 00:15:27.360 --> 00:15:32.930 other improvements you could make to the game if a new deck is not created for each new game 167 00:15:32.930 --> 00:15:37.390 and the game could have an option to shuffle and let's add that as well so you can 168 00:15:37.390 --> 00:15:42.440 randomly click on a button and have it do a shuttle for us to do that we can come down 169 00:15:42.440 --> 00:15:45.980 to the end where we actually added the new game button 170 00:15:45.980 --> 00:15:54.720 we're going to add a shuffle button so.... 171 00:15:54.720 --> 00:16:01.520 .... 172 00:16:05.150 --> 00:16:11.820 .... 173 00:16:11.820 --> 00:16:22.830 ...and we now need 174 00:16:22.830 --> 00:16:26.630 to write this function and the functions is just going to shuffle so what I'm going to do there is 175 00:16:26.630 --> 00:16:31.270 take that line out as well and call this function so.... 176 00:16:32.920 --> 00:16:36.000 even thought we haven't written it yet we're gonna go ahead ad write that now so gonna come up to 177 00:16:36.000 --> 00:16:47.280 the last method up here and...... 178 00:16:47.280 --> 00:16:53.170 ...and that should stopped those errors from showing up now we are calling the shuttle function 179 00:16:53.170 --> 00:16:58.230 and the command shuffle is now working alright so let's run that and just make sure 180 00:16:58.230 --> 00:17:01.230 that it is working 181 00:17:02.810 --> 00:17:05.830 ok we now got a shuffle button so just click on shuffle 182 00:17:07.670 --> 00:17:11.600 we are not getting any indication that's working but it's also not crashing which is good so let's 183 00:17:11.600 --> 00:17:17.200 have the dealer win but the dealer lost and that's probably 184 00:17:17.200 --> 00:17:19.990 something you can also look at changing you notice what happened there is the 185 00:17:19.990 --> 00:17:25.200 dealer actually had 15 but I continue to draw another card and that's because our 186 00:17:25.200 --> 00:17:30.740 code had the logic that while the score was 17 or less well less than 17 its going 187 00:17:30.740 --> 00:17:34.240 to try and draw another card so what it should probably be doing is each time its drawing a 188 00:17:34.240 --> 00:17:37.630 card its also checking to see whether it's one or not that will be another enhancement you 189 00:17:37.630 --> 00:17:48.260 can look at making to the game click on new game and click on dealer again 19 so the dealer won and click on shuffle on obviously I click on new game 190 00:17:48.260 --> 00:17:53.450 that's good that's all working nicely and perhaps one other final thing you could do is you 191 00:17:53.450 --> 00:17:58.750 could add a score how many games each player's won and display the tally at the 192 00:17:58.750 --> 00:18:03.240 top of the screen so have a go at modifying the game or to add that functionality that 193 00:18:03.240 --> 00:18:08.140 will be a nice enhancement you can make and perhaps let us know how you went about doing it and 194 00:18:08.140 --> 00:18:09.920 maybe even show us the code 195 00:18:09.920 --> 00:18:14.180 and also perhaps look at some other features that feature that I just mentioned 196 00:18:14.180 --> 00:18:17.280 there with the dealer when its going to draw a new cards it's already 197 00:18:17.280 --> 00:18:21.060 won it shouldn't be drawing another card as you saw do that because ultimately lost 198 00:18:21.060 --> 00:18:26.720 because it didn't check the status to see whether it won and I'm gonna finish the video here 199 00:18:26.720 --> 00:18:30.320 now because its getting very long but their is one last final mini challenge and that's what 200 00:18:30.320 --> 00:18:34.970 would be how would you change the program to play the game with several 201 00:18:34.970 --> 00:18:38.450 packs of cards in other words just assuming your adding 2 or 3 202 00:18:38.450 --> 00:18:42.470 packs of cards and you got one deck that contains two or three packs how would 203 00:18:42.470 --> 00:18:47.460 you actually do that so if you can figure that out right now and pause the video and 204 00:18:47.460 --> 00:18:50.470 I'll come back to me when you come back I'll show you quickly how to do that 205 00:18:50.470 --> 00:18:53.470 so pause the video now 206 00:18:54.190 --> 00:18:55.180 ...ok so the 207 00:18:55.180 --> 00:19:01.060 solution to that the moment you can see here on line 166 deck = list cards 208 00:19:01.060 --> 00:19:10.220 that's one deck of cards so we could simply just put..... 209 00:19:10.220 --> 00:19:15.320 and effectively you've got three packs of cards now that are being put into our 210 00:19:15.320 --> 00:19:16.590 overall deck 211 00:19:16.590 --> 00:19:19.720 and we're still calling the shuffle which will go through quite happily shuffle 212 00:19:19.720 --> 00:19:26.980 that entire deck which now contains the three packs as I mentioned and looking at that the game 213 00:19:26.980 --> 00:19:30.530 functions like it would before so that's it I'm gonna finish the video 214 00:19:30.530 --> 00:19:36.540 here and we'll move on now to more in the way of modules I'm gonna be talking about 215 00:19:36.540 --> 00:19:40.370 using your program itself as a module so see you in the next video