一.象棋规则
象棋是二人对弈的棋类游戏,棋盘由 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.吃子与胜负
- 吃子:走到对方棋子位置,将其从棋盘移除。
- 胜负:将死对方 “将(帅)” 或对方认输则胜;双方均无能力将死对方,判和棋。
二.详细分析
每个棋子按照上述规则在棋盘上移动、吃子,双方通过合理运用棋子的走法,以将死对方的将(帅)为目标,最终决出胜负。
若一个棋子,他只能在这米字格里横竖方向的移动,便是象棋当中将(帅)的走法;
只能在米字格中沿斜线行走的话,就是士;
而可以横竖方向,无论距离的走,便是车;
若与车的行走完全一致,但必须跳过一颗棋子进行吃子的是炮(砲);
当两块格子组成"日"字,只能走其对角线,这就是马;
若需走四个格子对角线的话,这样跳过"田"字的是象,注意只能在己方阵营行动;
一颗只能向前移动在己方阵营,过届之后才能能左右行走且无法向后回头的是兵(卒)
抽象为计算机模型:
用二维列表表示棋盘,每个元素代表棋盘上的一个位置。
定义棋子类,每个棋子对象有其颜色、类型等属性,以及移动合法性判断方法。
实现棋盘初始化、棋子移动、吃子、判断胜负等功能。
三.用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 = kind
def is_move_valid(self, start, end, board):
# 该方法需在子类中具体实现,用于判断棋子从start到end的移动是否合法
pass
class King(Piece):
def is_move_valid(self, start, end, board):
x1, y1 = start
x2, y2 = end
# 判断将(帅)是否在九宫格内
if self.color == '红':
if not (3 <= x1 <= 5 and 7 <= y1 <= 9):
return False
else:
if not (3 <= x1 <= 5 and 0 <= y1 <= 2):
return False
# 判断是否沿横竖方向移动一格
return abs(x1 - x2) + abs(y1 - y2) == 1
class Advisor(Piece):
def is_move_valid(self, start, end, board):
x1, y1 = start
x2, y2 = end
# 判断士是否在九宫格内
if self.color == '红':
if not (3 <= x1 <= 5 and 7 <= y1 <= 9):
return False
else:
if not (3 <= x1 <= 5 and 0 <= y1 <= 2):
return False
# 判断是否沿斜线移动一格
return abs(x1 - x2) == 1 and abs(y1 - y2) == 1
class Elephant(Piece):
def is_move_valid(self, start, end, board):
x1, y1 = start
x2, 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) // 2
mid_y = (y1 + y2) // 2
return board[mid_y][mid_x] is None
return False
class Horse(Piece):
def is_move_valid(self, start, end, board):
x1, y1 = start
x2, y2 = end
dx = 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) // 2
block_y = y1 if dy == 2 else (y1 + y2) // 2
return board[block_y][block_x] is None
return False
class Chariot(Piece):
def is_move_valid(self, start, end, board):
x1, y1 = start
x2, y2 = end
# 判断是否在横竖方向移动且路径无阻挡
if x1 == x2:
for y in range(min(y1, y2) + 1, max(y1, y2)):
if board[y][x1] is not None:
return False
elif y1 == y2:
for x in range(min(x1, x2) + 1, max(x1, x2)):
if board[y1][x] is not None:
return False
else:
return False
return True
class Cannon(Piece):
def is_move_valid(self, start, end, board):
x1, y1 = start
x2, y2 = end
# 判断移动路径是否为空或有且仅有一个炮台
if x1 == x2:
count = 0
for y in range(min(y1, y2) + 1, max(y1, y2)):
if board[y][x1] is not None:
count += 1
if (end[1] == start[1] and count == 0) or (end[1]!= start[1] and count == 1):
return True
elif y1 == y2:
count = 0
for x in range(min(x1, x2) + 1, max(x1, x2)):
if board[y1][x] is not None:
count += 1
if (end[0] == start[0] and count == 0) or (end[0]!= start[0] and count == 1):
return True
return False
class Soldier(Piece):
def is_move_valid(self, start, end, board):
x1, y1 = start
x2, y2 = end
# 判断兵(卒)是否符合移动规则
if self.color == '红':
if y1 < 5:
if y2!= y1 + 1 or x2!= x1:
return False
else:
if y2!= y1 + 1 and x2 not in [x1 - 1, x1 + 1]:
return False
else:
if y1 > 4:
if y2!= y1 - 1 or x2!= x1:
return False
else:
if y2!= y1 - 1 and x2 not in [x1 - 1, x1 + 1]:
return False
return 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]] = None
self.board[end[0]][end[1]] = self.board[start[0]][start[1]]
self.board[start[0]][start[1]] = None
return True
return False
def 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 True
return 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 = color
self.kind = kind
def is_move_valid(self, start, end, board):
"""判断棋子从start到end的移动是否合法。
此方法为抽象方法,需在子类中具体实现。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
pass
class King(Piece):
def is_move_valid(self, start, end, board):
"""帅(将)的移动规则:只能在九宫格内活动,每次沿横竖方向移动一格。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
x1, y1 = start
x2, y2 = end
if self.color == '红':
if not (3 <= x1 <= 5 and 7 <= y1 <= 9):
return False
else:
if not (3 <= x1 <= 5 and 0 <= y1 <= 2):
return False
return abs(x1 - x2) + abs(y1 - y2) == 1
class Advisor(Piece):
def is_move_valid(self, start, end, board):
"""仕(士)的移动规则:只能在九宫内走动,行棋路径只能是九宫内的斜线。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
x1, y1 = start
x2, y2 = end
if self.color == '红':
if not (3 <= x1 <= 5 and 7 <= y1 <= 9):
return False
else:
if not (3 <= x1 <= 5 and 0 <= y1 <= 2):
return False
return abs(x1 - x2) == 1 and abs(y1 - y2) == 1
class Elephant(Piece):
def is_move_valid(self, start, end, board):
"""相(象)的移动规则:循对角线走两格,俗称“相飞田”,不能过河。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
x1, y1 = start
x2, 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) // 2
mid_y = (y1 + y2) // 2
return board[mid_y][mid_x] is None
return False
class Horse(Piece):
def is_move_valid(self, start, end, board):
"""马的移动规则:走“日”字,每步走一直一斜,注意“蹩马腿”。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
x1, y1 = start
x2, y2 = end
dx = 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) // 2
block_y = y1 if dy == 2 else (y1 + y2) // 2
return board[block_y][block_x] is None
return False
class Chariot(Piece):
def is_move_valid(self, start, end, board):
"""车的移动规则:无论横线、竖线均可行走,只要无子阻拦,步数不受限制。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
x1, y1 = start
x2, y2 = end
if x1 == x2:
for y in range(min(y1, y2) + 1, max(y1, y2)):
if board[y][x1] is not None:
return False
elif y1 == y2:
for x in range(min(x1, x2) + 1, max(x1, x2)):
if board[y1][x] is not None:
return False
else:
return False
return True
class Cannon(Piece):
def is_move_valid(self, start, end, board):
"""炮的移动规则:移动方式与车相同,吃子时需借助一个棋子作为炮台。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
x1, y1 = start
x2, y2 = end
if x1 == x2:
count = 0
for y in range(min(y1, y2) + 1, max(y1, y2)):
if board[y][x1] is not None:
count += 1
if (end[1] == start[1] and count == 0) or (end[1]!= start[1] and count == 1):
return True
elif y1 == y2:
count = 0
for x in range(min(x1, x2) + 1, max(x1, x2)):
if board[y1][x] is not None:
count += 1
if (end[0] == start[0] and count == 0) or (end[0]!= start[0] and count == 1):
return True
return False
class Soldier(Piece):
def is_move_valid(self, start, end, board):
"""兵(卒)的移动规则:未过河时只能向前移动一格,过河后可向前或横向移动一格。
:param start: 起始位置,格式为(x, y)的元组。
:param end: 目标位置,格式为(x, y)的元组。
:param board: 棋盘,二维列表。
:return: bool,移动是否合法。
"""
x1, y1 = start
x2, y2 = end
if self.color == '红':
if y1 < 5:
if y2!= y1 + 1 or x2!= x1:
return False
else:
if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):
return False
else:
if y1 > 4:
if y2!= y1 - 1 or x2!= x1:
return False
else:
if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):
return False
return True
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):
"""移动棋子从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]] = None
self.board[end[0]][end[1]] = self.board[start[0]][start[1]]
self.board[start[0]][start[1]] = None
return True
return False
def 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 True
return False
def create_chessboard():
"""创建10x9的二维列表表示棋盘,初始值为None代表空位置。"""
return [[None] * 9 for _ in range(10)]
class Piece:
"""棋子基类,包含颜色和类型属性,及移动合法性判断抽象方法。"""
def __init__(self, color, kind):
self.color = color
self.kind = kind
def is_move_valid(self, start, end, board):
"""判断棋子从start到end移动是否合法,需子类实现。"""
pass
class King(Piece):
def is_move_valid(self, start, end, board):
"""帅(将):只能在九宫格内沿横竖方向移动一格。"""
x1, y1 = start
x2, y2 = end
if self.color == '红':
if not (3 <= x1 <= 5 and 7 <= y1 <= 9):
return False
else:
if not (3 <= x1 <= 5 and 0 <= y1 <= 2):
return False
return abs(x1 - x2) + abs(y1 - y2) == 1
class Advisor(Piece):
def is_move_valid(self, start, end, board):
"""仕(士):只能在九宫内沿斜线移动一格。"""
x1, y1 = start
x2, y2 = end
if self.color == '红':
if not (3 <= x1 <= 5 and 7 <= y1 <= 9):
return False
else:
if not (3 <= x1 <= 5 and 0 <= y1 <= 2):
return False
return abs(x1 - x2) == 1 and abs(y1 - y2) == 1
class Elephant(Piece):
def is_move_valid(self, start, end, board):
"""相(象):循对角线走两格(相飞田),不能过河,塞象眼则不能走。"""
x1, y1 = start
x2, 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) // 2
mid_y = (y1 + y2) // 2
return board[mid_y][mid_x] is None
return False
class Horse(Piece):
def is_move_valid(self, start, end, board):
"""马:走“日”字,蹩马腿则不能走。"""
x1, y1 = start
x2, y2 = end
dx = 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) // 2
block_y = y1 if dy == 2 else (y1 + y2) // 2
return board[block_y][block_x] is None
return False
class Chariot(Piece):
def is_move_valid(self, start, end, board):
"""车:可在横竖方向不限格数移动,路径无阻挡。"""
x1, y1 = start
x2, y2 = end
if x1 == x2:
for y in range(min(y1, y2) + 1, max(y1, y2)):
if board[y][x1] is not None:
return False
elif y1 == y2:
for x in range(min(x1, x2) + 1, max(x1, x2)):
if board[y1][x] is not None:
return False
else:
return False
return True
class Cannon(Piece):
def is_move_valid(self, start, end, board):
"""炮:移动同车,吃子时需借助炮台。"""
x1, y1 = start
x2, y2 = end
if x1 == x2:
count = 0
for y in range(min(y1, y2) + 1, max(y1, y2)):
if board[y][x1] is not None:
count += 1
if (end[1] == start[1] and count == 0) or (end[1]!= start[1] and count == 1):
return True
elif y1 == y2:
count = 0
for x in range(min(x1, x2) + 1, max(x1, x2)):
if board[y1][x] is not None:
count += 1
if (end[0] == start[0] and count == 0) or (end[0]!= start[0] and count == 1):
return True
return False
class Soldier(Piece):
def is_move_valid(self, start, end, board):
"""兵(卒):未过河前直走一格,过河后可直走或横走一格。"""
x1, y1 = start
x2, y2 = end
if self.color == '红':
if y1 < 5:
if y2!= y1 + 1 or x2!= x1:
return False
else:
if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):
return False
else:
if y1 > 4:
if y2!= y1 - 1 or x2!= x1:
return False
else:
if y2 not in [y1 - 1, y1 + 1] or (y2 == y1 and x2 not in [x1 - 1, x1 + 1]):
return False
return True
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]] = None
self.board[end[0]][end[1]] = self.board[start[0]][start[1]]
self.board[start[0]][start[1]] = None
return True
return False
def 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 True
return False
- 类和函数备注:简化了 docstring,突出关键信息,去除重复和冗长描述。例如,类的 docstring 只保留核心功能说明,函数 docstring 强调功能要点。
- 规则描述:在棋子移动合法性判断函数的备注中,简洁地概括了棋子移动规则,避免复杂表述。
优化代码
'''
代码结构优化:将棋子的初始化部分提取到一个独立的函数中,使__init__方法更简洁。同时,将棋盘的大小定义为常量,方便修改和维护。
代码逻辑优化:在is_move_valid方法中,对一些条件判断进行了合并和简化,提高代码的可读性。对于Cannon类的移动判断,逻辑更加清晰。
代码风格优化:遵循 Python 的命名规范,使用更具描述性的变量名,并适当添加注释以提高代码的可理解性。
'''
# 定义棋盘的行数和列数
BOARD_ROWS = 10
BOARD_COLS = 9
def create_chessboard():
"""创建10x9的二维列表表示棋盘,初始值为None代表空位置。"""
return [[None] * BOARD_COLS for _ in range(BOARD_ROWS)]
class Piece:
"""棋子基类,包含颜色和类型属性,及移动合法性判断抽象方法。"""
def __init__(self, color, kind):
self.color = color
self.kind = kind
def is_move_valid(self, start, end, board):
"""判断棋子从start到end移动是否合法,需子类实现。"""
pass
class King(Piece):
def is_move_valid(self, start, end, board):
"""帅(将):只能在九宫格内沿横竖方向移动一格。"""
x1, y1 = start
x2, 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 False
return abs(x1 - x2) + abs(y1 - y2) == 1
class Advisor(Piece):
def is_move_valid(self, start, end, board):
"""仕(士):只能在九宫内沿斜线移动一格。"""
x1, y1 = start
x2, 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 False
return abs(x1 - x2) == 1 and abs(y1 - y2) == 1
class Elephant(Piece):
def is_move_valid(self, start, end, board):
"""相(象):循对角线走两格(相飞田),不能过河,塞象眼则不能走。"""
x1, y1 = start
x2, 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) // 2
mid_y = (y1 + y2) // 2
return board[mid_y][mid_x] is None
return False
class Horse(Piece):
def is_move_valid(self, start, end, board):
"""马:走“日”字,蹩马腿则不能走。"""
x1, y1 = start
x2, y2 = end
dx = 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) // 2
block_y = y1 if dy == 2 else (y1 + y2) // 2
return board[block_y][block_x] is None
return False
class Chariot(Piece):
def is_move_valid(self, start, end, board):
"""车:可在横竖方向不限格数移动,路径无阻挡。"""
x1, y1 = start
x2, y2 = end
if x1 == x2:
for y in range(min(y1, y2) + 1, max(y1, y2)):
if board[y][x1] is not None:
return False
elif y1 == y2:
for x in range(min(x1, x2) + 1, max(x1, x2)):
if board[y1][x] is not None:
return False
else:
return False
return True
class Cannon(Piece):
def is_move_valid(self, start, end, board):
"""炮:移动同车,吃子时需借助炮台。"""
x1, y1 = start
x2, y2 = end
if 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 True
elif 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 True
return False
class Soldier(Piece):
def is_move_valid(self, start, end, board):
"""兵(卒):未过河前直走一格,过河后可直走或横走一格。"""
x1, y1 = start
x2, y2 = end
if self.color == '红':
if y1 < 5:
return y2 == y1 + 1 and x2 == x1
else:
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 == x1
else:
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]] = None
self.board[end[0]][end[1]] = self.board[start[0]][start[1]]
self.board[start[0]][start[1]] = None
return True
return False
def is_checkmate(self, color):
"""判断指定颜色的将(帅)是否被将死。"""
king_pos = None
for 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 False
for 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 True
return False
5.2 测试运行
game = ChessGame()
#尝试移动红方车
game.move_piece((9, 0), (7, 0)) print(game.is_checkmate('黑'))
整理不易,诚望各位看官点赞 收藏 评论 予以支持,这将成为我持续更新的动力源泉。若您在阅览时存有异议或建议,敬请留言指正批评,让我们携手共同学习,共同进取,吾辈自当相互勉励!