pythonpython-3.xlistmathindexing

How does this code to create a board for a Tic-Tac-Toe game work?


After I couldn't figure out, how to build a board for a Tic-Tac-Toe game by myself, I randomly discoverd an already finished Tic-Tac-Toe program from another programmer.

What she did was:

board = [' ' for _ in range(9)]

def print_board():
    for row in [board[i*3:(i+1)*3] for i in range(3)]:
        print('| ' + ' | '.join(row) + ' |')

print_board()

Output:

|   |   |   |

|   |   |   |

|   |   |   |

Now I am totally confused with this sector of the code:

board[i*3:(i+1)*3]

What does this part of the code mean and why is it so essential to use it in this case?

If you want the whole context of the program or try it yourself: https://github.com/kying18/tic-tac-toe/blob/master/game.py


Solution

  • You have a board that you want to represent as a 2D object (3x3)

    a b c
    d e f
    g h i
    

    However, you are storing this board as a 1D list

        [a b c d e f g h i]
    idx  0 1 2 3 4 5 6 7 8
    

    idx represent the index of each element, so if you want to print the board line by line you need to first print:

    a b c  (which corresponds to indices 0,1,2)
    

    then

    d e f  (which corresponds to indices 3,4,5)
    

    and finally

    g h i  (which corresponds to indices 6,7,8)
    

    As you can see, the start indices will be 0,3,6 and the final indices will be 3,6,9 (since python slicing never includes the last index, and therefore it has to be 1 unit more than the last index you actually want to include)

    so we can make a loop that iterates 3 times (we have 3 rows), so the iteration variable will have the values (0,1,2)

    Now we have to convert (0,1,2) to the start indices (0,3,6) which is just multiplying by 3, this is where the 3*i comes from

    And we have to convert (0,1,2) to the end indices (3,6,9) which is just (i+1)*3

    So the slicing for a given loop iteration must be board[i*3:(i+1)*3] which is what you have in the code

    Instead of a 1D list, you could have represented the board as a list of lists, and have two indices: one for row and one for column

    board = [[a, b, c], 
             [d, e, f], 
             [g, h, i]]