简体   繁体   中英

How to Check Diagonals in Connect Four

I've checked the rows and columns for a winner, but I have zero clue on how to solve for diagonals. Here's what I have for my winner determination function:

def winner(board):
    """This function accepts the Connect Four board as a parameter.
    If there is no winner, the function will return the empty string "".
    If the user has won, it will return 'X', and if the computer has
    won it will return 'O'."""
    for row in range(7):
        count = 0
        last = ''
        for col in range(7):
            row_win = board[row][col]
            if row_win == " ":
                count = 0
                continue
            if row_win == last:
                count += 1
            else:
                count = 1
            if count >= 4:
                return row_win
            last = row_win

    for col in range(7):
        count = 0
        last = ''
        for row in range(7):
            col_win = board[row][col]
            if col_win == " ":
                count = 0
                continue
            if col_win == last:
                count += 1
            else:
                count = 1
            if count >= 4:
                return col_win
            last = col_win

I can't think of a way to check diagonals for a win. Here's the rest of the code if you need any references: https://paste.pythondiscord.com/epihuvujal.py Any tips would be greatly appreciated!

here is a simple sample, you can try it and modify to suite your needs:

def winner(board, length):
    """Returns the 'mark' of the winning player"""
    W = range(len(board))     # width
    H = range(len(board[0]))  # height
    directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
    
    for dx, dy in directions:
        edges = []  
        
        if dx > 0:
            edges += [(0, y) for y in H]
            
        if dy > 0:   # scanning down
            edges += [(x, 0) for x in W]
            
        if dy < 0:   # scanning up
            edges += [(x, H[-1]) for x in W]
            
        for ex, ey in edges: 
            row = 0; mark = None
            x, y = ex, ey
            
            while x in W and y in H:
                if board[x][y] == mark:
                    row += 1
                else:
                    mark = board[x][y]
                    row = 1
                if mark is not None and row >= length:
                    return mark
                x, y = x + dx, y + dy
    return None

print(winner([
    ['X', 'O', 'O', 'O'],
    ['O', 'X', 'O', 'X'],
    ['O', 'O', 'X', 'O'],
    ['O', 'X', 'X', 'X'] ], 4))  # X

To check for the diagonals you need a nested loop.

A for loop may do the work but a while loop also works.

The for loop you need is not the one in your code but the one with i and j for iteration.

Notice that starting from a value board[i][j] there are 4 diagonals to check.

The one in the top left, top right, bottom left and bottom right.

You can access them by adding 1 or substracting it each time from i and j.

Like this board[i+1][j+1] and board[i][j] and board[i-1][j-1] are in the same diagonal.

You can access as much as values you want ( if it's connect 3 or 4 or K )

But be careful for not exceeding the board boundaries ( maybe you can use a try - catch).

One more thing is don't be afraid if a diagonal is checked twice because your code will end up checking new diagonals.

You can also add a list of diags you visited before so it doesn't repeat the work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM