鱼C论坛

 找回密码
 立即注册
查看: 39|回复: 9

python中国象棋

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
怎么写棋盘呢?python中国象棋怎么移动棋子呢,怎么学?棋盘怎么绘制?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 3 小时前 | 显示全部楼层
你的问题涉及Python中国象棋的多个方面,我们逐一用简洁的代码和思路解答。

---

### 1. 棋盘怎么写(数据结构)

推荐用二维列表(9行10列,对应9×10格),每个位置存储一个字符表示棋子或空位。例如:


  1. # 初始化空棋盘:9行10列,用'.'表示空白
  2. board = [['.' for _ in range(10)] for _ in range(9)]
  3. # 放一个红“车”在(0,0)位置
  4. board[0][0] = 'Rc'   # 'R'表示红方(car)
复制代码


更标准的方式是使用整数或类对象,但初学用字符最直观。也可以为每种棋子定义类,但非必须。

---

### 2. 棋盘怎么绘制(文本版)

只需遍历棋盘列表,逐行打印。例如:


  1. def print_board(board):
  2.     print("  0 1 2 3 4 5 6 7 8 9")   # 列号
  3.     for i, row in enumerate(board):
  4.         print(f"{i} " + " ".join(row))
复制代码


这样会输出类似网格。若想更美观,可加上边框符号(如用│││等),但初学这样已足够。

如果要用图形界面,推荐pygameturtle库,绘制矩形网格和棋子图片,但代码较多。建议先掌握文本版。

---

### 3. 怎么移动棋子

移动棋子本质是改变棋盘上某个位置为空白,目标位置放该棋子。但必须加上“走法规则”判断。

简化的移动函数(不判断规则):


  1. def move_piece(board, from_row, from_col, to_row, to_col):
  2.     piece = board[from_row][from_col]
  3.     if piece == '.':
  4.         print("该位置无棋子")
  5.         return False
  6.     board[to_row][to_col] = piece
  7.     board[from_row][from_col] = '.'
  8.     return True
复制代码


要加入规则,比如车只能走直线、中间不能有棋子,可以写:


  1. def can_move_rook(board, from_pos, to_pos):
  2.     # 检查路径上是否全部空白,且目标合法(略)
  3.     pass
复制代码


初学者建议先实现【不判断规则的自由移动】,慢慢增加规则类。

---

### 4. 怎么学(学习路径)

1. **基础数据结构**:掌握列表、字典、嵌套列表。
2. **写一个类ChineseChess**:包含棋盘、棋子列表、玩家轮次。
3. **文本界面**:控制台输入坐标,调用移动函数。
4. **加入走法规则**:从简单棋子(车、炮)开始,再写马、象等。每种棋子写一个合法性函数。
5. **添加吃子、将军判断**:用一个循环判断是否被将杀。
6. **GUI扩展**:用pygame或tkinter给棋盘画图,绑定鼠标点击事件。

慢慢来,每天写一小块,不要强求一步到位。

---

### 完整最小示例(控制台版,忽略规则)


  1. board = [['.' for _ in range(10)] for _ in range(9)]
  2. board[0][0] = 'Rc'   # 红车在(0,0)
  3. board[8][4] = 'Bk'   # 黑将在(8,4)

  4. def print_board(board):
  5.     for i, row in enumerate(board):
  6.         print(f"{i}: " + " ".join(row))
  7.     print("   a b c d e f g h i j")  # 列标记

  8. while True:
  9.     print_board(board)
  10.     cmd = input("输入移动:from行 from列 to行 to列(空格分隔),q退出:")
  11.     if cmd == 'q':
  12.         break
  13.     try:
  14.         fr, fc, tr, tc = map(int, cmd.split())
  15.         if 0 <= fr < 9 and 0 <= fc < 10 and 0 <= tr < 9 and 0 <= tc < 10:
  16.             piece = board[fr][fc]
  17.             if piece != '.':
  18.                 board[tr][tc] = piece
  19.                 board[fr][fc] = '.'
  20.             else:
  21.                 print("起点无棋子")
  22.         else:
  23.             print("坐标越界")
  24.     except:
  25.         print("输入格式错误")
复制代码


运行后可以自由移动(不检查规则,但已能体验)。

---

希望这些代码和思路能帮你快速起步。记住:从最简版本开始,逐步增加规则,最终做出完整象棋。加油!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 3 小时前 | 显示全部楼层
怎么使用pythonpygame或turtle库,绘制矩形网格和棋子图片
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层
过默 发表于 2026-07-22 13:21
怎么使用pythonpygame或turtle库,绘制矩形网格和棋子 ...


以下使用 pygame 库讲解,适合初学者,代码简洁直观。

---

### 1. 绘制棋盘网格

用循环画横线和竖线,分割矩形格子。假设棋盘左上角留边距,每个格子宽度固定。


  1. import pygame
  2. import sys

  3. # 初始化
  4. pygame.init()
  5. WINDOW_WIDTH = 550
  6. WINDOW_HEIGHT = 610
  7. screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
  8. pygame.display.set_caption("中国象棋棋盘")

  9. # 颜色定义
  10. WHITE = (255,255,255)
  11. BLACK = (0,0,0)
  12. BROWN = (205,133,63)  # 棋盘底色

  13. # 格子参数
  14. CELL_SIZE = 55   # 每个格子边长
  15. MARGIN_X = 35    # 左边距
  16. MARGIN_Y = 35    # 上边距
  17. ROWS = 9         # 行数(纵向)
  18. COLS = 10        # 列数(横向)注意:传统棋盘是9×10

  19. def draw_board():
  20.     screen.fill(BROWN)  # 背景
  21.     # 画横线
  22.     for row in range(ROWS):
  23.         y = MARGIN_Y + row * CELL_SIZE
  24.         pygame.draw.line(screen, BLACK,
  25.                          (MARGIN_X, y),
  26.                          (MARGIN_X + (COLS-1)*CELL_SIZE, y), 2)
  27.     # 画竖线
  28.     for col in range(COLS):
  29.         x = MARGIN_X + col * CELL_SIZE
  30.         pygame.draw.line(screen, BLACK,
  31.                          (x, MARGIN_Y),
  32.                          (x, MARGIN_Y + (ROWS-1)*CELL_SIZE), 2)
  33.     # 画河界(中间空白区域可以画虚线或文字,此处省略)
  34.     pygame.display.flip()

  35. # 主循环
  36. running = True
  37. while running:
  38.     for event in pygame.event.get():
  39.         if event.type == pygame.QUIT:
  40.             running = False
  41.     draw_board()
  42. pygame.quit()
  43. sys.exit()
复制代码


---

### 2. 绘制棋子(用圆形代替图片)

每个棋子用一个圆表示,可以设定不同颜色(红、黑)。棋子位置对应网格交点坐标。


  1. # 棋子参数
  2. RADIUS = 22
  3. RED = (200,0,0)
  4. BLACK_PIECE = (50,50,50)

  5. def draw_piece(screen, row, col, color, text):
  6.     """在(row, col)位置画一个棋子,row:0~8, col:0~9"""
  7.     x = MARGIN_X + col * CELL_SIZE
  8.     y = MARGIN_Y + row * CELL_SIZE
  9.     pygame.draw.circle(screen, color, (x, y), RADIUS)
  10.     # 绘制文字(如"车""马")
  11.     font = pygame.font.SysFont("simsun", 24)  # 宋体
  12.     img = font.render(text, True, WHITE)
  13.     screen.blit(img, (x-img.get_width()//2, y-img.get_height()//2))
复制代码


draw_board() 内部调用 draw_piece 即可显示棋子。例如棋盘初始化:


  1. # 在draw_board()中画一个红"车"
  2. draw_piece(screen, 0, 0, RED, "车")
  3. draw_piece(screen, 8, 4, BLACK_PIECE, "将")
复制代码


---

### 3. 完整示例(单窗口+网格+棋子)

将以上代码整合,再添加一个棋子列表来自定义布局。下面是最简版本:


  1. import pygame
  2. import sys

  3. pygame.init()
  4. screen = pygame.display.set_mode((550, 610))
  5. clock = pygame.time.Clock()

  6. # 常量
  7. CELL = 55
  8. MX, MY = 35, 35
  9. ROWS, COLS = 9, 10
  10. BROWN = (205,133,63)
  11. BLACK = (0,0,0)
  12. RED = (200,0,0)
  13. BLACK_PIECE = (50,50,50)

  14. font = pygame.font.SysFont("simsun", 24)

  15. def draw_board():
  16.     screen.fill(BROWN)
  17.     # 画线
  18.     for row in range(ROWS):
  19.         y = MY + row * CELL
  20.         pygame.draw.line(screen, BLACK, (MX, y), (MX + (COLS-1)*CELL, y), 2)
  21.     for col in range(COLS):
  22.         x = MX + col * CELL
  23.         pygame.draw.line(screen, BLACK, (x, MY), (x, MY + (ROWS-1)*CELL), 2)
  24.     # 画棋子示例(红车在(0,0),黑将在(8,4))
  25.     draw_piece(0, 0, RED, "车")
  26.     draw_piece(8, 4, BLACK_PIECE, "将")
  27.     pygame.display.flip()

  28. def draw_piece(row, col, color, text):
  29.     x = MX + col * CELL
  30.     y = MY + row * CELL
  31.     pygame.draw.circle(screen, color, (x, y), 22)
  32.     img = font.render(text, True, (255,255,255))
  33.     screen.blit(img, (x-14, y-12))

  34. while True:
  35.     for event in pygame.event.get():
  36.         if event.type == pygame.QUIT:
  37.             pygame.quit(); sys.exit()
  38.     draw_board()
  39.     clock.tick(30)
复制代码


---

### 4. 使用turtle库的简单方法(选读)

turtle也可以画网格和画圆,但交互性不如pygame。核心思路是用 turtle.penup()turtle.goto() 定位,用 turtle.pendown() 画线段和圆。代码略长,建议初学者优先尝试pygame。

---

### 如何学

1. 先安装 pygame(命令行: pip install pygame)。
2. 运行上面的代码,理解窗口、事件、绘图函数。
3. 修改颜色、尺寸,加入更多棋子(用列表存储每颗棋子的位置和类型)。
4. 下一步:实现鼠标点击选中棋子、拖动或点选目标位置移动(监听 MOUSEBUTTONDOWN 事件,计算点击的网格坐标)。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 3 小时前 | 显示全部楼层
pygame 2.6.1 (SDL 2.28.4, Python 3.8.10)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "C:/Program Files/Python38/pychw.py", line 18, in <module>
    font = pygame.font.SysFont("simsun", 24)
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 416, in SysFont
    initsysfonts()
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 355, in initsysfonts
    fonts = initsysfonts_win32()
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 82, in initsysfonts_win32
    if splitext(font)[1].lower() not in OpenType_extensions:
  File "C:\Program Files\Python38\lib\ntpath.py", line 204, in splitext
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not int
>>>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层
过默 发表于 2026-07-22 13:31
pygame 2.6.1 (SDL 2.28.4, Python 3.8.10)
Hello fr ...


你的代码运行时报错 `TypeError: expected str, bytes or os.PathLike object, not int`,这是因为 `pygame.font.SysFont("simsun", 24)` 在初始化时扫描系统字体时出现了内部错误。常见于某些 Windows 系统或 pygame 版本兼容问题。

**解决方案**:改用默认字体或指定一个字体文件路径。

---

### 方案一:使用默认字体(最简单)

将字体加载行改为:


font = pygame.font.Font(None, 24)


`None` 表示使用 pygame 内置的默认字体,可以正常显示英文字符和数字。缺点是可能无法显示中文棋子名称(会显示为方块)。但程序可以运行。

---

### 方案二:手动指定一个中文字体文件

先下载一个字体文件(如 `simhei.ttf` 或 `msyh.ttc`),放在程序同目录,然后:


font = pygame.font.Font("simhei.ttf", 24)


如果你没有字体文件,可以复制系统字体(例如 Windows 的 `C:/Windows/Fonts/simhei.ttf`),但路径可能不同。可用以下代码查找可用字体:


import pygame
pygame.font.init()
print(pygame.font.get_default_font())  # 查看默认字体文件路径
fonts = pygame.font.get_fonts()
if 'simsun' in fonts:
    print("simsun 可用")


如果不确定,先用 `None` 测试。

---

### 修改后的完整代码(使用默认字体)


import pygame
import sys

pygame.init()
screen = pygame.display.set_mode((550, 610))
clock = pygame.time.Clock()

CELL = 55
MX, MY = 35, 35
ROWS, COLS = 9, 10
BROWN = (205,133,63)
BLACK = (0,0,0)
RED = (200,0,0)
BLACK_PIECE = (50,50,50)

# 使用默认字体(不依赖系统字体扫描)
font = pygame.font.Font(None, 24)

def draw_board():
    screen.fill(BROWN)
    for row in range(ROWS):
        y = MY + row * CELL
        pygame.draw.line(screen, BLACK, (MX, y), (MX + (COLS-1)*CELL, y), 2)
    for col in range(COLS):
        x = MX + col * CELL
        pygame.draw.line(screen, BLACK, (x, MY), (x, MY + (ROWS-1)*CELL), 2)
    draw_piece(0, 0, RED, "R")   # 用英文代替中文,避免字体问题
    draw_piece(8, 4, BLACK_PIECE, "K")
    pygame.display.flip()

def draw_piece(row, col, color, text):
    x = MX + col * CELL
    y = MY + row * CELL
    pygame.draw.circle(screen, color, (x, y), 22)
    img = font.render(text, True, (255,255,255))
    screen.blit(img, (x-14, y-12))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit(); sys.exit()
    draw_board()
    clock.tick(30)


---

### 如果仍然出错

可能是 pygame 2.6.1 与 Python 3.8.10 的某种特定兼容问题。尝试升级或降级 pygame:


pip install pygame==2.5.2   # 回退到稳定版本


或者升级 Python 到 3.9+。建议先使用默认字体方案,绝大部分问题都能解决。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 3 小时前 | 显示全部楼层
================== RESTART: C:/Program Files/Python38/pychw.py =================
pygame 2.5.2 (SDL 2.28.3, Python 3.8.10)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "C:/Program Files/Python38/pychw.py", line 18, in <module>
    font = pygame.font.SysFont("simsun", 24)
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 418, in SysFont
    initsysfonts()
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 357, in initsysfonts
    fonts = initsysfonts_win32()
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 82, in initsysfonts_win32
    if splitext(font)[1].lower() not in OpenType_extensions:
  File "C:\Program Files\Python38\lib\ntpath.py", line 204, in splitext
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not int
>>>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层
过默 发表于 2026-07-22 13:34
================== RESTART: C:/Program Files/Pytho ...


你的错误仍然出现在 `pygame.font.SysFont("simsun", 24)` 这一行。即使降级到 2.5.2,pygame 内部扫描系统字体时的 bug 依然存在(可能是特定 Python 3.8 与 Windows 环境的兼容问题)。**解决方案非常简单:不要使用 SysFont,改用 Font(None, size) 或指定字体文件。** 现在请你直接修改你的代码,把第 18 行:

  1. font = pygame.font.SysFont("simsun", 24)
复制代码


替换为:

  1. font = pygame.font.Font(None, 24)
复制代码


然后重新运行。这时会使用 pygame 内置默认字体,虽然无法显示中文,但程序不会崩溃。如果你需要显示中文棋子名称(如“车”、“马”),请先下载一个中文字体文件(比如从网上下载 `simhei.ttf` 或 `msyh.ttc`),并放在你的代码同一目录下,然后改为:

  1. font = pygame.font.Font("simhei.ttf", 24)
复制代码


或者直接指定系统字体绝对路径(例如 Windows 的 `C:/Windows/Fonts/simhei.ttf`):

  1. font = pygame.font.Font("C:/Windows/Fonts/simhei.ttf", 24)
复制代码


**注意:使用中文字体前,建议先检查该字体文件是否存在,否则又会报错。**

现在请修改代码并重新运行,应该不会再出现之前的 TypeError 了。如果你仍然卡在这一步,可以把修改后的代码(至少第 18~20 行)贴出来,我帮你确认。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 3 小时前 | 显示全部楼层
======
pygame 2.5.2 (SDL 2.28.3, Python 3.8.10)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "C:/Program Files/Python38/pychw.py", line 18, in <module>
    font = pygame.font.SysFont(None, 24)
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 418, in SysFont
    initsysfonts()
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 357, in initsysfonts
    fonts = initsysfonts_win32()
  File "C:\Program Files\Python38\lib\site-packages\pygame\sysfont.py", line 82, in initsysfonts_win32
    if splitext(font)[1].lower() not in OpenType_extensions:
  File "C:\Program Files\Python38\lib\ntpath.py", line 204, in splitext
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not int
>>>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层
过默 发表于 2026-07-22 13:36
======
pygame 2.5.2 (SDL 2.28.3, Python 3.8.10)
...


你的代码中仍然使用了 `pygame.font.SysFont(None, 24)`,而 `SysFont` 即使传 `None` 也会触发系统字体扫描,导致同样的错误。请**务必改为**:

`font = pygame.font.Font(None, 24)`

`Font(None, size)` 不扫描系统字体,直接使用 pygame 内置的默认字体,不会报错。现在请你**修改第18行**为上面的形式,然后重新运行。如果还是同样的错误,请检查你实际修改的代码。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-7-22 16:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表