-1
\$\begingroup\$

There are 2 issues with my code:

a) If I put numbers in the following order (as my input) '1', '2', '3', '4', '5', '6', '7' -- this where the game should end, because X (or O) would have won now (because 3, 5, 7 are a diagonal win). But my program realizes this after X (or again, O) plays their 4th turn (another turn is played by the other player even after X or O has visually won). <-- you'll understand this better (hopefully) when you try running it.

b) When I am asked if I want to play again and I say yes (more like 'y'), I get a traceback error.

Here's my code:

# variables

board = ['-', '-', '-','-', '-', '-', '-', '-', '-']
count = 0             # will track the number of filled slots
winner = False        # check if anyone has won
play = True           # check if the game should continue
tie = False           # check if there is a tie/draw
current_player = 'O'   # variable that will hold the current player
player_details = []   # list that will hold the player identifier and marker

# functions

# takes one of the users' input.
# in ['X', 'O'] --> X is the first player and O is the second player.
def get_player_details(current_player):
    if current_player == 'O':
        return ['X', 'O']
    else:
        return ['O', 'X']

# this function is to display the board to the console.
def display_board(board):
    print(' 1 | 2 | 3       ' + board[0] + '  |  ' + board[1] + '  |  ' + board[2])
    print(' 4 | 5 | 6       ' + board[3] + '  |  ' + board[4] + '  |  ' + board[5])
    print(' 7 | 8 | 9       ' + board[6] + '  |  ' + board[7] + '  |  ' + board[8])

# this function checks for a winner diagonally, across and down.
def win_game(marker, player_identification):
    # all the winning combinations:
    if ((board[0] == marker and board[1] == marker and board[2] == marker) or
        (board[3] == marker and board[4] == marker and board[5] == marker) or
        (board[6] == marker and board[7] == marker and board[8] == marker) or
        (board[0] == marker and board[3] == marker and board[6] == marker) or
        (board[1] == marker and board[4] == marker and board[7] == marker) or
        (board[1] == marker and board[5] == marker and board[8] == marker) or
        (board[3] == marker and board[5] == marker and board[7] == marker)):
        display_board(board)
        print('Player',player_identification,'wins!')
        return True
    else:
        return False

# checks if the input is being put in an "open" space.
def insert_input(slot_number, marker):
    print('slot number:',slot_number,'\nmarker:',marker)
    print('board[slot_number]:',board[slot_number])
    while board[slot_number] != '-':
        print('Please pick another spot, this one is already taken!')
        slot_number = int(input())
    board[slot_number] = marker

# play again option, if the person wants to replay
def play_again():
    print('Would you like to play again?')
    play_again = input()

    if play_again == 'Y' or play_again == 'y':
        for v in board:
            board[v] = ' '
        return True

    else:
        print('Ok, thank you for playing!')
        return False

# the main block of the program (where all the functions and variables are tied together)
while play:

    display_board(board)
    player_details = get_player_details(current_player)
    current_player = player_details[0]
    print('Please enter a number from 1 - 9.')
    input_slot = int(input())
    print('board:' + str(board))

    insert_input(input_slot, player_details[1])
    count += 1
    print('player details[1]:',player_details[1],'\n')

    winner = win_game(player_details[1], current_player)
    if count == 9 and not winner:
        print('It\'s a tie!')
        tie = True
        display_board(board)

    if winner or tie:
        play = play_again()
        if play:
            current_player = ''
            count = 0

Note: I have added some debugging statements because I am still a "newbie" and I need them for clarity's sake.

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to code review. This question is not fit for codereview.stackexchange site. Please read our tour on how to ask questions here \$\endgroup\$ – theProgrammer Jan 6 at 5:25
  • \$\begingroup\$ Ok, sorry about that. I thought this was a valid question, as I have all my code, and I'm just running into errors. \$\endgroup\$ – fast_and_curious Jan 6 at 14:14
  • 1
    \$\begingroup\$ For future reference, note that this site is for improving working code, not fixing broken code. You want Stack Overflow to help with errors. \$\endgroup\$ – Carcigenicate Jan 6 at 15:09
1
\$\begingroup\$

I can help with part b) of your issue.

But before that,

# checks if the input is being put in an "open" space.
def insert_input(slot_number, marker):
    print('slot number:',slot_number,'\nmarker:',marker)
    print('board[slot_number]:',board[slot_number])
    while board[slot_number] != '-':
        print('Please pick another spot, this one is already taken!')
        slot_number = int(input())
    board[slot_number] = marker # <-- ⭐ this line of code is causing your program to crash. 

You have some broken code. With board[slot_number] = marker, when I insert 1, my marker isn't placed on the first section of the board, it is instead placed on the 2nd section as your program is taking in the index, not the position. You have to look at the relationship between your positions on your 'dupe board' and your actual board, what do you see? Your position is 1 more than your index or (in code) your position is board[slot_number - 1] = marker

Therefore, your code block should look like this:

def insert_input(slot_number, marker):
    print('slot number: ' + str(slot_number) + '\nmarker: ' + str(marker))
    print('board[slot_number]: ' + board[slot_number])
    while board[slot_number] != '-':
        print('Please pick another spot, this one is already taken!')
        slot_number = int(input())
    board[slot_number - 1] = marker # <-- ⭐ this is the line I fixed

And now for part b) of your problem.

This is your code segment:

def play_again():
    print('Would you like to play again?')
    play_again = input()

    if play_again == 'Y' or play_again == 'y':
        for v in board:
            board[v] = ' '
        return True

    else:
        print('Ok, thank you for playing!')
        return False

and particularly this section of the segment is incorrect:

    for v in board:
        board[v] = ' '

you can't put strings into [] (which is where your variable 'v' is held), as this is for indices. And all the values that belong to 'v' are strings ⚠

what you should do instead is use the len() function.

for v in range(0, len(board)):
    board[v] = '-'

instead of

for v in board:
    board[v] = ' ' # <-- here you're not even clearing the board to what it was before ('-')

and this is what your segment should look like:

def play_again():
    print('Would you like to play again?')
    play_again = input()
    print(type(board))
    if play_again == 'Y' or play_again == 'y':
        for v in range(0, len(board)):
            board[v] = '-'
        return True

    else:
        print('Ok, thank you for playing!')
        return False

and, guess what? the board is actually returned back like this:

 1 | 2 | 3       -  |  -  |  -
 4 | 5 | 6       -  |  -  |  -
 7 | 8 | 9       -  |  -  |  -

Hope you found this helpful ✌🏼

\$\endgroup\$
1
  • \$\begingroup\$ thank you so much for this! I appreciate your time and effort! \$\endgroup\$ – fast_and_curious Jan 6 at 14:15

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