Search code examples
pythonenumerate

'int' object has no attribute '__getitem__' when using enumerate?


I'm trying to make a tic tac toe game, the problem is the function that checks the table and then updates it with the players '0' or 'X' at the chosen index.

Please tell me how I can fix this because I can't see what's wrong with this.

table = [['1','2','3'],
         ['4','5','6'],
         ['7','8','9']]

def title():
    for row in table:
        print row

def check(indx, sym):
    for indd, row in enumerate(table):
        for ind, cell in enumerate(row):
            if cell == indx and cell != '0' or cell != 'X':
                table[indd][ind] = sym
            else:
                return False

def main():

    moves_left = 1
    while moves_left > 0:
        if moves_left == 1:
            title()
            indx = raw_input('Where do you want your nought?: ')
            new_table = check(indx, '0')
            if new_table != False:
                moves_left += 1
            else:
                print 'Invalid selection'
        elif moves_left == 2:
            title()
            indx = raw_input('Where do you want your cross?: ')
            new_table = check(indx, 'X')
            if new_table != False:
                moves_left -= 1
            else:
                print 'Invalid Selection'
        else:
            print 'it\'s a draw'

if __name__=='__main__':
    main()

My Traceback:

Traceback (most recent call last):
  File "tictac.py", line 45, in <module>
    main()
  File "tictac.py", line 28, in main
    new_table = check(indx, '0')
  File "tictac.py", line 19, in check
    table[indd[ind]] = sym
TypeError: 'int' object has no attribute '__getitem__'

Solution

  • DeveloperXY already got your immediate problem. There are several more. The one vexing you at the moment is because your if logic is incorrect:

    if cell == indx and cell != '0' or cell != 'X':
    

    Either use parentheses, or learn the order of evaluation for Boolean operators. Among other things, this statement must always come up True at the start: every cell is something other than 'X'. Since you perform the update for every cell in the loop, you change them all to '0'.

    Instead, you need to design logic that finds the one cell you want to change (at cell == indx) and then changes only that one cell. Try this for starters:

    def check(indx, sym):
        for indd, row in enumerate(table):
            for ind, cell in enumerate(row):
                if cell == indx:
                    table[indd][ind] = sym
    print table  # I added this to watch what happens to the actual game state.
    

    Note that I got rid of the return value: you were returning either None or False, which have the same effect in the statement if new_table. By the way, notice that if you return True from check, then moves_left becomes 2, and your main program goes into an infinite loop.

    Now, note that your title function pays no attention at all to the game state: it won't print anything but the initial numbering.

    Does that move you along far enough to close this issue?