Tic Tac Toe — An Object Oriented Design
By: Nitish Sharma
Tags: Tic Tac Toe, Design Patterns, Strategy Pattern, Object Oriented

Came across some dusty old school notebooks while cleaning today. Upon opening them, I wasn’t surprised to see random games of tic-tac-toe between notes.

And so, I got my “real world thing” for today.

Noughts and Crosses

A game for two players, X and O, who take turns marking the spaces in a 3×3 grid. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row is the winner.

Let’s get crackin’

Whenever it comes to board games, the first thing that comes to mind is ways to win.

To say it in one word; strategy.

In order to win, a player will have to choose a strategy and more often than not switch to another strategy based on the opponent’s move and board setting.

How might we play this game?

Play in an open square

Play to an open corner

How can we stay in the game?

Block the opponent from winning

How can we win the game?

Place a third piece in a row to win

Based on this behaviour of the system, we can incorporate the Strategy Pattern

Strategy Design Pattern

Strat­e­gy is a behav­ioural design pat­tern that lets you define a fam­i­ly of algo­rithms, put each of them into a sep­a­rate class, and make their objects inter­change­able.

Strategy pattern UML diagram

Con­text stories a ref­er­ence to one of the con­crete strate­gies and com­mu­ni­cates with this object only via the strat­e­gy interface

stories a ref­er­ence to one of the con­crete strate­gies and com­mu­ni­cates with this object only via the strat­e­gy interface Strat­e­gy inter­face is com­mon to all con­crete strate­gies. It declares a method the con­text uses to exe­cute a strategy.

inter­face is com­mon to all con­crete strate­gies. It declares a method the con­text uses to exe­cute a strategy. Con­crete Strate­gies imple­ment dif­fer­ent vari­a­tions of an algo­rithm the con­text uses

imple­ment dif­fer­ent vari­a­tions of an algo­rithm the con­text uses Con­text calls the exe­cu­tion method on the linked strat­e­gy object each time it needs to run the algo­rithm and doesn’t know what type of strat­e­gy it works with or how the algo­rithm is executed

calls the exe­cu­tion method on the linked strat­e­gy object each time it needs to run the algo­rithm and doesn’t know what type of strat­e­gy it works with or how the algo­rithm is executed Client cre­ates a spe­cif­ic strat­e­gy object and pass­es it to the con­text. The con­text expos­es a set­ter which lets clients replace the strat­e­gy asso­ci­at­ed with the con­text at runtime

Classes and Objects

The classes for our design will be:

TicTacToeStrategy — The interface used by all strategies

The interface used by all strategies Player — The player serves as the context and executes the strategy

The player serves as the context and executes the strategy Classes for concrete strategies — AnyOpenSquare, AnyOpenCorner BlockOpponent, PlayToWin

TicTacToeBoard — Class to represent the game board state

Class to represent the game board state Position — Class to represent position of a piece

Class diagram for the system

The Code

Classes to represent the game board and piece position

Strategy interface and concrete classes for various game playing strategies

Player as context with the ability to set and execute strategies

This is how this system will function

# Create a game board

board = TicTacToeBoard.new # Create player and set strategy for their first moves

player1 = Player.new(AnyOpenCorner.new)

player2 = Player.new(AnyOpenSquare.new) # Players change strategies as the game progresses

player1.strategy = AnyOpenSquare.new

player1.execute_strategy(board) # ... game continues

# player1 at the verge of winning

player2 = Player.new(BlockOpponent.new)

References