Finding neighbor cells in a grid with the same value. Ideas how to improve this function?

后端 未结 1 900
無奈伤痛
無奈伤痛 2020-12-02 01:50

I am new to Python (learning it for a little over 1 month) and I tried creating Tic Tac Toe. However once I finished it, I decide to expand the board (from 3x3 to 9x9 depend

相关标签:
1条回答
  • 2020-12-02 02:07

    Here's an approach that involves less copying and pasting -- hopefully it gives you some idea of how to break things down into the smallest number of the most reusable pieces possible. :)

    The general idea here is to come up with a way of expressing the concept of scanning a line across the board in different directions in such a way that you can just express the direction and then let the same block of code handle the scan regardless of what the direction is.

    from typing import List, Optional, Tuple
    
    
    def do_we_have_a_winner(board: List[List[Optional[str]]], length: int) -> Optional[str]:
        """Returns the 'mark' of the player with a row of the given length."""
        width = range(len(board))
        height = range(len(board[0]))
        # Do four scans across the board -- right, down, and diagonals.
        for dx, dy in [(0, 1), (1, 0), (1, 1), (1, -1)]:
            edges: List[Tuple[int, int]] = []
            if dx > 0:
                # scanning right, start from left edge
                edges += [(0, y) for y in height]
            if dy > 0:
                # scanning down, start from top edge
                edges += [(x, 0) for x in width]
            if dy < 0:
                # scanning up, start from bottom edge
                edges += [(x, height[-1]) for x in width]
            for ex, ey in edges:
                mark: Optional[str] = None
                row = 0
                x, y = ex, ey
                while x in width and y in height:
                    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(do_we_have_a_winner([
        ['X', 'O', 'O'],
        ['O', 'X', 'O'],
        ['O', 'O', 'X'],
    ], 3))  # X
    

    Note that this function assumes one at most winner, so if there are multiple winners, it will only return one of them -- I'll leave it as an exercise for the reader to figure out how to change it to handle that situation better. :)

    0 讨论(0)
提交回复
热议问题