当前位置: 首页 > article >正文

通过Python编写的中国象棋小游戏

通过Python编写的中国象棋小游戏

    • 以下为游戏原始代码
    • 以下为游戏优化行进规则后的代码

确保代码简洁,结构清晰,方便后续扩展或添加功能,比如悔棋、保存游戏等。但用户可能只需要基本功能,所以先完成核心部分。

以下为游戏原始代码

import sys

class ChessPiece:
    def __init__(self, name, color):
        self.name = name
        self.color = color  # 'red' 或 'black'

    def display(self):
        colors = {'red': '\033[91m', 'black': '\033[94m'}
        return f"{colors[self.color]}{self.name}\033[0m"

class ChineseChess:
    def __init__(self):
        self.board = [[None for _ in range(9)] for _ in range(10)]
        self.current_player = 'red'
        self.setup_board()
        
    def setup_board(self):
        # 初始化棋子布局
        pieces = [
            ('車', '馬', '象', '士', '將', '士', '象', '馬', '車'),
            (None, None, None, None, None, None, None, None, None),
            (None, '炮', None, None, None, None, None, '炮', None),
            ('兵', None, '兵', None, '兵', None, '兵', None, '兵'),
            (None, None, None, None, None, None, None, None, None),
            (None, None, None, None, None, None, None, None, None),
            ('卒', None, '卒', None, '卒', None, '卒', None, '卒'),
            (None, '砲', None, None, None, None, None, '砲', None),
            (None, None, None, None, None, None, None, None, None),
            ('俥', '傌', '相', '仕', '帥', '仕', '相', '傌', '俥')
        ]
        
        for row in range(10):
            for col in range(9):
                name = pieces[row][col]
                if name:
                    color = 'red' if row in [9, 8, 7] else 'black'
                    self.board[row][col] = ChessPiece(name, color)

    def print_board(self):
        print("\n   ", end="")
        for col in range(9):
            print(f" {chr(65 + col)}  ", end="")
        print("\n  +" + "----+" * 9)
        
        for row in range(10):
            print(f"{row} |", end="")
            for col in range(9):
                piece = self.board[row][col]
                if piece:
                    print(f" {piece.display()} |", end="")
                else:
                    print("    |", end="")
            print(f" {row}\n  +" + "----+" * 9)

    def is_valid_move(self, start_row, start_col, end_row, end_col):
        # 实现各棋子的移动规则(此处为简化版,需完善)
        piece = self.board[start_row][start_col]
        if not piece or piece.color != self.current_player:
            return False
            
        dx = abs(end_col - start_col)
        dy = abs(end_row - start_row)
        target = self.board[end_row][end_col]
        
        # 通用规则检查
        if target and target.color == self.current_player:
            return False
            
        # 各棋子特殊规则
        name = piece.name
        if name in ['將', '帥']:
            return dx <= 1 and dy <= 1 and 3 <= end_col <= 5 and (
                (self.current_player == 'red' and 7 <= end_row <= 9) or 
                (self.current_player == 'black' and 0 <= end_row <= 2))
                
        elif name in ['士', '仕']:
            return dx == 1 and dy == 1 and 3 <= end_col <= 5 and (
                (self.current_player == 'red' and 7 <= end_row <= 9) or 
                (self.current_player == 'black' and 0 <= end_row <= 2))
                
        elif name in ['象', '相']:
            # 简化象的走法(需添加蹩脚检查)
            return dx == 2 and dy == 2 and end_row <= 4 if self.current_player == 'black' else end_row >= 5
            
        elif name in ['馬', '傌']:
            # 简化马走日(需添加蹩脚检查)
            return (dx == 1 and dy == 2) or (dx == 2 and dy == 1)
            
        elif name in ['車', '俥']:
            return self.check_straight_line(start_row, start_col, end_row, end_col)
            
        elif name in ['炮', '砲']:
            obstacles = self.count_obstacles(start_row, start_col, end_row, end_col)
            if target:
                return obstacles == 1  # 炮需要隔一个棋子吃子
            else:
                return obstacles == 0  # 移动时不能有障碍
                
        elif name in ['兵', '卒']:
            # 简化兵的前进规则
            direction = 1 if self.current_player == 'black' else -1
            if (self.current_player == 'black' and start_row < 5) or \
               (self.current_player == 'red' and start_row > 4):
                return (end_row - start_row == direction and dx == 0) or \
                       (abs(dx) == 1 and dy == 0)
            else:
                return end_row - start_row == direction and dx == 0
                
        return False

    def check_straight_line(self, sr, sc, er, ec):
        if sr != er and sc != ec:
            return False
        step_r = 1 if er > sr else -1 if er < sr else 0
        step_c = 1 if ec > sc else -1 if ec < sc else 0
        r, c = sr + step_r, sc + step_c
        while (r, c) != (er, ec):
            if self.board[r][c] is not None:
                return False
            r += step_r
            c += step_c
        return True

    def count_obstacles(self, sr, sc, er, ec):
        count = 0
        if sr == er:
            step = 1 if ec > sc else -1
            for c in range(sc + step, ec, step):
                if self.board[sr][c]:
                    count += 1
        else:
            step = 1 if er > sr else -1
            for r in range(sr + step, er, step):
                if self.board[r][sc]:
                    count += 1
        return count

    def move_piece(self, start_row, start_col, end_row, end_col):
        if self.is_valid_move(start_row, start_col, end_row, end_col):
            self.board[end_row][end_col] = self.board[start_row][start_col]
            self.board[start_row][start_col] = None
            self.current_player = 'black' if self.current_player == 'red' else 'red'
            return True
        return False

    def play(self):
        while True:
            self.print_board()
            print(f"\n当前玩家: {self.current_player}")
            try:
                move = input("输入起始位置和目标位置(例如:A2 A3): ").upper().split()
                if len(move) != 2:
                    raise ValueError
                
                sc = ord(move[0][0]) - 65
                sr = int(move[0][1])
                ec = ord(move[1][0]) - 65
                er = int(move[1][1])
                
                if 0 <= sr <= 9 and 0 <= sc <= 8 and 0 <= er <= 9 and 0 <= ec <= 8:
                    if self.move_piece(sr, sc, er, ec):
                        continue
                print("无效移动,请重试!")
            except (ValueError, IndexError):
                print("输入格式错误,请使用类似 A0 B2 的格式")

