python – Tic Tac Toe program

Print Statements

If you write print(...), that includes a newline character. In your draw_board function, you have a couple lines where you specifically tell Python you don’t want a newline, and then on the very next line you call print with no argument to get a newline. You should just remove the end='' in those cases:

def draw_board(board):
    """Draw board"""
    for i in range(3):
        print('+' + '-' * 5 + '+' + '-' * 5 + '+' + '-' * 5 + '+')
        print('|' + ' ' * 5 + '|' + ' ' * 5 + '|' + ' ' * 5 + '|')
        for j in range(3):
            k = str(i) + str(j)
            print('| ' + str(board(k)) + ' ' * 3, end='')
        print('|')
        print('|' + ' ' * 5 + '|' + ' ' * 5 + '|' + ' ' * 5 + '|')
    print('+' + '-' * 5 + '+' + '-' * 5 + '+' + '-' * 5 + '+')

Choice of Dictionary

I won’t actually be providing the code for this change, because it would require rewriting a lot. However, look at how you index your dictionary:

board('10')

This means board row 1, column 0. This is identical to just using nested lists:

board(1)(0)

So your board would probably be better off as nested lists:

def board():
    "Creating Board"
    board = ((3 * row + col for col in range(1, 4)) for row in range(3))
    # ((1, 2, 3), (4, 5, 6), (7, 8, 9))

This is easier to wrap your head around in the context of the problem.

Main Statement

In your current code, you actually handle the processing of the game from board, a function which declares in its docstring to be a function that “creates the game board dictionary”. This is bad practice. A function should do what it claims to do. Beyond that, you should never have a function which serves as both a supporting function and the showrunner. Do this instead:

def board():
    "Creating Board dictionary"
    dic_board = {}
    v = 1
    for i in range(3):
        for j in range(3):
            k = str(i) + str(j)
            dic_board(k) = v
            v += 1
    return dic_board

...

if __name__ == "__main__":
    update_board(board())

This might look like a small change but it makes a big difference. In fact, using my suggested changes to board, you could just instantiate the board in the main block as well and remove the definition for board altogether. The block contained in

if __name__ == "__main__":

runs if and only this file specifically was run, which allows you to import all other functions that you’ve defined here into another module without running your game. It also adds some readability: anyone reading your code can go straight to this code block and understand that this is the program being run.