1
00:00:00,150 --> 00:00:00,750
So far,

2
00:00:00,750 --> 00:00:05,750
we've managed to get our starting segments for our snake to appear on screen.

3
00:00:06,630 --> 00:00:11,630
And then we managed to get our snake to automatically move forwards and to

4
00:00:12,930 --> 00:00:17,930
figure out a way for the tail of the snake to follow where the head is going.

5
00:00:18,750 --> 00:00:23,750
Now it's time to tidy up our code a little bit so that all the parts that are

6
00:00:24,390 --> 00:00:29,390
related to the snake's behavior and the snake's appearance go into a separate

7
00:00:30,090 --> 00:00:33,300
class. So that by the end of the whole project,

8
00:00:33,330 --> 00:00:37,410
we should end up with three classes; a snake class, a food class,

9
00:00:37,500 --> 00:00:41,130
and a scoreboard. And all of these classes will be in separate files,

10
00:00:41,370 --> 00:00:43,170
managing only one thing.

11
00:00:43,650 --> 00:00:48,150
And the goal of the refactoring is so that you could create a separate file,

12
00:00:48,150 --> 00:00:52,860
snake.py, import the snake class that you've created in that file.

13
00:00:53,430 --> 00:00:55,500
And then once you initialize this snake,

14
00:00:55,560 --> 00:01:00,330
it will do everything that we have so far and create our three segments snake

15
00:01:00,600 --> 00:01:04,890
onto the screen. And then finally, while the game loop is running,

16
00:01:05,129 --> 00:01:10,110
we're going to get the snake to continuously move forward just by calling snake

17
00:01:10,140 --> 00:01:13,140
.move. This is what you're aiming for.

18
00:01:14,310 --> 00:01:17,910
Have a think about how you can take the existing code that you've got in the

19
00:01:17,910 --> 00:01:22,910
main.py and extract all of the snake related functionality into a separate

20
00:01:23,610 --> 00:01:28,230
snake class and make your main.py end up looking like this.

21
00:01:28,740 --> 00:01:31,860
The program should do the exact same things as before.

22
00:01:32,160 --> 00:01:36,450
The only difference is how the code is organized. Have a think about this.

23
00:01:36,660 --> 00:01:39,810
You might need to revise some of the things you learned about how to create

24
00:01:39,810 --> 00:01:43,860
classes, how to create objects from the previous lessons.

25
00:01:44,010 --> 00:01:45,060
But pause the video,

26
00:01:45,330 --> 00:01:49,230
I want you to give this a good try before you come back when we'll go through

27
00:01:49,230 --> 00:01:50,250
the solution together.

28
00:01:53,960 --> 00:01:54,380
Alright.

29
00:01:54,380 --> 00:01:57,020
So the first thing we need to do is of course,

30
00:01:57,050 --> 00:02:02,050
to create our snake class. And remember that in Python, class names are in Pascal

31
00:02:03,350 --> 00:02:06,470
case, so the first letter needs to be capitalized.

32
00:02:07,070 --> 00:02:10,280
And then inside this class, I'm going to create my init.

33
00:02:11,000 --> 00:02:15,590
Now the code in here is going to determine what should happen when we initialize

34
00:02:15,620 --> 00:02:19,250
a new snake object. So firstly,

35
00:02:19,310 --> 00:02:24,310
I'm going to take the starting positions and take it over to our snake.py.

36
00:02:25,460 --> 00:02:29,960
Now, I'm actually going to put this in as a constant. So right at the top,

37
00:02:30,350 --> 00:02:32,150
and remember that in Python,

38
00:02:32,480 --> 00:02:36,380
the constants are named with all caps like this,

39
00:02:36,530 --> 00:02:40,550
and also with snake case with underscores separating each of the words.

40
00:02:41,000 --> 00:02:46,000
Now we can use these starting positions inside our snake class to create our new

41
00:02:47,430 --> 00:02:51,410
snake. So we're going to need to move our segments over as well.

42
00:02:51,830 --> 00:02:55,850
So let's create a new attribute that's associated with our snake class called

43
00:02:55,850 --> 00:02:57,650
segments. And remember,

44
00:02:57,650 --> 00:03:01,120
we're going to need to use self when we're working within a class.

45
00:03:02,020 --> 00:03:05,290
After that, we're going to create our snake.

46
00:03:05,620 --> 00:03:10,210
So I'm going to create a method called create_snake down here.

47
00:03:13,350 --> 00:03:18,350
And this method is going to do everything that we previously had over here,

48
00:03:19,680 --> 00:03:22,320
but we're going to move that into this method.

49
00:03:22,740 --> 00:03:25,230
Now there's a couple of things we need to change. Firstly,

50
00:03:25,230 --> 00:03:28,260
we change these starting positions into a constant,

51
00:03:28,560 --> 00:03:30,270
so let's make that consistent.

52
00:03:30,750 --> 00:03:35,700
Second thing is that we need to import turtle into this file from the turtle

53
00:03:35,700 --> 00:03:39,720
module in order to use it to create a new segment.

54
00:03:40,350 --> 00:03:44,640
And then finally, in order to refer to our attribute segments,

55
00:03:44,730 --> 00:03:49,730
we have to say self.segments and then append this new segment to our snake

