簡體   English   中英

Python:如何將“if”語句的數量減少到適合我的游戲的合理數量?

[英]Python: How can I reduce the number of 'if' statements down to a reasonable amount for my game?

我在 python 中進行國際象棋游戲,並試圖使用“if”語句生成每個棋子的合法移動,以查看玩家想要移動到的空間是否是空閑的,以及移動是否實際上在棋盤的邊界內。 問題是有太多的“if”語句以及嵌套的“if”語句。 這確實使我的文件看起來像意大利面條代碼,並使過程過於復雜。

這是一個例子:

def valid_moves(self, board):
    i = self.row
    j = self.col

    moves = []

    if i > 0:
        # TOP LEFT
        if j > 0:
            p = board[i - 1][j - 1]
            if p == 0: # checks if space empty
                moves.append((j - 1, i - 1,))
            elif p.color != self.color:
                moves.append((j - 1, i - 1,))

        # TOP MIDDLE
        p = board[i - 1][j]
        if p == 0: # checks if space empty
            moves.append((j, i - 1))
        elif p.color != self.color:
            moves.append((j, i - 1))

        # TOP RIGHT
        if j < 7:
            p = board[i - 1][j + 1]
            if p == 0: # checks if space empty
                moves.append((j + 1, i - 1,))
            elif p.color != self.color:
                moves.append((j + 1, i - 1,))

    if i < 7:
        # BOTTOM LEFT
        if j > 0:
            p = board[i + 1][j - 1]
            if p == 0: # checks if space empty
                moves.append((j - 1, i + 1,))
            elif p.color != self.color:
                moves.append((j - 1, i + 1,))

        # BOTTOM MIDDLE
        p = board[i + 1][j]
        if p == 0: # checks if space empty
            moves.append((j, i + 1))
        elif p.color != self.color:
            moves.append((j, i + 1))

        # BOTTOM RIGHT
        if j < 7:
            p = board[i + 1][j + 1]
            if p == 0: # checks if space empty
                moves.append((j + 1, i + 1))
            elif p.color != self.color:
                moves.append((j + 1, i + 1))

    # MIDDLE LEFT
    if j > 0:
        p = board[i][j - 1]
        if p == 0: # checks if space empty
            moves.append((j - 1, i))
        elif p.color != self.color:
            moves.append((j - 1, i))

    # MIDDLE RIGHT
    if j < 7:
        p = board[i][j + 1]
        if p == 0: # checks if space empty
            moves.append((j + 1, i))
        elif p.color != self.color:
            moves.append((j + 1, i))

    return moves

此示例僅適用於 6 個中的 1 個,因此出現了很多“if”語句。 我怎樣才能將它折射到我不需要使用盡可能多的“if”語句的地方?

本地 function 有助於避免代碼重復:

def valid_moves(self, board):
    i = self.row
    j = self.col

    moves = []

    def move(a: int, b: int) -> None:
        p = board[a][b]
        if p == 0 or p.color != self.color:
            moves.append((b, a))

    if i > 0:
        # TOP LEFT
        if j > 0:
            move(i - 1, j - 1)

        # TOP MIDDLE
        move(i - 1, j)

        # TOP RIGHT
        if j < 7:
            move(i - 1, j + 1)

    if i < 7:
        # BOTTOM LEFT
        if j > 0:
            move(i + 1, j - 1)

        # BOTTOM MIDDLE
        move(i + 1, j)

        # BOTTOM RIGHT
        if j < 7:
            move(i + 1, j + 1)

    # MIDDLE LEFT
    if j > 0:
        move(i, j - 1)

    # MIDDLE RIGHT
    if j < 7:
        move(i, j + 1)

    return moves

首先生成所有可能的移動,包括非法移動。 然后過濾非法的。 您還檢查i > 0還是i < 7 ,如果您對 8x8 棋盤使用從零開始的索引,我認為您的意思是i >= 0i < 8

def valid_moves(self, board):
    i = self.row
    j = self.col

    destinations = [
        (j + dj, i + di)
        for di [-1, 0, 1] for dj in [-1, 0, 1]
        # Disallow staying in place - not a move.
        if not (di == 0 and dj == 0)
    ]

    legal_moves = [
        (mj, mi)
        for mj, mi in destinations
        # In bounds.
        if 0 <= mi < 8 and 0 <= mj < 8
        # And empty or enemy occupied.
        and (board[mi][mj] == 0 or board[mi][mj].color != self.color)
    ]

    return legal_moves

您似乎只在尋找一個空格移動,因此可以通過在每個方向的垂直和水平增量上循環來簡化它:

def valid_moves(self, board):
    moves = []
    for v,h in [(-1,-1),(0,-1),(0,1),(-1,0),(1,0),(1,1)]: # directions
        r,c = self.row+v,self.col+h       # advance by 1
        if r not in range(8): continue    # vertical bounds
        if c not in range(8): continue    # horizontal bounds
        p = board[r][c]
        if p==0 or p.color != self.color:  # playable position
            moves.append((r,c))
    return moves

這不會涵蓋多步移動和非線性移動。 這里有適用於所有類型移動的策略。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM