python实现象棋

学会一些时间,应该玩一会,劳逸结合才好,我将之前的象棋进行优化调试

pip install --upgrade pip

pip install --only-binary=all pygame -i https://mirrors.tools.huawei.com/pypi/simple/

python 复制代码
import pygame
import sys

# 初始化Pygame
pygame.init()

# 游戏常量
WIDTH, HEIGHT = 600, 600
BOARD_SIZE = 9  # 棋盘列数
ROWS = 10  # 棋盘行数
CELL_SIZE = WIDTH // BOARD_SIZE

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (128, 128, 128)
BROWN = (139, 69, 19)

# 初始化窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("中国象棋")


# 棋盘坐标系
def get_board_pos(x, y):
    col = x // CELL_SIZE
    row = y // CELL_SIZE
    return col, row


# 棋子类
class Piece:
    def __init__(self, name, color, row, col):
        self.name = name
        self.color = color  # 'red' 或 'black'
        self.row = row
        self.col = col
        self.selected = False
        self.valid_moves = []

    def draw(self, screen):
        x = self.col * CELL_SIZE + CELL_SIZE // 2
        y = self.row * CELL_SIZE + CELL_SIZE // 2
        font = pygame.font.SysFont('SimHei', 40)
        text = font.render(self.name, True, BLACK if self.color == 'red' else WHITE)
        text_rect = text.get_rect(center=(x, y))
        screen.blit(text, text_rect)

    def get_valid_moves(self, board):
        # 简化版:只实现基本移动规则
        self.valid_moves = []
        row, col = self.row, self.col

        # 根据棋子类型确定移动规则
        if self.name == '车':
            # 横向移动
            for c in range(col + 1, BOARD_SIZE):
                if board[row][c] is None:
                    self.valid_moves.append((row, c))
                else:
                    if board[row][c].color != self.color:
                        self.valid_moves.append((row, c))
                    break
            for c in range(col - 1, -1, -1):
                if board[row][c] is None:
                    self.valid_moves.append((row, c))
                else:
                    if board[row][c].color != self.color:
                        self.valid_moves.append((row, c))
                    break
        elif self.name == '马':
            # 马走日
            for dr, dc in [(2, 1), (2, -1), (-2, 1), (-2, -1), (1, 2), (1, -2), (-1, 2), (-1, -2)]:
                r, c = row + dr, col + dc
                if 0 <= r < ROWS and 0 <= c < BOARD_SIZE:
                    if board[r][c] is None or board[r][c].color != self.color:
                        self.valid_moves.append((r, c))
        elif self.name == '炮':
            # 炮移动(直线)和吃子(必须隔一个棋子)
            # 横向移动
            for c in range(col + 1, BOARD_SIZE):
                if board[row][c] is None:
                    self.valid_moves.append((row, c))
                else:
                    # 如果是吃子,必须中间有一个棋子
                    if board[row][c].color != self.color:
                        # 检查中间是否有棋子
                        has_piece = False
                        for i in range(col + 1, c):
                            if board[row][i] is not None:
                                has_piece = True
                                break
                        if has_piece:
                            self.valid_moves.append((row, c))
                        break
                    else:
                        break
            for c in range(col - 1, -1, -1):
                if board[row][c] is None:
                    self.valid_moves.append((row, c))
                else:
                    if board[row][c].color != self.color:
                        has_piece = False
                        for i in range(c + 1, col):
                            if board[row][i] is not None:
                                has_piece = True
                                break
                        if has_piece:
                            self.valid_moves.append((row, c))
                        break
                    else:
                        break
        elif self.name == '兵':
            # 兵移动(红方向下,黑方向上)
            if self.color == 'red':
                # 向下移动
                if row + 1 < ROWS and board[row + 1][col] is None:
                    self.valid_moves.append((row + 1, col))
                # 过河后可左右移动
                if row >= 5:
                    for c in [col - 1, col + 1]:
                        if 0 <= c < BOARD_SIZE and board[row][c] is not None and board[row][c].color != self.color:
                            self.valid_moves.append((row, c))
            else:
                # 向上移动
                if row - 1 >= 0 and board[row - 1][col] is None:
                    self.valid_moves.append((row - 1, col))
                # 过河后可左右移动
                if row <= 4:
                    for c in [col - 1, col + 1]:
                        if 0 <= c < BOARD_SIZE and board[row][c] is not None and board[row][c].color != self.color:
                            self.valid_moves.append((row, c))
        elif self.name == '士':
            # 士只能在九宫格内斜走
            for dr, dc in [(1, 1), (1, -1), (-1, 1), (-1, -1)]:
                r, c = row + dr, col + dc
                if 0 <= r < 3 and 3 <= c < 6:  # 红方九宫格
                    if board[r][c] is None or board[r][c].color != self.color:
                        self.valid_moves.append((r, c))
        elif self.name == '相':
            # 相走田字,不能过河
            for dr, dc in [(2, 2), (2, -2), (-2, 2), (-2, -2)]:
                r, c = row + dr, col + dc
                if 0 <= r < ROWS and 0 <= c < BOARD_SIZE:
                    # 检查是否被阻挡
                    if (dr == 2 and dc == 2 and board[row + 1][col + 1] is None) or \
                            (dr == 2 and dc == -2 and board[row + 1][col - 1] is None) or \
                            (dr == -2 and dc == 2 and board[row - 1][col + 1] is None) or \
                            (dr == -2 and dc == -2 and board[row - 1][col - 1] is None):
                        if board[r][c] is None or board[r][c].color != self.color:
                            self.valid_moves.append((r, c))
        elif self.name == '将':
            # 将只能在九宫格内移动
            for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                r, c = row + dr, col + dc
                if 0 <= r < 3 and 3 <= c < 6:  # 红方九宫格
                    if board[r][c] is None or board[r][c].color != self.color:
                        self.valid_moves.append((r, c))


