0
\$\begingroup\$

I am a beginner so please keep it in mind while answering! For player vs CPU is there any more effective way to make CPU better ??

import numpy as np

board=['-','-','-',
       '-','-','-',
       '-','-','-']


def check_win():
    global winner
    global game_over

    if board[0]=='X' and board[1]=='X' and board[2]=='X':
        winner='Player'
        game_over=True

    elif board[3]=='X' and board[4]=='X' and board[5]=='X':
        winner='Player'
        game_over=True

    elif board[6]=='X' and board[7]=='X' and board[8]=='X':
        winner='Player'
        game_over=True

    elif board[0]=='X' and board[4]=='X' and board[8]=='X':
        winner='Player'
        game_over=True

    elif board[2]=='X' and board[4]=='X' and board[6]=='X':
        winner='Player'
        game_over=True

    elif board[0]=='X' and board[3]=='X' and board[6]=='X':
        winner='Player'
        game_over=True

    elif board[1]=='X' and board[4]=='X' and board[7]=='X':
        winner='Player'
        game_over=True

    elif board[2]=='X' and board[5]=='X' and board[8]=='X':
        winner='Player'
        game_over=True

    elif board[0]=='O' and board[1]=='O' and board[2]=='O':
        winner='CPU'
        game_over=True

    elif board[3]=='O' and board[4]=='O' and board[5]=='O':
        winner='CPU'
        game_over=True

    elif board[6]=='O' and board[7]=='O' and board[8]=='O':
        winner='CPU'
        game_over=True

    elif board[0]=='O' and board[4]=='O' and board[8]=='O':
        winner='CPU'
        game_over=True

    elif board[2]=='O' and board[4]=='O' and board[6]=='O':
        winner='CPU'
        game_over=True

    elif board[0]=='O' and board[3]=='O' and board[6]=='O':
        winner='CPU'
        game_over=True

    elif board[2]=='O' and board[5]=='O' and board[8]=='O':
        winner='CPU'
        game_over=True



def res_gm():
    board=['-','-','-',
       '-','-','-',
       '-','-','-']
    play_game()



def player_turn():
    a=int(input("Enter the position to pux X (1-9) : "))
    valid=False
    while valid==False:
        if a<=9 and board[a-1]=='-':
            board[a-1]='X'
            valid=True
        elif a=='':
            print("You Cannot Leave This Empty")
        else:
            print("This move is invalid ! ")
            a=int(input("Enter the position to pux X (1-9) : "))


def Compute():
    if board[0]=='O' and board[1]=='O' and board[2]=='-':
        board[2]='O'
        main_board()

    elif board[0]=='O' and board[2]=='O' and board[1]=='-':
        board[1]='O'
        main_board()

    elif board[1]=='O' and board[2]=='O' and board[0]=='-':
        board[0]='O'
        main_board()

    elif board[3]=='O' and board[4]=='O' and board[5]=='-':
        board[5]='O'
        main_board()

    elif board[3]=='O' and board[5]=='O' and board[4]=='-':
        board[4]='O'
        main_board()

    elif board[4]=='O' and board[5]=='O' and board[3]=='-':
        board[3]='O'
        main_board()

    elif board[6]=='O' and board[7]=='O' and board[8]=='-':
        board[8]='O'
        main_board()

    elif board[7]=='O' and board[8]=='O' and board[6]=='-':
        board[6]='O'
        main_board()

    elif board[6]=='O' and board[8]=='O' and board[7]=='-':
        board[7]='O'
        main_board()

    elif board[0]=='O' and board[4]=='O' and board[8]=='-':
        board[8]='O'
        main_board()

    elif board[4]=='O' and board[8]=='O' and board[0]=='-':
        board[0]='O'
        main_board()

    elif board[0]=='O' and board[8]=='O' and board[4]=='-':
        board[4]='O'
        main_board()

    elif board[0]=='X' and board[1]=='X' and board[2]=='-':
        board[2]='O'
        main_board()

    elif board[0]=='X' and board[2]=='X' and board[1]=='-':
        board[1]='O'
        main_board()

    elif board[1]=='X' and board[2]=='X' and board[0]=='-':
        board[0]='O'
        main_board()

    elif board[3]=='X' and board[4]=='X' and board[5]=='-':
        board[5]='O'
        main_board()

    elif board[3]=='X' and board[5]=='X' and board[4]=='-':
        board[4]='O'
        main_board()

    elif board[4]=='X' and board[5]=='X' and board[3]=='-':
        board[3]='O'
        main_board()

    elif board[6]=='X' and board[7]=='X' and board[8]=='-':
        board[8]='O'
        main_board()

    elif board[7]=='X' and board[8]=='X' and board[6]=='-':
        board[6]='O'
        main_board()

    elif board[6]=='X' and board[8]=='X' and board[7]=='-':
        board[7]='O'
        main_board()

    elif board[0]=='X' and board[4]=='X' and board[8]=='-':
        board[8]='O'
        main_board()

    elif board[4]=='X' and board[8]=='X' and board[0]=='-':
        board[0]='O'
        main_board()

    elif board[0]=='X' and board[8]=='X' and board[4]=='-':
        board[4]='O'
        main_board()

    elif board[0]=='X' and board[3]=='X' and board[6]=='-':
        board[6]='O'
        main_board()

    elif board[2]=='X' and board[5]=='X' and board[8]=='-':
        board[8]='O'
        main_board()

    elif board[1]=='X' and board[4]=='X' and board[7]=='-':
        board[7]='O'
        main_board()


    else:
        valid=False
        while valid==False:
            b=np.random.randint(0,9)
            if board[b]=='-':
                board[b]='O'
                main_board()
                valid=True

            else:
                valid=False


