Tic Tac Toe using Cartesian coordinate system I am trying to learn the Cartesian Coordinate System, starting with a basic tic tac toe grid for simplicity, then perhaps moving to chess. I was able to make the following code to start out:

board = []

def new_board():
    for row in range(4):
        board.append([])
        for column in range(4):
            board[row].append('_')

def print_board():
    print(board)
    print('  %s | %s | %s' % (board[1][1], board[1][2], board[1][3]))
    print('----+---+----')
    print('  %s | %s | %s' % (board[2][1], board[2][2], board[2][3]))
    print('----+---+----')
    print('  %s | %s | %s' % (board[3][1], board[3][2], board[3][3]))

new_board()
print(board)
print_board()


When the list 'board' is printed, it gives the following:

[['_', '_', '_', '_'], ['_', '_', '_', '_'], ['_', '_', '_', '_'], ['_', '_', '_', '_']]
[['_', '_', '_', '_'], ['_', '_', '_', '_'], ['_', '_', '_', '_'], ['_', '_', '_', '_']]


Which is fine, but my issue is that in order for my commands to match the board (e.g. board[1][2] targeting the 1st row and the 2nd column of the board), I have to have a 'dummy entry' for [0], for both the sublists and the entries in the sublists.

Is there a way to do this without the dummy entries and still have my board list references match the actual board spaces?
It is a convention in Python to use the _ variable as the 'throw away variable'.
In your case you can replace column with it.
Rather than using a for loop with list.append you can use a list comprehension.

data = []
for i in range(4):
    data.append(i)

data = [i for i in range(4)]

When you build an array with all of the items having the same immutable value you can make an array with just one value and multiply the array.

foo = [None for _ in range(4)]

foo = [None] * 4

You should not rely on globals to hold state. There are two solutions:


Pass and return the values from the functions.
Use a class to encapsulate state.

Strings % method for formatting is somewhat archaic and buggy. It should be noted that str.format or f-strings are a better alternate with more features.

values = (1, 2)

'%s %s' % values

'{0[0]} {0[1]}'.format(values)
'{} {}'.format(*values)

f'{values[0]} {values[1]}'

It is best practice to use an if __name__ == '__main__' guard to prevent your code from running if imported by accident.
Python uses 0 based indexing. I have had no problems with it once adjusted. However if you do you'd be better off not using Python.

Lua, Julia and R are all languages that use 1-based indexing.


def new_board():
    return [['_'] * 3 for _ in range(3)]


def print_board(board):
    print(
        '  {} | {} | {}  '.format(*board[0])
        + '----+---+----'
        + '  {} | {} | {}  '.format(*board[1])
        + '----+---+----'
        + '  {} | {} | {}  '.format(*board[2])
    )


if __name__ == '__main__':
    board = new_board()
    print(board)
    print_board(board)