# 初始化棋盘
def create_board():
    board = [[None for _ in range(BOARD_SIZE)] for _ in range(ROWS)]

    # 红方棋子
    pieces = [
        ('车', 'red', 0, 0),
        ('马', 'red', 0, 1),
        ('相', 'red', 0, 2),
        ('仕', 'red', 0, 3),
        ('帅', 'red', 0, 4),
        ('仕', 'red', 0, 5),
        ('相', 'red', 0, 6),
        ('马', 'red', 0, 7),
        ('车', 'red', 0, 8),
        ('炮', 'red', 2, 1),
        ('炮', 'red', 2, 7),
        ('兵', 'red', 3, 0),
        ('兵', 'red', 3, 2),
        ('兵', 'red', 3, 4),
        ('兵', 'red', 3, 6),
        ('兵', 'red', 3, 8),
    ]

    # 黑方棋子
    pieces.extend([
        ('车', 'black', 9, 0),
        ('马', 'black', 9, 1),
        ('相', 'black', 9, 2),
        ('仕', 'black', 9, 3),
        ('将', 'black', 9, 4),
        ('仕', 'black', 9, 5),
        ('相', 'black', 9, 6),
        ('马', 'black', 9, 7),
        ('车', 'black', 9, 8),
        ('炮', 'black', 7, 1),
        ('炮', 'black', 7, 7),
        ('兵', 'black', 6, 0),
        ('兵', 'black', 6, 2),
        ('兵', 'black', 6, 4),
        ('兵', 'black', 6, 6),
        ('兵', 'black', 6, 8),
    ])

    for name, color, row, col in pieces:
        board[row][col] = Piece(name, color, row, col)

    return board


