Placeholder Image

Subtitles section Play video

  • All right.

  • Hello, world.

  • This is CS Moody Live.

  • My name is Colton Ogden.

  • In case you're tuning in and you're not sure what sees 50 is CS 50 is Harvard's Internet computer science, taught by David Malin, and this is sort of offshoot livestream format.

  • But if you'd like a more traditional introduction of computer science, as taught here at Harvard University, definitely check out our YouTube channel youtube dot com slash CS 50 where you might actually watching this video now and check out David's lecture series.

  • We do a lecture series every year, but check out the latest one or go back in time if you want to see some of the earlier P sets and other lectures that we did.

  • But anyways, this is a separate sort of Siri's from that.

  • This is where we do live programming, and we talk about technology and do all sorts of other things.

  • And today in particular, is part three of a Siri's that we've done recently on a game called 2048 which is a sliding tile game on, and we're implementing this in Lewis and Love to D and so shot it's all the people that live in the chat there.

  • Bella cares.

  • Job on three.

  • I saw a few other folks beforehand, but I think the twitch chat it got refresh because I brought it up.

  • Pop out money, but say hi.

  • If I didn't shut your name and I will say hi back.

  • I'm gonna switch over to my laptop screen here.

  • Like this.

  • Um, and interestingly, it is.

  • Wait, why is it showing up like that?

  • That is weird.

  • It is an outdated screen for some reason.

  • Unless I am.

  • Unless I'm just tripping out.

  • Oh, is it set to a second monitor?

  • That might be it.

  • Hold on one second.

  • Let me just confirm that that is indeed the case displays.

  • Am I not mirroring displays?

  • I am marrying displays.

  • Why is it being weird like that?

  • It got froze air.

  • Sorry.

  • Let me just unplug and re plug it in.

  • It looks like it got messed up when we were testing things out.

  • Give it, give it a sec.

  • And that looks more.

  • And now it's not smearing this place because I think I turned that button off.

  • So let me let me unseated again.

  • Let me hit mirror displays and Where is that?

  • It is displays color mayor options on the menu and available.

  • This is this is whack.

  • Sorry, everybody going Thio We started off so strong and then it just kind of got destroyed their cause My, for some reason, they see my connection got really wacky Gather windows arrangement mere displays.

  • And if we're lucky, everything should now be mirrored.

  • Awesome.

  • So what?

  • I meant what I meant to say.

  • Great too was the love to D, uh, sort of website here because this is the game framework that we're using to implement 2048.

  • And if you're tuning in now, it might be better to turn into the prior two streams on 2048 just that you you can see where we've come from.

  • From the very beginning, we implemented sort of the grid on the first dream a little bit, And then the second stream we got to the actual numbers sliding and then combining together.

  • And today we're gonna actually take everything to the very end and talk about getting the numbers to properly combine and move around, and then also calculate winning and losing and also sort of deriving an arbitrary score formula where we've taken a consideration How many times the user has made a move before they got into the number 2048.

  • And I did a little bit of prior work on this just to prevent this from going into a part for and wrote in advance a sort of series of notes here and actually a separate get huh branch.

  • So if we go over to the repo, I'm gonna actually go to my terminal here when l s I'm going to get pole because this repo is a little bit out of date and I should not be able to get check out complete, which I'm already on.

  • It turns out I might have actually done this in advance.

  • And if I go ahead and run this in my editor, which is here, just make sure I'm in the right place around This should be able to move everything and it I actually think it's not even I don't think it's currently up to date.

  • You know, this doesn't look accurate for some reason, So let me go ahead and get status or get log.

  • Actually, just make sure that this is the right.

  • Oh, interesting.

  • It didn't actually pull the correct.

  • It didn't actually pull the correct stuff.

  • So let me go ahead and get check out or get fetch and then get status.

  • I should have probably tested this in advance.

  • Yeah, this this is for some reason, not.

  • It didn't actually pull the code from get home.

  • So I'm gonna I'm gonna just pull the repo completely.

  • See, You can see stable moving and combining them.

  • It was my last commit.

  • So what I'm gonna do is I'm gonna actually just fresh clone this.

  • I tested this on my other account.

  • Not actually my, um, test account and I assumed to get pulled was going to work, but it doesn't look like that's actually the case.

  • So I'm going to CD backwards and just going Thio, delete this.

  • Go and get clone.

  • If you get cloned, the report now from get hub, it should just work automatically.

  • And then Aiken, check out complete, actually, after CD into it 1st 2048 get check out.

  • Complete and complete is not a accurate sort of word to describe this branch.

  • It is.

  • The combining of numbers is complete, but rather than the branch name was just to sort of be farther ahead than the stream itself, and we will be today sort of working backwards from the We'll be working backward as much as we'll be looking at the prior code from last week and sort of getting it up to date with what's incomplete.

  • The branch, if you're not familiar with get hub and get branching.

  • Branches are sort of two different alternate paths that your code splits off to when your programming using get, which is a source control ah, form of source control and the master branch is usually what's ever in production.

  • So you have sort of your main sort of a timeline of get snapshots.

  • You know where you sort of saved your code.

  • You can always revert back to a prior snapshot or commit history, and branches sort of deviate from the master branch.

  • And they sort of are sort of like alternate timelines almost, um, and you can switch back and forth between them as you want to, and then even merge prior branches into the master so you can actually have that branch upper below your your master sort of come back into Master at some point and then become part of your production branch.

  • And I created a separate branch just so that we could go back to the prior coat from last week while also having a sort of firm point at which we know we're working towards, If that makes sense, So I'm going to now open up the coat.

  • I'm gonna quit V s code, and I'm going to reopen the repo in V s code here, which now, if we go to maine dot Lou and we go to the very bottom, we'll see that things have definitely changed.

  • You can see that.

  • I've actually brought out a few of the functions separately from the all those individual.

  • Move up.

  • Move down.

  • Move left, move right commands.

  • I've taken out some of the code that was common to those, and we'll take a closer look at this one.

  • Perfect revert back to the main branch, but it's allowed me to shrink down the functions.

  • The move functions to not too long, still a bit long.

  • I didn't spend enough time to actually turn this into an abstract function that would take care of all directions and one function.

  • But you could visualize, you know, possibly a way to do that, Certainly with enough work.

  • But here are some of the small functions.

  • Last week we actually separated out merge Tween, and, um, was it merged Tween and many, uh, move Tween.

  • I think it was these two functions and added make merge and make movies were just blocks of code that we're in the move up, move down, move left, move right functions, but were repeated, and I just basically parameter rise them a little bit just to make it a little bit easier.

  • So if I run this code now, if I move everything, you can see that it does behave correctly, which is nice.

  • So it does.

  • There is a part of this where it'll actually, if there are three like numbers on the same row or if they're too like numbers that mixed together, and then the that larger times two number is to the left of those or wherever, and they all move together, it will combine up to three numbers.

  • There is a way to protect against that, but currently the code does not support that.

  • But we could we could We could, uh add that without too much difficulty, but you can see that it does work now.

  • Um, all of the stuff is nicely mixing together, which is nice.

  • See you.

  • See, Right there.

  • It happened here at the very bottom.

  • There was a four.

  • There were two twos on a four here.

  • So the two twos mixed into a four and then that for mixed this into an eight.

  • Now, depending on your philosophy, maybe that's a feature and not a bug.

  • It's kind of a bug if we're looking at it from the perspective of the original code base, because I don't believe the original code based worked that way.

  • But all we would really need to do is set a flag on that tile to say that it's already been involved in a mixed operation.

  • So we could set the flag to maybe mixed equals True.

  • And then when we actually test for that merge, we can say if the tile that were emerging to or we potentially moving too dot um, mixed is equal to true or false.

  • Then merge accordingly.

  • So we can say only merge if mixed is equal to false, and that would prevent the behavior that we're just that we've just observed.

  • Um, okay, so let me just go ahead and read.

  • Guy White says, Morning, Colton, will you be facilitating cease indie gaming at Harvard Summer this year?

  • Thanks for these learning so much.

  • Um, I will be.

  • Yeah.

  • Course instructor for the For the game, Of course.

  • This summer?

  • Yes, if that's what you mean.

  • If there is another meeting to that, I definitely do.

  • Do you write that in the chat?

  • Nadia says hi, Colton.

  • How are you?

  • I'm doing great.

  • Thank you very much.

  • Feeling feeling pretty Spritely em, Kloppenburg.

  • Hello, everyone.

  • Berries and cream says hello.

  • Albin off.

  • 3398 Says, yo.

  • Hello, Oben.

  • Auf.

  • Good to see you on.

  • Yeah.

  • So this is what I did last night to get us sort of up and running.

  • Oh, Jail 97 says love the podcast.

  • Awesome.

  • Thank you so much.

  • Will be releasing another episode very shortly.

  • Potentially even today, depending on we're basically waiting for the r s s to spread up to Spotify and iTunes.

  • So whenever that's all done, we'll, uh, we'll pub the next episode of the podcast, but yeah, that one's get I think this this last podcast episode was pretty good.

  • They were filming another one tomorrow, actually.

  • Did I push these changes to get him as well?

  • I did.

  • So you'll see all of the changes in get hub and specifically these air located in the complete branch, which is right here.

  • So if you want to download all this code, clone it as normal and then run the command that I did, which was get check out where I do it complete right here.

  • So that will actually switch you into a branch if it already exists.

  • And if it doesn't exist, I believe you have to actually get check out or get branch.

  • Um, and then the name.

  • And then well, actually, that will take your existing code and create a new branch.

  • But named that that's that you can develop in.

  • And it won't affect your master branch.

  • Your main production branch, so to speak.

  • Um, but yeah, that's cool.

  • It works.

  • Everything is great.

  • And this gives us the framework now upon which we can start adding checking for, uh, we can check for whether the user is unable to move.

  • We can check for one of the numbers being equal to 2048 we can check their score s so on and so forth.

  • But we'll walk through the code that I implemented last night and however find it, and then we'll add those additional features after that's all taken care of.

  • And in order to do that, the first thing that we need to do is actually go back to master.

  • So all I have to do is get check out, Master, and then what will happen is you'll notice that the code is now the more complicated worst code that it waas last time last week.

  • So we'll work through that.

  • I added a quite a bit of re factoring to this in order to shrink it.

  • Even though it's not completely ideal, it's still much better than it used to be.

  • So if anybody has any questions, let me know.

  • Otherwise we will dive into looking at how I fixed up the sort of functions that were using last time.

  • And thankfully, I have some handy dandy notes here so that I can remember exactly how I did it.

  • The, uh, downside to doing some of the stuff live on stream is that especially for the more complicated stuff?

  • It doesn't get engineered the most efficiently.

  • And so we end up, we end up sort of coding and not the most ideal way.

  • However, it's a nice opportunity for us to look about.

  • Look at re factoring code to.

  • So there is a plus to it, I suppose.

  • Um, and it also kind of depends on my mental state that day.

  • If I'm actually capable of thinking well earlier in the day, I tend not to be as good as I am in the evening.

  • So I did all of this, like, last night and like, one in the morning, So I was actually pretty sharp, but that's that's just me.

  • Different people were gonna Some people work well the morning.

  • Some people work well in the evening.

  • I tend to work well after the day has gone by usually.

  • Okay.

  • All right.

  • Well, if there are no questions, we can proceed to the actual, um, re factoring of the code and sort of one of the one of the first things that I did was I actually noticed.

  • Well, it looks like we have a little bit of work to do here because I don't think we actually have.

  • No, we don't have some of this isn't actually Reef acted out.

  • So one of the things that we need to d'oh is there's a There's a few.

  • There are a few little small functions that should be reflected out.

  • Let me just make sure I have my notes here in order.

  • And a couple of those functions are the actual merging and the moving of the tiles.

  • You'll notice that, for example, this code and sort of you know, this code and this code sort of where we're setting and clearing the tiles, and we're actually doing the Tween operation.

  • And then same thing with this code here.

  • We're doing this merging.

  • And I actually thought that we did this last week, the separating out of the merging of stuff, so I'm might be tripping a little bit.

  • Um oh, unless I didn't Oh, you know what it might be?

  • I think I might not have committed those last couple changes actual merging of the tiles and moving of the tiles.

  • So that's okay.

  • I mean, we have again, we have the completed branch toe to go up to so If worse comes to worse, we'll switch over to complete.

  • And then we'll add the features rather than try to reverse engineer.

  • But I'll talk about all the code that I did, and we can at least understand how everything works.

  • We'll add.

  • We'll add layers onto that.

  • So one of the first things that we probably want to dio There are a few functions like I said, related to the moving and the merging.

  • Someone write a function here called Merge Tween.

  • This is the This is the actual merging stuff here.

  • So this right here, we're actually sort of adding a tile.

  • What we're doing is Rex.

  • We're moving a tile, removing a tile.

  • That's, you know, we're moving up.

  • It's one of the lower ones left right up or whatever.

  • We're moving it to the new tile.

  • That's the same number.

  • But we're deleting the old tile and we're just multiplying the other tile by two, right?

  • Uh, and specifically, one of the things that I realized is that, uh, in order to get this working, we need to change its number right away so that to Tuesday emerge in tow.

  • The end, too, because they think it's the same number.

  • We have to actually sit the internal number right away two times two.

  • But we need to keep it displaying the original number so it doesn't switch to four right away.

  • For example, it still waits until they merge.

  • Finishes right, which is the behavior that the original game sort of has.

  • So we need to do is keep two numbers inside of the inside of the tile data structure, a number in the actual number that it's holding inside of itself and then the number it's displaying.

  • So I called it display numb.

  • And so what we needed to end up doing for that is actually going into here and adding to the tile class a self dot display gnome, which is equal to its own, um, by default.

  • And then we we ourselves set, display numb and them later on in the merge function down here in Maine.

  • Da Lua and let me just finish writing this Tween so this will take a tile, and it's essentially going to be this code here, but a little bit Maura, little bit different, so I'll just ride it out here.

  • So, uh, we do, is we get a tile first if I'm doing this correctly.

  • All right?

  • Yeah.

  • So we get tiled up Tile X and then tile dot tile.

  • Why dot nam And then this is what we're doing.

  • We're setting that equal two times two.

  • Right.

  • So this is that so emerging towards the tile that we care about right?

  • Which we pass into this function?

  • Well, we'll end up passing that into this merge tile function.

  • So we're sitting the actual internal number, the value of that tile, which allows us to calculate whether the towel should merge into it or not.

  • But we're not adjusting the display number yet, so that it will still stay is, for example, will still keep the number two displayed on the front.

  • And I realized one crucial piece of this is in the actual tiled out.

  • Lou, we need to set this to display them to render the display.

  • No, I'm not the actual number.

  • Right.

  • And then after that weaken d'oh, our usual timer dot Tween, we're doing it over the span of 0.0.1 seconds, and then it takes in a an object, a table, and it's gonna take the tile right, and it's going to set its grid equal Thio grid grid tile that tile Why tile that tile ex dot Exe and then why Set to grid dot grid at tile that tile y tile dot tile ex dot Why?

  • Right says this is the Tween objects or of the list of key value pairs at which were tweeting the object towards We're taking the tile object and then we're Tween ing the, um the, uh Pereira the fields that we care about in this case, the x and y.

  • So we're taking the tile were tweeting It's x towards this X the tiles.

  • Why in tile ex dot ex sexual grid part of it, um and then we are After that.

  • What we do is we We wait for that whole Tween to finish before we set the display number correctly.

  • So we're finished takes in a anonymous function to execute once it's done.

  • So once the timer has actually Tween, it's done, It's thing Over the span of 0.1 seconds, it's going to execute this block of code s oh, it's a function on the timer dot Tween object timer between actually returns an object that has functions associated with it, which is pretty cool.

  • And Adam, to answer a question between the library is knife.

  • So there is a knife and it has a timer function within it.

  • So it's air struck.

  • Slash knife, air struck knife lips.

  • I spelled it wrong.

  • Their Strunk knife right here.

  • It's, Ah, specifically the timer module within the knife library, and Adam also said work for to work for 2 12 hour shift the past couple of days.

  • Not happy happy to be here.

  • Well, I'm glad that you're happy to be here.

  • I'm sorry.

  • They were 2 12 hour shifts.

  • That sounds pretty miserable, Hugo says.

  • Quick question.

  • If you had to make and publish a two game, would you prefer to develop it in love to D or a unity to D?

  • That's a good question.

  • It depends on the game.

  • I really like love to D, and I feel like I have more control over certain things in love to D.

  • But unity is pretty good.

  • Um, Unity has more coverage for platforms than Lou and left to die.

  • He will then lived love to d does.

  • For that reason, I would probably use if I were going to goes super commercial, and I wanted it to be available on, like, the switch.

  • And like all over the place, I would probably try and fit my code base into unity somehow and do it that way.

  • And I also as an intellectual exercise, would like to get more acquainted with unity.

  • I think unity is a pretty cool platform.

  • That said, Love has an appeal for me personally, and so I find it more enjoyable to program with love than a Then I enjoy programming immunity so far that might change in the future.

  • I haven't done a lot of two D game development with unity, which is a big part of that.

  • Um, it's a little bit harder to do certain things.

  • I remember having a tough time getting pixel perfect retro resolution working in unity.

  • But I was able to get it working in love with the help of a library very easily, and it was amazing.

  • So it has a special place in my heart.

  • But I think, um, honestly and pragmatically, unity would probably make the most market sense.

  • So that's probably where I would say, I would say, probably probably learned that unless you like the AP, I for Lou and for love to d.

  • And you want to get involved with that?

  • Um, where were we?

  • Right.

  • We were back at the code.

  • Um, we were writing this function here, so once it has actually finished Tween ng we want to set can move equal to true.

  • So what happens is can move, get set to false use usually, um, and actually let me see.

  • All right.

  • This this actually I think gets set into a different function.

  • I make a I made a little function here, Um, which actually calls the merge.

  • Things were actually not calling merge anymore.

  • The merged Tween function anymore from within the move up, move down.

  • Left, right, move.

  • Forget move left, move right.

  • But moved down.

  • We don't call emerge Tween anymore.

  • So we're actually gonna make a second function that takes in this information and then calls this code here.

  • Well, the between itself.

  • So that was one of the other changes.

  • The re factors that I made to the code base.

  • It actually made sense because I was able to parameter rise it a little bit.

  • Um uh, also land mining.

  • Thank you.

  • very much for rating.

  • Appreciate it.

  • Um, And Hugo, you are welcome.

  • The, um What was I saying?

  • The merch Tween.

  • We're just making a function for the Tween operation itself.

  • We're not really concerned about the game logic, but this function as much.

  • Thomas.

  • It can move, but we are concerned about a couple things.

  • So once between is finished, we're setting can move to true.

  • Remember, Ken move is the flag that lets us actually perform Tween operations.

  • Let's actually move tiles left right up down.

  • No true Guineas and hello, land mining.

  • So when we said can move back to true, remember can move.

  • Um, at least in our isn't here.

  • I think it's here.

  • Um, it's this flag here which allows us to actually test for the key, being up down, left right in our key pressed callback function.

  • And so this is an important thing.

  • This essentially pauses our input when we set can move equal to false.

  • So when we're finished with the Tween, we said it equal to true.

  • And then, um we do after that is we call get tile again.

  • Now, this is where we're actually taking the display.

  • Numb.

  • Remember we we edited the regular number, the internal number that that is responsible for the math for the combination of tiles.

  • But now we need it's time.

  • For once between is finished, toe actually update the display number so it actually change what's being shown on the tile itself, which is important.

  • So we kind of do the thing that we did before we're gonna do tile, a tile, X tile, a tile.

  • Why, um, we're going to grab the display number, and we're gonna set it equal to the same thing.

  • Tile that tile ak style, that tile.

  • Why on Bergen said that equal to the number, the internal numbers are essentially just doing an update.

  • We're taking that tile and we're setting equal to its internal number.

  • And then once that is finished with, we can say tile dot remove is equal to true and grid remove deleted tiles.

  • I believe this is this part we've already done in the last year were done that this just clears the tiles from the grid from our second table.

  • Because, remember, we we can have two tiles that are potentially or other tiles that are not actually part of the grid but are still existing or they're tweeting right?

  • Because essentially, what we do is we take the tile.

  • When we move it, we remove, we clear its prior space, and But while it's merging, it still exists, right, because it's still moving towards its destination.

  • But all we end up doing is keeping the tile at the destination.

  • And then after the Tween, we just multiply its number by two.

  • Right?

  • So we're not actually getting rid of the tile from the grid?

  • Well, we are getting rid of the tall from the grid, but we're still maintaining a reference to it so we can still move it and we can still see it, right?

  • We don't want to delete it, because if we delete the tile, we won't see it Tween.

  • It'll it won't exist will be sent to know.

  • So that's why in our grid we actually have a separate tiles table here which is responsible for keeping track of the references to the individual tiles.

  • HTM Town 97 says hi from Vietnam.

  • Hello, H damn good to see you.

  • And Berries and cream duck.

  • Purple rocks.

  • Thank both of you for the follow miss.

  • That earlier.

  • So let me go and clear our close out the grid class.

  • This is our merged Tween function.

  • Now we also need a move Tween function.

  • So this this happens when we don't actually merge.

  • But we do still move the tile.

  • So in this case, we're not doing any of the number.

  • Calculations were not multiplying the number by two.

  • We're not doing any of that.

  • But we are moving a tile from one spot to another spot and were tweeting it in the process.

  • And in order to do this, it's essentially just a timer dot between 0.1 and we take an object.

  • And then we set tile equal to ex being equal to grid dot grid tiled a tall Why tile a tile X x.

  • And then world's going another line down here we'll set.

  • Why equal to grid grid tile?

  • That tile.

  • Why tile tile ex dot Why boom And then after that again, this See this right here We're not actually setting like we did this other function.

  • We're not setting the number of times too because we're not doing any combination.

  • We're just moving one tile to another.

  • This is for exempt.

  • This is if a tile moves to an empty spot at the end of the grid or before another tile.

  • That's not the same number.

  • So just moving from one spot to another spot must be finished.

  • We have a callback function.

  • This callback function, in this case we'll just set can move equally true, very simple compared to the merge Tween function.

  • And then we'll be able to go back here, remove a lot of these functions and remove a lot of these redundant blocks of code rather, and then shrink down our functions.

  • Now the couple of the other functions that I ended up doing toe actually abstract.

  • On top of these two were a function called Make Merge like this.

  • And you'll notice that, for example, before we actually do the merge, there is a lot of this code.

  • And then before we make the move, there's this code without the prints, right?

  • But a lot of this is all redundant.

  • We don't need any of this stuff.

  • And Adam Adam, fighter Hello, good to see you.

  • But a lot of this is redundant and weaken parameter Rise it.

  • We can We can abstract this out into functions that just take arguments and then reduce these six lines, or however many lines of code down in his one function call.

  • And this is a big part of what shrinks down the code base.

  • Ultimately, it makes our up down left right functions a little bit smaller.

  • So if I say make merges gonna take in a tile, it's gonna take in an old accident old y as well as a new X and a new why right?

  • Because the merger's gonna actually Clint's gonna do the it's gonna clear the old tile.

  • And then it's going to set the old tile to the new X Knew why?

  • Or rather it's going thio multiply its gonna do emerge on the new X and the new Why, right?

  • So what we do is, we say can move eagles false.

  • So this is one of, for example, one of the lines of code that was up above in our up down left right functions.

  • Remember, this prevents us from actually entering in keyboard input.

  • So it's just setting that flag, which you can see you remember After the merge is done or the move is done, this gets set to right here is get sent to true again so he can move again.

  • Right?

  • So he said can move equal to false we then set tile the tile X equal to New X and then member tile accent tile.

  • Why are the grid coordinates not the actual X and Y coordinates.

  • The X and A Y coordinates are Tweens.

  • Remember, we do that here.

  • We actually we set the grid.

  • We figure out, you know, the member of the grid maintains an internal reference to those pixel coordinates.

  • We calculate those in advance.

  • I believe if we pull that up, we can actually see it happen.

  • Um, here in initialized grid, we do all of that here.

  • Remember, we take into consideration that padding the window with window, high grade tile size, blah, blah, blah.

  • Every grid spot maintains an X Y position that we then set tight.

  • We we reference it.

  • Here we go.

  • We in our actual Tween we set the x and y of the tile to grid dot grid that internal grid at why x.

  • And then we get the actual ex pixel value.

  • And why pics of value here.

  • That's what that's That's what's going on there.

  • So he said, Tile, a tile, a title X two New X and tile, that tile.

  • Why equal to new?

  • Why?

  • Because it's gonna move to that new tile.

  • Coordinate that new grid coordinate specifically.

  • So this is between one and four.

  • And then when we index into New X knew why on the grid and beget dot x and dot why, that will be an actual pixel value.

  • And then after that, we say grid clear tile.

  • Old ex bold.

  • Why?

  • Because when we're merging, we take the old tile we sent you get rid of it, but we maintain a reference to it, and we Tween it to the tile that were emerging into.

  • And then once that's done, um, we flagged it as deleted here.

  • As you can see, we said it to remove his equal to true.

  • And then we called grid removed deleted tiles, which will actually remove it from our tiles table.

  • Right?

  • Hopefully this is making sense.

  • It's ah, it's a little bit of work, A little bit of engineering, not it's not too bad.

  • It's it's just really All it is is taking its abstracting a lot of the redundant code that we've had in parameter raising it a little bit.

  • Once we have called clear tile, we're not actually setting any new tiles.

  • In this case.

  • We're just reusing the tile that's existing at that position were tweeting toward and were just flipping it where multiplying at times, too.

  • So what we do is, we say, merge between tile and that's it, right?

  • And then there was one other function that it created.

  • And this is this is the similar and spirit to make merge.

  • But this is if we're just making a move and we're not actually merging.

  • So this actually takes care of setting the new tile, right?

  • Cause if we're moving to a new position of the grid, not only do I have to clear the old tile, but we're moving the tile and then we're setting it again.

  • So we have to actually set the tile in the grid correctly.

  • Remember, the grid maintains a reference to each tile as a dot tile attributes, which here we can look at here again.

  • Remember, we have this tile is equal to nil by default, but this maintains a reference to whatever tile is currently seated at that grid index.

  • So that's what's happening there.

  • So I'm gonna do make move.

  • I'm going Thio.

  • It takes a very similar signature to the old function, actually, or to the make merge function in this case.

  • So in this case, though, what we're gonna do is we're gonna set same thing we did before can move equal false tile, the tile accidental new X title, that tile.

  • Why is equal to know why?

  • And there's actually a little bit of repeated code here.

  • So there is an opportunity Thio even maybe abstracted that out to a small function.

  • But that's, you know, that's may be going overboard.

  • Um, we're going to set the tile in this case, Um, two new X knew why, and we're gonna set that to tile.

  • So that tile we're moving, we're actually gonna set at the new X, knew why, and then we're going to clear the tile at the old ex and the old wine, and then we're going to move Tween um tile, right, because we're setting the new acts of the new Why?

  • So when we do move Tween, that'll just between its X Y values to match up with whatever is at the grid at the Tile X and Tyler.

  • Why?

  • So if anybody has questions, let me know.

  • Uh, all this essentially does is break out a lot of the redundant code.

  • A lot of the redundant stuff that we're doing across all of our functions and make it a little bit simpler.

  • But this gives us now the groundwork, weaken, sort of almost completely rewrite all this code.

  • Now, what I'm gonna do is this the shell for this is still accurate.

  • So the move, right?

  • Ah, lot of this code is kind of busted, and now a lot of it has been abstracted out into the smaller functions.

  • So what I'm gonna do is I'm gonna delete basically all of this starting from here.

  • We're gonna we're gonna keep the farthest ex bit.

  • But I'm gonna delete all of this code here just like that.

  • So now we have this move right function.

  • I'm going to consult my handy dandy set of notes for the actual new move right function.

  • And we can use this as a template upon which we can write the other move left, moved down and move up functions.

  • So, um, once we get the farthest tile, I can say check the tile.

  • Um, beyond for the same number and emergent.

  • So what we're gonna do is essentially if the we're gonna grab the farthest X and we're going to check to see if the tile beyond that farthest ex Remember the farthest X?

  • Because this is how we wrote our right most top, most left, most bottom, most functions.

  • It'll return the nearest empty tile, and sometimes this could actually be our tile.

  • That actual tile, that is the of the tile that we're checking to move on.

  • Because, remember, we're essentially iterating over all of our why, in the case of move rights, we're going every, um, every row one by one and then for every column.

  • Where century starting.

  • Since we're moving right, we're essentially going to and this is reversed for you.

  • I'll try to do this.

  • Uh, this is right right for you.

  • So we're going.

  • We're working our way from the right, most tiles one by one to the left.

  • And we're just seeing where the nearest open right tile is.

  • And it's the exact same function, the exact same algorithm for every other direction.

  • It's just flipped or wrote or mirrors or flip 90 degrees.

  • And, um, what happens is the functions that we wrote these left, most top, most bottom, most etcetera functions.

  • They'll just essentially started a given x y or why X and they will give us the nearest empty spot on the grid.

  • And if there isn't an empty spot, it'll just give us wherever we started, right, which is, uh, the exact same tile upon which were beginning to loop through the rest of that axis.

  • Right.

  • If we're on the X axis, will move along the X axis.

  • If we're If we're you know, we're trying to move right, we'll move to the right.

  • If we're trying to move left, we'll go to the left, up and down, down.

  • And if we are, if we get to an empty title, first of all, that means we can make a move.

  • And we need to also check to see if the tile beyond we're removing is the same number as the towel that we are.

  • Because if it is, we can not only move, we can move to that tile and merge with it.

  • If it's not the same, then we'll just move to that empty spot.

  • But if it is the same, we want to move to this spot afterwards.

  • And we want also restrict ourselves from not moving, trying to move past the the edge of the grid.

  • So we go.

  • We only go until you know four spaces or one if we're going left or up, right, so we stay within the grid boundaries.

  • But we do check to see plus one on farthest X if it's within the boundaries to see if it's the same number as the towel.

  • We're moving because we want to make that merge happen.

  • If so, so we do that.

  • If it's not the same, then we, uh it is not the same.

  • We just moved to the empty tile.

  • But if we if we do get the same tile, like if the nearest tile or rather the furthest empty Tao is our tile, meaning that we are jetting up against another tile if it just returns the current tile, we can still make a move because let's say that we are stuck.

  • Let's say we're we're a two and we're stuck against another two right.

  • Most is going to return our index because the next tile is filled, but we should still be able to merge into it.

  • So we also need to take that into consideration.

  • We need to move one beyond our current tile, even in that situation as well.

  • So we need to check for Emerge regardless of whether we're butting up against another tile, which is one of the mistakes we made last time.

  • We weren't actually checking for that, and I think that was one of the things that we ended up trying to figure out.

  • So that's where that's what we're gonna do here.

  • We're gonna get the farthest X, and we're gonna check the tile beyond it to make sure that that it is not the same number.

  • And if it is, we want emergent.

  • Tow it.

  • So what I can do is I can say, if farthest X plus one in this case is less than or equal to four, cause, remember, we wanna move.

  • We want a check for one beyond it.

  • But not if it's greater than four, cause if it is, that means you've gone past the edge of the grid, which would be an error because there are no spots in the grid of that index.

  • Right?

  • Um then so if it's the case that farthest X plus one is still within the grid boundary, What we'll do is we'll say, um, local far this tile is equal thio grid at get tile far this X plus one.

  • And why?

  • So this is gonna actually get the tile that is one beyond the empty space that we're trying to move towards.

  • So now we have a reference to whatever tile is one beyond the nearest empty space.

  • This could be either This could be an empty, the one tile beyond in empty space or if there were no empty spaces.

  • You know, it's just the towel one to the right of us, because that means that we returned our current tile spot.

  • Um and so we're gonna do is we're gonna say if farthest tile dot numb is equal to tile dot nam.

  • Well, this means that this means we can actually make a merge happen, right?

  • So all I say is, make merge of tile tile dot Exe No, This remember it takes in the old X and Y and the new X and Y tile the tile X.

  • Why?

  • For this X plus one and why?

  • So we're actually going to emerge operation.

  • We're going to get rid of our old tile x and Y, and we're gonna move it too far.

  • This X plus one and why?

  • And we're gonna wear this specifically is gonna be emerged.

  • Right?

  • Um, else if the farthest X is not equal to X, we want to do is want to make a move, right?

  • We want to do just a regular move.

  • Tile the tile.

  • Uh, reptile ex, Uh, why and then farthest x And then why?

  • So we're in this case, we're just getting the the farthest ex not farthest X plus one.

  • So, um, And then, in this case here, we're checking to see if far this X plus one is less than or equal to four.

  • Now, if it if it's the case that farthest X plus one is actually four or five, then we can still make a move.

  • It's still gonna be an empty tile, but there's no possibility of making emerge.

  • So what we want to do in this case, is just say, um, otherwise we want thio.

  • Just make an ordinary move right.

  • So this is moving to the edge of the of the grid.

  • So we just say else and then make move at tile.

  • A tile, a tile, X.

  • Why farthest ex away?

  • And, uh, also, the one thing we need to do is I think, a missing continue statement in here.

  • I think we are.

  • Oh, did I get rid of continue?

  • I might have completely gotten rid of it, actually on.

  • And then I just didn't update my source code to do so.

  • Yeah, because I don't I don't think we need to continue, do we?

  • Yeah, I don't think so.

  • Let me just sanity check.

  • They save this.

  • Let me check out.

  • Get make sure that it didn't I didn't flub this.

  • Let me get check out, Master, and then let's go over here.

  • Oh, it looks like I got rid of continue here, but it didn't get rid of Okay, not master.

  • Get check out.

  • Um, complete, but, uh oh, I gotta commit.

  • Okay, that's fine.

  • Get commit.

  • Um, started re factor.

  • Okay, cool.

  • So now we'll check out Master complete.

  • I think I might have just goofed and not Yeah, because there's no more We don't.

  • We're not using go to continue anymore because they re factor the code in such a way that we wouldn't need it.

  • So, yeah, I'm just gonna get rid of these.

  • I messed that up again.

  • I was finishing this at, like, two.

  • In the morning.

  • That might be part of it, but, um, that simplifies the code a little bit.

  • Cool.

  • I'm gonna go ahead and just get commit.

  • Um, cleaned up continues, which is nice, because I actually don't like I don't like having to use the go to if I don't need it.

  • I mean, it's kind of unfair that Louis doesn't give you a continue construct like you get in most programming languages.

  • But that being said, still, it's ah preferable, I think not preferable to avoid Go to gets a little bit.

  • It's very assembly, like it's not, you know, it's not clean.

  • There's a reason that people say don't use go to it.

  • Could be very hard to track everything.

  • I'm gonna go ahead and get check out master again.

  • And then now we have where we we need to go down here, right?

  • Yeah.

  • So we have this function.

  • It's very clean right.

  • This compared to how it was before.

  • This is like half the size of the prior functions.

  • And we could do this same exact thing for the other four functions.

  • I think, to save us a little bit of time, I might cheat because now we have the idea, right?

  • We have the idea that this is how it works.

  • All we're doing essentially is taking these functions.

  • And, um, we're just copying the exact same thing back to move left and then move down and then move up.

  • They're all the same.

  • Just the parameters changed a little bit.

  • And then I shot us.

  • Thio David in the chat David Malin who, if you're not familiar again with CS 50 is the course instructor for CS 50 the professor rather up CS 50.

  • Definitely check out those lecture videos on YouTube.

  • They're amazing.

  • Um, yeah.

  • So what I was saying previously was that I don't think it's worth the time for us tow, since everything's already laid out to just manually go through these functions and re factored in the same way I illustrated here how we re factored the move right function, But the same process exists for a move up.

  • Move down.

  • Move left.

  • So what I think we're going to do is I'll just go back to the complete branch, and you can check this out on your machine.

  • If you have downloaded the repo, you'll have access to this.

  • Um, but let's see how many lines do we save?

  • So we're at 2 34 on the complete branch, and if we go back to master, we're at 3 28 So he saved almost 100 lines of code from the re factor, which is pretty cool.

  • Um, could save theoretically a bit more if we wanted to take the time to actually re factor the up down left, right functions the one function, Ah mahn a function, I guess you could say, but now we won't worry about that too much.

  • So now we have this code, we can run it.

  • Everything sort of works the way that we expect it to.

  • Um yeah, pretty awesome.

  • Yeah, I will say I'm I'm pretty happy after after it feels like we've been on a long journey after, you know, however many, uh, weeks it's been in getting this actually working to see if we can get Thea, let's see how I'll see how high we can get.

  • Let's let's enjoy the fact that we got to this point right and see how high of a number we can get.

  • There are a few core functions that were missing before we actually have the game finished and bad ignites is yea cool.

  • It's working vinyl it We're still copy pasting, meaning we still have a chance to factored out.

  • Yep, that is correct, but we do have a chance to re factor it.

  • It's going to take a little bit of work just because the were doing an access flip in 90 degrees whenever we do want to.

  • If we didn't want.

  • Whenever we're moving left and right versus upper down, we're doing an axis flip.

  • And so the inner, the inner and outer loops get flip, so we'd have to abstract those loops out.

  • And I would just be a little bit of work.

  • Um, that I haven't had time to do or think too hard about.

  • It works now, and it works good, and it's it's much better than it was last time, so we'll stay with it.

  • But I welcome your effort in maybe doing a better job of abstracting it.

  • So let's see how how high can we get?

  • Um, let's have a little bit of not as productive time here actually playing the game that we've worked so hard on completing.

  • Let's see, I have a couple sixteens.

  • Here we go.

  • There's one.

  • Okay, there's a 32.

  • There's a 64 128.

  • Cool things are working, Actually not.

  • Not horribly right now.

  • Um, I don't know if it's easier to do it with the weights coded now, because again, it a

All right.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it