56
00:03:51,030 --> 00:03:53,610
segments. That's this part done.

57
00:03:53,910 --> 00:03:58,910
The next thing we need to do is to get rid of this code and move it inside the

58
00:04:00,480 --> 00:04:02,010
snake. So again,

59
00:04:02,040 --> 00:04:06,780
I'm going to create another method that's associated with the snake class called

60
00:04:06,810 --> 00:04:09,600
move. So when the snake moves,

61
00:04:09,660 --> 00:04:14,660
it's going to look to this code to figure out how it should do that. Again,

62
00:04:15,090 --> 00:04:18,510
because we're inside our class, it's no longer just segments.

63
00:04:18,779 --> 00:04:21,029
It's now self.segments.

64
00:04:21,510 --> 00:04:25,500
So let's go ahead and replace it in all the places where we have our red

65
00:04:25,530 --> 00:04:29,220
underlines and now that's pretty much it for our snake class.

66
00:04:29,520 --> 00:04:33,780
We can create a new snake object and each time we do that,

67
00:04:33,930 --> 00:04:38,930
it creates a three-segment snake using the starting positions

68
00:04:39,600 --> 00:04:44,490
which are declared at the top. So if we want the snake to show up on screen,

69
00:04:44,760 --> 00:04:49,260
then we're going to have to first import the snake class from the snake file,

70
00:04:49,800 --> 00:04:54,800
and then we're going to create a new snake object from that class.

71
00:04:55,830 --> 00:05:00,060
And once this line gets triggered, then we're going to be calling

72
00:05:00,060 --> 00:05:04,800
create_snake and our three-segment snake will show up on screen like this.

73
00:05:05,610 --> 00:05:08,490
Now the next step is while the game is on,

74
00:05:08,670 --> 00:05:12,780
the screen is going to update every 0.1 second.

75
00:05:13,080 --> 00:05:15,000
So that's essentially what this is doing.

76
00:05:15,030 --> 00:05:19,620
It's saying that delay for 0.1 second and then refresh the screen.

77
00:05:20,250 --> 00:05:22,530
And every time the screen refreshes,

78
00:05:22,770 --> 00:05:26,640
we're going to get the snake to move forwards by one step.

79
00:05:27,120 --> 00:05:31,410
Now at the moment, each step is defined here as 20.

80
00:05:31,830 --> 00:05:36,270
So again, I want to extract that into a constant up here,

81
00:05:36,630 --> 00:05:39,450
so we're going to call it the MOVE_DISTANCE

82
00:05:40,950 --> 00:05:45,950
and we can set that to 20 and then change this to use the constant here.

83
00:05:47,430 --> 00:05:51,600
And the reason why we have all these constants is so that if we wanted to tweak

84
00:05:51,600 --> 00:05:52,240
our game,

85
00:05:52,240 --> 00:05:56,940
say if we wanted the snake to start at a different position or for it to move

86
00:05:56,990 --> 00:06:01,250
further each time, then we don't have to dig through the body of our code.

87
00:06:01,430 --> 00:06:03,290
All we have to do is look at the top,

88
00:06:03,320 --> 00:06:06,680
look at all the things that we can change and then change it accordingly.

89
00:06:07,160 --> 00:06:10,100
So now coming back to our code here,

90
00:06:10,490 --> 00:06:15,490
all we now really have here is just these few lines of code and everything that

91
00:06:15,830 --> 00:06:17,360
is snake related,

92
00:06:17,390 --> 00:06:22,390
creating the snake or moving the snake is now abstracted into it's own class.

93
00:06:24,350 --> 00:06:26,690
This way when something goes wrong with our snake,

94
00:06:26,780 --> 00:06:30,470
we know who's responsible and which file to dig through

95
00:06:30,470 --> 00:06:33,380
to figure out the reason. Now, at this point,

96
00:06:33,380 --> 00:06:35,900
if we go ahead and rerun our code,

97
00:06:36,260 --> 00:06:39,710
you can see that our program works exactly the same as before.

98
00:06:39,740 --> 00:06:43,820
Nothing should have changed and nothing should have broken ow because our game

99
00:06:43,820 --> 00:06:46,550
isn't yet able to go into the game over sequence,

100
00:06:46,760 --> 00:06:50,150
there's no way of stopping the snake other than hitting the stop button.

101
00:06:50,450 --> 00:06:53,420
So don't worry if at this stage inside your console

102
00:06:53,450 --> 00:06:57,020
you see a lot of red and it says things like keyboard interrupt,

103
00:06:57,020 --> 00:07:00,050
or trace back errors. All of these are normal.

104
00:07:00,380 --> 00:07:04,520
The thing that you're more concerned about is whether if, when you run the game,

105
00:07:04,700 --> 00:07:07,430
whether if it actually works like it used to,

106
00:07:07,460 --> 00:07:10,220
so namely your snake moving across the screen.

107
00:07:10,760 --> 00:07:15,760
If it does exactly what it used to and your main.py is now much simpler and

108
00:07:17,180 --> 00:07:22,040
all of your snake functionality and behavior and appearance is now inside its

109
00:07:22,040 --> 00:07:26,060
own class, then you have successfully achieved the goal of this lesson.

