python实现象棋
学会一些时间,应该玩一会,劳逸结合才好,我将之前的象棋进行优化调试
pip install --upgrade pip
pip install --only-binary=all pygame -i https://mirrors.tools.huawei.com/pypi/simple/
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_SIZErow = y // CELL_SIZEreturn col, row# 棋子类
class Piece:def __init__(self, name, color, row, col):self.name = nameself.color = color # 'red' 或 'black'self.row = rowself.col = colself.selected = Falseself.valid_moves = []def draw(self, screen):x = self.col * CELL_SIZE + CELL_SIZE // 2y = self.row * CELL_SIZE + CELL_SIZE // 2font = 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))breakfor 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))breakelif 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 + dcif 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 = Falsefor i in range(col + 1, c):if board[row][i] is not None:has_piece = Truebreakif has_piece:self.valid_moves.append((row, c))breakelse:breakfor 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 = Falsefor i in range(c + 1, col):if board[row][i] is not None:has_piece = Truebreakif has_piece:self.valid_moves.append((row, c))breakelse:breakelif 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 + dcif 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 + dcif 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 + dcif 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 boardboard = create_board()selected_piece = Nonerunning = Truewhile running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.MOUSEBUTTONDOWN:x, y = event.poscol, 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 = Falseselected_piece = None# 如果点击的是目标位置elif (row, col) in selected_piece.valid_moves:# 移动棋子if piece:# 吃子board[row][col] = selected_pieceboard[selected_piece.row][selected_piece.col] = Noneselected_piece.row = rowselected_piece.col = colselected_piece.selected = Falseselected_piece = Noneelse:# 移动board[row][col] = selected_pieceboard[selected_piece.row][selected_piece.col] = Noneselected_piece.row = rowselected_piece.col = colselected_piece.selected = Falseselected_piece = None# 如果点击的是其他棋子,选择它elif piece and piece.color == selected_piece.color:selected_piece.selected = Falseselected_piece = pieceselected_piece.selected = True# 如果点击的是对方棋子,但不在有效移动范围内,取消选择elif piece and piece.color != selected_piece.color:selected_piece.selected = Falseselected_piece = Noneelse:selected_piece.selected = Falseselected_piece = None# 如果没有选择棋子,选择当前棋子elif piece:selected_piece = pieceselected_piece.selected = Trueselected_piece.get_valid_moves(board)# 如果点击的是空位,取消选择else:selected_piece = None# 如果点击的是棋子,获取其有效移动if piece and not selected_piece:selected_piece = pieceselected_piece.selected = Trueselected_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()
整理不易,诚望各位看官点赞 收藏 评论 予以支持,这将成为我持续更新的动力源泉。若您在阅览时存有异议或建议,敬请留言指正批评,让我们携手共同学习,共同进取,吾辈自当相互勉励!
