You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python获取国际象棋所有合法走法(附现有代码)

实现国际象棋合法走法的方案

一、先完善棋盘数据结构

你的原有代码没有区分棋子颜色,这会导致无法判断兵的前进方向等核心逻辑,先修改print_pieces函数,给棋子加上黑白区分:

def print_pieces(square_board):
    letters = ["a", "b", "c", "d", "e", "f", "g", "h"]

    # 区分白方和黑方棋子初始位置
    white_pawns = ["a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2"]
    black_pawns = ["a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7"]
    white_knights = ["b1", "g1"]
    black_knights = ["b8", "g8"]
    white_rooks = ["a1", "h1"]
    black_rooks = ["a8", "h8"]
    white_queen = ["e1"]
    black_queen = ["e8"]
    white_king = ["d1"]
    black_king = ["d8"]
    white_bishops = ["c1", "f1"]
    black_bishops = ["c8", "f8"]

    # 黑白棋子符号映射
    pieces = {
        "white_pawn": "♙", "black_pawn": "♟",
        "white_knight": "♘", "black_knight": "♞",
        "white_bishop": "♗", "black_bishop": "♝",
        "white_rook": "♖", "black_rook": "♜",
        "white_queen": "♕", "black_queen": "♛",
        "white_king": "♔", "black_king": "♚"
    }

    board = square_board.copy()  # 避免修改原字典

    # 放置白方棋子
    for square in white_pawns:
        board[square] = pieces["white_pawn"]
    for square in white_knights:
        board[square] = pieces["white_knight"]
    for square in white_bishops:
        board[square] = pieces["white_bishop"]
    for square in white_rooks:
        board[square] = pieces["white_rook"]
    for square in white_queen:
        board[square] = pieces["white_queen"]
    for square in white_king:
        board[square] = pieces["white_king"]

    # 放置黑方棋子
    for square in black_pawns:
        board[square] = pieces["black_pawn"]
    for square in black_knights:
        board[square] = pieces["black_knight"]
    for square in black_bishops:
        board[square] = pieces["black_bishop"]
    for square in black_rooks:
        board[square] = pieces["black_rook"]
    for square in black_queen:
        board[square] = pieces["black_queen"]
    for square in black_king:
        board[square] = pieces["black_king"]

    # 清空中间格子
    numbers = ["3", "4", "5", "6"]
    squares = []
    for letter in letters:
        for number in numbers:
            squares.append(letter + number)
    for square in squares:
        board[square] = " "

    board = dict(reversed(list(board.items())))
    return board

二、编写辅助工具函数

这些函数用于处理坐标转换、合法性判断等基础操作:

1. 棋盘坐标与数字坐标互转

def square_to_coords(square):
    # 例:a1 -> (0,0),h8 -> (7,7)
    col = ord(square[0]) - ord('a')
    row = int(square[1]) - 1
    return (col, row)

def coords_to_square(coords):
    # 例:(0,0) -> a1
    col = chr(coords[0] + ord('a'))
    row = str(coords[1] + 1)
    return col + row

2. 判断格子是否在棋盘范围内

def is_valid_square(coords):
    col, row = coords
    return 0 <= col < 8 and 0 <= row < 8

3. 判断棋子颜色

def get_piece_color(piece):
    white_pieces = ["♙", "♘", "♗", "♖", "♕", "♔"]
    black_pieces = ["♟", "♞", "♝", "♜", "♛", "♚"]
    if piece in white_pieces:
        return "white"
    elif piece in black_pieces:
        return "black"
    return None  # 空格子

三、实现各棋子的合法走法逻辑

针对每种棋子的规则,编写对应的走法生成函数:

1. 兵的走法

def get_pawn_moves(board, square):
    moves = []
    piece = board[square]
    color = get_piece_color(piece)
    col, row = square_to_coords(square)

    if color == "white":
        # 白兵向前走(row+1)
        forward_square = coords_to_square((col, row + 1))
        if board.get(forward_square) == " ":
            moves.append((square, forward_square))
            # 初始位置可走两步
            if row == 1:
                forward_two_square = coords_to_square((col, row + 2))
                if board.get(forward_two_square) == " ":
                    moves.append((square, forward_two_square))
        # 斜向吃子
        for dc in [-1, 1]:
            capture_square = coords_to_square((col + dc, row + 1))
            if is_valid_square((col + dc, row + 1)):
                capture_piece = board.get(capture_square)
                if capture_piece != " " and get_piece_color(capture_piece) == "black":
                    moves.append((square, capture_square))
    else:
        # 黑兵向前走(row-1)
        forward_square = coords_to_square((col, row - 1))
        if board.get(forward_square) == " ":
            moves.append((square, forward_square))
            # 初始位置可走两步
            if row == 6:
                forward_two_square = coords_to_square((col, row - 2))
                if board.get(forward_two_square) == " ":
                    moves.append((square, forward_two_square))
        # 斜向吃子
        for dc in [-1, 1]:
            capture_square = coords_to_square((col + dc, row - 1))
            if is_valid_square((col + dc, row - 1)):
                capture_piece = board.get(capture_square)
                if capture_piece != " " and get_piece_color(capture_piece) == "white":
                    moves.append((square, capture_square))
    return moves

