Skip to content

Instantly share code, notes, and snippets.

@apsicle
Created October 11, 2016 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apsicle/0274e62d30a66d4310fdb7c41ee0d366 to your computer and use it in GitHub Desktop.
Save apsicle/0274e62d30a66d4310fdb7c41ee0d366 to your computer and use it in GitHub Desktop.
# Written by: Ryan Yan
# Paired with Oskar Thoren
# Date: October 11th, 2016
#
# This program lets you play tic tac toe in the console using keyboard input against a computer.
import random
class Player:
'''Player objects keep track of the spaces they control on the grid (add_square and get_squares)
and has their symbol, default X's and O's as their string representation'''
def __init__(self, symbol, human = True):
self._squares = set() #Set of controlled spaces. Holds indices from 0-8 held by player in Board._grid
self._symbol = symbol
self._human = human
def add_square(self, ind):
self._squares.add(ind)
def get_squares(self):
return self._squares.copy()
def is_Human(self):
return self._human
def __str__(self):
return self._symbol
class Board:
'''Tictactoe game class. Contains the grid to be printed, a list of available spaces, and makes moves
occur and determines the victor.'''
def __init__(self):
self._grid = list(range(1, 10, 1)) #Grid to be printed. filled with X and Os
self._squares = list(range(9)) #List of available spaces. Holds indices from 0-8 open in _grid
self._win_conditions = [{0,1,2}, {3,4,5}, {6,7,8}, #rows
{0,3,6}, {1,4,7}, {2,5,8}, #columns
{0,4,8}, {2,4,6}] #diagonals
self._victor = None
def clear_grid(self):
self._grid = [""] * 9
def make_move(self, player):
if not self._squares: #If no spaces are left, but someone has to move, then it was a tie
self._victor = "Nobody"
if player.is_Human():
#Asks for input and updates all the square lists in Player and in Board, then checks win condition
while(True):
#Checks and validates input
try:
move = int(input("%s's move: " % str(player))) - 1
self._squares.index(move)
break
except ValueError:
print("Please enter an integer between 1 and 9")
else:
move = self.computer_move(player)
#Updates lists containing squares and checks victory conditions.
self._squares.remove(move)
player.add_square(move)
self._grid[move] = str(player)
self.check_win(player)
def computer_move(self, player):
#The computer checks if any moves will result in victory, and does that. Failing this, it picks
#a random square.
for square in self._squares:
for condition in self._win_conditions:
combined = player.get_squares()
combined.add(square)
if condition.issubset(combined):
return square;
chosen = random.randint(0, len(self._squares) - 1)
move = self._squares[chosen]
return move
def check_win(self, player):
#Checks if any victorious set of squares is a subset of squares held by a particular player
held_squares = player.get_squares()
for condition in self._win_conditions:
if condition.issubset(held_squares):
self._victor = player
return
def play(self):
#Sets up the game
player_one = Player("X")
player_two = Player("O", False)
players = [player_one, player_two]
current_player = 0
print(self)
self.clear_grid()
print("Use integers 1-9 to specify the location on the board")
#Gameplay
while(self._victor == None):
self.make_move(players[current_player%2])
print(self)
current_player = current_player + 1
print("The %s's have it!" % str(self._victor))
def __str__(self):
#Prints out the game board
for row in range(3):
adjust = 3 * row
print("%2s%2s%2s%2s%2s" % (self._grid[adjust+0], "|", self._grid[adjust+1], "|", self._grid[adjust+2]))
if(row != 2):
print("___|___|___")
else:
print("%4s%4s" % ("|", "|"))
return ""
if __name__ == "__main__":
new_game = Board()
new_game.play()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment