Advertisement
asweigart

tictactoe_pythonic_oop.py

Dec 8th, 2017
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.90 KB | None | 0 0
  1. # Tic Tac Toe
  2.  
  3. TL, TM, TR, ML, MM, MR, BL, BM, BR = 'TL', 'TM', 'TR', 'ML', 'MM', 'MR', 'BL', 'BM', 'BR'
  4. ALL_SPACES = (TL, TM, TR, ML, MM, MR, BL, BM, BR)
  5. X, O, BLANK = 'X', 'O', ' '
  6.  
  7. def main():
  8.     print('Welcome to Tic Tac Toe!')
  9.     mainBoard = TicTacToeBoard()
  10.     turn = X
  11.     nextTurn = O
  12.  
  13.     while True:
  14.         print('It is ' + turn + '\'s turn.')
  15.         print(mainBoard)
  16.         move = mainBoard.getPlayerMove()
  17.         mainBoard[move] = turn
  18.  
  19.         if mainBoard.isWinner(turn):
  20.             print(mainBoard)
  21.             print(turn + ' has won the game!')
  22.             break
  23.         elif len(mainBoard) == 9:
  24.             print(mainBoard)
  25.             print('The game is a tie!')
  26.             break
  27.         print()
  28.  
  29.         turn, nextTurn = nextTurn, turn
  30.  
  31.  
  32. class TicTacToeBoard:
  33.     def __init__(self, startingMarks=None):
  34.         # Create a new, blank tic tac toe board.
  35.         if startingMarks is None:
  36.             startingMarks = {}
  37.         self._spaces = {}
  38.         for space in ALL_SPACES:
  39.             self._spaces.setdefault(space, startingMarks.get(space, BLANK))
  40.         self._i = 0
  41.  
  42.     def __len__(self):
  43.         spacesUsed = 0
  44.         for space in ALL_SPACES:
  45.             if self[space] != BLANK:
  46.                 spacesUsed += 1
  47.         return spacesUsed
  48.  
  49.     def __str__(self):
  50.         # Display a text-representation of the board.
  51.         s = [f'{self[TL]}|{self[TM]}|{self[TR]}',
  52.              '-----',
  53.              f'{self[ML]}|{self[MM]}|{self[MR]}',
  54.              '-----',
  55.              f'{self[BL]}|{self[BM]}|{self[BR]}']
  56.         return '\n'.join(s)
  57.  
  58.     def __iter__(self):
  59.         return self
  60.  
  61.     def __next__(self):
  62.         if self._i == 9:
  63.             self._i = 0
  64.             raise StopIteration
  65.         self._i += 1
  66.         space = ALL_SPACES[self._i - 1]
  67.         return (space, self[space])
  68.  
  69.     def __repr__(self):
  70.         className = type(self).__name__
  71.         return f'{className}({dict(self)})'
  72.  
  73.     def isWinner(self, mark):
  74.         le = mark # Syntactic sugar to make the following code shorter.
  75.         return ((self[TL] == m and self[TM] == m and self[TR] == m) or # across the top
  76.                 (self[ML] == m and self[MM] == m and self[MR] == m) or # across the middle
  77.                 (self[BL] == m and self[BM] == m and self[BR] == m) or # across the selfttom
  78.                 (self[TL] == m and self[ML] == m and self[BL] == m) or # down the left side
  79.                 (self[TM] == m and self[MM] == m and self[BM] == m) or # down the middle
  80.                 (self[TR] == m and self[MR] == m and self[BR] == m) or # down the right side
  81.                 (self[TL] == m and self[MM] == m and self[BR] == m) or # diagonal
  82.                 (self[TR] == m and self[MM] == m and self[BL] == m)) # diagonal
  83.  
  84.     def getPlayerMove(self):
  85.         # Let the player type in their move.
  86.         move = None
  87.         while move not in ALL_SPACES or not self[move] == BLANK:
  88.             print('What is your move? (TL TM TR ML MM MR BL BM BR)')
  89.             move = input().upper()
  90.         return move
  91.  
  92.     #def isFull(self):
  93.     #    # Return True if every space on the board has been taken. Otherwise return False.
  94.     #    return len(self) == 9
  95.  
  96.     def __getitem__(self, key):
  97.         if key not in ALL_SPACES:
  98.             raise KeyError(f'index must be one of {ALL_SPACES}')
  99.         return self._spaces[key]
  100.  
  101.     def __setitem__(self, key, value):
  102.         # Sets the space on the board to mark, if it is valid.
  103.         if key not in ALL_SPACES:
  104.             raise KeyError(f'index must be one of {ALL_SPACES}')
  105.         if value not in (X, O, BLANK):
  106.             raise ValueError('invalid mark for space')
  107.         self._spaces[key] = value
  108.  
  109.     def __delitem__(self, key):
  110.         if key not in ALL_SPACES:
  111.             raise KeyError(f'index must be one of {ALL_SPACES}')
  112.         self._spaces[key] = BLANK
  113.  
  114. if __name__ == '__main__':
  115.     pass#main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement