Tic-Tac-Toe with computer and two player (Python)

Semicomplete code

Hi, I am a beginner in Python and I would like to learn how to implement a way to play against the computer in a console based Tic Tac Toe (I already have the 2 player one working). I am trying to avoid spaghetti code/excessive code, and I would also like to know how to create a Minimax algorithm and implement it into my code (if it's not possible, please tell me!) Thank you! (If it is possible, I would like there to be a random chance of who goes first if the player wants to go against the computer!)

from colorama import Fore, Style
from random import random
from time import sleep

posDict = {1: 202, 2: 209, 3: 216, 4: 128, 5: 135, 6: 142, 7: 54, 8: 61, 9: 68}
players = ['X', 'O']
print(Fore.RED + "Tic Tac Toe!" + Style.RESET_ALL)


def display_board():
    global board
    board = ''
    for x in range(-1, 6):
        if x % 2 == 0:
            board += '|      ' * 4 + '\n|      |      |      |'
        else:
            board += ' _____ ' * 3
        board += '\n'
    return board

def demo():
    demoBoard = list(display_board())
    for i, k in enumerate(posDict.keys()):
        demoBoard[posDict[k]] = Fore.LIGHTBLUE_EX + f'{i + 1}' + Style.RESET_ALL
    return ''.join(demoBoard)


def errorHandle(i):
    while True:
        try:
            x = int(input(Fore.YELLOW + f'Where would you like to place your {players[i]}? ' + Style.RESET_ALL))
            if x > 9:
                print(Fore.LIGHTRED_EX + 'Please input an number between 1 and 9! ' + Style.RESET_ALL)
                continue
        except ValueError:
            print(Fore.LIGHTRED_EX + "Please input a number between 1 and 9! " + Style.RESET_ALL)
            continue
        break
    return x


def chooseEnemy():
    cPlay = input(
        Fore.LIGHTGREEN_EX + 'Would you like to play the computer (c) or another person (p)? ' + Style.RESET_ALL)
    return cPlay.upper().startswith('C')

def winCheck(board, mark):
    return (board[posDict[4]] == board[posDict[5]] == board[posDict[6]] == mark or
            (board[posDict[1]] == board[posDict[2]] == board[posDict[3]] == mark) or
            (board[posDict[7]] == board[posDict[4]] == board[posDict[1]] == mark) or
            (board[posDict[8]] == board[posDict[5]] == board[posDict[2]] == mark) or
            (board[posDict[9]] == board[posDict[6]] == board[posDict[3]] == mark) or
            (board[posDict[7]] == board[posDict[5]] == board[posDict[3]] == mark) or
            (board[posDict[9]] == board[posDict[5]] == board[posDict[1]] == mark))

def computerMove(board, firstMove):
    simBoard = list(board)
    for j in range(1,10):
        if simBoard[posDict[j]] == ' ':
            simBoard[posDict[j]] = '{}'.format('O' if firstMove else 'X')
            if winCheck(simBoard, '{}'.format('O' if firstMove else 'X')):
                return j #as mark
            simBoard[posDict[j]] = ' '

    for j in range(1,10):
        if simBoard[posDict[j]] == ' ':
            simBoard[posDict[j]] = '{}'.format('X' if firstMove else 'O')
            if winCheck(simBoard, '{}'.format('X' if firstMove else 'O')):
                return j
            simBoard[posDict[j]] = ' '
    if board[posDict[5]] == ' ': return 5

    for j in (1,3,7,9):
        if board[posDict[j]] == ' ':
            print(Fore.LIGHTYELLOW_EX + "Computer is thinking..." + Style.RESET_ALL)
            sleep(1.5)
            return j

def displayPrompt(cPlay, i=0, mF = False):
    if cPlay:
        if mF:
            mF = False
            return computerMove(board,True) #as mark
        mF = True
    return errorHandle(i)

def midGame(cPlay, board):
    gameWon = False
    def move(cPlay, j=0, mF = False):
        print(cPlay)
        if True: #just for sake
            print(computerMove(board,False))

        if not j:
            if not winCheck(board, Fore.GREEN + 'O' + Style.RESET_ALL):
                mark = displayPrompt(cPlay)
                while mark in listCheck:
                    mark = displayPrompt(cPlay)
                listCheck.append(mark)
                board[posDict[mark]] = Fore.RED + 'X' + Style.RESET_ALL
                print(''.join(board))
                return False
            return True
        if not winCheck(board, Fore.RED + 'X' + Style.RESET_ALL) and not winCheck(board,
                                                                                  Fore.GREEN + 'O' + Style.RESET_ALL):
            mark = displayPrompt(cPlay, 1)
            while mark in listCheck:
                mark = displayPrompt(cPlay, 1)
            listCheck.append(mark)
            board[posDict[mark]] = Fore.GREEN + 'O' + Style.RESET_ALL
            print(''.join(board))
            return False
        print(
            Fore.MAGENTA + "Winner: {}".format('O' if len(listCheck) % 2 == 0 else 'X') + Style.RESET_ALL)
        return True

    board = list(board)
    listCheck = []

    if cPlay:
        if not gameWon:
            move(False)
            gameWon = move(False,1)

    print(''.join(board))
    while not gameWon:
        move(False)
        if len(listCheck) == 9:
            if winCheck(board, Fore.RED + 'X' + Style.RESET_ALL): print("Nice last move win!")
            break
        gameWon = move(False,1)
    replay = input(Fore.CYAN + "Would you like to play again? " + Style.RESET_ALL)
    return replay.upper().startswith('Y')


def highlightWin(wM): #Highlights winning sequence (incomplete)
    if wM:
        pass
    return None


def renew(replay=True):
    while replay:
        print(demo())
        cPlay = chooseEnemy()
        replay = midGame(cPlay, board)
    else:
        print(Fore.YELLOW + "Good game!")


renew()

I had some problems with loading in the computer move (It wouldn't register at all), so I basically scrapped the midgame version for it. I don't know much about OOP, and I'm trying to do it using functions. Thank you very much!

Posted Dec 16, 2018, 11:10 PM UTC · edited

13
Loading comments…