2
\$\begingroup\$

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:
        print('Please choose again.')
        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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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...')
            print('Computer blocks your winning move.')
            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: ')
    answer = input().lower()
    if answer in ('y','ye','yes'):
        who_goes_first()
    elif answer in ('n','no'):
        print('Hope you enjoyed the game!')
        sys.exit()
    else:
        print('Sorry, I didn\'t get that..')
        play_again()



who_goes_first()
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Dillon Davis Jan 17 at 0:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.