Tic Tac Toe (3)¶
In today’s lecture, we will continue our discussion on building a simple text-based board game (Tic Tac Toe). In the process, we will learn about the benefits of inheritance, encapsulation and more generally of object-oriented design.
Tic Tac Toe Letter¶
Last time we looked at TTTBoard, which inherits from Board and also adds Tic Tac Toe specific features. Today we’ll look at the final two classes: TTTLetter and TTTGame.
# TTTLetter class
"""Implements the functionality of a letter in Boggle."""
from graphics import *
class TTTLetter:
"""A TTT letter has several attributes that define it:
* _row, _col coordinates indicate its position in the grid (ints)
* _textObj denotes the Text object from the graphics module,
which has attributes such as size, style, color, etc
and supports methods such as getText(), setText() etc.
"""
__slots__ = ['_row', '_col', '_textObj']
def __init__(self, win, col=-1, row=-1, letter=""):
# global variables needed for graphical testing
xInset = 50; yInset = 50; size = 50
# set row and column attributes
self._col = col
self._row = row
self._textObj = Text(Point(xInset + size * col + size / 2,
yInset + size * row + size / 2), letter)
self._textObj.setSize(20)
self._textObj.setStyle("bold")
self._textObj.setTextColor("black")
self._textObj.draw(win)
def getLetter(self):
"""Returns letter (text of type str) associated with property textObj"""
return self._textObj.getText()
def setLetter(self, char):
self._textObj.setText(char)
def __str__(self):
l, col, row = self.getLetter(), self._col, self._row
return "{} at Board position ({}, {})".format(l, col, row)
def __repr__(self):
return str(self)
win = GraphWin("Tic Tac Toe", 400, 400)
letter = TTTLetter(win, 1, 1, "X")
letter2 = TTTLetter(win, 1, 2, "O")
letter3 = TTTLetter(win, 2, 1, "X")
letter2.setLetter("T")
print(letter2)
win.close()
Tic Tac Toe Game¶
Finally, let’s put it all together and implement the game logic in TTTGame.
"""Implements the logic of the game of tic tac toe."""
from graphics import GraphWin
from tttboard import TTTBoard
from tttletter import TTTLetter
class TTTGame:
__slots__ = [ "_board", "_numMoves", "_player" ]
def __init__(self, win):
self._board = TTTBoard(win)
self._player = "X"
self._numMoves = 0
def doOneClick(self, point):
"""Implements the logic for processing one click.
Returns True if play should continue, and False if the
game is over."""
# step 1: check for exit button and exit
if self._board.inExit(point):
# game over
return False
# step 2: check for reset button and reset game
elif self._board.inReset(point):
self._board.reset()
self._board.clearUpperText()
self._numMoves = 0
self._player = "X"
# step 3: check if click is on a cell in the grid
elif self._board.inGrid(point):
tlet = self._board.getTTTLetterAtPoint(point)
# make sure this square is vacant
if tlet.getLetter() == "":
tlet.setLetter(self._player)
# valid move, so increment numMoves
self._numMoves += 1
# check for win or draw
winFlag = self._board.checkForWin(self._player)
if winFlag:
self._board.setStringToUpperText(self._player + " WINS!")
elif self._numMoves == 9:
self._board.setStringToUpperText("DRAW!")
# not a win or draw, swap players
else:
# set player to X or O
if self._player == "X":
self._player = "O"
else:
self._player = "X"
# keep going!
return True
win = GraphWin("Tic Tac Toe", 400, 400)
game = TTTGame(win)
keepGoing = True
while keepGoing:
point = win.getMouse()
keepGoing = game.doOneClick(point)
win.close()