If you have a board set up as follows:
board =
([1,0,2,0],
[0,1,2,0],
[0,0,0,0],
[0,0,0,0])
You can imagine it as x and y coordinates, starting from the upper left hand corner, having downward movement as positive y and rightward movement as positive x. A move at board[3][3]
by either player would be a winning move. Using Teodor Pripoae process, we can construct the horizontal, vertical and diagonals around the last move. The horizontal case is easy.
def horizontal(board, y_coord):
return board[y_coord]
The vertical case requires us to select the x_coord from each row:
def vertical(board, x_coord):
return [row[x_coord] for row in board]
The diagonal case is a bit trickier. For this first function, it's computing the diagonal that goes from left to right as it goes top to bottom. Distance basically represents the horizontal distance from zero, when y is equal to zero.
def diagonal1(board, x_coord, y_coord):
length = len(board[0])
distance = x_coord - y_coord
if distance >= 0:
return [y[x] for x, y in enumerate(board) if distance + x <= length]
else:
return [y[x] for x, y in enumerate(board) if x - distance >= 0 and x - distance <= length]
This second function computes the diagonal that goes right to left as it goes top to bottom. In this function distance represents the vertical distance from zero as the horizontal distance is at zero.
def diagonal2(board, x_coord, y_coord):
length = len(board[0])
distance = y_coord + x_coord
return [y[distance - x] for x, y in enumerate(board) if distance - x <= length]
Once you have these defined, you just need a way to check if a player has won. Something like this might do:
def game_over(direction, number_to_win, player_number):
count = 0
for i in direction:
if i == player_number:
count += 1
if count = number_to_win:
return True
else:
count = 0
return False
Having written all of this, it seems like this is overkill, unless you have quite large M and N. While it may be more efficient than checking every victory condition, it does construct the entire horizontal, vertical and diagonal directions, rather than just those coordinates surrounding the last move, it isn't as efficient as it could be.
Maybe this is helpful, but it seems like Brian's suggestion to simply remove x's might be better.