JavaScript Game Tutorial - Create Tic Tac Toe with HTML, CSS, and JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
i'm a big big believer that before you use a front-end framework like angular react view you should have really good core javascript skills so in this video let's try to build on those skills by building a tic-tac-toe game with vanilla html css and javascript so i want to start by saying that this video is sponsored by scramble one of the most unique and interesting platforms out there and i think as an aspiring web developer there's lots of free content out there on youtube just like this video that you're watching now but what scrimba can offer you is a complete front-end developer career path they're going to walk you through html css and javascript responsive design apis react get and then getting into getting hired your resume and soft skills and things like that so this front-end developer career path has 75 hours of content hundreds of coding challenges study group access where you can join a discord with other like-minded individuals who are going through the same exact thing you are so if you compare the monthly subscription to the front end developer career path on scrimba to a boot camp that can cost thousands of dollars up front it's a no-brainer there's no reason not to give this a shot there's a link below you'll get to do some amazing content on one of the most interactive platforms out there so check out the link below give it a shot and let me know what you think all right so just show you really quickly what this is going to look like uh this is a tic tac toe game which you've probably seen before and we've got our board down here we've got our x's and o's we've got a restart button and then we've got text to show which one of the users wins hopefully one of them wins so that's what we're going to build and we're going to do this all with vanilla html css and javascript nothing no packages no libraries nothing like that so let's start with creating our index.html file and one of the really cool things inside of vs code is that you can hit this bang character the exclamation and then autocomplete after pressing enter to create the boilerplate for an html file and i'm going to zoom in here so we can see this a little bit better so here i'm going to rename this documentato and then i'm also going to create an app css file and an app.js file and we'll go ahead and import those so we'll want our link to our css file up here and this will be app css and then at the bottom of our body we'll have a script tag with the source being our app js so we should have both of those linked together and let's just go ahead and do all the markup up front so there won't be a whole lot of html we'll do a lot of styling on this and then we'll add a lot of our game logic inside of javascript which i'm really excited to get to so i'm going to use some emit snippets here dot container will create a div with a class of container i've got a video on invent snippets if this is new to you so i'm going to create a container and then inside of this container i'm going to have a title so an h1 and this is going to be i have an id of play text i didn't really have a better name for that and it's going to start off by saying let's just play so let's play then i want a button and this is going to be a button with an id of restart button obviously we'll use this in our javascript to be able to restart our game and tell that to be restart and then next we want a div with an id of game board so this is actually going to be the board itself and the way this is going to work is we're going to have nine different boxes that represent our board so they'll be kind of blank boxes and then we'll add borders to each one to get the grid system set up there so i want to have this div with an id of container so i can do or not id of container id of game board so i can have an id of game board and then inside of that game board i want to have nine different divs with a class of box so i can do a dot box and then times nine so this will create you can see the little view up here of what's to come we've got a div with an id of game board and then inside of it we've got nine boxes uh with a class of box and also want to have an id uh i'm gonna start with just uh one in here so let's go ahead and auto complete that again if you're new to emit you could type all this stuff out no worries there at all but this is a really quick way to be able to generate this markup that i really like using so the only thing is we'll go through and update these so these would just be one through nine and actually i actually want these and actually i want these to be zero based index so i'm going to go ahead and update those that way all right so this will start at zero and go up through nine now what we can do is i've got an extension called the live server extension in vs code which is amazing you should absolutely check it out especially for vanilla html css and javascript stuff so if i right-click in my html file i can click the open with live server what this will do is it will open a live server inside of my browser at port 5500. so here it is right here so there's our game and just to kind of show you that this works i could type in some dummy text here and notice that this will auto reload with that new text there which is really cool so we don't want that and now let's start to give kind of some base styles to our application and we're going to use this purple color and i'm going to use css variables for this you can kind of see this purple color here that's what we want to use in several different places so we're going to use css variables to do this we'll have a dot root element and then on that dot root element we'll declare a variable called purple and then it will be a 3 e 0 2 4 9. all right so that's going to be our purple color that we will reuse and then we'll have our body uh we'll get rid of all the margin on our body so margin and padding will be zero it will use our var purple variable so that will be the color of text inside of the body and the font family nothing too fancy here we'll just set this to a sans serif next i'm going to set everything to a box sizing of border box so what that means is uh these elements will now if you define a width and height for them that width and height will include the border and the padding so if you have border and padding that will be included in the height and the width of the element itself so uh next up we have our h1 and uh we'll just give that a general uh kind of big font there 54 and then we'll go ahead and uppercase that text so text transform of uppercase and you can start to see this coming in a little bit so there's our purple color there's our big text the next thing we want to have is our container now this is the thing that's going to kind of position everything and so we'll add some padding to it uh 40 pixels and then we want it to take up the entire height of the screen so we'll set the height to 100 view height so that will take up the entire height of the screen and then i'm going to make this a display of flex and the reason is i want to display all the content in the very center of the screen so we'll do a justify content center and then align items center as well this will make sure that all of that stuff is centered uh in the screen and then you'll notice this is going to put these things side by side we want them to be top to bottom so do a flex direction of columns this will kind of stack them on top of each other so that's starting to look close to what we want the last thing is the game board or i guess two things the game board the boxes three things maybe game board boxes and the button so let's grab our game board and i guess let's actually style these boxes first so let's do these boxes so i can show you what this is going to look like so we'll have our individual box they're going to be 150 pixels by 150 pixels so this is important because we're going to use specific sizes here we're going to set a box to be a display of flex this is going to be the exact same reasoning as we did before where we want to have the justify content and align item centered so that will make sure to center the content which will be the letter x and o right inside of that box and then lastly we'll set the var or set the color to our purple variable and just so we can see these boxes i'm going to add a background of red so background color uh red just so we can see them to start so you see we have a lot of these and they're kind of stacked on top of each other we obviously don't want them stacked on top we want them to kind of wrap around so we want there to be three per row and then wrap around so the way we'll do this we know that each of these is 150 pixels by 150 pixels we're going to take our game board which is the container for all of that and we're going to set the width to 450 pixels and then we can also use flexbox again so display of flex uh the flex direction naturally will be row so it'll go one two three and then we want it to wrap so there's a flex wrap property or we can tell it to wrap those elements so once it gets to 450 pixels which will be three it'll wrap down to the next line and then i'm just going to add some margin top here of 40 pixels to give this some spacing so now when we go and look let's see if we have the right i think this is a lowercase b game board now if we look so you see this big block now and this is each individual element we can see these if we come into inspect and hover you can see these are the different blocks so those are actually lining up exactly how we want we just don't want to have that big bold red color so let's go ahead and get rid of that get rid of that red color and then just for a little bit of kind of moving along here i'm going to copy in the button style so these are fairly straightforward let me copy them in we'll add some padding some border radius background color again using that purple color including the border font size then we'll transition so when we hover we'll translate that thing up two pixels so let's save that and then we can see uh what this looks like so a little bit of hover effect there to make that thing uh move up so that's perfect now we're ready to jump into our javascript and actually i'll start to work on the logic for this and start to actually draw our board so the first thing we're going to do is actually draw the board so to do this what we're doing is for the top the elements that are on the top row we want to add a border bottom for the elements on the bottom row we want to add a border top for the elements on the left we want to add a border right and for the elements on the right we want to add a border left if that makes sense so let's go ahead and just kind of give this a shot so to do this we're going to need to get access to each of the different boxes so if you remember inside of here we've got class name of box so we want to get a reference to all of those so there is the document.getelementsbyclassname function that we can call and we tell it we want to get all the ones with a class of box and then we want to assign that to a variable and just to kind of show what this returns let's log this out so let's log out boxes here and this will also kind of prove that our javascript is connected well boxes returns uh what's in this case an html collection but we actually want an array so we can convert this to an array by calling array.from and then passing that in so this will give us a natural array in javascript that we're used to and then from there we want to create our drawboard function so const drawboard and you'll see that i use arrow functions here so this is my arrow function definition here and then we want to take each of our boxes and we want to iterate through them so for each one we'll get a reference to the box itself and the index and then what do we want to do well i want to end up building a style string so the styles that i want to add to this box which in some elements is just one border some is two borders uh so we wanna build that up through our javascript so let's start with kind of using this idea of the accumulator pattern where we have a style string and this is just gonna start off as an empty string and then we wanna do a couple of different checks and update that style string along the way so let's first check if index is less than three and maybe take a second to pause and think about what this means but i'll go ahead and tell you if index is less than three that means the box is on the top so if the box is on the top we want to add a border bottom so we can take our style string and we can add to it a border bottom three pixels solid and then we'll use that purple color so var purple right here all right so this is basically what we're going to do but in a couple of different scenarios so the other option is and these are actually just subsequent ifs so if the index mod 3 is 0 meaning it's cleanly divisible by 3 and did i type this out right index mod 3 equals 0 if it's cleanly divisible by 3 what does that tell you about that element again you can pause and take a second and then i'll tell you uh this is looking for there this to be an element that's on the left so it could be on the top but now we're checking is it also on the left and if it is on the left we want to add a similar thing so let's copy and paste that style string let's add now a border right so if you're on the left you want that border on the right cool hopefully this is starting to make a little bit of sense and so now the other option is if the index mod 3 equals 2 and what does that tell you maybe pause the video and think about this well this will tell you that the element is on the right hand side which if it's on the right we want a border on the left so let's copy our style string again and let's type in our border left and then lastly i'm going to cheat a little bit here i'm going to copy this entire one and i'm going to say if the index is greater than 5 greater than 5 means it's on the bottom row so 0 one two three four five six is greater than five which means it's on the bottom row if it's on the bottom we want there to be a border top hopefully this makes sense i know that's a little bit a little bit interesting to think about i guess but we're just drawing out this board based on where the individual boxes are we're adding those different borders so let's call draw board and let's see if this actually works and it does not and the reason is that we're not actually using our style string so we want to take our box and say style equal style string now let's see if we get our box and it looks a little bit off so let's go back and double check what we are missing here so if index is less than three and i think we are probably missing our semicolons at the end so we wanna make sure that that statement finishes before it adds on another one let's give this another check and we're close but not quite and we didn't flip this so this should be uh greater than five so i said it out loud but i didn't actually update it so now let's look now we've got a nice little board which is pretty cool so the next thing is we want to be able to track like when a user clicks on these so what we'll do is we'll go ahead and set a listener for each one of these boxes we'll say box dot add event listener and we're listening for the click event and we'll call a function called box clicked we haven't defined this function yet so now we need to go ahead and define that so box clicked is going to accept an event so e there and then it'll be just kind of an arrow function here and just to kind of show that this is working we can say box was clicked so let's go ahead and just test out this log let's click on one of these and all of them seem to be working so that's really good so now we're getting into the logic of uh when a boxes clicked how do we then update that square and what we're going to do is we're going to figure out which player's turn it is so we're going to start with o and then every time a box is clicked if that if it's a valid click a valid move in tic-tac-toe then we will update and switch the current player to be the opposite so a couple things we're going to need to track let's start with a couple of variables in here const o text and i'm this is a little probably over engineered but i'm just kind of setting these to some sort of constant that we can reference instead of hard coding them that way if you wanted to change it to y and z you could uh the next one is the x text which i guess a better name for this would be like player one text and player two text but it doesn't matter a whole lot and then i'm gonna set the current player to start to the o text all right so this is saying this is what's gonna get displayed when they play and this variable is checking to see which player's turn it actually is now the other thing we're going to need is we're going to need some way to keep track of what's already in these boxes because if something is in the box we don't want to let the user click already so let's start with a spaces array and this is going to be an array that will have nine items in it one for each box so let's start by setting them to all nulls so we'll make sure all of these are set to null when we start and now we're able to kind of work with all right what if a user clicks well the first thing we want to do is get the actual id of that element so we'll say const id equals e.target.id and let's log that so this way we can tell which one of the boxes was clicked and remember these should be 0 base index so 0 1 2 here 3 4 5 six seven eight okay so those clicks are working and now based on that index we can check what's inside of this spaces array so if there's nothing in that spaces array then we're okay so we can say if not spaces of id that means there's nothing in there and then if that's the case we're gonna update spaces the item at uh index id of spaces and we're gonna set that to the current player okay so we have that and then we're gonna take the uh e dot target which is the actual box we're gonna set the inner text of uh of that box to be the current player so remember current player is set to either the big x or the big o and lastly in here we're going to update the current player so i'm going to do this with a ternary so if the current player equals o text then we want to make them the x text otherwise we will set it to the o text so we're basically just flipping this if you're x now you become o if you're o now you become x so let's see what this does let's actually give this a shot and check in here if we click one there's our o which is really small i think we missed in our app css for our box this should be a font size of 150 pixels all right and then that'll format so now that'll be a little bit bigger that looks better and then x o x o if i click uh the same one in here it doesn't change so that's good and then i can continue to play out here so that works now all we need is the logic to figure out if a player has one and what we'll do is when we handle the submit in here let's get rid of this extra extra one before we update our current player let's then check if a player has one so let's say if player has one and we'll pass it the current player actually we don't need to pass the current player because it's a variable that we have access to everywhere so if player has one then we will update our play text and we need to get a reference to that so we'll get i've got a little shortcut here which is really nice a git id shortcut inside of vs code and this uh says that i'm going to get a variable play text from an element by id of play text so if someone has one we'll set the play text dot enter text to b and i will use our current player current player variable has one and this is inside of es6 backticks es6 template literals to show that we can do variable interpolation as well as just kind of regular string stuff right inside of there and then if the player is one we don't want to continue we just want to return out of this function so now we're handling if a player has one but we're not actually checking so now we'll create our player has one function and this logic gets a little interesting where where i don't really have a better way to do this except for checking just the common ways that a user could win so by knowing who the current player is whatever the current player is if the current player is x if they have this top left thing then you can check all right do they have this next right one if they do then do they have this next right one or if they have this top one do they have this middle one and this one or if they have this one do they have this one and this one so we're kind of just like enumerating on the different combinations of wins and i'm curious if you have a more efficient way of solving this in terms of code let me know but we're just going to kind of rock through this and kind of lay out these different conditions so we're going to start with if spaces of 0 equals the current player so that means if the current player has this top right one now we can check do they have either these other two or these other two or these other two and if so they're the winner so this will get a little bit old but let's type these a couple of first ones out so if spaces of one equals current player and spaces of 2 equals current player then i'm just going to log to say current player wins up top so this is we could actually use this as part of our feedback to the user too but in this case i'm just logging this out so i'm kind of specifying exactly how the user wins in this case so in this case the user wins up top and then we return true so there's a couple of different ways so if the user has this top right one now we can check not only do they win sideways now do they also win diagonally and this would be spaces of three and spaces of six actually this will be on the left sorry so wins on the left all right so this will check winning on the left so we've got winning across the top winning on the left now from that same spot we can check did the user win uh diagonally so zero one two three four and then eight will be that last one so four here and then eight on the last one so this will be wins diagonally so let's test let's actually see if we can make that work so start off with an o here x o x and go here and it looks like i've typed in player probably instead of current player yeah this one here so i'm going to use multiple cursors in vs code which is really nice and then update these all at the same time so current player instead of player so let's try this again let's do top and then there and here and it actually says o has one okay so what if uh we don't have restart functionality yet so let's uh refresh this and what if x does the same thing then x has one cool so that works and then we can also check all right what if we go diagonally that will work and then let's refresh again and what if we go actually i mess that up try to test on the left so down here see if that wins as well so those checks are working now we just need to kind of work on the the different possibilities for the user to win so we saw if the user has that top left piece or that top left spot that will work now we can kind of check like what if the user has the bottom right so i'm going to cheat a little bit and copy a lot of this code let's just copy the entire thing and let's say else if so we copied this entire thing but what we want to check is if the user is actually in the bottom right so if the user has the bottom right square then you can check up on the right you can check over on the left and then you don't need to check the diagonal because that's already been done so the diagonal check we can actually get rid of here and then we can update these things to be able to check appropriately on the right hand side so this will be two and five and this will be wins on the right and uh then this one is checking on the bottom so this one will be seven or actually six and seven so it has those two uh those two bottom left and then bottom middle so if that's the case user wins on the bottom all right and we can check this one as well so let's see if we play and we give o here and actually we want to go there and there and there did that work it looks like that didn't work so let's double check this so we're starting oh we actually should be checking if uh spaces of eight so that's the update here if the user has the space in the bottom right now let's try to check this that should be a winner and this should be a winner cool so that's working as well now the last combination that we need to look for is what if they have three across in the middle or three across in the or three across in the middle and or three uh up and down in the middle i guess and i don't think this actually doesn't have to be an else they could actually have uh that spot as well so these can just be or should just be extra if conditions so now we're checking uh spaces of if they have the middle piece which is four so if they are in the middle now we want to check does the user have the top middle and the bottom middle so let's copy again one of these and then we'll just kind of add or change up these numbers so the top middle would be one the bottom middle would be seven and so if that's the case they're gonna win vertically in the middle i guess and then let's uh do this one more time and then in this case what we're checking is do they have a cross and if they have a cross the the middle left one will be three and the middle right one will be five and this will be horizontally in the middle all right so let's test these out too this is a little bit tedious but uh let's say we start there uh we used player again instead of current player where do we do that there we go this should be current player and let's try this again so we'll start in the middle and then what if we go across there that works and then what if we do uh actually we'll do x's this time since i messed up and here x is one cool so that all is working now the only thing extra that we need to do is add this restart functionality so let's do our const restart so we'll have our restart function and basically when we finish we can set the text to whoever won and then we can restart the game actually we probably want to leave the board there until the user decides to leave the game so in that case we'll get our restart button so get id here i want to get the restart button and is it btn let's just double check here yeah btn for restart button so we'll get that restart button and then we're going to add and event handler to our restart button so event or restart button dot add event listener and this is listening for a click event and then we'll have the call back here and then we can actually do our restart so we don't actually need a separate restart function now we can just do our restart right inside of the restart button event handler so what i want to do is we may actually be able to completely wipe out the array and just set it to an empty array but just to be kind of sure on this we want to basically wipe out each space inside of our spaces array so we'll do a four each and we'll get the space and the index and then for each space we want to set the space index to null so we're basically resetting that thing to what it was before then we also want to wipe out the text in the boxes so boxes dot four each and we'll get a reference to the box and then for the given box we wanna set the enter text to be an empty string so we wanna get rid of the text that's inside of there then we can grab the play text set the inner text to be let's play again so we'll kind of reset that thing to what it was initially i think i need to use backticks in this case so that i can use my single quote in there and then lastly we'll reset the current player to the o and so interestingly enough what we can do now is instead of initializing spaces up here with all of these nulls and instead of initializing our current player we can just have those variables be there and then we can call before we call our drawboard we could call that restart function but we don't actually have it as a separate function so i lied we do want to break this out so let's break this out into a new function and we don't actually need the e in here we don't need the event even though this is a click and let's grab all the stuff that's inside of this and let's say this is going to call restart we'll paste all of this into restart and let's get a little bit of formatting here and then let's just call restart before we call draw game board so this will make sure that it updates all of our spaces with nulls it will make sure that all the inner text of the boxes are set and then it will set the player uh enter text and we'll update the current player so let's see what this looks like hopefully this will work missing initializer in const declaration for oh we actually just need to initialize this to an empty array and hopefully that will take care of it so let's restart and can't access restart before it is defined let's move the event handler down below that function so we want to make sure that we have that function defined before we actually use it inside of our button so now the board gets drawn we can do o x o x o that's a winner restart that works now we can do uh oh and in this case it's not letting us click so let's go back and double check when we try to play what is it checking in here and we can probably actually just log out what our spaces is in this case it looks like it's doing uh something weird here what's in space is it's not quite what we expected so let's double check that logic we've got our spaces.for each and we've got our space and index space at index should be null i would think or actually space is at index should be null that's what it is so now let's try this again let's try to play that's a winner restart and then can we play again yes we can and does that win cool and let's just double check and x can win so we can go up there and here and here x is one as well and we've got our restart here and all of this stuff works really well let me clear clear that out that's not how that works clear there we go so anyway i like i said at the beginning of this video i think having core html css and javascript skills is really really important to being a web developer this may seem like a trivial example or maybe it seemed really tough depending on your skill level but i think it's really great experience to be able to build something from scratch not lean on any frameworks and to kind of figure it out along the way this i thought was the creative way to do it i'm curious if you have anything that you would have changed to do this differently or let me know in the comments below what you learned in this video i would love to hear from you as always thank you for checking out the video i really appreciate it i had fun working on the tic-tac-toe and i'll see you in the next one
Info
Channel: James Q Quick
Views: 15,821
Rating: undefined out of 5
Keywords: javascript tic tac toe, javascript tutorial, tic tac toe javascript, js tic tac toe, javascript game tutorial, build a game with javascript, js game tutorial, web development, tic tac toe tutorial, javascript games, coding tic tac toe, vanilla javascript, html, css, scrimba, javascript games for beginners, javascript game development, gamedev, js, javascript template literals, javascript tutorial 2020, javascript tutorial mosh, web development tutorial for beginners
Id: E621N5GBKv8
Channel Id: undefined
Length: 32min 20sec (1940 seconds)
Published: Tue Oct 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.