Tic Tac Toe Game using Python I'm brand-new (just joined today) to code review and I am super excited to share my tic tac toe game code with all of you! Please let me know what I could fix up in my program to make it more efficient. Thanks in advance!
P.S. I'm also not sure how to add an actual board to this game (an actual board rather than the way I have done here)
Code:
import time

# Initialize board
board = {1: ' ', 2: ' ', 3: ' ',
         4: ' ', 5: ' ', 6: ' ',
         7: ' ', 8: ' ', 9: ' '}

# Initialize variables
count = 0  # counter to track number of filled slots
winner = False  # boolean to check if anyone won
play = True  # boolen to check if the game should continue
tie = False  # boolean to check if there is a tie
curr_player = ''  # variable to store current player identifier
player_details = []  # list to store player identifier and marker


# Helper functions
def get_player_details(curr_player):
    &quot;&quot;&quot;Function to get player identifier and marker&quot;&quot;&quot;
    if curr_player == 'A':
        return ['B', 'O']
    else:
        return ['A', 'X']


def print_board():
    &quot;&quot;&quot;Function to print the board&quot;&quot;&quot;
    for i in board:
        print(i, ':', board[i], ' ', end='')
        if i % 3 == 0:
            print()


def win_game(marker, player_id):
    &quot;&quot;&quot;Function to check for winning combination&quot;&quot;&quot;
    if board[1] == marker and board[2] == marker and board[3] == marker or \
            board[4] == marker and board[5] == marker and board[6] == marker or \
            board[7] == marker and board[8] == marker and board[9] == marker or \
            board[1] == marker and board[4] == marker and board[7] == marker or \
            board[2] == marker and board[5] == marker and board[8] == marker or \
            board[3] == marker and board[6] == marker and board[9] == marker or \
            board[1] == marker and board[5] == marker and board[9] == marker or \
            board[3] == marker and board[5] == marker and board[7] == marker:

        print_board()
        time.sleep(1)
        print(&quot;Player&quot;, player_id, &quot;wins!&quot;)
        return True

    else:
        return False


def insert_input(slot_num, marker):
    &quot;&quot;&quot;Function for capturing user inputs&quot;&quot;&quot;
    while board[slot_num] != ' ':
        print(&quot;spot taken, pick another no.&quot;)
        slot_num = int(input())
    board[slot_num] = marker


def play_again():
    &quot;&quot;&quot;Function to check if player wants to play again&quot;&quot;&quot;
    print(&quot;Do you want to play again?&quot;)
    play_again = input()

    if play_again.upper() == 'Y':
        for z in board:
            board[z] = ' '
        return True
    else:
        print(&quot;Thanks for playing. See you next time!&quot;)
        return False


# Main program
while play:

    print_board()

    player_details = get_player_details(curr_player)
    curr_player = player_details[0]
    print(&quot;Player {}: Enter a number between 1 and 9&quot;.format(curr_player))
    input_slot = int(input())

    # Inserting 'X' or 'O' in desired spot
    insert_input(input_slot, player_details[1])
    count += 1

    # Check if anybody won
    winner = win_game(player_details[1], curr_player)
    if count == 9 and not winner:
        print(&quot;It's a tie!!&quot;)
        tie = True
        print_board()

    # Check if players want to play again
    if winner or tie:
        play = play_again()
        if play:
            curr_player = ''
            count = 0
Your board dictionary can be simplified from
board = {1: ' ', 2: ' ', 3: ' ',
         4: ' ', 5: ' ', 6: ' ',
         7: ' ', 8: ' ', 9: ' '}

to a dict comprehension:
board = {n: ' ' for n in range(1, 10)}

Your win_game function can be greatly simplified, from
def win_game(marker, player_id):
    &quot;&quot;&quot;Function to check for winning combination&quot;&quot;&quot;
    if board[1] == marker and board[2] == marker and board[3] == marker or \
            board[4] == marker and board[5] == marker and board[6] == marker or \
            board[7] == marker and board[8] == marker and board[9] == marker or \
            board[1] == marker and board[4] == marker and board[7] == marker or \
            board[2] == marker and board[5] == marker and board[8] == marker or \
            board[3] == marker and board[6] == marker and board[9] == marker or \
            board[1] == marker and board[5] == marker and board[9] == marker or \
            board[3] == marker and board[5] == marker and board[7] == marker:

        print_board()
        time.sleep(1)
        print(&quot;Player&quot;, player_id, &quot;wins!&quot;)
        return True

    else:
        return False

to
def win_game(marker, player_id):
    &quot;&quot;&quot;Function to check for winning combination&quot;&quot;&quot;
    if board[1] == board[2] == board[3] == marker or \
       board[4] == board[5] == board[6] == marker or \
       board[7] == board[8] == board[9] == marker or \
       board[1] == board[4] == board[7] == marker or \
       board[2] == board[5] == board[8] == marker or \
       board[3] == board[6] == board[9] == marker or \
       board[1] == board[5] == board[9] == marker or \
       board[3] == board[5] == board[7] == marker:
       print_board()
       time.sleep(1)
       print(&quot;Player&quot;, player_id, &quot;wins!&quot;)
       return True
    return False

You see, the else statement is not necessary, as the return statement will make the program jump out of the function. Also, as you can probably tell,
a == 1 and b == 1 and c == 1

is the same as
a == b == c === 1


The unnecessary else statement applies to your other functions as well
For get_player_details:
def get_player_details(curr_player):
    &quot;&quot;&quot;Function to get player identifier and marker&quot;&quot;&quot;
    if curr_player == 'A':
        return ['B', 'O']
    else:
        return ['A', 'X']

to
def get_player_details(curr_player):
    &quot;&quot;&quot;Function to get player identifier and marker&quot;&quot;&quot;
    if curr_player == 'A':
        return ['B', 'O']
    return ['A', 'X']

For play_again:
def play_again():
    &quot;&quot;&quot;Function to check if player wants to play again&quot;&quot;&quot;
    print(&quot;Do you want to play again?&quot;)
    play_again = input()

    if play_again.upper() == 'Y':
        for z in board:
            board[z] = ' '
        return True
    else:
        print(&quot;Thanks for playing. See you next time!&quot;)
        return False

to
def play_again():
    &quot;&quot;&quot;Function to check if player wants to play again&quot;&quot;&quot;
    print(&quot;Do you want to play again?&quot;)
    play_again = input()
    if play_again.upper() == 'Y':
        for z in board:
            board[z] = ' '
        return True
    print(&quot;Thanks for playing. See you next time!&quot;)
    return False

In your print_board function, you can increase the readability of your print statement with a formatted string. Using not instead of == 0 is considered more pythonic:
def print_board():
    &quot;&quot;&quot;Function to print the board&quot;&quot;&quot;
    for i in board:
        print(i, ':', board[i], ' ', end='')
        if i % 3 == 0:
            print()

to
def print_board():
    &quot;&quot;&quot;Function to print the board&quot;&quot;&quot;
    for i in board:
        print(f'{i} : {board[i]}  ', end='')
        if not i % 3:
            print()