基于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
相关产品推荐
相关产品推荐

