code_monki
code_monki

Reputation: 27

Printing Tic Tac Toe game board without extra lines at right and bottom

I'm making a tic tac toe game in python and I have all of the actual game play functions working properly but I can't get the game board to print correctly.

game = [[' ',' ',' '],[' ',' ',' '],[' ',' ',' ']]
for row in game:
  print('   |'*(len(game)-1)+'   ')
  for space in row:
    print(' '+space+' |',end='')
  print('\n'+'   |'*(len(game)-1)+'   ')
  if game.index(row) < len(game)-1:
    print('----'+('----'*(len(game)-2))+'---')

for some reason the row index isn't incrimenting unless there's a move in each row. When the game begins empty the output is:

   |   |   
   |   |   |
   |   |   
-----------
   |   |   
   |   |   |
   |   |   
-----------
   |   |   
   |   |   |
   |   |   
----------- 

There shouldn't be a line along the bottom but it goes away when there's a move in each row. I'm also trying to get rid of the | in the middle of each space on the right.

Upvotes: 0

Views: 1920

Answers (4)

Junaid
Junaid

Reputation: 149

Although my solution is different from yours, I have a recommendation. Why not simply print the board using string formatting, instead of using nested loops as follows:

values = [' ' for x in range(9)]
print("\n")
print("\t     |     |")
print("\t  {}  |  {}  |  {}".format(values[0], values[1], values[2]))
print('\t_____|_____|_____')

print("\t     |     |")
print("\t  {}  |  {}  |  {}".format(values[3], values[4], values[5]))
print('\t_____|_____|_____')

print("\t     |     |")

print("\t  {}  |  {}  |  {}".format(values[6], values[7], values[8]))
print("\t     |     |")
print("\n")

The output is as follows:

     |     |   
_____|_____|_____
     |     |
     |     |   
_____|_____|_____
     |     |
     |     |   
     |     |

Upvotes: 0

Vaibhav Tiwari
Vaibhav Tiwari

Reputation: 1

def print_board(
    for i,row in enumerate(board):
        print(" | ".join(row))  # Join elements of each row with "|"
        if i<2:
            print("-"*9)

It is also gonna print the required one.

class TicTacToe:
    def __init__(self):
        self.board = [
            [" ", " ", " "],
            [" ", " ", " "],
            [" ", " ", " "],
        ]

    def print_board(self):
        for i in range(3):
            print(f"{self.board[i][0]}  | {self.board[i][1]} | {self.board[i][2]}")

            if i < 2:
                print("-----------")

I think this is also nice way to go nice and simple.

I think there are numerous way to create it, the best is to see others way and try it different way.

Upvotes: 0

Dudly01
Dudly01

Reputation: 513

I think you should do string formatting as suggested before me.

Though my solution greatly differs from your code, here is a piece of function that prints (creates string, then prints that string) a general board with the tiles separated by | and each row separated by -. Each element in myboard will be placed in the middle of a tile_width space.

def print_board(myboard, tile_width=3):
    msg = ""
    for i, row in enumerate(myboard):
        # Print row
        element = row[0]  # first element does not need leading |
        element_str = '{:^{width}}'.format(element, width=tile_width)
        msg = msg + element_str

        for element in row[1:]:
            element_str = '|{:^{width}}'.format(element, width=tile_width)  # elements with leading |
            msg = msg + element_str

        msg = msg + '\n'

        # Print row divider if its not the last row
        if i is not len(myboard) - 1:
            element_str = '{:-^{width}}'.format("", width=((tile_width + 1) * len(row) - 1))  # '*' as fill char
            msg = msg + element_str
            msg = msg + '\n'
    print(msg)


cur = [['x', ' ', 'x'], [' ', 'o', ' '], ['o', '', ' ']]
print_board(cur)

This outputs this.

 x |   | x 
-----------
   | o |   
-----------
 o |   |   

Upvotes: 3

Stidgeon
Stidgeon

Reputation: 2723

The problem seems to be that you are using the index method instead of something like enumerate. index returns the position of a given element in a list, whereas enumerate can be used to do more of what you want (see Accessing the index in 'for' loops?). When you use index(row), you are asking for the lowest index value at which the given row occurs. On a blank board, this always comes back as 0.

Another way to get around this is to set a counter for the rows (as in the example below).

As for the extra line on the character row, you can get around this by printing the row contents differently, as in the example below.

cur = [[' ',' ',' '],[' ',' ',' '],[' ',' ',' ']]

# initialize a row counter
rownumb = 0

for row in cur:
    print(cur.index(row))

    # increment the row counter
    rownumb += 1
    print('   |'*(len(cur)-1)+'   ')

    # a different approach to printing the contents of each row
    print(' ' + row[0] + ' | ' + row[1] + ' | ' + row[2])

    print('   |'*(len(cur)-1)+'   ')

    # check the counter and don't print the line after the final row
    if rownumb < 3:
        print('----'+('----'*(len(cur)-2))+'---')

Upvotes: 1

Related Questions