学会一些时间,应该玩一会,劳逸结合才好,我将之前的象棋进行优化调试
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()
整理不易,诚望各位看官点赞 收藏 评论 予以支持,这将成为我持续更新的动力源泉。若您在阅览时存有异议或建议,敬请留言指正批评,让我们携手共同学习,共同进取,吾辈自当相互勉励!