FCC Speedrun — Project #3: Tic-Tac-Toe

fiftyfivebells
3 min readMay 11, 2017

--

My third project of the speedrun has taken the word speed right out of it. I wasn’t moving quickly before (about a week/project), but this was a different thing altogether. I hit a wall with this project that slowed me down significantly, but this was also a great learning experience that I think will be very helpful in the future.

Part 1 (days 1–4):

I started this project off the way I’ve started the past couple: I made a skeleton in HTML/CSS and then set to work making the JavaScript section. I decided I would make a game object that created the board and handled the moves, then make the logic of the game use that object. My first step was just making sure that I could pair the JavaScript with the HTML/CSS, so I made a function that would alternate turns every click, putting an X, then an O, and so forth. After this, it quickly got complicated. It turns out that trying to handle the JavaScript and the display of the page together was very difficult.

I was also struggling with keeping track of the state. I was trying to use global variables that interacted with the object, and passed the state of the game into it. It became apparent that this was a lot more work than I had anticipated. It was on the third or fourth day that I came across a concept in JavaScript Allonge that basically said the logic of your program should work entirely independently of the DOM. This was a turning point for me!

Part 2 (days 4–9):

At this point, I realized that I could have my game object keep track of everything related to the game and have it return any important pieces of info that I needed. I didn’t start totally from scratch, but I was pretty close. Having all of the logic closed up in the game object made it much easier to manage what was going on, and I could use the values returned to make everything happen on the page. It was pretty much smooth sailing from here on out.

There were really only two major issues after this point. The first was figuring out how exactly to determine the winner, and the second was how to make the computer choose its own moves. For checking the winner, I made an array of winning combinations. Then I checked those combos against my game-board array. Each AI move put a 10 in the array, and each user move was a 1. That way, if the winning combo added up to 30 or 3, I had found a winner.

For the logic of the computer’s moves, I just drew heavily from the Tic-Tac-Toe Wikipedia entry. Basically, the program would attempt to win first, then attempt to block the opponent’s win second. Depending on whether it was the start of the game or not, it would choose a corner, a side, or the center. I don’t think it’s perfect, but I haven’t managed to beat it yet! I was initially going to try to implement the minimax algorithm I read about, but it seemed a bit over my head. When I try this project again, I’ll give that another shot and see how it goes.

The final annoying issue was that after I had everything working on Chrome, it was not working on Firefox. As it turns out, Chrome’s click event has a .path event, but Firefox’s does not. Luckily, they both have a .target event that has the info I was looking for, so after changing those lines, everything works great!

Final Thoughts

This was probably the most challenging FCC project I’ve done yet, but I also learned a lot. I feel like the revelation about separating the program logic from the DOM was a pretty big breakthrough for me. It seems obvious now, but I was super excited to come across that in the book and apply it to this problem. I think it’ll make a big difference for me in future projects.

There is a live version of the project here.

The code for this project can be found in this repository.

Notes:

  • The big takeaway here is to remember to keep my program logic separate from the DOM. I can write code to make the program and the DOM interact, but the program can (and should?) stand alone and work without it. I’ll try to stick with this rule of thumb much more strictly in the next project, the Simon game.

Done so far:

--

--