1

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

d2w3t
  • 13
  • 5
  • 2
    Does this answer your question? [Understanding slicing](https://stackoverflow.com/questions/509211/understanding-slicing) – mkrieger1 Dec 14 '22 at 13:33
  • Or do you not understand [What does "list comprehension" and similar mean? How does it work and how can I use it?](https://stackoverflow.com/questions/34835951/) – mkrieger1 Dec 14 '22 at 13:35
  • It's essential because it contains the 3 cells of the board that belong to the row that is printed. – mkrieger1 Dec 14 '22 at 13:36

3 Answers3

2

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]]
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Sembei Norimaki
  • 745
  • 1
  • 4
  • 11
  • One last question, why will the iteration variable, will have the values (0, 1, 2) in it. Is it because we want to create a 3x3 board or because of start indicies (a=0, b=1, c=2) ? – d2w3t Dec 15 '22 at 12:10
  • 1
    when you iterate usually you just take consecutive values starting at 0. So if you iterate 3 times you will get 0,1,2. Then you have to convert those values into the desired ones applying the necessary formulas, which are the ones you found in the code and I explained here. – Sembei Norimaki Dec 15 '22 at 14:46
  • Very well described, thank you for your help :) – d2w3t Dec 15 '22 at 17:29
1

Be aware that this code is more complicated than it needs to be.

An equivalent but simpler version would be

def print_board():
    for i in range(3):
        row = board[i*3:(i+1)*3]
        print('| ' + ' | '.join(row) + ' |')
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
-3

Link to flawless code

Working board

def printboard(xState, oState):
    # Printing Board By using gameValues 's List
    zero = 'X' if xState[0] else ('O' if oState[0] else 0)
    one = 'X' if xState[1] else ('O' if oState[1] else 1)
    two = 'X' if xState[2] else ('O' if oState[2] else 2)
    three = 'X' if xState[3] else ('O' if oState[3] else 3)
    four = 'X' if xState[4] else ('O' if oState[4] else 4)
    five = 'X' if xState[5] else ('O' if oState[5] else 5)
    six = 'X' if xState[6] else ('O' if oState[6] else 6)
    seven = 'X' if xState[7] else ('O' if oState[7] else 7)
    eight = 'X' if xState[8] else ('O' if oState[8] else 8)
    print(f"{zero} | {one} | {two}")
    print(f"---------")
    print(f"{three} | {four} | {five}")
    print(f"---------")
    print(f"{six} | {seven} | {eight}")

contact if you have any doubts.

  • Don't create one line and one variable for each cell. that's what loops and lists are made for. Just imagine a customized tic-tac-toe that is played in a board of size 100 x 100 – Sembei Norimaki Dec 14 '22 at 13:54
  • Are you sure we can play tic tac toe on 100x100 board? Kindly provide some sample code it will be interesting – rishabh11336 Dec 14 '22 at 14:04
  • actually you can if you modify the rules and increase the length required to win. My example was more to illustrate that your code is not portable though. If you want an example of an actual game take Chess or Checkers that is played in a 8x8 board, requiring to define 64 variables. – Sembei Norimaki Dec 14 '22 at 14:08
  • winning criteria are different in chess or checkers from "tic tac toe". what is winning criteria on large board? – rishabh11336 Dec 15 '22 at 04:52