Revisiting ‘Tic-Tac-Toe’
Presenting at last week’s ‘Flatiron School Presents’ made me think of 5 months ago, pre-Flatiron, when I was on the other side, watching current students present their cool projects and trying to digest all their tech lingo. It was also around then that I’d be racking my brain trying to complete Flatiron’s Tic Tac Toe code challenge, with more or less 2 months of self-taught Ruby.
I decided to revisit it, 5 months later, halfway through bootcamp, to attempt to refactor the game with what I’ve learned so far.
The good: my original code (kinda) worked!
The bad: it goes against good practices of object orientation.
The ugly: it really goes against good practices of object orientation.
Pre-Flatiron me would break every single one of Sandi Metz’ 4 rules for good object-oriented programming. I didn’t really understand the purpose of classes back then, so my original code didn’t have any. No classes that knows, for example, which player object is playing, which board object is the one being used in a given game, and which player will play next. It’s important to keep the classes concise, with one functionality, just as it is to follow the single responsibility principle for methods. My methods are painfully long.
Here’s a snippet of my check_winner method in my original code (cringe) aka a chunk of long, repetitive code:

Step one is to realize my code would be much more readable and clean if I used smaller methods that each accomplish one purpose. Here’s a (less painful) snippet of the refactored version — smaller methods within the Board class — one line of functionality for each:


I’ll then pass the @board object in the Player class to determine the winner and to check if the game is tied.

I also want to add a class that makes winning moves for the computer and that’ll block potential wins by the human player. That said, I still have a long way to go to refactor and become more fluent with OO principles (click here to see what I have so far), but I’m definitely learning how important it is to write clean, reusable code.