2. 马的走法

def get_knight_moves(board, square):
    moves = []
    piece = board[square]
    color = get_piece_color(piece)
    col, row = square_to_coords(square)
    # 马的8种可能走法
    knight_dirs = [(-2, -1), (-2, 1), (-1, -2), (-1, 2),
                   (1, -2), (1, 2), (2, -1), (2, 1)]
    for dc, dr in knight_dirs:
        new_col = col + dc
        new_row = row + dr
        if is_valid_square((new_col, new_row)):
            target_square = coords_to_square((new_col, new_row))
            target_piece = board.get(target_square)
            if target_piece == " ":
                moves.append((square, target_square))
            else:
                if get_piece_color(target_piece) != color:
                    moves.append((square, target_square))
    return moves

3. 象的走法

def get_bishop_moves(board, square):
    moves = []
    piece = board[square]
    color = get_piece_color(piece)
    col, row = square_to_coords(square)
    # 象的4个对角线方向
    bishop_dirs = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
    for dc, dr in bishop_dirs:
        step = 1
        while True:
            new_col = col + dc * step
            new_row = row + dr * step
            if not is_valid_square((new_col, new_row)):
                break
            target_square = coords_to_square((new_col, new_row))
            target_piece = board.get(target_square)
            if target_piece == " ":
                moves.append((square, target_square))
                step += 1
            else:
                if get_piece_color(target_piece) != color:
                    moves.append((square, target_square))
                break  # 遇到棋子就停止延伸
    return moves

4. 车的走法

def get_rook_moves(board, square):
    moves = []
    piece = board[square]
    color = get_piece_color(piece)
    col, row = square_to_coords(square)
    # 车的4个直线方向
    rook_dirs = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    for dc, dr in rook_dirs:
        step = 1
        while True:
            new_col = col + dc * step
            new_row = row + dr * step
            if not is_valid_square((new_col, new_row)):
                break
            target_square = coords_to_square((new_col, new_row))
            target_piece = board.get(target_square)
            if target_piece == " ":
                moves.append((square, target_square))
                step += 1
            else:
                if get_piece_color(target_piece) != color:
                    moves.append((square, target_square))
                break
    return moves

5. 后的走法

后的走法是象和车的组合:

def get_queen_moves(board, square):
    return get_bishop_moves(board, square) + get_rook_moves(board, square)

6. 王的走法

def get_king_moves(board, square):
    moves = []
    piece = board[square]
    color = get_piece_color(piece)
    col, row = square_to_coords(square)
    # 王的8个相邻方向
    king_dirs = [(-1, -1), (-1, 0), (-1, 1),
                 (0, -1),          (0, 1),
                 (1, -1),  (1, 0), (1, 1)]
    for dc, dr in king_dirs:
        new_col = col + dc
        new_row = row + dr
        if is_valid_square((new_col, new_row)):
            target_square = coords_to_square((new_col, new_row))
            target_piece = board.get(target_square)
            if target_piece == " ":
                moves.append((square, target_square))
            else:
                if get_piece_color(target_piece) != color:
                    moves.append((square, target_square))
    return moves

四、生成所有合法走法

编写主函数遍历棋盘,收集所有棋子的合法走法:

def get_all_legal_moves(board):
    all_moves = []
    # 棋子到对应走法函数的映射
    piece_move_funcs = {
        "♙": get_pawn_moves, "♟": get_pawn_moves,
        "♘": get_knight_moves, "♞": get_knight_moves,
        "♗": get_bishop_moves, "♝": get_bishop_moves,
        "♖": get_rook_moves, "♜": get_rook_moves,
        "♕": get_queen_moves, "♛": get_queen_moves,
        "♔": get_king_moves, "♚": get_king_moves
    }
    for square, piece in board.items():
        if piece != " ":
            move_func = piece_move_funcs.get(piece)
            if move_func:
                moves = move_func(board, square)
                all_moves.extend(moves)
    return all_moves

五、测试代码

修改主程序,调用生成走法的函数:

if __name__ == "__main__":
    from colorama import init, Back, Fore
    init()

    board = create_board()
    board_with_pieces = print_pieces(board)
    draw_board(board_with_pieces)
    
    # 获取并打印所有合法走法
    legal_moves = get_all_legal_moves(board_with_pieces)
    print("\n\n所有合法走法:")
    for move in legal_moves:
        print(f"{move[0]} -> {move[1]}")

说明

以上代码实现了除王车易位、吃过路兵、兵升变之外的所有合法走法,每个走法以(起始格子, 目标格子)的元组形式返回。

内容的提问来源于stack exchange,提问作者PawnShopChessboard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 03:57:14