def main_board():
    print(board[0]+'|'+board[1]+'|'+board[2]+'   For reference 1|2|3')
    print(board[3]+'|'+board[4]+'|'+board[5]+'                 4|5|6')
    print(board[6]+'|'+board[7]+'|'+board[8]+'                 7|8|9')


def play_game():
    global game_over
    global winner
    main_board()
    game_over=False
    n=0
    while game_over==False:
        if n<9 and n%2==0:
            player_turn()
            n+=1
            check_win()
        elif n<9 and n%2!=0:
            Compute()
            check_win()
            n=n+1
        elif n==9 and board[0]!='-' and board[1]!='-' and board[2]!='-' and board[3]!='-'and board[4]!='-' and board[5]!='-' and board[6]!='-' and board[7]!='-' and board[8]!='-' and game_over==False:
            print('Tie')
            winner='None'
            game_over=True
    print('The winner is ',winner)

print('Choose a game mode :  \n1. Player Vs CPU \n2. Player1 vs Player2')
q=int(input('Enter the Corresponding number of game mode : '))
while q in [1,2,3]:
    if q==1:
        p='y'
        while p=='y':
            play_game()
            p=str(input('Want to play again ? '))
        else:
            print('Exiting Game!')
            q=3
    elif q==2:
        print('this game mode is not available yet, ask Utkarsh to develop it ')
        q=int(input('Enter the Corresponding number of game mode : '))
    else:
        quit()

else:
    print('There is no game mode like this ')
    q=int(input('Enter the Corresponding number of game mode : '))
\$\endgroup\$
0
2
\$\begingroup\$

You need to fix indentation for the program to run (the fix is easy though, just look at the elif branches on line 102 onwards).

What you've essentially done is an explicit if-else structure where you've hardcoded all possible positions. While this works, it's quite difficult to read and it's easy to make mistakes. Thus, it would be a good idea to use a data structure not only for the board, but for the wins (rows, diagonals, columns) as well:

player_symbol = 'X'
cpu_symbol = 'O'

board=np.array(['-','-','-',
                '-','-','-',
                '-','-','-'])

wins = [
        [0,1,2], [3,4,5], [6,7,8],  # rows
        [0,4,8], [2,4,6],           # diagonals
        [0,3,6], [1,4,7], [2,5,8],  # columns
       ]

Now, to check for a win we can do something much simpler like:

def check_win():
    player_win = any(len(set(board[pos])) == 1 and player_symbol in board[pos] for pos in wins)
    cpu_win = any(len(set(board[pos])) == 1 and cpu_symbol in board[pos] for pos in wins)

    game_over = player_win or cpu_win
    winner = None
    if game_over:
        winner = 'Player' if player_win else 'CPU'

    return game_over, winner

In here, note that we can simply return values and we don't need global variables which are always difficult to reason about. Further, the "win checks" a reduced to simple generator expression: it goes over each element of wins, grabs the corresponding row, column or diagonal from board, checks to see if it has all of the same symbols (i.e., if the set taken over the elements of board has size 1) and checks if the unique symbol it contains is the player_symbol or cpu_symbol.

  • For Compute(), the function could use a better name: it starts with an uppercase letter while all the other functions don't. Also, compute() is a very generic name and it doesn't explain what the function is supposed to move. So perhaps a better name would be e.g., compute_cpu_move().

  • Now, using the same logic we could beautify Compute() as well but this is not necessarily a great idea. If you are interested in more challenge, you could make the CPU perfect by playing with the optimal strategy or implementing the minimax algorithm.

There's definitely more we could say here as well, but I hope this is enough to get you going. There are tons of questions and resources on tic-tac-toe on this site and elsewhere online that you can get more inspiration from.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.