2

I want to create a function that prints out a tic-tac-toe board with a given list that position its index value on the board in a reverse order like on a number keyboard that is from 9 to 1, with the 1st row having the index value of 7, 8, 9: 2nd row 4, 5, 6: 3rd row 1, 2, 3.

For example: a given list

test_board = ['O','O','X','X','X','O','X','O','X']

That show print out like this:

 X | O | X 
---|---|---
 X | X | O 
---|---|---
 O | O | X  

I wrote this function:

def display_board(board):

    h_sep = '-' * 3
    for i in range(3):

        for j in reversed(board[1:]):

            print(f"{j:^3}|{j:^3}|{j:^3}")

        if i != 2:
            print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}")

But i get this print out when i call the function with the given list:

test_board = ['O','O','X','X','X','O','X','O','X']
display_board(test_board)

Output:

 X | X | X 
 O | O | O 
 X | X | X 
 O | O | O 
 X | X | X 
 X | X | X 
 X | X | X 
 O | O | O 
---|---|---
 X | X | X 
 O | O | O 
 X | X | X 
 O | O | O 
 X | X | X 
 X | X | X 
 X | X | X 
 O | O | O 
---|---|---
 X | X | X 
 O | O | O 
 X | X | X 
 O | O | O 
 X | X | X 
 X | X | X 
 X | X | X 
 O | O | O 

Edited: Can i use for loop to achieve this without writing multiple print statement like this:

print(f"{board[6]:^3}|{board[7]:^3}|{board[8]:^3}")
print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}")
print(f"{board[3]:^3}|{board[4]:^3}|{board[5]:^3}")
print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}")
print(f"{board[0]:^3}|{board[1]:^3}|{board[2]:^3}")

5 Answers 5

2

In your second for you are printing it 3 times before going to the next line.

Your function with the following modifications would work for your problem:

def display_board(board):
h_sep = '-' * 3
for i in reversed(range(3)):

    print(f"{board[i*3]:^3}|{board[i*3+1]:^3}|{board[i*3+2]:^3}")

    if i != 0:
        print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}")
Sign up to request clarification or add additional context in comments.

Comments

0

You can use join to insert the vertical lines and then loop in reverse order.

test_board = ['O','O','X','X','X','O','X','O','X']

for i in range(3,-1,-1):
    li=test_board[i*3:(i+1)*3]
    print('|'.join(li))
    if 0<i<3: print('-'*5)

Comments

0

a longer version of the solution that can handle size of board greater than 3

    def display_board(board, size=3):
        parts = []
        h_seps = []
        for i in range(size):
            begin = i * size
            end = begin + size
            parts.append(board[begin:end])
            h_seps.append("-" * 3)

        first = True
        while len(parts) > 0:
            part = parts.pop()

            if first is False:
                print("|".join(h_seps))

            first = False
            print(" " + " | ".join(part))

    display_board(["O", "O", "X", "X", "X", "O", "X", "O", "X"])

Comments

0

If you want pythonic-one-liner, then here you go

def display_board(board):
    def display_board(board):
        for i in range(3,-1,-1): print(' | '.join(board[i*3:(i+1)*3]),'\n--|---|---' if 0 < i < 3 else '' )

test_board = ['1','2','3','4','5','6','7','8','9']
display_board(test_board)

Comments

0

You can use an iter to achieve this.

Solution

def display_board(board):
    h_sep = '-' * 3
    it = iter(reversed(board))
    count = 0
    for j in it:
        print(f"{j:^3}|{next(it):^3}|{next(it):^3}")
        if count < 2: 
            print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}")
            count+=1

test_board = ['X','O','O','O','X','X','X','O','X']
display_board(test_board)

Just to visualize the result, I used numbers in your test_board:

def display_board(board):
    h_sep = '-' * 3
    it = iter(reversed(board))
    for j in it:
        print(f"{int(j)-2:^3}|{int(next(it)):^3}|{int(next(it))+2:^3}")
        if int(j) > 3: print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}")

test_board = ['1','2','3','4','5','6','7','8','9']
display_board(test_board)

OUT:

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

3 Comments

Oh this is great, I'm not familiar with iter() function yet, i will look into it, but i want to write an if condition which doesn't print the last print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}") when the iteration ends, i did this if next(it)[] != len(board): print(f"{h_sep:^3}|{h_sep:^3}|{h_sep:^3}") but i don't know how to return the index number of the next(it) to compare with the` len(board)`
It work perfectly with numbers, but not with strings like my list ['O','O','X','X','X','O','X','O','X'] i get ValueError: invalid literal for int() with base 10: 'X'
@KwameBenqazy I added the solution separately, this was merely to visualize if the order is important. It probably makes sense to have generate the list in the right order that you want in that case (X,O,O,O,X,X,XO,X)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.