# Repetitive Tic-Tac-Toe AI game with Python 3

I have a text based Tic-Tac-Toe game with a simple AI element that will take winning moves and block losing moves. The one piece of criticism I received was that I was 'hard coding' too much. I can see this, for example, in check_computer_win. How can I use a dictionary to cut down on hard coding? What are some of the best ways I can solve my repetition problem?

#! python

""" This my Tic Tac Toe game with python.

2019-01-10

"""

import random
import sys

board = [1,2,3,4,5,6,7,8,9]
open_boxes = 9
human_letter = ''
opp_letter = ''
winner = False
can_block = False

def choose_letter():
global human_letter
global opp_letter
human_letter = input('Please choose "x" or "o": ').lower()
if human_letter == 'x':
opp_letter = 'o'
elif human_letter == 'o':
opp_letter = 'x'
else:
choose_letter()

def show_board():
print (board[0], '|', board[1], '|', board[2])
print ("----------")
print (board[3], '|', board[4], '|', board[5])
print ("----------")
print (board[6], '|', board[7], '|', board[8])
print (" ")

def checkLine(char, first, second, third):
if board[first] == char and board[second] == char and board[third] == char:
return True

def checkAll(char):
if checkLine(char,0,1,2):
return True
if checkLine(char,3,4,5):
return True
if checkLine(char,6,7,8):
return True
if checkLine(char,0,3,6):
return True
if checkLine(char,1,4,7):
return True
if checkLine(char,2,5,8):
return True
if checkLine(char,0,4,8):
return True
if checkLine(char,2,4,6):
return True

def computer_move():
global open_boxes
if open_boxes > 0:
check_computer_win()
if not winner:
block_human_win()
if not can_block:
opp_move = random.randint(0,8)
if board[opp_move] != 'o' and board[opp_move] != 'x':
open_boxes -= 1
board[opp_move] = opp_letter
print('Computer\'s turn')
print('Computer is thinking...')
print('\n')
show_board()
else:
computer_move()
else:
print('--DRAW--')
play_again()

def check_computer_win():
#check for a top horizontal win
if board[0] == opp_letter and board[1] == opp_letter:
if board[2] != human_letter:
board[2] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[0] == opp_letter and board[2] == opp_letter:
if board[1] != human_letter:
board[1] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[1] == opp_letter and board[2] == opp_letter:
if board[0] != human_letter:
board[0] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a middle horizontal win
if board[3] == opp_letter and board[4] == opp_letter:
if board[5] != human_letter:
board[5] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[3] == opp_letter and board[5] == opp_letter:
if board[4] != human_letter:
board[4] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[4] == opp_letter and board[5] == opp_letter:
if board[3] != human_letter:
board[3] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a bottom horizontal win
if board[6] == opp_letter and board[7] == opp_letter:
if board[8] != human_letter:
board[8] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[6] == opp_letter and board[8] == opp_letter:
if board[7] != human_letter:
board[7] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[7] == opp_letter and board[8] == opp_letter:
if board[6] != human_letter:
board[6] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a left vertical win
if board[0] == opp_letter and board[3] == opp_letter:
if board[6] != human_letter:
board[6] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[0] == opp_letter and board[6] == opp_letter:
if board[3] != human_letter:
board[3] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[3] == opp_letter and board[6] == opp_letter:
if board[0] != human_letter:
board[0] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a left vertical win
if board[0] == opp_letter and board[3] == opp_letter:
if board[6] != human_letter:
board[6] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[0] == opp_letter and board[6] == opp_letter:
if board[3] != human_letter:
board[3] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[3] == opp_letter and board[6] == opp_letter:
if board[0] != human_letter:
board[0] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a middle vertical win
if board[1] == opp_letter and board[4] == opp_letter:
if board[7] != human_letter:
board[7] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[1] == opp_letter and board[7] == opp_letter:
if board[4] != human_letter:
board[4] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[4] == opp_letter and board[7] == opp_letter:
if board[1] != human_letter:
board[1] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a right vertical win
if board[2] == opp_letter and board[5] == opp_letter:
if board[8] != human_letter:
board[8] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[2] == opp_letter and board[8] == opp_letter:
if board[5] != human_letter:
board[5] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[5] == opp_letter and board[8] == opp_letter:
if board[2] != human_letter:
board[2] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a left to right diagonal win
if board[0] == opp_letter and board[4] == opp_letter:
if board[8] != human_letter:
board[8] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[4] == opp_letter and board[8] == opp_letter:
if board[0] != human_letter:
board[0] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[0] == opp_letter and board[8] == opp_letter:
if board[4] != human_letter:
board[4] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
#check for a right to left diagonal win
if board[2] == opp_letter and board[4] == opp_letter:
if board[6] != human_letter:
board[6] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[4] == opp_letter and board[6] == opp_letter:
if board[2] != human_letter:
board[2] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()
if board[2] == opp_letter and board[6] == opp_letter:
if board[4] != human_letter:
board[4] = opp_letter
winner = True
print ("--COMPUTER WINS--")
show_board()
play_again()

