Python实现超完整文字版国际象棋游戏:规则全涵盖,附详细代码与棋谱记录
以下是一个用 Python 编写的文字版国际象棋游戏,包含了你所要求的各种规则: ```python # 国际象棋棋盘大小 BOARD_SIZE = 8 # 棋子类型 PIECES = { 'P': 'Pawn', 'R': 'Rook', 'N': 'Knight', 'B': 'Bishop', 'Q': 'Queen', 'K': 'King' } # 初始化棋盘 def initialize_board(): board = [[' ' for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)] # 白方棋子 board[0] = ['R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R'] board[1] = ['P'] * 8 # 黑方棋子 board[6] = ['p'] * 8 board[7] = ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'] return board # 打印棋盘 def print_board(board): print(" a b c d e f g h") for i in range(BOARD_SIZE): row_str = str(8 - i) + " " for j in range(BOARD_SIZE): row_str += board[i][j] + " " print(row_str + str(8 - i)) print(" a b c d e f g h") # 将坐标转换为棋盘位置 def coord_to_pos(coord): col = ord(coord[0].lower()) - ord('a') row = 8 - int(coord[1]) return row, col # 获取棋子的颜色 def get_piece_color(piece): if piece.isupper(): return 'white' elif piece.islower(): return 'black' return None # 检查坐标是否在棋盘内 def is_on_board(row, col): return 0 <= row < BOARD_SIZE and 0 <= col < BOARD_SIZE # 获取棋子的合法移动位置 def get_legal_moves(board, row, col): piece = board[row][col] color = get_piece_color(piece) moves = [] if piece.upper() == 'P': # 兵 if color == 'white': if row > 0 and board[row - 1][col] == ' ': moves.append((row - 1, col)) if row == 6 and board[row - 2][col] == ' ': moves.append((row - 2, col)) if row > 0 and col > 0 and get_piece_color(board[row - 1][col - 1]) == 'black': moves.append((row - 1, col - 1)) if row > 0 and col < BOARD_SIZE - 1 and get_piece_color(board[row - 1][col + 1]) == 'black': moves.append((row - 1, col + 1)) else: if row < BOARD_SIZE - 1 and board[row + 1][col] == ' ': moves.append((row + 1, col)) if row == 1 and board[row + 2][col] == ' ': moves.append((row + 2, col)) if row < BOARD_SIZE - 1 and col > 0 and get_piece_color(board[row + 1][col - 1]) == 'white': moves.append((row + 1, col - 1)) if row < BOARD_SIZE - 1 and col < BOARD_SIZE - 1 and get_piece_color(board[row + 1][col + 1]) == 'white': moves.append((row + 1, col + 1)) elif piece.upper() == 'R': # 车 directions = [(0, 1), (0, -1), (1, 0), (-1, 0)] for dr, dc in directions: r, c = row + dr, col + dc while is_on_board(r, c): if board[r][c] == ' ': moves.append((r, c)) elif get_piece_color(board[r][c]) != color: moves.append((r, c)) break else: break r += dr c += dc elif piece.upper() == 'N': # 马 offsets = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)] for dr, dc in offsets: r, c = row + dr, col + dc if is_on_board(r, c) and (board[r][c] == ' ' or get_piece_color(board[r][c]) != color): moves.append((r, c)) elif piece.upper() == 'B': # 象 directions = [(1, 1), (1, -1), (-1, 1), (-1, -1)] for dr, dc in directions: r, c = row + dr, col + dc while is_on_board(r, c): if board[r][c] == ' ': moves.append((r, c)) elif get_piece_color(board[r][c]) != color: moves.append((r, c)) break else: break r += dr c += dc elif piece.upper() == 'Q': # 后 directions = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)] for dr, dc in directions: r, c = row + dr, col + dc while is_on_board(r, c): if board[r][c] == ' ': moves.append((r, c)) elif get_piece_color(board[r][c]) != color: moves.append((r, c)) break else: break r += dr c += dc elif piece.upper() == 'K': # 王 offsets = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] for dr, dc in offsets: r, c = row + dr, col + dc if is_on_board(r, c) and (board[r][c] == ' ' or get_piece_color(board[r][c]) != color): moves.append((r, c)) # 过滤掉会导致自己被将军的移动 legal_moves = [] for move in moves: new_board = [row[:] for row in board] new_board[move[0]][move[1]] = new_board[row][col] new_board[row][col] = ' ' if not is_in_check(new_board, color): legal_moves.append(move) return legal_moves # 检查是否被将军 def is_in_check(board, color): king_row, king_col = None, None enemy_color = 'white' if color == 'black' else 'black' # 找到自己的王 for i in range(BOARD_SIZE): for j in range(BOARD_SIZE): if (color == 'white' and board[i][j] == 'K') or (color == 'black' and board[i][j] == 'k'): king_row, king_col = i, j break if king_row is not None: break # 检查敌方棋子是否能攻击到王 for i in range(BOARD_SIZE): for j in range(BOARD_SIZE): if get_piece_color(board[i][j]) == enemy_color: moves = get_legal_moves(board, i, j) if (king_row, king_col) in moves: return True return False # 检查是否被将死 def is_checkmate(board, color): if not is_in_check(board, color): return False for i in range(BOARD_SIZE): for j in range(BOARD_SIZE): if get_piece_color(board[i][j]) == color: moves = get_legal_moves(board, i, j) if moves: return False return True # 检查是否是平局 def is_stalemate(board, color): if is_in_check(board, color): return False for i in range(BOARD_SIZE): for j in range(BOARD_SIZE): if get_piece_color(board[i][j]) == color: moves = get_legal_moves(board, i, j) if moves: return False return True # 移动棋子 def move_piece(board, from_row, from_col, to_row, to_col): board[to_row][to_col] = board[from_row][from_col] board[from_row][from_col] = ' ' return board # 主游戏循环 def play_game(): board = initialize_board() current_player = 'white' move_history = [] while True: print_board(board) print(f"{current_player}'s turn") if is_in_check(board, current_player): print(f"{current_player} is in check!") if is_checkmate(board, current_player): print(f"Checkmate! {current_player} loses.") break elif is_stalemate(board, current_player): print("Stalemate! The game is a draw.") break try: move_input = input("Enter move (e.g. e2 e4), 'surrender' or 'draw': ") if move_input == 'surrender': opponent = 'black' if current_player == 'white' else 'white' print(f"{current_player} surrenders. {opponent} wins.") break elif move_input == 'draw': opponent_choice = input(f"{current_player} offers a draw. {opponent} accepts (y/n)? ") if opponent_choice.lower() == 'y': print("The game is a draw.") break else: print("Draw offer rejected.") else: from_coord, to_coord = move_input.split() from_row, from_col = coord_to_pos(from_coord) to_row, to_col = coord_to_pos(to_coord) piece = board[from_row][from_col] if get_piece_color(piece) != current_player: print("You can only move your own pieces.") continue legal_moves = get_legal_moves(board, from_row, from_col) if (to_row, to_col) in legal_moves: board = move_piece(board, from_row, from_col, to_row, to_col) move_history.append(move_input) current_player = 'black' if current_player == 'white' else 'white' else: print("Illegal move.") except ValueError: print("Invalid input. Please try again.") print("Game over.") print("Move history:") for move in move_history: print(move) if __name__ == "__main__": play_game() ``` 代码说明: 1. 初始化棋盘:`initialize_board` 函数用于创建一个初始的国际象棋棋盘。 2. 打印棋盘:`print_board` 函数将当前棋盘状态打印到控制台。 3. 坐标转换:`coord_to_pos` 函数将用户输入的坐标(如 `e2`)转换为棋盘上的行和列索引。 4. 合法移动:`get_legal_moves` 函数根据棋子的类型和规则,计算出该棋子的合法移动位置,并过滤掉会导致自己被将军的移动。 5. 检查将军和将死:`is_in_check` 函数检查当前玩家是否被将军,`is_checkmate` 函数检查是否被将死。 6. 移动棋子:`move_piece` 函数将棋子从一个位置移动到另一个位置。 7. 主游戏循环:`play_game` 函数是游戏的主循环,处理用户输入、检查游戏状态,并更新棋盘。 棋谱记录: 游戏结束后,会打印出所有的移动记录,方便查看棋谱。 投降和求和机制: 玩家可以输入 `surrender` 投降,输入 `draw` 求和。如果求和,对手可以选择是否接受。 注意事项: - 该代码没有实现一些复杂的规则,如王车易位、兵的升变等。 - 输入格式为 `e2 e4`,表示将 `e2` 位置的棋子移动到 `e4` 位置。 ######[AI问答 | 3059点数解答 | 2025-12-14 15:08:29]
- 超燃年会来袭!诗舞歌戏轮番上阵,共赴欢乐盛宴! (字节豆包 | 206点数解答 | 2025-01-08 10:59:43)347
- Python 运行报错:urllib3 网络连接创建失败,原因及排查建议(字节豆包 | 161点数解答 | 2024-10-31 00:39:36)467
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)349
- 卡牌游戏技能“教化”机制全解析:规则、代码与注意要点 (DeepSeek | 353点数解答 | 2025-07-07 15:40:28)171
- Python 模拟无名杀“教化”技能:出牌阶段规则与代码实现及优化建议(字节豆包 | 546点数解答 | 2025-07-07 15:41:02)175
- Java 实现“教化”技能:出牌阶段限两次的牌获取规则代码解析(字节豆包 | 1003点数解答 | 2025-07-07 15:41:54)146
- JavaScript 实现“教化”技能:两次出牌限制与牌型记录逻辑揭秘(字节豆包 | 846点数解答 | 2025-07-07 15:42:46)184
- 缜密逻辑,全新无名杀“风餐”技能代码精心打造与深度解析 (字节豆包 | 469点数解答 | 2025-04-05 11:37:06)246
- C++实现超全功能文字版象棋游戏:多文件代码大揭秘!(字节豆包 | 2285点数解答 | 2025-12-20 08:21:39)37
- Python 实战:学生信息列表转字典、遍历、深拷贝及数据修改全流程(GPT | 422点数解答 | 2024-10-29 15:43:54)420
- Python实战:学生成绩列表转字典,深拷贝与数据修改操作全解析(字节豆包 | 254点数解答 | 2024-10-29 16:01:39)414
- C++ 实现我的世界基岩版:从简单框架到开发要点揭秘(字节豆包 | 182点数解答 | 2025-02-22 15:53:11)201