Skip to content

Instantly share code, notes, and snippets.

@jarrodhroberson
Created July 25, 2019 17:10
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 jarrodhroberson/c39a8a4e5a5f9dd686fde86dc224b240 to your computer and use it in GitHub Desktop.
Save jarrodhroberson/c39a8a4e5a5f9dd686fde86dc224b240 to your computer and use it in GitHub Desktop.
Python 3 TicTacToe Game for Console
# Import needed modules
import os
import time
import re
# Regular Expression to validate that the input is in the expected format!
inputPattern = re.compile('^\d{1},\d{1}$')
#Initialize a 2D array to represent the board using a SPACE to represent unclaimed cells.
board = [[' ' for x in range(3)] for y in range(3)]
# keep up with the current player.
current_player = 0
# Draw a single row of the board.
def drawRow(row,board):
print(u"{0} {1}|{2}|{3}".format(row,board[row][0], board[row][1], board[row][2]))
# Draw the entire board.
def drawBoard(board):
# Draw the Column Indexes
print(" 0 1 2")
for r in range(3):
drawRow(r,board)
if r < 2:
print(" \u2014 \u2014 \u2014")
# Validate the input to make sure the input is in range and not already taken.
# Pause 3 seconds on failures so the player can read the error message!
def validateCoordinates(row,col,board):
if row not in range(0,3):
print('Row must be between 0 and 2')
time.sleep(3)
return False
elif col not in range(0,3):
print('Column must be between 0 and 2')
time.sleep(3)
return False
elif board[row][col] != ' ':
print("{},{} is already taken by {}".format(row, col, board[row][col]))
time.sleep(3)
return False
else:
return True
# Register the players move on the board.
def registerMove(board,row,column,player):
if validateCoordinates(row,column,board):
board[row][column] = "O" if player == 0 else "X"
return True
else:
return False
#Clear the Screen ( works on Linux and Windows (nt) differently! )
def clearScreen():
os.system('cls' if os.name == 'nt' else 'clear')
# Evaluate the state of the board and determine if the game is over.
def is_game_over(board,current_player):
# An Entire Row is captured by the same player.
for r in range(0,3):
if board[r][0] != ' ' and (board[r][0] == board[r][1] and board[r][0] == board[r][2]):
print("Player {} WINS!".format(current_player))
return True
# An entire column is captured by the same player.
for c in range(0,3):
if board[0][c] != ' ' and (board[0][c] == board[1][c] and board[0][c] == board[2][c]):
print("Player {} WINS!".format(current_player))
return True
# Diagonal is captured by the same player.
if board[0][0] != ' ' and (board[0][0] == board[1][1] and board[1][1] == board[2][2]):
print("Player {} WINS!".format(current_player))
return True
elif board[0][2] != ' ' and (board[0][2] == board[1][1] and board[1][1] == board[2][0]):
print("Player {} WINS!".format(current_player))
return True
else:
# All the cells are captured but no one wins!
for r in range(0,3):
for c in range(0,3):
if board[r][c] == ' ':
return False
print("DRAW! Nobody Wins!")
return True
# Start the script running!
clearScreen()
drawBoard(board)
# Game Loop runs until the game is over. Win or Draw will return True
while not is_game_over(board,current_player):
move = input("Player {} Enter Row,Column: ".format(current_player + 1))
# make sure the input is formatted as expected
if inputPattern.match(move):
# parse the input into something we can use
parsed = move.split(",")
row = int(parsed[0])
col = int(parsed[1])
if registerMove(board,row,col,current_player):
current_player ^= 1
clearScreen()
drawBoard(board)
else:
clearScreen()
drawBoard(board)
continue
else:
print("Input must match the format #,#! '{}' does not match this format!".format(move))
time.sleep(3)
clearScreen()
drawBoard(board)
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment