sorry if this is really basic! i'm in first year computer science.
i am trying to write a function to check if there is a win on a tictactoe board of NxN size (so i can't hardcode any values); the win has to be from the top left, to the bottom right.
i've already written a function for the upwards diagonal, so i'ved based it around that, but with a list like this: [ [ 'X' , ' ' ] , [ ' ' , ' ' ] ] the function returns True - which it definitely should not.
here's what i have right now, but i have tried many things:
#these can be anything but here's just an example of what i'm using to test
cur = [['X',' '],[' ',' ']]
player= 'X'
def check_down_diag(cur, player):
columncount = 0
for row in cur:
if row[columncount] != player:
columncount = 1
return False
else:
return True
CodePudding user response:
The first step to figure out is the logic. You have a player symbol (here 'X') and a Tic-Tac-Toe size ('N', usually 3 for TTT). So to see if there is a diagonal winner, you would check the two diagonals:
(0, 0), (1, 1), (2, 2), ... (N-1, N-1)
and:
(N-1, 0), (N-2, 1), (N-3, 2) ... (0, N-1)
which are the indeces into the fields to check.
So now you know the two sets of locations to check, and you know which symbol to check for. So write a function which accepts an N
for size/dimension and a symbol
for which player, and you should be good to go. You can check for both diagonals in one loop, or you can check them in separate loops to start. If you do one loop, you must go through the whole loop once until both checks fail. If you do one loop/diagonal at a time, you should break from the loop as soon as you find a single failure condition, to improve performance.
CodePudding user response:
A while back I wrote a function for pattern finding in 2d arrays specifically for something like this:
def find_pattern(array, pattern, value):
for row in range(len(array)):
for column in range(len(array[0])):
try:
for y, x in pattern:
_value = array[y row][x column]
if value != _value:
break
else:
return pattern, (pattern[0][0] row, pattern[0][1] column)
except IndexError:
break
return None
The patterns are formed like so (these specific ones are for the standard tic tac toe board (all win conditions)):
win_patterns = [
((0, 0), (0, 1), (0, 2)),
((0, 0), (1, 0), (2, 0)),
((0, 0), (1, 1), (2, 2)),
((0, 2), (1, 1), (2, 0)),
]
The way it works is simple, it is just a tuple of (x, y)
coordinates in the grid, starting from 0
, so the first pattern would search for straight lines horizontally, second for vertical lines, third and fourth for both diagonals.
Then you can loop over the patterns, pass them to the function along with the 2d array of the board and the value that has to be found in this pattern (' '
values don't mean anything they are there so that the array is more readable):
board = [
['x', ' ', 'x', ' ', ' '],
[' ', 'x', ' ', ' ', ' '],
[' ', ' ', 'x', ' ', 'x'],
[' ', ' ', ' ', ' ', ' '],
[' ', ' ', 'x', ' ', ' '],
]
for pattern in win_patterns:
found = find_pattern(board, pattern, 'x')
if found:
print(found)
break
CodePudding user response:
For the main diagonal, check that all the values that are at the same row and column (i.e. the main diagonal) are equal to the player's symbol:
def check_down_diag1(cur, player):
return all( cur[i][i]==player for i in range(len(cur)) )
For the other diagonal, simply invert one of the dimensions:
def check_down_diag2(cur, player):
return all( cur[i][-1-i]==player for i in range(len(cur)) )
You could also check both diagonals at the same time:
def check_down_diags(cur, player):
return all( cur[i][i]==player for i in range(len(cur)) ) \
or all( cur[i][-1-i]==player for i in range(len(cur)) )