JavaScript Tic Tac Toe Project Tutorial - Unbeatable AI w/ Minimax Algorithm

freeCodeCamp.org · Beginner ·🌐 Frontend Engineering ·8y ago

Key Takeaways

Builds an unbeatable Tic Tac Toe game using vanilla JavaScript, HTML, and CSS, implementing the Minimax algorithm

Full Transcript

in this video i will be showing you how to create a tic tac toe game from start to finish using javascript html and css i will also show you how to create the ai using the minimax algorithm i expect you to have basic knowledge about html css and javascript but you don't have to know anything too advanced however it may take a few re-watches to completely understand the minimax algorithm if all you are interested in is the minimax algorithm feel free to skip to that section by clicking the link in this description for section seven to get the most out of this video you should create the tic tac toe game along with me on your own computer if you get lost while writing the code you can check out the github repository that goes along with this video this video has many sections and there is a folder in the github repo for every section in the video the folder has what your code should look like at the end of each section check out this video's description for links to the code for each section as well as links to skip ahead to that part of the video before we start creating anything let's make sure your development environment is set up an easy way to create this project is to use codepin.io just go to the site and then create a new pin there is a section to put your html your css and your javascript and then everything you create will show up right over here also don't forget to give your pin a name and save it however i'm actually going to create the project locally on my machine instead you can do that with any text editor i'm using sublime text i'm going to open sublime text and then go to file open now i'm selecting a folder i already created for this project inside this project create three files i use the sidebar enhancement package add-on so i get more options when i right-click here so we're gonna create the three files we're gonna create tic-tac-toe.html now style.css and then the last one is going to be script.js in tic-tac-toe.html i'm going to paste in basic html boilerplate code that should be included in most projects you can see that in the head there is already a link to style.css and also at the end of the body there is a link to the script.js javascript file so that's how all these three files that we created are connected the first thing you should do is insert the title so right inside the title here i'll put tic tac toe and if you're creating the project in codepen you actually don't need any of this code all of this is automatically included now let's start setting up the basic html structure first of all i want to let you know that just like any programming project there are an infinite ways to create a tic-tac-toe game there's not really a right way to do it as long as it works we're going to use a table to create the 9x9 grid needed for the tic-tac-toe board after we get this code in we'll add some css to make it look more like a traditional tic-tac-toe board now press command shift d to duplicate that three times and we'll just change this to one this to two and then command shift d two more times three four five six seven eight we're also going to need to display who is the winner of the game so at the bottom we'll add a div with the class of end game also we'll add a button that will allow the player to reset the game after it ends while we are putting this at the bottom later we'll add some css to position the in-game message on the top of the tic tac toe board also that reset button will eventually go into the in-game element next we'll start working on the css okay before we switch over to our css file you can see that i opened up a browser window right here and it's going to show everything that we've created right now the table there's nothing in the table so it doesn't show the table but we can see the replay button also i did realize i named one of my files incorrectly this was supposed to be script.js so i'm going to right click and rename now this is with my special add-on here so not everyone can rename right from in sublime so now we have the right name script.js not script.css okay we'll go over to our style tab here and the first thing we're going to style is the td element the td element if we go back into our html that's what all the cells in our tic tac toe game all the squares are the td elements so we're going to set a border and a height and a width we'll just stop for a second just to see what that looks like so far so it's already starting to look like a tic-tac-toe board let's put in a few more things and let's see what that does i'll save that refresh the page and now you can see well we did add this cursor pointer so it looks like you can click each square when you're on it and you can see it still doesn't look like a tic-tac-toe board exactly so again a few more things for the styling now i'm going to add some styles to the table element so that's going to style the whole table element that includes everything else here so border claps collapse that's what is going to make it look more like this so we don't have the two lines for each cell now this is just some stuff for positioning it's going to make sure it's centered position absolute means it's not going to be related to other things on the page and the left 50 and then margin left negative 155 pixels is just a way to center it so it's going to move 50 to the left and if we just if we didn't have the margin left it would the edge would be at the center so if i take that out and then refresh that you can see the edge is right in the center but we have to move it back over so the negative 155 pixels the whole thing is 310 pixels 310 divided by 2 is 155 so that's why we go negative 155 pixes left and the top 50 is just so there'll be some space at the top because it's absolute now it's not related to where this button is so this button just pops up to the top now we want to make this look more like a tic tac toe game by removing the edge border all the way around we're going to use the first child selector so let's see what this would actually select table tr first child td so first we're gonna go to the table and then the t our first child so this is the first child this is the second child this is the third child so we're only selecting the first child which is basically the whole top row here and td which is going which will be every td element so for every square in this first row here we're going to do something border top equals zero let's save that and refresh that page you can see now there's not a border on top so i'm just gonna copy this scroll down here copy this let's get that more toward the top here so we have more room paste here so now instead of first child we're going to do last child instead of border top we'll do border bottom and then if we just look at what that looks like we just remove the bottom now we're going to just change this up slightly we're going to cut that and then put it on the end of the td so we're going to select every table tr and then just the first child td so we go back here this is the first child this is the first child and this is the first child instead of border top it's going to be border left and we can see what that's going to look like and then just the same thing instead of first child last child and border right okay now it's starting to look like a tic-tac-toe board now i'm just going to add some code that's going to style this this in-game element this in-game element is going to look like a little modal that pops on top of the tic-tac-toe board at the end of the game so let me add code for that okay now i got this whole in-game element you can see we have it display none because it's not going to display until the end of the game and actually just to see what it looks like let's just remove this display none for a second and see what that's going to look like see it's going to just pop on top just like that and let's put that back again you can change styling any way you want to make it look a little more exciting than what i'm doing now we're going to finally get into the javascript code the javascript part of this video is broken up into four sections first we're going to set up some variables and add the ability to click a square and show a mark second we are going to add logic to determine the winner and show the winning combination third we'll create a very basic ai and add the code to notify who the winner is and finally and this is the most complicated section will create the logic for an unbeatable ai using the minimax algorithm i'll demonstrate how it works with some diagrams so like i said this first section we'll set up some variables so first we're going to initialize the board so the var or edge board means original board and this is eventually going to be an array that keeps track of what's in each square the tic-tac-toe board if it's an x or it's an o or nothing and now this is how we'll show that the human player is going to be zero and we'll have also have a const of the ai player which will set to x now you can create these as anything it doesn't even have to be x and o and it'll show up in the boards over there and now we're going to create an array that's going to show the winning combinations for the tic-tac-toe board and inside this each winning combination is going to be an array so it's an array full of arrays so we have 0 1 2. so each square this is square zero this is square one and this is square two if if we have 00 across that would score for tic-tac-toe and the other two ways to win across 0-3-6 this would be 0 3 six so that would be a diagonal win and now i just put the other winning combinations in there so cells equals document.queryselectorall and a dot cell and let's zoom out a little bit so that means the cells variable is going to store a reference to each cell here document.queryselectorall is going to select each element on the page that has the class of cell which are all these td elements and then we're going to have to call a function to start the game which is just going to be the start game function and now we have to define the function so this is what will happen when the game starts also one thing to point out is that remember when you click replay it's also going to run the start game function so this start game function will run at the beginning but also whenever you click replay it will run the start game function we have the document.query selector and we're going to select the in game element and we're going to set the style so we're going to modify the css style specifically the display property we're going to set the display property to none now if we go back into the style you can see that this the display property is already set to none but remember this will also happen when you hit the replay button that will run the start game function and at the end of the game the in-game element is not going to be set to display none is actually showing up so when you click replay it will be set to none again and now we're going to finally load something into the original board variable that we have up here we're going to set it to array.from array9.keys this is just a fancy way right here to make the array be every number from 0 to nine so it's going to create an array of nine elements and it's gonna be get just the keys for that element which is zero through nine and it's gonna create an array from that other array so just to show you what i'm talking about i'm just going to console.log that here so if i save that i'm going to run this now i'll open up the javascript console you'll see we have an array of element 0 through 8 here but let's remove this for now now throughout the course of the game we'll actually be adding x and x's and o's to this so whenever we restart the game we want to remove all the x's and o's from the board so we're going to do that with a for loop so we're just going to go through cells.length and remember cells is this up here so it's a reference to every cell up here and we're going to go through every cell up there and we're going to do three things each cell so cells i is going to be each item of the cell when it loops through this for loop we're going to set the inner text to nothing so there will be nothing in the cell and we're going to do remove property background color that's because i already know that when someone wins we're going to highlight each square that's part of the winning combination in a certain color and if the game is restarting we want to remove that background color so we're back to having no background color and then one final thing we're going to add an event listener on the click event and we're going to call the turn click function so now every time anybody clicks one of these things we're going to call the term click function and the turn click function is the next thing we're going to define in our program for now just so you can see what's going to happen we're going to do console.log and actually inside the term click function we're going to pass in something so i'm just going to call this square it's just going to pass in the click event so we're going to console.log square.target.id so now it's just going to log the id of whatever square was clicked so i'm going to save this i'll refresh this page and then let's see what happens i'm going to click oh i'm getting an unexpected token let's see what i did wrong there says number line 28 and oh i just forgot to put the word function here so this is supposed to be a function let's save that refresh and okay cannot read property remove property it looks like i spelled this wrong this would be style so maybe you already noticed while i was typing it in earlier but this is a good way to troubleshoot your code just look in the javascript console and i'll give you an idea of what you did wrong so now let's refresh this that's why it's good to try things out periodically while you're programming so you can catch things quickly i'm actually going to clear the console and then refresh so you can see that there's no errors and now if i click it oh six because that's the zero one two three four five six see i'm going to click there click there wherever i click you can see in the console here's zero here's eight you can see it appearing down in the console down here i know it's kind of small but it's showing the id of the square that i'm clicking but we actually don't want it to just console.log every time you click somewhere so i'm going to delete this here and we're going to call another function inside the turn click we're going to call the turn function and we're going to pass in the id that we're clicking and we're going to pass in hu player because it's the human player that's doing the turn so actually that's the only thing that's going to be in the turn click function is calling the turn function and the reason why we don't go directly to the turn function is because the turn function can be called with either the human player or the ai player so if a human is clicking we're going to call the turn function with the human player and not the ai player so now let's define the turn function this time i'll remember to put the word function the turn function is going to take two parameters the square id and the player and you can see that's what we pass in up here the square id and the player this is the human player and so we're going to set two things so first of all we're gonna set the board array origin board at the id that we've clicked to player so on this array it's gonna show the player who just took a turn in that spot but we don't actually see that array we're also going to have to update the display so we can see where you just clicked okay document.getelementbyid that's going to select an element with the id and the square id if you remember from the html we have the square ids here so we're going to select the element that was just clicked and set the inner text to equal player so if i save that and refresh if i click here wherever i click you can see an o it pops up so right now we can fill that all up and then that's all we can do but let's see if the replay button works yeah we can click replay and we can keep putting an o's in here so this is kind of fun for a few seconds but i think we need some more functionality of our game here so now we're entering the second part of the javascript section which is actually the fifth part of this video where i'm going to add logic to determine the winner and show the winning combination remember you can check the link in the description of this video to link to the github repo where you can get the actual code that i'm using and remember the folder for each section shows what the code should look like at the end of each section so if you get the code for the end of section 4 you'll be exactly where i am now so whenever a turn is taken we are going to check if the game has been won so i'm going to add this let game one equals check when and check when is going to be another function we're going to define in just a second but we're going to pass in two things the original board array which is an array that shows everything on the board where the x's and o's are and the player the current player because we want to check if a certain player has just won if game one so if we find out the game has been won call the game over function with the game one variable you'll see here that this is not just going to be a true or false variable we're going to have some other information that we'll be passing into the game over function okay now i will define the check when function which is going to receive the board and the player the reason why we have to pass in the original board here and we don't just reference the original board variable in this function is because later in this program we will be passing in things that are not the original board that are different versions of the board than what the current version of the board actually is you'll understand that when i get to it now this line that i'm typing is really just a fancy way to find all the places on the board that have already been played in let's bring this down to this line here so we're going to use the reduce method the reduce method is going through going to go through every element of the board array and do something and it's going to give back one single value the accumulator is the value that is going to give back at the end and we're going to initialize the accumulator to an empty array the e is the element in the board array that we're going through and the eyes index so if the element equals the player then this is a ternary operator so then we're going to do this we're going to just concat i that just means we're going to take the array the accumulator array and we're going to add the index to that array and then if e does not equal player we're just going to return the accumulator just as it was so we're not going to add anything to the accumulator so this is just a way to find every index that the player has played in and we're going to set game one to equal null and then we're going to check if the game has been won we're going to do that with a for loop so this is a four of loop actually this is supposed to be wing combos dot entries so remember at the very top we have the wing combos this is every single thing that could create a win every array here could create a win so we're going to have to loop through every win combo every possible way that that a player could can win so win combos dot entries is just a way to get the index and the win so we're going to have one variable that's zero because this is index 0 that's going to be the index and the win each wind that we're looping through the wind is going to be this array with 0 1 2. so we're going to need the index of the wind so we need the index and the wind in this for of loop if when dot every win.every means we're going gonna go through every element in the wind so for instance the first one would just every element would be zero one two so if wind.every so for every element in that 0 1 and 2 we're going to check if plays dot index of l is more than negative 1. so the plays is from up here plays is the all the places that the player has played on the board and index of so we're going to see if the index of the element is more than negative one that's just a fancy way of saying of saying has the player played in every spot that counts as a win for that win so has the player play in all these spots and then it's a loop has the player playing all these spots has the player play in all these spots we go through every single one to see if the players play in all the spots that constitutes a win combo if so that means the player has won so we're gonna set game one to equal index index player player so now we know which win combo the player one at and we know which player has won and now we're just going to break from the function and after all that we're going to return game one so if nobody wins game one will be null if someone does win game one will contain which win it was and which player won so let's go back up here if game one then run game over if game hasn't if game one is null this will be false if game one contains this here this will be true and will run the game over function so now let's define the game over function and the game over function is going to accept game one or game one was defined right up here and we're going to pass in here and it's going to go into here inside the game over function we're going to have two for loops first of all we want to highlight all the squares that are part of the winning combination and then we want to make it so the user cannot click any more squares because the game is over let index of wing combos and we're going to pass in gameone gameone.index so that was the index of the wing combo that was the winner for this game so we're gonna go through every index of that wing combo and we're going to do something document.getelementbyid the index that's the index from the wing combo dot style dot background color so we're going to set the background color to something what we set the background color will depend on who just won the game game one dot player that's who won the game if game one dot player equals the human player now this is a tern area operator we're going to set the background color to blue if it's the ai player we're going to set the background color to red and that's the end of this for loop now we're going to have one more for loop and now we're going to go through every cell and we're going to make it so you can't click that cell anymore so we're going to remove the event listener the remove the click event listener and we have to also pass in what that click of enter event listener was to the term click and set this to false okay so now let's see how this works we're going to refresh here with all of our new code oh we have some error here missing initializer and destructuring declaration 41. so let's go up there oh we just i think it's just so we have an extra parentheses here let's see if that solves the problem now let's clear the console and refresh unexpected token 44. so let's see what happened there and here it looks like here i was missing a parenthesis it should be index of element is less than negative one so let's try that we're going to refresh this and another error okay let's see what we did here i don't think we need this parentheses so let's see if that fixed the problem i think it just fixed the problem so let's try this out okay if we put three in a row it turns the blue and we can't click anywhere let's replay now we should be able to click three in a row it turns the blue and we can't click anywhere turns of blue we can't click anywhere so that works we can now determine a winner next up we're going to create a basic ai and show the winner box well i hope you're still following along and creating your own program along with my program we've just started section six so if you get the code from the github repository that shows the end of section five you should be caught up with where i'm at now again just check the link in the description for that code right now there's no ai so the computer doesn't even do anything when you play you're just only putting o's in there so we're going to change that in this section this will just be a basic ai without the min max algorithm in the next section we're going to implement the minimax algorithm so let's go back up to the turn click function so when the turn click function is run the human player is going to take a turn but right after the human player takes a turn the ai player will take a turn so before the ai player takes a turn we're going to check if it's a tie so if it's a tie game that means every square is full and nobody has one yet so if every square is full the computer player is not going to take a turn so if there's not a tie then the computer player will take a turn turn best spot ai player so just up like up here we put in the target id that was clicked here we're going to get the id based on this other function the best spot function is going to return the id to click and instead of the human player we have the ai player taking the turn let's do one last thing while we're in this function right now you can click on a place that's already been clicked so we want to make it so you cannot click on a place that's already been clicked so let's add that logic right up here if typeof a ridgeboard square.target.id equals equals number so if you remember the original board array gets filled with the numbers zero through nine and then when a turn is taken that index will be replaced not with a number anymore but with the x or the o the human player or the ai player so if the type of the id that was just clicked is a number that means that neither the human nor the ai player has played in that spot so if nobody is playing that spot then let's cut those out put it right here then we'll do this we'll run the turns here so the human player and then the computer player right there so you can see we made two functions check tie and best spot so let's create those functions let's go down to the bottom here and we'll start with the best spot function now this is how we're going to find the spot for the ai player to play remember i said that eventually we'll make it more complicated but this time we're just going to make something really simple so the best spot function is just going to run a different function we still have to create that's going to find all the empty squares and just get the first element from the empty square so it's just always going to play in the first empty squares so before we create the check tie function let's finish creating the empty squares function i'll put it right up here so function empty squares so we're going to filter every element in the original board to see if the type of the element equals a number if the type of is a number we're going to return that so all the squares that are a number are empty and the squares are an x or an o are not empty and the best spot is just going to find the first square that's not empty so now like i said we're going to have the check tie function so to check if it's a tie we just use the empty squares function that we just created if the length equals equals 0 that means every square is filled up and nobody's won yet because normally every time someone um plays a turn it checks to see if someone's won so if every square is filled up and nobody is one that means there's a tie we're gonna do a few things inside a for loop because we're going to do something to every single cell in the tic-tac-toe board so we're going to set the background color of every cell to green and we're going to remove the event listener so the user can't click anywhere right now because the game's over and we're going to declare a winner this is actually a function we still have to create declare winner tie game that's how we're going to pass in the words tie game and return true because true it's a true that is a tie or if this if statement is false we're going to return false okay we just create a new function so now we have to define that function declare winner let's put that one right up here declare winner oh and we've passed in who right down here we passed him thai game but we'll also sometimes pass in if the computer wins or if the human wins so inside this function we're going to do something so we're finally going to show the in-game section it was that the style was set to display none but now it's going to be set to display block i'm just going to duplicate this line i'm going to select the endgame.txt so now if we go back into the html um [Music] the text is here so the inside ingame and then inside text dot enter we're gonna set the inner text to who that's what we passed in here so if it's a tie game it's gonna say tie game so we also wanted to say if you win or you lose so let's go over to game over up here and when there's a game over we're going to also call the declare winner function and we're going to have a turn area operator to see what we're going to pass into the declare winner function so if the game1.player is a human player we're going to pass in the words you win else we're going to pass in the words you lose so i think we're done implementing this basic ai so you can actually play a full game of tic-tac-toe let's save and test and see if we get any errors oh no error so far let's see yep so i played here the computer automatically played in the next open spot the computer play on the next open spot and it says you win so let's replay now let's see if i can get the computer to win you lose now let's see if we can get a tie game tie game so we just saw every in-state you win you lose and tie game at this point you have a fully functional tic-tac-toe game however as you can see it's pretty easy to beat now we will create an unbeatable ai using the minimax algorithm after we implement the minimax algorithm you will never see the message you win on the screen much of this section on the minimax algorithm is taken by a great article by ahmed abdulsaheb on the topic i have linked to the article in the description of this video i definitely recommend you check it out a minimax algorithm can best be defined as a recursive function that does the following things one returns a value if a terminal state is found in this case positive 10 0 and negative 10 two go through available spots on the board three call the min max function on each available spot recursion four evaluate returning values from function calls and five return the best value i'm going to go through the code for the minimax function don't worry if you don't completely understand it at first after i show the code i'm going to use an example and diagram to demonstrate the algorithms function calls one by one also if you're anything like me you may want to watch this section more than once to get a grasp on it before we define the minimax function we'll change the best spot function it's actually just going to return the result of calling the minimax function it's going to call the minimax function passing in a ridgeboard and ai player because it's the ai player playing and it's going to get dot index because the result of the minimax function is an object and dot index will be the index that the computer should play in so we'll define the minimax function with two arguments new board and player then we need to find the indexes of the available spots in the board using the empty squares function and set them to a square called avail spots we'll check for terminal states meaning someone winning and return a value accordingly if zero wins you should return negative ten if x wins you should return positive ten in addition if the length of the available spots array is zero that means there is no more room to play the game has resulted in a tie and you should return zero next you need to collect the scores from each of the empty spots to evaluate later therefore make an array called moves and loop through empty spots while collecting each moves index and score in an object called move then set the index number of the empty spot that was stored as a number in the ridge board to the index property of the move object then set the empty spot on the new board to the current player and call the minimax function with the other player and the newly changed new board next you should store the object resulted from the minimax function call that includes a score property to the score property of the move object if the minimax function does not find a terminal state it keeps recursively going level by level deeper into the game this recursion happens until it reaches a terminal state and returns a score one level up finally minimax resets new board to what it was before and pushes the move object to the moves array then the minimaps algorithm needs to evaluate the best move in the moves array it should choose the move with the highest score when ai is playing and the move with the lowest score when the human is playing therefore if the player is ai player it sets a variable called best score to a very low number and loops through the moves array if a move has a higher score than best score the algorithm stores that move in case there are moves with similar score only the first one will be stored the same evaluation process happens when player is hue player but this time best score would be set to a high number and minimax looks for a move with the lowest score to store at the end minimax returns the object stored in best move i want to emphasize again that it's okay if it takes a few reviews to understand this i had to go over it multiple times when i first learned it but this next example should help before we go over the example let's actually just try this out just to make sure i didn't make any mistakes when i was creating the code so i'm going to save that refresh over here and let's see oh reference air origin board not defined javascript 76 let's go up to 76 up here and this should be there's been i in there okay let's save that refresh and let's see if we have any more errors and this seems to be working let's see if it's possible to win it's not possible to win that i did something right okay i'm going to try it out a little more later but let's go over to the example in this example we're starting with this board configuration and then following how the minimax algorithm determines the next move assume the ai is x and the human player's o i'm going to use this figure right here to follow the algorithm's function calls one by one remember in this example we're pretending we're at the end of a tic-tac-toe game so there's just one more move left so the board looks like this so we're going to go through the code to figure out the exact logic that the program takes to figure out where to play so in figure one um we're at the very beginning of the minimax algorithm and the origin board and the ai player is fed into the algorithm and the algorithm is going to make a list of the three empty spots that it finds so if you see right here we have the spot here here the middle and then the bottom left it's going to check for terminal states and then loop through every empty spot starting from the first one here it's going to change the new board by placing the ai player in the first empty spot after that it's going to call itself with new board and the human player and wait for the function call to return a value so we're just on the first function call we're not to the end of the first function call yet but now we're already going to the second function call so while the first function call is still running the second one starts by making a list of the two empty spots it finds just these two that's here where it's making a list of the two empty spots it's going to check for terminal states and then loop through the empty spot starting at the first one then it changes the new board by placing the human player in the first empty spot after that it calls itself with new board and ai player and waits for the function call to return a value we're at the third function call which is right here still a function called two and one have not finished the algorithm makes a list of empty spots and this time it's going to find a win the human player is going to win therefore it returns an object with the score property and value of negative 10. and since this second function call up here listed two empty spots the min and max changes the new board by placing the human player in the second empty spot so it'll be right here and then it calls itself with the new port in the ai player so from function two we got to function three by placing a spot here in the middle and then we go from function two to function four by placing a spot in on the bottom left the algorithm makes a list of four spots the algorithm just makes a list of empty spots and finds a win for the human player after checking for terminal states and then it's going to return negative 10 again on the second function call the algorithm collects the values coming from lower levels the third and the fourth function calls since the human player's turn resulted in the two values the algorithm chooses the lowest of the two values on the second function called algorithm collects the values coming from the lower levels so we already have the index and then we're going to assign the score here and we're going to assign the index the new board and then we're pushing all the moves onto the moves array so that's how all the values have been collected from the third and fourth function calls since the human player's turn resulted in the two values the algorithm chooses the lowest of the two values so here's if the player is the ai player else which is what we're at now because the player is a human player it's going to run this code to select the lowest of the values since both values are similar it chooses the first one and returns up to the first function call that's down here when it returns moves best move at this point the first function call has evaluated the score of moving the ai player in the first empty spot next it changes the new board by placing ai player in the second empty spot so this was the first empty spot here's the second one in the middle it's going to call itself with the new board and the human player and i'm going to skip through some of this of every single thing that happens but you can see in function call one there are three empty spots and that's why there are three and level one so the first entry spots function called two the second empty spot is function call five and the third empty spot is function called six two empty spots here two moves here and here since we found a terminal state you don't actually go any further and here there's two empty spots so we try these two and then eventually you get down to eight and because of the recursive nature and like i was showing before this gets passed up to the top now toward the end of running the algorithm the three branches of the first function call have all been evaluated we got the negative 10 the 10 and the negative 10. but because the ai player's turn resulted in those values the algorithm returns an object containing the highest score which is the plus 10 at index four which is the middle index so in this scenario the minimax concludes that moving the x to the middle of the board results in the best outcome now to speed things along i didn't explain every single function call but if you check the article that i link to in the description it goes into even more detail about this i hope with my explanation and just being able to play with the code a little bit you'll be able to understand the logic behind the minimex algorithm okay and there's one final thing i still need to do you can see that the replay button is right up here in the corner and we want to put it in the pop-up box so i'm just going to go over to the html file and i'm going to select this button and then at least on a mac it's ctrl command up so it's going to move that line up and then it's going to tab it over and that should put the button in the right spot so let's refresh here and now the replay button doesn't show up until the game is over and you can click the replay button right on that little pop-up and you now have an unbeatable tic tac toe game there are many ways this game can be improved so for extra practice you can think about other features you can implement for instance maybe you want to make it two-player so there can be two human players instead of a human and computer player well thanks for watching my name is beau carnes don't forget to subscribe and remember use your code for good

