While making a game of Connect Four, I encounter a strange problem in a function called make_move
, when two equivalent return statements behaving differently.
The only direct dependency function is put_piece(board, column, player)
, which puts a player's piece in the bottommost empty spot in the given column of the board. put_piece
returns a tuple of two elements: the index of the row the piece ends up in (or -1 if the column is full) and the updated board. The put_piece
function is implemented correctly.
The make_move
function is where the disagreement occurs. It successfully returns row
(the index of the row the piece is placed in) and board
(the updated board) if I implement using the usual if else return notation, as shown here:
def make_move(board, max_rows, max_cols, col, player):
"""
Put player's piece in column COL of the board, if it is a valid move.
Return a tuple of two values:
1. If the move is valid, make_move returns the index of the row the
piece is placed in. Otherwise, it returns -1.
2. The updated board
"""
if 0 <= col < len(board[0]):
return put_piece(board, max_rows, col, player)
return -1, board
This is how make_move
should return:
>>> rows, columns = 2, 2
>>> board = create_board(rows, columns)
>>> row, board = make_move(board, rows, columns, 0, 'X')
>>> row
1
>>> board
[['-', '-'], ['X', '-']]
However, if I change make_move
to
def make_move(board, max_rows, max_cols, col, player):
"""
Put player's piece in column COL of the board, if it is a valid move.
Return a tuple of two values:
1. If the move is valid, make_move returns the index of the row the
piece is placed in. Otherwise, it returns -1.
2. The updated board
"""
return put_piece(board, max_rows, col, player) if 0 <= col < len(board[0]) else -1, board
Both return values get assigned as a tuple to row
, and board
simply carries on the previous value.
>>> rows, columns = 2, 2
>>> board = create_board(rows, columns)
>>> row, board = make_move(board, rows, columns, 0, 'X')
>>> row
(1, [['-', '-'], ['X', '-']])
>>> board
[['-', '-'], ['-', '-']]
The two ways of writing the function are literally the same except notation. Any idea why this happens?
This is due to precedence. The comma has fairly low precedence, so
put_piece(board, max_rows, col, player) if 0 <= col < len(board[0]) else -1, board
is equivalent to
((put_piece(board, max_rows, col, player) if 0 <= col < len(board[0]) else -1), board)
But you really want
put_piece(board, max_rows, col, player) if 0 <= col < len(board[0]) else (-1, board)