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()