def block_human_win():
global open_boxes
#Block top horizontal win
if board[0] == human_letter and board[1] == human_letter:
if board[2] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[2] = opp_letter
show_board()
human_first()
if board[0] == human_letter and board[2] == human_letter:
if board[1] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[1] = opp_letter
show_board()
human_first()
if board[1] == human_letter and board[2] == human_letter:
if board[0] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[0] = opp_letter
show_board()
human_first()
#Block middle horizontal win
if board[3] == human_letter and board[4] == human_letter:
if board[5] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[5] = opp_letter
show_board()
human_first()
if board[3] == human_letter and board[5] == human_letter:
if board[4] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[4] = opp_letter
show_board()
human_first()
if board[4] == human_letter and board[5] == human_letter:
if board[3] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[3] = opp_letter
show_board()
human_first()
#Block bottom horizontal win
if board[6] == human_letter and board[7] == human_letter:
if board[8] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[8] = opp_letter
show_board()
human_first()
if board[6] == human_letter and board[8] == human_letter:
if board[7] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[7] = opp_letter
show_board()
human_first()
if board[7] == human_letter and board[8] == human_letter:
if board[6] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[6] = opp_letter
show_board()
human_first()
#Block left vertical win
if board[0] == human_letter and board[3] == human_letter:
if board[6] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[6] = opp_letter
show_board()
human_first()
if board[0] == human_letter and board[6] == human_letter:
if board[3] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[3] = opp_letter
show_board()
human_first()
if board[3] == human_letter and board[6] == human_letter:
if board[0] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[0] = opp_letter
show_board()
human_first()
#Block middle vertical win
if board[1] == human_letter and board[4] == human_letter:
if board[7] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[7] = opp_letter
show_board()
human_first()
if board[1] == human_letter and board[7] == human_letter:
if board[4] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[4] = opp_letter
show_board()
human_first()
if board[4] == human_letter and board[7] == human_letter:
if board[1] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[1] = opp_letter
show_board()
human_first()
#Block right vertical win
if board[2] == human_letter and board[5] == human_letter:
if board[8] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[8] = opp_letter
show_board()
human_first()
if board[2] == human_letter and board[8] == human_letter:
if board[5] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[5] = opp_letter
show_board()
human_first()
if board[5] == human_letter and board[8] == human_letter:
if board[2] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[2] = opp_letter
show_board()
human_first()
#Block left to right diagonal win
if board[0] == human_letter and board[4] == human_letter:
if board[8] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[8] = opp_letter
show_board()
human_first()
if board[0] == human_letter and board[8] == human_letter:
if board[4] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[4] = opp_letter
show_board()
human_first()
if board[4] == human_letter and board[8] == human_letter:
if board[0] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[0] = opp_letter
show_board()
human_first()
#Block right to left diagonal win
if board[2] == human_letter and board[4] == human_letter:
if board[6] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[6] = opp_letter
show_board()
human_first()
if board[2] == human_letter and board[6] == human_letter:
if board[4] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[4] = opp_letter
show_board()
human_first()
if board[4] == human_letter and board[6] == human_letter:
if board[2] != opp_letter:
can_block = True
open_boxes -= 1
print('Computer is thinking...')
board[2] = opp_letter
show_board()
human_first()

def human_first():
can_block = False
global open_boxes
if open_boxes > 0:
while True:
move = input('Please pick a number from 1 - 9: ')
if move.isdigit():
move = int(move) - 1
else:
print('Sorry, please pick a number from 1 - 9: ')
human_first()
winner = False

if board[move] != 'x' and board[move] != 'o':
board[move] = human_letter
open_boxes -= 1
show_board()

else:
print('\n')
print('Sorry that space is taken. Try again')
print('\n')
show_board()
human_first()

if checkAll(human_letter) == True:
winner = True
print ("--HUMAN WINS--")
print ('\n')
play_again()
break;

computer_move()

if checkAll(opp_letter) == True:
winner = True
print ("--COMPUTER WINS--")
print ('\n')
play_again()
break;
else:
print('--DRAW--')
play_again()

def computer_first():
global open_boxes
if open_boxes > 0:
computer_move()
while True:
move = input('Please pick a number from 1 - 9: ')
if move.isdigit():
move = int(move) - 1
else:
print('Sorry, please pick a number from 1 - 9: ')
human_first()

winner = False

if board[move] != 'x' and board[move] != 'o':
board[move] = human_letter
open_boxes -= 1
show_board()
else:
print('\n')
print('Sorry that space is taken. Try again')
print('\n')
show_board()
human_first()

if checkAll(human_letter) == True:
winner = True
print ("--HUMAN WINS--")
print ('\n')
play_again()
break;

computer_move()

if checkAll(opp_letter) == True:
winner = True
print ("--COMPUTER WINS--")
print ('\n')
play_again()
break;
else:
print('--DRAW--')
play_again()

def who_goes_first():
global board
global open_boxes
open_boxes = 9
print ('Welcome to Tic Tac Toe!This is your game board: ')
print ('\n')
show_board()
choose_letter()
print ('\n')
print('The first player will be chosen at random.')
print('...')
first = random.randint(0,1)
if first == 1:
print('Human goes first')
human_first()
else:
print('Computer goes first')
computer_first()

def play_again():
global board
board = [1,2,3,4,5,6,7,8,9]
print('Do you want to play again? Y/N: ')
who_goes_first()
print('Hope you enjoyed the game!')
sys.exit()
else:
print('Sorry, I didn\'t get that..')
play_again()

who_goes_first()

• Two big things come to mind. 1) don't use globals- pass everything as function arguments and return values, it will make it easier to reset things. 2) use board for display purposes only. Its difficult to check anything more than move validity using the literal game board matrix. Instead, keep 8 lists (one for each potential 3-in-a-row), and remove elements as moves are made. – Dillon Davis Jan 17 at 0:40