Original Description

A full web development tutorial for beginners that demonstrates how to create an unbeatable tic tac toe game using vanilla JavaScript, HTML, and CSS. Learn the Minimax algorithm! ⌨ Part 1: Introduction (0:00) Code: none ⌨ Part 2: HTML (2:58) Code: https://github.com/beaucarnes/fcc-project-tutorials/tree/master/tictactoe/2 ⌨ Part 3: CSS (4:23) Code: https://github.com/beaucarnes/fcc-project-tutorials/tree/master/tictactoe/3 ⌨ Part 4: JavaScript: Basic Setup (10:28) Code: https://github.com/beaucarnes/fcc-project-tutorials/tree/master/tictactoe/4 ⌨ Part 5: JavaScript: Determine Winner (20:32) Code: https://github.com/beaucarnes/fcc-project-tutorials/tree/master/tictactoe/5 ⌨ Part 6: JavaScript: Basic AI & Winner Box (30:45) Code: https://github.com/beaucarnes/fcc-project-tutorials/tree/master/tictactoe/6 ⌨ Part 7: JavaScript: Minimax Algorithm (39:25) Code: https://github.com/beaucarnes/fcc-project-tutorials/tree/master/tictactoe/7 --- Special thanks to David Daly and myloginistaken who found a mistake where the game sometimes incorrectly shows a tie game. The 'Part 7' GitHub code now contains this fix. 🔗Minimax article: https://medium.freecodecamp.org/how-to-make-your-tic-tac-toe-game-unbeatable-by-using-the-minimax-algorithm-9d690bad4b37 🐦 Beau Carnes on Twitter: https://twitter.com/carnesbeau --- Learn to code for free and get a developer job: https://www.freecodecamp.com Read hundreds of articles on technology: https://medium.freecodecamp.com And subscribe for new programming videos every day: https://youtube.com/subscription_center?add_user=freecodecamp ❤️ Support for this channel comes from our friends at Scrimba – the coding platform that's reinvented interactive learning: https://scrimba.com/freecodecamp
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from freeCodeCamp.org · freeCodeCamp.org · 0 of 60

← Previous Next →
1 React: Production Server Setup Part 2 - Live Coding with Jesse
React: Production Server Setup Part 2 - Live Coding with Jesse
freeCodeCamp.org
2 cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
freeCodeCamp.org
3 Browser history tutorial - Beau teaches JavaScript
Browser history tutorial - Beau teaches JavaScript
freeCodeCamp.org
4 Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
freeCodeCamp.org
5 React: Parameterized Routing with Next.js - Live Coding with Jesse
React: Parameterized Routing with Next.js - Live Coding with Jesse
freeCodeCamp.org
6 React: Dealing with jQuery Issues - Live Coding with Jesse
React: Dealing with jQuery Issues - Live Coding with Jesse
freeCodeCamp.org
7 setInterval and setTimeout: timing events - Beau teaches JavaScript
setInterval and setTimeout: timing events - Beau teaches JavaScript
freeCodeCamp.org
8 Browser and Device Testing - Live Coding with Jesse
Browser and Device Testing - Live Coding with Jesse
freeCodeCamp.org
9 Last Minute Updates - Live Coding with Jesse
Last Minute Updates - Live Coding with Jesse
freeCodeCamp.org
10 Post Launch Updates - Live Coding with Jesse
Post Launch Updates - Live Coding with Jesse
freeCodeCamp.org
11 React: Setting Up Google Analytics - Live Coding with Jesse
React: Setting Up Google Analytics - Live Coding with Jesse
freeCodeCamp.org
12 React: Masonry Layout - Live Coding with Jesse
React: Masonry Layout - Live Coding with Jesse
freeCodeCamp.org
13 Load Balancing Digital Ocean Droplets - Live Coding with Jesse
Load Balancing Digital Ocean Droplets - Live Coding with Jesse
freeCodeCamp.org
14 try, catch, finally, throw - error handling in JavaScript
try, catch, finally, throw - error handling in JavaScript
freeCodeCamp.org
15 Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
freeCodeCamp.org
16 Graphs: breadth-first search - Beau teaches JavaScript
Graphs: breadth-first search - Beau teaches JavaScript
freeCodeCamp.org
17 React: Masonry Layout Part 2 - Live Coding with Jesse
React: Masonry Layout Part 2 - Live Coding with Jesse
freeCodeCamp.org
18 React: WordPress API Live Search - Live Coding with Jesse
React: WordPress API Live Search - Live Coding with Jesse
freeCodeCamp.org
19 Creating WordPress Custom Post Types - Live Coding With Jesse
Creating WordPress Custom Post Types - Live Coding With Jesse
freeCodeCamp.org
20 Dates - Beau teaches JavaScript
Dates - Beau teaches JavaScript
freeCodeCamp.org
21 Miscellaneous Front End Updates - Live Coding with Jesse
Miscellaneous Front End Updates - Live Coding with Jesse
freeCodeCamp.org
22 Merging a Pull Request from GitHub - Live Coding with Jesse
Merging a Pull Request from GitHub - Live Coding with Jesse
freeCodeCamp.org
23 React + Prettier + Standard JS - Live Coding with Jesse
React + Prettier + Standard JS - Live Coding with Jesse
freeCodeCamp.org
24 React: Sortable Responsive Table - Live Coding with Jesse
React: Sortable Responsive Table - Live Coding with Jesse
freeCodeCamp.org
25 Geolocation Sorting by Distance - Live Coding with Jesse
Geolocation Sorting by Distance - Live Coding with Jesse
freeCodeCamp.org
26 Tradeoff Matrix - Agile Software Development
Tradeoff Matrix - Agile Software Development
freeCodeCamp.org
27 The Definition of Ready - Agile Software Development
The Definition of Ready - Agile Software Development
freeCodeCamp.org
28 Getting first React job without experience - Ask Preethi
Getting first React job without experience - Ask Preethi
freeCodeCamp.org
29 React: Google Analytics Click Tracking - Live Coding with Jesse
React: Google Analytics Click Tracking - Live Coding with Jesse
freeCodeCamp.org
30 Submitting a PR to an Open Source Project - Live Coding with Jesse
Submitting a PR to an Open Source Project - Live Coding with Jesse
freeCodeCamp.org
31 Should I go back to school to get CS degree? - Ask Preethi
Should I go back to school to get CS degree? - Ask Preethi
freeCodeCamp.org
32 Hero Section CSS Changes - Live Coding with Jesse
Hero Section CSS Changes - Live Coding with Jesse
freeCodeCamp.org
33 Working Agreement - Agile Software Development
Working Agreement - Agile Software Development
freeCodeCamp.org
34 A day at Pennybox with Co-Founder Reji Eapen
A day at Pennybox with Co-Founder Reji Eapen
freeCodeCamp.org
35 React: Sorting and Filtering Data - Live Coding with Jesse
React: Sorting and Filtering Data - Live Coding with Jesse
freeCodeCamp.org
36 React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
freeCodeCamp.org
37 React: Building a New UI - Live Coding with Jesse
React: Building a New UI - Live Coding with Jesse
freeCodeCamp.org
38 Definition of Done - Agile Software Development
Definition of Done - Agile Software Development
freeCodeCamp.org
39 Getting started with jQuery (tutorial) - Beau teaches JavaScript
Getting started with jQuery (tutorial) - Beau teaches JavaScript
freeCodeCamp.org
40 Making a React Blog with WordPress Content - Live Coding with Jesse
Making a React Blog with WordPress Content - Live Coding with Jesse
freeCodeCamp.org
41 React, NextJS, CSS - Live Coding with Jesse
React, NextJS, CSS - Live Coding with Jesse
freeCodeCamp.org
42 jQuery events - Beau teaches JavaScript
jQuery events - Beau teaches JavaScript
freeCodeCamp.org
43 React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
freeCodeCamp.org
44 React: Working with API Data - Live Coding with Jesse
React: Working with API Data - Live Coding with Jesse
freeCodeCamp.org
45 React: Refactoring Components - Live Streaming with Jesse
React: Refactoring Components - Live Streaming with Jesse
freeCodeCamp.org
46 jQuery effects - Beau teaches JavaScript
jQuery effects - Beau teaches JavaScript
freeCodeCamp.org
47 More React Refactoring - Live Coding with Jesse
More React Refactoring - Live Coding with Jesse
freeCodeCamp.org
48 animate in jQuery - Beau teaches JavaScript
animate in jQuery - Beau teaches JavaScript
freeCodeCamp.org
49 "Finishing" My React Site - Live Coding with Jesse
"Finishing" My React Site - Live Coding with Jesse
freeCodeCamp.org
50 Starting a New React Project (P2D1) - Live Coding with Jesse
Starting a New React Project (P2D1) - Live Coding with Jesse
freeCodeCamp.org
51 React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
freeCodeCamp.org
52 The Agile Manifesto - Agile Software Development
The Agile Manifesto - Agile Software Development
freeCodeCamp.org
53 jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
freeCodeCamp.org
54 React Project 2 Day 3 - Live Coding with Jesse
React Project 2 Day 3 - Live Coding with Jesse
freeCodeCamp.org
55 The INVEST approach to product backlog items
The INVEST approach to product backlog items
freeCodeCamp.org
56 React Project 2 Day 4 - Live Coding with Jesse
React Project 2 Day 4 - Live Coding with Jesse
freeCodeCamp.org
57 Chickens and Pigs - Agile Software Development
Chickens and Pigs - Agile Software Development
freeCodeCamp.org
58 React Project 2 Day 5 - Live Coding with Jesse
React Project 2 Day 5 - Live Coding with Jesse
freeCodeCamp.org
59 jQuery: add and remove DOM elements - Beau teaches JavaScript
jQuery: add and remove DOM elements - Beau teaches JavaScript
freeCodeCamp.org
60 React Project 2 Day 6 - Live Coding with Jesse
React Project 2 Day 6 - Live Coding with Jesse
freeCodeCamp.org

Related Reads

📰
Say Goodbye To Electron?
Learn about a new approach to building native applications without Electron, using frontend-style development
Medium · Programming
📰
Why Vanilla JS? In the article below, I am sharing my story of building SaaS product in vanilla js and explaining why I decided to go with this approach. https://guseyn.com/html/posts/why-vanilla-js.html
Learn why choosing Vanilla JS can be a great approach for building SaaS products and how it can simplify development
Dev.to · Guseyn Ismayylov
📰
How to Create a Cursor Tail Using HTML, CSS, and JavaScript
Learn to create a colorful cursor tail using HTML, CSS, and JavaScript for a unique user interface effect
Medium · JavaScript
📰
I built a landing page with Three.js, vanilla JS, and zero frameworks — here's what I learned
Learn how to build a landing page with Three.js and vanilla JS without relying on frameworks, and discover the key takeaways from this project
Dev.to · Ayush Shekhar
Up next
How To Build A Twitter Clone - React Next JS - Appwrite Crash Course
Adrian Twarog
Watch →