由于象棋程序的复杂性,代码会非常长,这里给出一个最简单的二维数组版象棋程序,仅供参考。
定义棋盘和棋子:
“`python
board = [
[‘車’, ‘馬’, ‘象’, ‘士’, ‘将’, ‘士’, ‘象’, ‘馬’, ‘車’],
[‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘],
[‘ ‘, ‘炮’, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘炮’, ‘ ‘],
[‘兵’, ‘ ‘, ‘兵’, ‘ ‘, ‘兵’, ‘ ‘, ‘兵’, ‘ ‘, ‘兵’],
[‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘],
[‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘],
[‘卒’, ‘ ‘, ‘卒’, ‘ ‘, ‘卒’, ‘ ‘, ‘卒’, ‘ ‘, ‘卒’],
[‘ ‘, ‘砲’, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘砲’, ‘ ‘],
[‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘],
]
pieces = {
‘K’: ‘将’, ‘A’: ‘士’, ‘B’: ‘象’, ‘N’: ‘马’, ‘R’: ‘車’, ‘C’: ‘炮’, ‘P’: ‘兵’,
‘k’: ‘帅’, ‘a’: ‘仕’, ‘b’: ‘相’, ‘n’: ‘马’, ‘r’: ‘车’, ‘c’: ‘炮’, ‘p’: ‘卒’
}
“`
定义各个函数:
“`python
def print_board():
# 打印棋盘
for row in board:
print(‘ ‘.join(row))
def get_player_at(position):
# 返回位置上的棋子,如无棋子返回 None
file, rank = position
return board[rank][file]
def get_legal_moves(position):
# 返回特定位置对应棋子可以移动到的合法位置
file, rank = position
piece = get_player_at(position)
moves = []
if piece in ‘Kk’: # 将/帅
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for d in directions:
f, r = file + d[0], rank + d[1]
if ((3 <= f <= 5) and (7 <= r <= 9)) or ((0 <= f <= 2) and (0 <= r <= 2)):
if not get_player_at((f, r)) or (get_player_at((f, r)) in ‘ka’ and piece in ‘K’) or (get_player_at((f, r)) in ‘KA’ and piece in ‘k’):
moves.append((f, r))
elif piece in ‘Ar’: # 車
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for d in directions:
for i in range(1, 10):
f, r = file + i * d[0], rank + i * d[1]
if not 0 <= f <= 8 or not 0 <= r <= 9:
break
if not get_player_at((f, r)):
moves.append((f, r))
else:
if get_player_at((f, r)) in ‘ka’ and piece == ‘A’:
moves.append((f, r)) # 如果是自己的棋子,不能继续走
if get_player_at((f, r)) in ‘KA’ and piece == ‘a’:
moves.append((f, r)) # 如果是自己的棋子,不能继续走
break # 如果是敌人的棋子,不能继续走
elif piece in ‘Nb’: # 马
directions = [(1, 2), (2, 1), (-1, 2), (2, -1), (-1, -2), (-2, -1), (1, -2), (-2, 1)]
for d in directions:
f, r = file + d[0], rank + d[1]
if not 0 <= f <= 8 or not 0 <= r <= 9:
continue
if not get_player_at((f – d[0] // 2, r – d[1] // 2)):
if not get_player_at((f, r)):
moves.append((f, r))
elif get_player_at((f, r)) in ‘ka’ and piece == ‘N’:
moves.append((f, r)) # 如果是自己的棋子,不能继续走
elif get_player_at((f, r)) in ‘KA’ and piece == ‘n’:
moves.append((f, r)) # 如果是自己的棋子,不能继续走
elif piece in ‘Cp’: # 炮
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for d in directions:
has_piece = False
for i in range(1, 10):
f, r = file + i * d[0], rank + i * d[1]
if not 0 <= f <= 8 or not 0 <= r <= 9:
break
if not has_piece:
if get_player_at((f, r)): # 第一次遇到棋子
has_piece = True
continue
moves.append((f, r))
else:
if get_player_at((f, r)):
if get_player_at((f, r)) in ‘ka’ and piece == ‘P’:
moves.append((f, r)) # 如果有敌人,就可以跳过去吃掉敌人
elif get_player_at((f, r)) in ‘KA’ and piece == ‘p’:
moves.append((f, r))
break
elif piece in ‘Ab’: # 士
directions = [(1, 1), (1, -1), (-1, 1), (-1, -1)]
for d in directions:
f, r = file + d[0], rank + d[1]
if ((3 <= f <= 5) and (7 <= r <= 9)) or ((3 <= f <= 5) and (0 <= r <= 2)) or ((0 <= f <= 2) and (3 <= r <= 5)):
if not get_player_at((f, r)):
moves.append((f, r))
elif get_player_at((f, r)) in ‘ka’ and piece == ‘A’:
moves.append((f, r))
elif get_player_at((f, r)) in ‘KA’ and piece == ‘a’:
moves.append((f, r))
elif piece in ‘Pp’: # 兵
directions = [(0, -1)]
if piece == ‘P’ and rank <= 4:
directions.append((-1, 0))
directions.append((1, 0))
if piece == ‘p’ and rank >= 5:
directions.append((-1, 0))
directions.append((1, 0))
for d in directions:
f, r = file + d[0], rank + d[1]
if not 0 <= f <= 8 or not 0 <= r <= 9:
continue
if not get_player_at((f, r)):
moves.append((f, r))
elif get_player_at((f, r)) in ‘ka’ and piece == ‘P’:
moves.append((f, r))
elif get_player_at((f, r)) in ‘KA’ and piece == ‘p’:
moves.append((f, r))
return moves
“`
实现游戏:
“`python
player = ‘R’
while True:
print_board()
piece = input(‘请 %s 走棋:’ % pieces[player]).strip()
file_from = ord(piece[0]) – ord(‘a’)
rank_from = ord(piece[1]) – ord(‘1’)
legal_moves = get_legal_moves((file_from, rank_from))
if not legal_moves:
print(‘该棋子无法移动’)
continue
dest = input(‘请 %s 移动到:’ % pieces[player]).strip()
file_to = ord(dest[0]) – ord(‘a’)
rank_to = ord(dest[1]) – ord(‘1’)
if (file_to, rank_to) not in legal_moves:
print(‘非法移动’)
continue
if

留言