# 绘制棋盘
def draw_board(screen):
    # 绘制棋盘格子
    for i in range(ROWS):
        for j in range(BOARD_SIZE):
            rect = pygame.Rect(j * CELL_SIZE, i * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            if (i + j) % 2 == 0:
                pygame.draw.rect(screen, BROWN, rect)
            else:
                pygame.draw.rect(screen, GRAY, rect)

    # 绘制九宫格
    for i in range(3):
        for j in range(3):
            if i == 0 or i == 2:
                rect = pygame.Rect(3 * CELL_SIZE + j * CELL_SIZE, i * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                pygame.draw.rect(screen, BROWN, rect)
            else:
                rect = pygame.Rect(3 * CELL_SIZE + j * CELL_SIZE, i * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                pygame.draw.rect(screen, BROWN, rect, 2)

    # 绘制横线
    for i in range(10):
        pygame.draw.line(screen, BLACK, (0, i * CELL_SIZE), (WIDTH, i * CELL_SIZE), 2)

    # 绘制竖线
    for j in range(9):
        pygame.draw.line(screen, BLACK, (j * CELL_SIZE, 0), (j * CELL_SIZE, HEIGHT), 2)

    # 绘制棋子
    for row in range(ROWS):
        for col in range(BOARD_SIZE):
            piece = board[row][col]
            if piece:
                piece.draw(screen)


# 主游戏循环
def main():
    global board
    board = create_board()
    selected_piece = None
    running = True

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                col, row = get_board_pos(x, y)

                # 检查是否在棋盘范围内
                if 0 <= row < ROWS and 0 <= col < BOARD_SIZE:
                    piece = board[row][col]

                    # 如果已经选择了棋子,尝试移动
                    if selected_piece:
                        # 如果点击的是同一个棋子,取消选择
                        if piece == selected_piece:
                            selected_piece.selected = False
                            selected_piece = None
                        # 如果点击的是目标位置
                        elif (row, col) in selected_piece.valid_moves:
                            # 移动棋子
                            if piece:
                                # 吃子
                                board[row][col] = selected_piece
                                board[selected_piece.row][selected_piece.col] = None
                                selected_piece.row = row
                                selected_piece.col = col
                                selected_piece.selected = False
                                selected_piece = None
                            else:
                                # 移动
                                board[row][col] = selected_piece
                                board[selected_piece.row][selected_piece.col] = None
                                selected_piece.row = row
                                selected_piece.col = col
                                selected_piece.selected = False
                                selected_piece = None
                        # 如果点击的是其他棋子,选择它
                        elif piece and piece.color == selected_piece.color:
                            selected_piece.selected = False
                            selected_piece = piece
                            selected_piece.selected = True
                        # 如果点击的是对方棋子,但不在有效移动范围内,取消选择
                        elif piece and piece.color != selected_piece.color:
                            selected_piece.selected = False
                            selected_piece = None
                        else:
                            selected_piece.selected = False
                            selected_piece = None
                    # 如果没有选择棋子,选择当前棋子
                    elif piece:
                        selected_piece = piece
                        selected_piece.selected = True
                        selected_piece.get_valid_moves(board)
                    # 如果点击的是空位,取消选择
                    else:
                        selected_piece = None

                # 如果点击的是棋子,获取其有效移动
                if piece and not selected_piece:
                    selected_piece = piece
                    selected_piece.selected = True
                    selected_piece.get_valid_moves(board)

        # 绘制
        screen.fill(WHITE)
        draw_board(screen)

        # 绘制有效移动
        if selected_piece:
            for r, c in selected_piece.valid_moves:
                pygame.draw.circle(screen, RED, (c * CELL_SIZE + CELL_SIZE // 2, r * CELL_SIZE + CELL_SIZE // 2), 10)

        pygame.display.flip()

    pygame.quit()


if __name__ == "__main__":
    main()

整理不易,诚望各位看官点赞 收藏 评论 予以支持,这将成为我持续更新的动力源泉。若您在阅览时存有异议或建议,敬请留言指正批评,让我们携手共同学习,共同进取,吾辈自当相互勉励!

相关推荐
棉猴2 小时前
《pygame中Sprite类实现多帧动画》注-通过多张序列帧显示动画2-2
开发语言·python·游戏·游戏程序·pygame
练习时长一年2 小时前
Spring AoP的切点匹配
java·开发语言
烛阴2 小时前
Python数据可视化:从零开始教你绘制精美雷达图
前端·python
27669582922 小时前
朴朴超市小程序分析
java·python·小程序·node·sign·朴朴超市·sign-v2
重生之我要当编程大佬3 小时前
关于打不开pycharm的解决方法(一)
ide·python·pycharm
深圳佛手3 小时前
AI 编程工具Claude Code 介绍
人工智能·python·机器学习·langchain
霜绛3 小时前
C#知识补充(一)——ref和out、成员属性、万物之父和装箱拆箱、抽象类和抽象方法、接口
开发语言·笔记·学习·c#
T.Ree.3 小时前
cpp_list
开发语言·数据结构·c++·list