Skip to content

Instantly share code, notes, and snippets.

@ana0
Created April 11, 2016 02:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ana0/9aaa29450a36bb2c384ff2cca681023f to your computer and use it in GitHub Desktop.
Save ana0/9aaa29450a36bb2c384ff2cca681023f to your computer and use it in GitHub Desktop.
import random
class Board(object):
def __init__(self):
self.board = [[" "," "," "], [" "," "," "], [" "," "," "]]
def print_board(self):
topstr = " a b c"
linestr = " +-----+-----+-----+"
rowstr = "%s | %s | %s | %s |"
print topstr
for i, row in enumerate(self.board):
print linestr
print rowstr % (i, self.board[i][0], self.board[i][1],
self.board[i][2])
print linestr
def set_position(self, position, char):
self.board[position[0]][position[1]] = char
return True
def look_for_win(self):
for i in range(len(self.board)):
# Check each row
if (self.board[i][0] == self.board[i][1] == self.board[i][2]
and self.board[i][0].isalpha()):
return self.board[i][0]
# Check each column
elif (self.board[0][i] == self.board[1][i] == self.board[2][i]
and self.board[0][i].isalpha()):
return self.board[0][i]
# Check diagonals
if (self.board[0][0] == self.board[1][1] == self.board[2][2]
and self.board[0][0].isalpha()):
return self.board[0][0]
if (self.board[0][2] == self.board[1][1] == self.board[2][0]
and self.board[0][2].isalpha()):
return self.board[0][2]
return False
def check_empty_spaces(self):
for row in self.board:
for i in row:
if i == " ":
return True
return False
class Game(object):
def __init__(self):
# Boolean triggers the outer game loop
self.playing_game = True
self.game_type = False
def set_game_type(self):
# At the moment, the game will force you to play a human
print "Would you like to play against another human or the computer?"
answer = raw_input("Type 'h' for human and 'c' for computer\n")
if answer.strip().lower() == "h":
print "You've chosen to play a human!\n"
self.game_type = "h"
elif answer.strip().lower() == "c":
print "You've chosen to play the computer!\n"
self.game_type = "c"
else:
print "I'm sorry that doesn't seem to be one of the options\n"
def set_players(self):
while not self.game_type:
self.set_game_type()
player_o = Player()
player_o.get_player_name("o")
if self.game_type == "c":
player_x = ComputerPlayer()
player_x.say_hello()
return [player_x, player_o]
player_x = Player()
player_x.get_player_name("x")
return [player_x, player_o]
def goes_first(self, players):
first = random.choice(players)
print "\nPlayer %s will go first" % first.name
not_first = [i for i in players if i != first]
players = [first, not_first[0]]
return players
def win(self, playing):
print "Congratilations %s, you won!" % playing.name
print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
return True
def tie(self):
print "The game is a tie!"
print "One of you should make more mistakes next time!"
def game_loop(self):
players = self.set_players()
board = Board()
players = self.goes_first(players)
board.print_board()
winner = board.look_for_win()
while not winner:
players[0].turn(board)
board.print_board()
winner = board.look_for_win()
if winner:
congratulations = self.win(players[0])
break
elif not board.check_empty_spaces():
self.tie()
break
players = [players[1], players[0]]
replay = self.play_again()
while not replay:
self.play_again()
def play_again(self):
answer = raw_input("Would you like to play again? 'y' or 'n'\n")
if answer.strip().lower() == "y":
print "Let's play again!"
return True
elif answer.strip().lower() == "n":
print "Ok, goodbye!"
self.playing_game = False
return True
else:
print "I'm sorry that doesn't seem to be one of the options"
return False
def tutorial():
print "Welcome to tictactoe! Would you like to hear the instructions?"
answer = raw_input("Type 'y' or 'n' and then press Enter\n")
if answer.strip().lower() == "y":
print "This is the board:"
test_board = Board()
test_board.print_board()
print "You can declare a move by typing the name of the row and column"
print "For example typing, '0a' would place your marker like this:"
test_board.set_position((0,0),"x")
test_board.print_board()
print "When you have three marks in a row, you win!\n"
return True
elif answer.strip().lower() == "n":
print "ok!\n"
return True
else:
print "I'm sorry that doesn't seem to be one of the options\n"
return False
class Player(object):
def __init__(self):
self.name = ""
self.marker = ""
def get_player_name(self, mark):
name = raw_input("Player %s enter your name\n" % mark)
self.name = name
self.marker = mark
def parse_position(self, position, board):
# Sort the input string
# This is so players can enter their row, column in any order
row =[c for c in position if c in "012"]
column = [c.lower() for c in position if c in "abcABC"]
# Was it a valid input?
if len(row) != 1 or len(column) != 1:
print "That doesn't seem to be a valid position\n"
return False
# Translate list/letter input to ints
row, column = int(row[0]), column[0]
if column == "a":
column = 0
elif column == "b":
column = 1
else:
column = 2
# Make sure the space is empty
if board.board[row][column] != " ":
print "Sorry that spot is already taken\n"
return False
return (row, column)
def turn(self, board):
move = raw_input("Player %s make your move!\n" % self.name)
valid_position = self.parse_position(move, board)
while not valid_position:
move = raw_input("Player %s make your move!\n" % self.name)
valid_position = self.parse_position(move, board)
board.set_position(valid_position, self.marker)
class ComputerPlayer(object):
def __init__(self):
self.hellostr = "\n'Hi I'm the computer, I'll be playing as 'x''\n"
self.name = "Computer"
self.marker = "x"
self.opponent = "o"
def say_hello(self):
print self.hellostr
def get_possible_moves(self, b):
possible_moves = []
priority = 0
for column, row in enumerate(b.board):
for i, row in enumerate(row):
if b.board[i][column] != " ":
continue
else:
possible_moves.append((i,column))
return possible_moves
def check_row(self, b, move, char):
count = 0
for i in range(len(b.board)):
if (move[0],i) != move and b.board[move[0]][i] == char:
count += 1
return count
def check_column(self, b, move, char):
count = 0
for i in range(len(b.board)):
if (i,move[1]) != move and b.board[i][move[1]] == char:
count += 1
return count
def check_diagonal_one(self, b, move, char):
count = 0
if move[0] == move[1]:
for m in [(0,0),(1,1),(2,2)]:
if m != move and b.board[m[0]][m[1]] == char:
count += 1
return count
def check_diagonal_two(self, b, move, char):
count = 0
if move[0]+move[1] == len(b.board)-1:
for m in [(0,2),(1,1),(2,0)]:
if m != move and b.board[m[0]][m[1]] == char:
count += 1
return count
def prioritize(self, board, move, char):
priority = []
priority.append(self.check_row(board, move, char))
priority.append(self.check_column(board, move, char))
priority.append(self.check_diagonal_one(board, move, char))
priority.append(self.check_diagonal_two(board, move, char))
return priority
def check_for_win_in_one(self, board, moves, char):
for move in moves:
can_win = self.prioritize(board, move, char)
if 2 in can_win:
return move
return False
def can_checkmate(self, board, moves, char):
for move in moves:
checkmate = self.prioritize(board, move, char)
if checkmate.count(1) >= 2:
checkmate = self.prioritize(board, move, " ")
if checkmate.count(1) >= 2:
return move
return False
def best_move(self, board):
moves = self.get_possible_moves(board)
if len(moves) == 1:
return moves[0]
if len(moves) >= 8:
rand = random.choice([(0,0),(0,2),(2,0),(2,2),(1,1),(1,1)])
while rand not in moves:
rand = random.choice([(0,0),(0,2),(2,0),(2,2),(1,1),(1,1)])
return rand
if self.check_for_win_in_one(board, moves, self.marker):
return self.check_for_win_in_one(board, moves, self.marker)
if self.check_for_win_in_one(board, moves, self.opponent):
return self.check_for_win_in_one(board, moves, self.opponent)
if self.can_checkmate(board, moves, self.marker):
return self.can_checkmate(board, moves, self.marker)
if self.can_checkmate(board, moves, self.opponent):
return self.can_checkmate(board, moves, self.opponent)
rand = random.choice([(0,1),(1,0),(2,1),(1,2),(1,1)])
while rand not in moves:
rand = random.choice([(0,1),(1,0),(2,1),(1,2),(1,1)])
return rand
def turn(self, b):
move = self.best_move(b)
b.set_position(move, self.marker)
def run():
play_instructions = tutorial()
while not play_instructions:
play_instructions = tutorial()
game = Game()
while game.playing_game:
game.game_loop()
if __name__ == "__main__":
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment