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

用python实现中国象棋

一.象棋规则

象棋是二人对弈的棋类游戏,棋盘由 9 条竖线和 10 条横线交叉构成,中间 “河界” 分楚汉,两端 “九宫” 各 9 个交叉点。棋子分红黑,各 16 枚,含 7 兵种。

1.棋子走法

1.1 红方棋子

  • :1 个,是红方的核心棋子,只能在九宫之内活动,可上可下,可左可右,每次走动只能按竖线或横线走动一格。
  • :2 个,是帅的贴身保镖,只能在九宫内走动,行棋路径只能是九宫内的斜线。
  • :2 个,每次循对角线走两格,俗称 “相飞田”。
  • :2 个,无论横线、竖线均可行走,只要无子阻拦,步数不受限制。
  • :2 个,走 “日” 字,每步走一直一斜,具有很高的灵活性和攻击性。
  • :2 个,行动迅速而易于成势,需要借助其他棋子的力量进行攻击,有击必应。
  • :5 个,只能向前走,第一步只能走一格,以后每步可以走一格或两格,但未过河前不能左右移动,过河后可以左右移动。

1.2 黑方棋子

  • :1 个,作用与红方的帅相同,是黑方的核心棋子,只能在九宫格内活动,每次只能横竖移动一格。
  • :2 个,作用与红方的仕相同,负责在九宫格内保护将,走的是斜线,每次只能斜着走一格。
  • :2 个,走法与红方的相相同,每次循对角线走两格,俗称 “象飞田”。
  • :2 个,走法与红方的车相同,无论横线、竖线均可行走,只要无子阻拦,步数不受限制。
  • :2 个,走法与红方的马相同,走 “日” 字,每步走一直一斜。
  • :2 个,走法与红方的炮相同,行动迅速而易于成势,需要借助其他棋子的力量进行攻击,有击必应。
  • :5 个,走法与红方的兵相同,只能向前走,第一步只能走一格,以后每步可以走一格或两格,但未过河前不能左右移动,过河后可以左右移动。

2.吃子与胜负

  1. 吃子:走到对方棋子位置,将其从棋盘移除。
  2. 胜负:将死对方 “将(帅)” 或对方认输则胜;双方均无能力将死对方,判和棋。

二.详细分析

每个棋子按照上述规则在棋盘上移动、吃子,双方通过合理运用棋子的走法,以将死对方的将(帅)为目标,最终决出胜负。

若一个棋子,他只能在这米字格里横竖方向的移动,便是象棋当中将(帅)的走法;

只能在米字格中沿斜线行走的话,就是士;

而可以横竖方向,无论距离的走,便是车;

若与车的行走完全一致,但必须跳过一颗棋子进行吃子的是炮(砲);

当两块格子组成"日"字,只能走其对角线,这就是马;

若需走四个格子对角线的话,这样跳过"田"字的是象,注意只能在己方阵营行动;

一颗只能向前移动在己方阵营,过届之后才能能左右行走且无法向后回头的是兵(卒)

抽象为计算机模型:

用二维列表表示棋盘,每个元素代表棋盘上的一个位置。

定义棋子类,每个棋子对象有其颜色、类型等属性,以及移动合法性判断方法。

实现棋盘初始化、棋子移动、吃子、判断胜负等功能。

三.用python 实现象棋

1.初始构建棋盘

用二维列表表示棋盘,每个元素代表棋盘上的一个位置。

def create_chessboard():# 创建一个10x9的二维列表,初始值为None,代表空位置chessboard = [[None] * 9 for _ in range(10)]return chessboard

2.定义各类棋子和属性(同类区分双方部分名称)

定义棋子类,每个棋子对象有其颜色、类型等属性,以及移动合法性判断方法。

class Piece:def __init__(self, color, kind):# 棋子颜色,如'红'或'黑'self.color = color# 棋子类型,如'将'、'车'等self.kind = kinddef is_move_valid(self, start, end, board):# 该方法需在子类中具体实现,用于判断棋子从start到end的移动是否合法passclass King(Piece):def is_move_valid(self, start, end, board):x1, y1 = startx2, y2 = end# 判断将(帅)是否在九宫格内if self.color == '红':if not (3 <= x1 <= 5 and 7 <= y1 <= 9):return Falseelse:if not (3 <= x1 <= 5 and 0 <= y1 <= 2):return False# 判断是否沿横竖方向移动一格return abs(x1 - x2) + abs(y1 - y2) == 1class Advisor(Piece):def is_move_valid(self, start, end, board):x1, y1 = startx2, y2 = end# 判断士是否在九宫格内if self.color == '红':if not (3 <= x1 <= 5 and 7 <= y1 <= 9):return Falseelse:if not (3 <= x1 <= 5 and 0 <= y1 <= 2):return False# 判断是否沿斜线移动一格return abs(x1 - x2) == 1 and abs(y1 - y2) == 1class Elephant(Piece):def is_move_valid(self, start, end, board):x1, y1 = startx2, y2 = end# 判断象是否过河if (self.color == '红' and y2 < 5) or (self.color == '黑' and y2 > 4):return False# 判断是否走“田”字对角且“田”字中心无棋子(不塞象眼)if abs(x1 - x2) == 2 and abs(y1 - y2) == 2:mid_x = (x1 + x2) // 2mid_y = (y1 + y2) // 2return board[mid_y][mid_x] is Nonereturn Falseclass Horse(Piece):def is_move_valid(self, start, end, board):x1, y1 = startx2, y2 = enddx = abs(x1 - x2)dy = abs(y1 - y2)# 判断是否走“日”字对角且不蹩马腿if (dx == 2 and dy == 1) or (dx == 1 and dy == 2):block_x = x1 if dx == 2 else (x1 + x2) // 2block_y = y1 if dy == 2 else (y1 + y2) // 2return board[block_y][block_x] is Nonereturn Falseclass Chariot(Piece):def is_move_valid(self, start, end, board):x1, y1 = startx2, y2 = end# 判断是否在横竖方向移动且路径无阻挡if x1 == x2:for y in range(min(y1, y2) + 1, max(y1, y2)):if board[y][x1] is not None:return Falseelif y1 == y2:for x in range(min(x1, x2) + 1, max(x1, x2)):if board[y1][x] is not None:return Falseelse:return Falsereturn Trueclass Cannon(Piece):def is_move_valid(self, start, end, board):x1, y1 = startx2, y2 = end# 判断移动路径是否为空或有且仅有一个炮台if x1 == x2:count = 0for y in range(min(y1, y2) + 1, max(y1, y2)):if board[y][x1] is not None:count += 1if (end[1] == start[1] and count == 0) or (end[1]!= start[1] and count == 1):return Trueelif y1 == y2:count = 0for x in range(min(x1, x2) + 1, max(x1, x2)):if board[y1][x] is not None:count += 1if (end[0] == start[0] and count == 0) or (end[0]!= start[0] and count == 1):return Truereturn Falseclass Soldier(Piece):def is_move_valid(self, start, end, board):x1, y1 = startx2, y2 = end# 判断兵(卒)是否符合移动规则if self.color == '红':if y1 < 5:if y2!= y1 + 1 or x2!= x1:return Falseelse:if y2!= y1 + 1 and x2 not in [x1 - 1, x1 + 1]:return Falseelse:if y1 > 4:if y2!= y1 - 1 or x2!= x1:return Falseelse:if y2!= y1 - 1 and x2 not in [x1 - 1, x1 + 1]:return Falsereturn True

3.构建获胜条件,判断胜负功能等

实现棋盘初始化、棋子移动、吃子、判断胜负等功能。

class ChessGame:def __init__(self):self.board = create_chessboard()self.init_pieces()def init_pieces(self):# 红方棋子初始化self.board[9][0] = Chariot('红', '车')self.board[9][1] = Horse('红', '马')self.board[9][2] = Elephant('红', '象')self.board[9][3] = Advisor('红', '士')self.board[9][4] = King('红', '将')self.board[9][5] = Advisor('红', '士')self.board[9][6] = Elephant('红', '象')self.board[9][7] = Horse('红', '马')self.board[9][8] = Chariot('红', '车')self.board[7][1] = Cannon('红', '炮')self.board[7][7] = Cannon('红', '炮')for i in range(0, 9, 2):self.board[6][i] = Soldier('红', '兵')# 黑方棋子初始化self.board[0][0] = Chariot('黑', '车')self.board[0][1] = Horse('黑', '马')self.board[0][2] = Elephant('黑', '象')self.board[0][3] = Advisor('黑', '士')self.board[0][4] = King('黑', '帅')self.board[0][5] = Advisor('黑', '士')self.board[0][6] = Elephant('黑', '象')self.board[0][7] = Horse('黑', '马')self.board[0][8] = Chariot('黑', '车')self.board[2][1] = Cannon('黑', '炮')self.board[2][7] = Cannon('黑', '炮')for i in range(0, 9, 2):self.board[3][i] = Soldier('黑', '卒')def move_piece(self, start, end):# 检查起始和目标位置是否在棋盘内if 0 <= start[0] < 10 and 0 <= start[1] < 9 and 0 <= end[0] < 10 and 0 <= end[1] < 9:piece = self.board[start[0]][start[1]]if piece is not None:if piece.is_move_valid(start, end, self.board):if self.board[end[0]][end[1]] is not None and self.board[end[0]][end[1]].color!= piece.color:# 吃子self.board[end[0]][end[1]] = Noneself.board[end[0]][end[1]] = self.board[start[0]][start[1]]self.board[start[0]][start[1]] = Nonereturn Truereturn Falsedef is_checkmate(self, color):king_pos = None# 找到将(帅)的位置for i in range(10):for j in range(9):if self.board[i][j] is not None and self.board[i][j].color == color and self.board[i][j].kind in ['将', '帅']:king_pos = (i, j)if king_pos is None:return False# 检查是否有对方棋子能吃掉将(帅)for i in range(10):for j in range(9):if self.board[i][j] is not None and self.board[i][j].color!= color:if self.board[i][j].is_move_valid((i, j), king_pos, self.board):return Truereturn False

4.测试运行

# 测试代码
game = ChessGame()
# 尝试移动红方车
game.move_piece((9, 0), (7, 0))
print(game.is_checkmate('黑'))

5.整体代码及测试

5.1 整体代码

def create_chessboard():"""创建一个10x9的二维列表,初始值为None,代表空位置。:return: 表示棋盘的二维列表"""return [[None] * 9 for _ in range(10)]class Piece:"""定义棋子的基类,包含颜色和类型属性,以及一个抽象方法用于判断移动是否合法。Attributes:color (str): 棋子颜色,如'红'或'黑'。kind (str): 棋子类型,如'将'、'车'等。"""def __init__(self, color, kind):self.color = colorself.kind = kinddef is_move_valid(self, start, end, board):"""判断棋子从start到end的移动是否合法。此方法为抽象方法,需在子类中具体实现。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""passclass King(Piece):def is_move_valid(self, start, end, board):"""帅(将)的移动规则:只能在九宫格内活动,每次沿横竖方向移动一格。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""x1, y1 = startx2, y2 = endif self.color == '红':if not (3 <= x1 <= 5 and 7 <= y1 <= 9):return Falseelse:if not (3 <= x1 <= 5 and 0 <= y1 <= 2):return Falsereturn abs(x1 - x2) + abs(y1 - y2) == 1class Advisor(Piece):def is_move_valid(self, start, end, board):"""仕(士)的移动规则:只能在九宫内走动,行棋路径只能是九宫内的斜线。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""x1, y1 = startx2, y2 = endif self.color == '红':if not (3 <= x1 <= 5 and 7 <= y1 <= 9):return Falseelse:if not (3 <= x1 <= 5 and 0 <= y1 <= 2):return Falsereturn abs(x1 - x2) == 1 and abs(y1 - y2) == 1class Elephant(Piece):def is_move_valid(self, start, end, board):"""相(象)的移动规则:循对角线走两格,俗称“相飞田”,不能过河。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""x1, y1 = startx2, y2 = endif (self.color == '红' and y2 < 5) or (self.color == '黑' and y2 > 4):return Falseif abs(x1 - x2) == 2 and abs(y1 - y2) == 2:mid_x = (x1 + x2) // 2mid_y = (y1 + y2) // 2return board[mid_y][mid_x] is Nonereturn Falseclass Horse(Piece):def is_move_valid(self, start, end, board):"""马的移动规则:走“日”字,每步走一直一斜,注意“蹩马腿”。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""x1, y1 = startx2, y2 = enddx = abs(x1 - x2)dy = abs(y1 - y2)if (dx == 2 and dy == 1) or (dx == 1 and dy == 2):block_x = x1 if dx == 2 else (x1 + x2) // 2block_y = y1 if dy == 2 else (y1 + y2) // 2return board[block_y][block_x] is Nonereturn Falseclass Chariot(Piece):def is_move_valid(self, start, end, board):"""车的移动规则:无论横线、竖线均可行走,只要无子阻拦,步数不受限制。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""x1, y1 = startx2, y2 = endif x1 == x2:for y in range(min(y1, y2) + 1, max(y1, y2)):if board[y][x1] is not None:return Falseelif y1 == y2:for x in range(min(x1, x2) + 1, max(x1, x2)):if board[y1][x] is not None:return Falseelse:return Falsereturn Trueclass Cannon(Piece):def is_move_valid(self, start, end, board):"""炮的移动规则:移动方式与车相同,吃子时需借助一个棋子作为炮台。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""x1, y1 = startx2, y2 = endif x1 == x2:count = 0for y in range(min(y1, y2) + 1, max(y1, y2)):if board[y][x1] is not None:count += 1if (end[1] == start[1] and count == 0) or (end[1]!= start[1] and count == 1):return Trueelif y1 == y2:count = 0for x in range(min(x1, x2) + 1, max(x1, x2)):if board[y1][x] is not None:count += 1if (end[0] == start[0] and count == 0) or (end[0]!= start[0] and count == 1):return Truereturn Falseclass Soldier(Piece):def is_move_valid(self, start, end, board):"""兵(卒)的移动规则:未过河时只能向前移动一格,过河后可向前或横向移动一格。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:param board: 棋盘,二维列表。:return: bool,移动是否合法。"""x1, y1 = startx2, y2 = endif self.color == '红':if y1 < 5:if y2!= y1 + 1 or x2!= x1:return Falseelse:if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):return Falseelse:if y1 > 4:if y2!= y1 - 1 or x2!= x1:return Falseelse:if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):return Falsereturn Trueclass ChessGame:def __init__(self):"""初始化棋盘和棋子。"""self.board = create_chessboard()self.init_pieces()def init_pieces(self):"""初始化棋盘上的棋子。"""# 红方棋子初始化self.board[9][0] = Chariot('红', '车')self.board[9][1] = Horse('红', '马')self.board[9][2] = Elephant('红', '象')self.board[9][3] = Advisor('红', '士')self.board[9][4] = King('红', '将')self.board[9][5] = Advisor('红', '士')self.board[9][6] = Elephant('红', '象')self.board[9][7] = Horse('红', '马')self.board[9][8] = Chariot('红', '车')self.board[7][1] = Cannon('红', '炮')self.board[7][7] = Cannon('红', '炮')for i in range(0, 9, 2):self.board[6][i] = Soldier('红', '兵')# 黑方棋子初始化self.board[0][0] = Chariot('黑', '车')self.board[0][1] = Horse('黑', '马')self.board[0][2] = Elephant('黑', '象')self.board[0][3] = Advisor('黑', '士')self.board[0][4] = King('黑', '帅')self.board[0][5] = Advisor('黑', '士')self.board[0][6] = Elephant('黑', '象')self.board[0][7] = Horse('黑', '马')self.board[0][8] = Chariot('黑', '车')self.board[2][1] = Cannon('黑', '炮')self.board[2][7] = Cannon('黑', '炮')for i in range(0, 9, 2):self.board[3][i] = Soldier('黑', '卒')def move_piece(self, start, end):"""移动棋子从start位置到end位置。:param start: 起始位置,格式为(x, y)的元组。:param end: 目标位置,格式为(x, y)的元组。:return: bool,移动是否成功。"""# 检查起始和目标位置是否在棋盘内if 0 <= start[0] < 10 and 0 <= start[1] < 9 and 0 <= end[0] < 10 and 0 <= end[1] < 9:piece = self.board[start[0]][start[1]]if piece is not None:if piece.is_move_valid(start, end, self.board):if self.board[end[0]][end[1]] is not None and self.board[end[0]][end[1]].color!= piece.color:# 吃子self.board[end[0]][end[1]] = Noneself.board[end[0]][end[1]] = self.board[start[0]][start[1]]self.board[start[0]][start[1]] = Nonereturn Truereturn Falsedef is_checkmate(self, color):"""判断指定颜色的棋子是否被将死。:param color: 棋子颜色,如'红'或'黑'。:return: bool,是否被将死。"""king_pos = None# 找到将(帅)的位置for i in range(10):for j in range(9):if self.board[i][j] is not None and self.board[i][j].color == color and self.board[i][j].kind in ['将', '帅']:king_pos = (i, j)if king_pos is None:return False# 检查是否有对方棋子能吃掉将(帅)for i in range(10):for j in range(9):if self.board[i][j] is not None and self.board[i][j].color!= color:if self.board[i][j].is_move_valid((i, j), king_pos, self.board):return Truereturn False
def create_chessboard():"""创建10x9的二维列表表示棋盘,初始值为None代表空位置。"""return [[None] * 9 for _ in range(10)]class Piece:"""棋子基类,包含颜色和类型属性,及移动合法性判断抽象方法。"""def __init__(self, color, kind):self.color = colorself.kind = kinddef is_move_valid(self, start, end, board):"""判断棋子从start到end移动是否合法,需子类实现。"""passclass King(Piece):def is_move_valid(self, start, end, board):"""帅(将):只能在九宫格内沿横竖方向移动一格。"""x1, y1 = startx2, y2 = endif self.color == '红':if not (3 <= x1 <= 5 and 7 <= y1 <= 9):return Falseelse:if not (3 <= x1 <= 5 and 0 <= y1 <= 2):return Falsereturn abs(x1 - x2) + abs(y1 - y2) == 1class Advisor(Piece):def is_move_valid(self, start, end, board):"""仕(士):只能在九宫内沿斜线移动一格。"""x1, y1 = startx2, y2 = endif self.color == '红':if not (3 <= x1 <= 5 and 7 <= y1 <= 9):return Falseelse:if not (3 <= x1 <= 5 and 0 <= y1 <= 2):return Falsereturn abs(x1 - x2) == 1 and abs(y1 - y2) == 1class Elephant(Piece):def is_move_valid(self, start, end, board):"""相(象):循对角线走两格(相飞田),不能过河,塞象眼则不能走。"""x1, y1 = startx2, y2 = endif (self.color == '红' and y2 < 5) or (self.color == '黑' and y2 > 4):return Falseif abs(x1 - x2) == 2 and abs(y1 - y2) == 2:mid_x = (x1 + x2) // 2mid_y = (y1 + y2) // 2return board[mid_y][mid_x] is Nonereturn Falseclass Horse(Piece):def is_move_valid(self, start, end, board):"""马:走“日”字,蹩马腿则不能走。"""x1, y1 = startx2, y2 = enddx = abs(x1 - x2)dy = abs(y1 - y2)if (dx == 2 and dy == 1) or (dx == 1 and dy == 2):block_x = x1 if dx == 2 else (x1 + x2) // 2block_y = y1 if dy == 2 else (y1 + y2) // 2return board[block_y][block_x] is Nonereturn Falseclass Chariot(Piece):def is_move_valid(self, start, end, board):"""车:可在横竖方向不限格数移动,路径无阻挡。"""x1, y1 = startx2, y2 = endif x1 == x2:for y in range(min(y1, y2) + 1, max(y1, y2)):if board[y][x1] is not None:return Falseelif y1 == y2:for x in range(min(x1, x2) + 1, max(x1, x2)):if board[y1][x] is not None:return Falseelse:return Falsereturn Trueclass Cannon(Piece):def is_move_valid(self, start, end, board):"""炮:移动同车,吃子时需借助炮台。"""x1, y1 = startx2, y2 = endif x1 == x2:count = 0for y in range(min(y1, y2) + 1, max(y1, y2)):if board[y][x1] is not None:count += 1if (end[1] == start[1] and count == 0) or (end[1]!= start[1] and count == 1):return Trueelif y1 == y2:count = 0for x in range(min(x1, x2) + 1, max(x1, x2)):if board[y1][x] is not None:count += 1if (end[0] == start[0] and count == 0) or (end[0]!= start[0] and count == 1):return Truereturn Falseclass Soldier(Piece):def is_move_valid(self, start, end, board):"""兵(卒):未过河前直走一格,过河后可直走或横走一格。"""x1, y1 = startx2, y2 = endif self.color == '红':if y1 < 5:if y2!= y1 + 1 or x2!= x1:return Falseelse:if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):return Falseelse:if y1 > 4:if y2!= y1 - 1 or x2!= x1:return Falseelse:if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):return Falsereturn Trueclass ChessGame:def __init__(self):"""初始化棋盘和棋子。"""self.board = create_chessboard()self.init_pieces()def init_pieces(self):"""初始化棋盘上红黑双方棋子。"""# 红方棋子初始化self.board[9][0] = Chariot('红', '车')self.board[9][1] = Horse('红', '马')self.board[9][2] = Elephant('红', '象')self.board[9][3] = Advisor('红', '士')self.board[9][4] = King('红', '将')self.board[9][5] = Advisor('红', '士')self.board[9][6] = Elephant('红', '象')self.board[9][7] = Horse('红', '马')self.board[9][8] = Chariot('红', '车')self.board[7][1] = Cannon('红', '炮')self.board[7][7] = Cannon('红', '炮')for i in range(0, 9, 2):self.board[6][i] = Soldier('红', '兵')# 黑方棋子初始化self.board[0][0] = Chariot('黑', '车')self.board[0][1] = Horse('黑', '马')self.board[0][2] = Elephant('黑', '象')self.board[0][3] = Advisor('黑', '士')self.board[0][4] = King('黑', '帅')self.board[0][5] = Advisor('黑', '士')self.board[0][6] = Elephant('黑', '象')self.board[0][7] = Horse('黑', '马')self.board[0][8] = Chariot('黑', '车')self.board[2][1] = Cannon('黑', '炮')self.board[2][7] = Cannon('黑', '炮')for i in range(0, 9, 2):self.board[3][i] = Soldier('黑', '卒')def move_piece(self, start, end):"""移动棋子,检查合法性并执行,吃子时移除对方棋子。"""if 0 <= start[0] < 10 and 0 <= start[1] < 9 and 0 <= end[0] < 10 and 0 <= end[1] < 9:piece = self.board[start[0]][start[1]]if piece is not None:if piece.is_move_valid(start, end, self.board):if self.board[end[0]][end[1]] is not None and self.board[end[0]][end[1]].color!= piece.color:self.board[end[0]][end[1]] = Noneself.board[end[0]][end[1]] = self.board[start[0]][start[1]]self.board[start[0]][start[1]] = Nonereturn Truereturn Falsedef is_checkmate(self, color):"""判断指定颜色的将(帅)是否被将死。"""king_pos = Nonefor i in range(10):for j in range(9):if self.board[i][j] is not None and self.board[i][j].color == color and self.board[i][j].kind in ['将', '帅']:king_pos = (i, j)if king_pos is None:return Falsefor i in range(10):for j in range(9):if self.board[i][j] is not None and self.board[i][j].color!= color:if self.board[i][j].is_move_valid((i, j), king_pos, self.board):return Truereturn False
  1. 类和函数备注:简化了 docstring,突出关键信息,去除重复和冗长描述。例如,类的 docstring 只保留核心功能说明,函数 docstring 强调功能要点。
  2. 规则描述:在棋子移动合法性判断函数的备注中,简洁地概括了棋子移动规则,避免复杂表述。
优化代码
'''
代码结构优化:将棋子的初始化部分提取到一个独立的函数中,使__init__方法更简洁。同时,将棋盘的大小定义为常量,方便修改和维护。
代码逻辑优化:在is_move_valid方法中,对一些条件判断进行了合并和简化,提高代码的可读性。对于Cannon类的移动判断,逻辑更加清晰。
代码风格优化:遵循 Python 的命名规范,使用更具描述性的变量名,并适当添加注释以提高代码的可理解性。
'''# 定义棋盘的行数和列数
BOARD_ROWS = 10
BOARD_COLS = 9def create_chessboard():"""创建10x9的二维列表表示棋盘,初始值为None代表空位置。"""return [[None] * BOARD_COLS for _ in range(BOARD_ROWS)]class Piece:"""棋子基类,包含颜色和类型属性,及移动合法性判断抽象方法。"""def __init__(self, color, kind):self.color = colorself.kind = kinddef is_move_valid(self, start, end, board):"""判断棋子从start到end移动是否合法,需子类实现。"""passclass King(Piece):def is_move_valid(self, start, end, board):"""帅(将):只能在九宫格内沿横竖方向移动一格。"""x1, y1 = startx2, y2 = end# 九宫格范围判断if (self.color == '红' and (x1 < 3 or x1 > 5 or y1 < 7 or y1 > 9)) or \(self.color == '黑' and (x1 < 3 or x1 > 5 or y1 < 0 or y1 > 2)):return Falsereturn abs(x1 - x2) + abs(y1 - y2) == 1class Advisor(Piece):def is_move_valid(self, start, end, board):"""仕(士):只能在九宫内沿斜线移动一格。"""x1, y1 = startx2, y2 = end# 九宫格范围判断if (self.color == '红' and (x1 < 3 or x1 > 5 or y1 < 7 or y1 > 9)) or \(self.color == '黑' and (x1 < 3 or x1 > 5 or y1 < 0 or y1 > 2)):return Falsereturn abs(x1 - x2) == 1 and abs(y1 - y2) == 1class Elephant(Piece):def is_move_valid(self, start, end, board):"""相(象):循对角线走两格(相飞田),不能过河,塞象眼则不能走。"""x1, y1 = startx2, y2 = end# 不能过河判断if (self.color == '红' and y2 < 5) or (self.color == '黑' and y2 > 4):return Falseif abs(x1 - x2) == 2 and abs(y1 - y2) == 2:mid_x = (x1 + x2) // 2mid_y = (y1 + y2) // 2return board[mid_y][mid_x] is Nonereturn Falseclass Horse(Piece):def is_move_valid(self, start, end, board):"""马:走“日”字,蹩马腿则不能走。"""x1, y1 = startx2, y2 = enddx = abs(x1 - x2)dy = abs(y1 - y2)if (dx == 2 and dy == 1) or (dx == 1 and dy == 2):block_x = x1 if dx == 2 else (x1 + x2) // 2block_y = y1 if dy == 2 else (y1 + y2) // 2return board[block_y][block_x] is Nonereturn Falseclass Chariot(Piece):def is_move_valid(self, start, end, board):"""车:可在横竖方向不限格数移动,路径无阻挡。"""x1, y1 = startx2, y2 = endif x1 == x2:for y in range(min(y1, y2) + 1, max(y1, y2)):if board[y][x1] is not None:return Falseelif y1 == y2:for x in range(min(x1, x2) + 1, max(x1, x2)):if board[y1][x] is not None:return Falseelse:return Falsereturn Trueclass Cannon(Piece):def is_move_valid(self, start, end, board):"""炮:移动同车,吃子时需借助炮台。"""x1, y1 = startx2, y2 = endif x1 == x2:pieces_between = sum(board[y][x1] is not None for y in range(min(y1, y2) + 1, max(y1, y2)))if (x2 == x1 and pieces_between == 0) or (x2!= x1 and pieces_between == 1):return Trueelif y1 == y2:pieces_between = sum(board[y1][x] is not None for x in range(min(x1, x2) + 1, max(x1, x2)))if (y2 == y1 and pieces_between == 0) or (y2!= y1 and pieces_between == 1):return Truereturn Falseclass Soldier(Piece):def is_move_valid(self, start, end, board):"""兵(卒):未过河前直走一格,过河后可直走或横走一格。"""x1, y1 = startx2, y2 = endif self.color == '红':if y1 < 5:return y2 == y1 + 1 and x2 == x1else:return (y2 == y1 + 1 or y2 == y1) and x2 in [x1 - 1, x1 + 1, x1]else:if y1 > 4:return y2 == y1 - 1 and x2 == x1else:return (y2 == y1 - 1 or y2 == y1) and x2 in [x1 - 1, x1 + 1, x1]class ChessGame:def __init__(self):"""初始化棋盘和棋子。"""self.board = create_chessboard()self.init_pieces()def init_pieces(self):"""初始化棋盘上红黑双方棋子。"""red_pieces = [(Chariot, '车', 9, 0), (Horse, '马', 9, 1), (Elephant, '象', 9, 2), (Advisor, '士', 9, 3), (King, '将', 9, 4),(Advisor, '士', 9, 5), (Elephant, '象', 9, 6), (Horse, '马', 9, 7), (Chariot, '车', 9, 8),(Cannon, '炮', 7, 1), (Cannon, '炮', 7, 7)]for piece_class, kind, row, col in red_pieces:self.board[row][col] = piece_class('红', kind)for i in range(0, BOARD_COLS, 2):self.board[6][i] = Soldier('红', '兵')black_pieces = [(Chariot, '车', 0, 0), (Horse, '马', 0, 1), (Elephant, '象', 0, 2), (Advisor, '士', 0, 3), (King, '帅', 0, 4),(Advisor, '士', 0, 5), (Elephant, '象', 0, 6), (Horse, '马', 0, 7), (Chariot, '车', 0, 8),(Cannon, '炮', 2, 1), (Cannon, '炮', 2, 7)]for piece_class, kind, row, col in black_pieces:self.board[row][col] = piece_class('黑', kind)for i in range(0, BOARD_COLS, 2):self.board[3][i] = Soldier('黑', '卒')def move_piece(self, start, end):"""移动棋子,检查合法性并执行,吃子时移除对方棋子。"""if 0 <= start[0] < BOARD_ROWS and 0 <= start[1] < BOARD_COLS and \0 <= end[0] < BOARD_ROWS and 0 <= end[1] < BOARD_COLS:piece = self.board[start[0]][start[1]]if piece is not None:if piece.is_move_valid(start, end, self.board):if self.board[end[0]][end[1]] is not None and self.board[end[0]][end[1]].color!= piece.color:self.board[end[0]][end[1]] = Noneself.board[end[0]][end[1]] = self.board[start[0]][start[1]]self.board[start[0]][start[1]] = Nonereturn Truereturn Falsedef is_checkmate(self, color):"""判断指定颜色的将(帅)是否被将死。"""king_pos = Nonefor i in range(BOARD_ROWS):for j in range(BOARD_COLS):if self.board[i][j] is not None and self.board[i][j].color == color and \self.board[i][j].kind in ['将', '帅']:king_pos = (i, j)if king_pos is None:return Falsefor i in range(BOARD_ROWS):for j in range(BOARD_COLS):if self.board[i][j] is not None and self.board[i][j].color!= color:if self.board[i][j].is_move_valid((i, j), king_pos, self.board):return Truereturn False

5.2 测试运行

game = ChessGame()
#尝试移动红方车
game.move_piece((9, 0), (7, 0)) print(game.is_checkmate('黑'))

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

相关文章:

用python实现中国象棋

一.象棋规则 象棋是二人对弈的棋类游戏&#xff0c;棋盘由 9 条竖线和 10 条横线交叉构成&#xff0c;中间 “河界” 分楚汉&#xff0c;两端 “九宫” 各 9 个交叉点。棋子分红黑&#xff0c;各 16 枚&#xff0c;含 7 兵种。 1.棋子走法 1.1 红方棋子 帅&#xff1a;1 个…...

GO 语言基础3 struct 结构体

更多个人笔记见&#xff1a; github个人笔记仓库 gitee 个人笔记仓库 个人学习&#xff0c;学习过程中还会不断补充&#xff5e; &#xff08;后续会更新在github上&#xff09; 文章目录 strcut结构体基本例子传入数值和指针的区别初始化方法汇总结构体特点结构体方法定义基于…...

VSCode C/C++ 开发环境完整配置及一些扩展用途(自用)update:2025/3/31

这里主要记录了一些与配置相关的内容。由于网上教程众多&#xff0c;部分解决方法并不能完全契合我遇到的问题&#xff0c;因此我选择以自己偏好的方式&#xff0c;对 VSCode 进行完整的配置&#xff0c;并记录在使用过程中遇到的问题及解决方案。后续内容也会持续更新和完善。…...

iOS 上线前的性能与稳定性检查流程实录:开发者的“最后一公里”(含 KeyMob 应用经验)

一个 iOS 项目写完功能、跑完测试&#xff0c;离上线只差一步了——但很多问题恰恰就在“这最后一公里”暴露&#xff1a;某些设备发热严重&#xff0c;部分流程偶发卡顿&#xff0c;某些崩溃只有长时间运行后才出现。 今天我分享的是我在多个 iOS 项目上线前实际执行过的性能…...

Docker系列(二):开机自启动与基础配置、镜像加速器优化与疑难排查指南

引言 docker 的快速部署与高效运行依赖于两大核心环节&#xff1a;基础环境搭建与镜像生态优化。本期博文从零开始&#xff0c;系统讲解 docker 服务的管理配置与镜像加速实践。第一部分聚焦 docker 服务的安装、权限控制与自启动设置&#xff0c;确保环境稳定可用&#xff1b…...

a16z:AI带来了全新的9种开发软件的模式

非常有启发的9条新兴模式&#xff0c;推荐给已经上手 vibeCoding 的读者们。 开发者正在将 AI 从简单的工具转变为构建软件的新基础。许多核心概念&#xff0c;如版本控制、模板、文档&#xff0c;甚至用户的定义&#xff0c;都在被重新思考。代理&#xff08;Agent&#xff09…...

20.迭代器模式:思考与解读

原文地址:迭代器模式&#xff1a;思考与解读 更多内容请关注&#xff1a;深入思考与解读设计模式 引言 在软件开发中&#xff0c;尤其是在处理集合数据时&#xff0c;你是否曾经遇到过这样的问题&#xff1a;你需要遍历一个集合&#xff08;如数组、列表、集合等&#xff09…...

Java 学习笔记:注解、泛型与 IO 流

目录 课程目标 Java 注解(Annotation) 1. 概念与作用 2. 自定义注解示例 3. JDK 内置注解 4.注释 Java 泛型(Generics) 1. 基本语法 2. 通配符与上下限 3. 常见应用场景 Java IO 流 1. 流的分类1.File文件类 2. 字节流与字符流 3. 经典示例:文件拷贝 总结与…...

在 Excel 使用macro————仙盟创梦IDE

Dim filePath As StringDim fileContent As StringDim lines() As StringDim dataArray() As StringDim lineCount As LongDim maxCols As LongDim i As Long, j As Long 文件路径filePath "" 检查文件是否存在If Dir(filePath) "" ThenMsgBox "文件…...

【MySQL】08.视图

视图就是一个由查询到的内容定义的虚拟表。它和真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表&#xff0c;基表的数据变化也会影响到视图。 1. 基本使用 mysql> select * from user; -------------------- | id | age | name …...

鸿蒙devEco studio如何创建模拟器

官网原文链接&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-emulator-create 操作步骤 点击菜单栏的Tools > Device Manager&#xff0c;点击右下角的Edit设置模拟器实例的存储路径Local Emulator Location&#xff0c;Mac默认存储在~/…...

鸿蒙路由参数传递

页面test.ets 代码如下&#xff1a; import router from ohos.router Entry Component struct Test {State message: string Hello WorldState username: string huState password: string 1build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWe…...

springboot 控制层调用业务逻辑层,注入报错,无法自动装配 解决办法

报错&#xff1a; 解决&#xff1a;愿意是业务逻辑层&#xff0c;即service层的具体实现类没有加注解Service导致的&#xff0c;加上解决了&#xff01;&#xff01;...

MySQL:11_事务

事务 一.CURD不加控制&#xff0c;会有什么问题&#xff1f; 二.什么是事务&#xff1f; 事务就是一组DML语句组成&#xff0c;这些语句在逻辑上存在相关性&#xff0c;这一组DML语句要么全部成功&#xff0c;要么全部失败&#xff0c;是一个整体。MySQL提供一种机制&#xf…...

Linux中的文件系统和软硬连接

磁盘的访问方式 CHS&#xff08;柱面&#xff0c;磁头&#xff0c;扇区&#xff09; 法&#xff08;磁盘硬件查找&#xff09;&#xff1a; 确定柱面&#xff08;C&#xff09; 磁头臂移动到对应的柱面位置。例如&#xff0c;柱面号为 5&#xff0c;则磁头移动到第 5 个磁道组…...

并发容器(Collections)

一、并发安全问题根源 1. List&#xff08;如ArrayList&#xff09; 问题表现&#xff1a;多线程同时调用add、remove等方法时&#xff0c;可能抛出ConcurrentModificationException或导致数据不一致。根本原因&#xff1a; 非原子性操作&#xff1a;如add操作的流程&#xf…...

SPA模式下的es6如何加快宿主页的显示速度

SPA的模式下&#xff0c;宿主页是首先加载的页面&#xff0c;会需要一些主要的组件&#xff0c;如element-plus&#xff0c;easyui&#xff0c;devextreme&#xff0c;ant-design等&#xff0c;这些组件及其依赖组件&#xff0c;文件多&#xff0c;代码量大&#xff0c;可能导致…...

windows powershell 判断 进程号是否存在

在 Windows PowerShell 中&#xff0c;你可以使用多种方法来检查一个特定的进程号&#xff08;PID&#xff09;是否存在。以下是几种常用的方法&#xff1a; 方法1&#xff1a;使用 Get-Process 命令 你可以尝试获取具有特定 PID 的进程。如果该进程存在&#xff0c;Get-Proce…...

c# 解码 encodeURIComponent

在C#中&#xff0c;如果你需要解码由encodeURIComponent方法编码的URL&#xff0c;你可以使用System.Web命名空间中的HttpUtility.UrlDecode方法。这个方法可以处理由JavaScript的encodeURIComponent方法编码的字符串。 首先&#xff0c;确保你的项目中引用了System.Web命名空…...

Spring AI:Java开发者的AI开发新利器

目录 一、引言 二、Spring AI 是什么 三、核心功能与特性 3.1 统一的 API 抽象 3.2 丰富的模型支持 3.3 低代码集成 3.4 结构化数据输出 3.5 流式数据响应 四、应用场景 4.1 智能客服系统 4.2 图像识别应用 4.3 数据分析与预测 五、快速上手 5.1 环境搭建 5.2 创…...

Android System UI 深度解析:从架构演进到车载 / TV 场景的全维度定制

Android System UI 是 Android 操作系统的核心组件,负责管理设备的系统级用户界面和交互逻辑。它通过状态栏、导航栏、通知面板、快速设置等功能,为用户提供与系统功能直接交互的入口,并与硬件、应用程序深度协同,构建完整的用户体验。以下是其核心架构、功能演进及定制化能…...

Spring Cloud Sleuth与Zipkin深度整合指南:微服务链路追踪实战

上篇文章简单介绍了SpringCloud系列熔断器&#xff1a;Sentinel的搭建及基本用法&#xff0c;今天继续讲解下SpringCloud的微服务链路追踪&#xff1a;Zipkin的使用&#xff01;在分享之前继续回顾下本次SpringCloud的专题要讲的内容&#xff1a; 前置知识说明 在开始本教程前…...

React从基础入门到高级实战:React 基础入门 - 列表渲染与条件渲染

列表渲染与条件渲染 在 React 开发中&#xff0c;列表渲染 和 条件渲染 是处理动态数据和用户交互的基础技术。通过列表渲染&#xff0c;你可以根据数据动态生成 UI 元素&#xff1b;而条件渲染则让你根据特定条件展示不同的内容。这两个技能在实际项目中非常常见&#xff0c;…...

在 stm32 中 volatile unsigned signed 分别有什么作用,分别在什么场景下使用?

在STM32开发中&#xff0c; plaintext 复制 volatile 、 plaintext 复制 unsigned 和 plaintext 复制 signed 是三个关键的关键字&#xff0c;它们的用途和场景如下&#xff1a; 1. plaintext 复制 volatile 关键字 作用&#xff1a; 禁止编译器优化&#xff…...

FreeBSD14.2因为爆内存而导致Xfce4视窗被卡,桌面变黑色,只能看到鼠标在窗体中心,鼠标无反应,键盘无反应

拿问题问AI pytest的时候因为内存不足导致xfce4卡住&#xff08;xfce4相关进程被关闭&#xff09;&#xff0c;桌面变黑色&#xff0c;只能看到鼠标在窗体中心&#xff0c;鼠标无反应&#xff0c;键盘无反应&#xff0c;请问应该怎么办&#xff1f; pytest的时候因为内存不足导…...

k8s-NetworkPolicy

在 Kubernetes 中&#xff0c;NetworkPolicy 是一种资源对象&#xff0c;用于定义 Pod 之间的网络通信策略。它允许你控制哪些 Pod 可以相互通信&#xff0c;以及如何通信。通过使用 NetworkPolicy&#xff0c;可以实现更细粒度的网络访问控制&#xff0c;增强集群的安全性。 1…...

spring-ai 集成 mcp 之投机取巧

主旨 这篇文章主旨就一点&#xff0c;罗列spring-ai对mcp集成导致出现的一系列问题 分析 由于mcp未问世之前&#xff0c;就早就已经有了工具调用&#xff0c;源码如下&#xff1a; public interface ToolCallback {/*** Definition used by the AI model to determine when a…...

大语言模型的完整训练周期从0到1的体系化拆解

以下部分内容参考了AI。 要真正理解大语言模型&#xff08;LLM&#xff09;的创生过程&#xff0c;我们需要将其拆解为一个完整的生命周期&#xff0c;每个阶段的关键技术相互关联&#xff0c;共同支撑最终模型的涌现能力。以下是体系化的训练流程框架&#xff1a; 阶段一&am…...

历年北京邮电大学保研上机真题

2025北京邮电大学保研上机真题 2024北京邮电大学保研上机真题 2023北京邮电大学保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/problem?classification1 32位二进制串加法 题目描述 输入一个32位的二进制01串&#xff0c;输出这个数1和3后的32位二进制串。 输入…...

elementUI 中el-date-picker和el-select的样式调整

1. el-date-picker <el-date-picker class"select1" size"small" v-model"timeRangeArr" type"daterange" align"right" unlink-panels range-separator"至" start-placeholder"开始日期" end-pla…...