if __name__ == "__main__":
    game = ChineseChess()
    game.play()

以下为游戏优化行进规则后的代码

import sys

class ChessPiece:
    def __init__(self, name, color):
        self.name = name
        self.color = color  # 'red' 或 'black'

    def display(self):
        colors = {'red': '\033[91m', 'black': '\033[94m'}
        return f"{colors[self.color]}{self.name}\033[0m"

class ChineseChess:
    def __init__(self):
        self.board = [[None for _ in range(9)] for _ in range(10)]
        self.current_player = 'red'
        self.setup_board()
        
    def setup_board(self):
        # 初始化棋子布局
        pieces = [
            ('車', '馬', '象', '士', '將', '士', '象', '馬', '車'),
            (None, None, None, None, None, None, None, None, None),
            (None, '炮', None, None, None, None, None, '炮', None),
            ('兵', None, '兵', None, '兵', None, '兵', None, '兵'),
            (None, None, None, None, None, None, None, None, None),
            (None, None, None, None, None, None, None, None, None),
            ('卒', None, '卒', None, '卒', None, '卒', None, '卒'),
            (None, '砲', None, None, None, None, None, '砲', None),
            (None, None, None, None, None, None, None, None, None),
            ('俥', '傌', '相', '仕', '帥', '仕', '相', '傌', '俥')
        ]
        
        for row in range(10):
            for col in range(9):
                name = pieces[row][col]
                if name:
                    color = 'red' if row in [9, 8, 7] else 'black'
                    self.board[row][col] = ChessPiece(name, color)

    def print_board(self):
        print("\n   ", end="")
        for col in range(9):
            print(f" {chr(65 + col)}  ", end="")
        print("\n  +" + "----+" * 9)
        
        for row in range(10):
            print(f"{row} |", end="")
            for col in range(9):
                piece = self.board[row][col]
                if piece:
                    print(f" {piece.display()} |", end="")
                else:
                    print("    |", end="")
            print(f" {row}\n  +" + "----+" * 9)

    def is_valid_move(self, start_row, start_col, end_row, end_col):
        piece = self.board[start_row][start_col]
        if not piece or piece.color != self.current_player:
            return False
            
        dx = abs(end_col - start_col)
        dy = abs(end_row - start_row)
        target = self.board[end_row][end_col]
        
        # 通用规则检查
        if target and target.color == self.current_player:
            return False
            
        # 各棋子特殊规则
        name = piece.name
        if name in ['將', '帥']:
            return self.validate_king(start_row, start_col, end_row, end_col, dx, dy)
                
        elif name in ['士', '仕']:
            return self.validate_advisor(start_row, start_col, end_row, end_col, dx, dy)
                
        elif name in ['象', '相']:
            return self.validate_bishop(start_row, start_col, end_row, end_col, dx, dy)
            
        elif name in ['馬', '傌']:
            return self.validate_knight(start_row, start_col, end_row, end_col, dx, dy)
            
        elif name in ['車', '俥']:
            return self.check_straight_line(start_row, start_col, end_row, end_col)
            
        elif name in ['炮', '砲']:
            return self.validate_cannon(start_row, start_col, end_row, end_col)
                
        elif name in ['兵', '卒']:
            return self.validate_pawn(start_row, start_col, end_row, end_col, dx, dy)
                
        return False

    def validate_king(self, sr, sc, er, ec, dx, dy):
        """将/帅移动规则"""
        # 移动距离为一格且直线
        if dx + dy != 1 or (dx != 0 and dy != 0):
            return False
        
        # 目标在九宫内
        if not (3 <= ec <= 5):
            return False
        if self.current_player == 'red':
            if not (7 <= er <= 9):
                return False
        else:
            if not (0 <= er <= 2):
                return False
        return True

    def validate_advisor(self, sr, sc, er, ec, dx, dy):
        """士/仕移动规则"""
        # 斜走一格
        if dx != 1 or dy != 1:
            return False
        
        # 目标在九宫内
        if not (3 <= ec <= 5):
            return False
        if self.current_player == 'red':
            return 7 <= er <= 9
        else:
            return 0 <= er <= 2

    def validate_bishop(self, sr, sc, er, ec, dx, dy):
        """象/相移动规则"""
        if dx != 2 or dy != 2:
            return False
        
        # 检查象眼
        if self.board[(sr + er)//2][(sc + ec)//2] is not None:
            return False
        
        # 不能过河
        if self.current_player == 'red':
            return er >= 5  # 红方相不过河
        else:
            return er <= 4  # 黑方象不过河

    def validate_knight(self, sr, sc, er, ec, dx, dy):
        """马移动规则"""
        if not ((dx == 2 and dy == 1) or (dx == 1 and dy == 2)):
            return False
        
        # 检查蹩马腿
        if dx == 2:  # 横向移动
            mid_col = (sc + ec) // 2
            if self.board[sr][mid_col] is not None:
                return False
        else:  # 纵向移动
            mid_row = (sr + er) // 2
            if self.board[mid_row][sc] is not None:
                return False
        return True

    def validate_cannon(self, sr, sc, er, ec):
        """炮移动规则"""
        if not self.check_straight_line(sr, sc, er, ec):
            return False
        
        obstacles = self.count_obstacles(sr, sc, er, ec)
        target = self.board[er][ec]
        
        if target:  # 吃子时需要1个障碍
            return obstacles == 1
        else:       # 移动时无障碍
            return obstacles == 0

    def validate_pawn(self, sr, sc, er, ec, dx, dy):
        """兵/卒移动规则"""
        color = self.current_player
        forward = er - sr if color == 'black' else sr - er
        
        # 移动方向必须向前(过河前)或允许横向(过河后)
        if color == 'black':
            crossed = sr >= 5  # 黑卒过河条件
        else:
            crossed = sr <= 4  # 红兵过河条件
        
        # 检查移动类型
        if crossed:
            # 过河后可以横向或纵向移动
            if dy == 0:  # 横向移动
                return dx == 1 and forward == 0
            else:        # 纵向移动
                return forward == 1
        else:
            # 未过河只能向前
            return dx == 0 and forward == 1

    def check_straight_line(self, sr, sc, er, ec):
        """检查直线路径是否畅通"""
        if sr != er and sc != ec:
            return False
        step_r = 1 if er > sr else -1 if er < sr else 0
        step_c = 1 if ec > sc else -1 if ec < sc else 0
        
        r, c = sr + step_r, sc + step_c
        while (r, c) != (er, ec):
            if self.board[r][c] is not None:
                return False
            r += step_r
            c += step_c
        return True

    def count_obstacles(self, sr, sc, er, ec):
        """统计直线路径上的障碍物数量"""
        count = 0
        if sr == er:
            start, end = sorted([sc, ec])
            for c in range(start + 1, end):
                if self.board[sr][c] is not None:
                    count += 1
        else:
            start, end = sorted([sr, er])
            for r in range(start + 1, end):
                if self.board[r][sc] is not None:
                    count += 1
        return count

    # 其他方法保持不变...

if __name__ == "__main__":
    game = ChineseChess()
    game.play()

http://www.kler.cn/a/536896.html

相关文章:

  • 完美解决phpstudy安装后mysql无法启动
  • 从java角度对比nodejs、fastapi,同步和异步区别
  • Spring的Bean的生命周期 笔记250206
  • GitHub 使用教程:从入门到进阶
  • 机器学习之数学基础:线性代数、微积分、概率论 | PyTorch 深度学习实战
  • 实现一个 LRU 风格的缓存类
  • mac 安装 dotnet 环境
  • 嵌入式硬件篇---OpenMV串口通信json字符串
  • Redis | 十大数据类型
  • Spring Boot:解决现代Java应用开发的难题
  • 关于阿里云 dataworks 运维中心下的任务运维的问题
  • 发布:大彩科技DN系列2.8寸高性价比串口屏发布!
  • TPC服务器与客户端的搭建
  • 【iOS自动化】Xcode配置WebDriverAgent
  • Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用
  • Android Studio 2024.2.2.13版本安装配置详细教程
  • leetcode 907. 子数组的最小值之和
  • MySql数据库SQL编写规范注意事项
  • 如何保证系统上线不出现bug?
  • 阿里云负载均衡:DDoS 攻击的坚固防线?
  • 单片机通讯中的时序图:初学者的入门指南
  • http cookie的作用学习
  • LM Studio 部署本地大语言模型
  • Spring Security 6.X + JWT + RBAC 权限管理实战教程(下)
  • 【SQL server】关于SQL server彻底的卸载删除。
  • 把bootstrap5.3.3整合到wordpress主题中的方法