扫雷

import pygame
import sys
import random

初始化pygame

pygame.init()

游戏常量

CELL_SIZE = 30
MARGIN = 10

中等难度设置(可调整)

GRID_WIDTH = 16
GRID_HEIGHT = 16
MINE_COUNT = 40

确保窗口尺寸合适

WINDOW_WIDTH = MARGIN * 2 + CELL_SIZE * GRID_WIDTH
WINDOW_HEIGHT = MARGIN * 2 + CELL_SIZE * GRID_HEIGHT + 50 # 额外空间用于显示信息

颜色定义

BG_COLOR = (200, 200, 200)
CELL_COLOR = (180, 180, 180)
COVERED_COLOR = (120, 120, 120)
HIGHLIGHT_COLOR = (150, 150, 150)
BORDER_COLOR = (100, 100, 100)
TEXT_COLORS = {
1: (0, 0, 255), # 蓝色
2: (0, 128, 0), # 绿色
3: (255, 0, 0), # 红色
4: (0, 0, 128), # 深蓝色
5: (128, 0, 0), # 暗红色
6: (0, 128, 128), # 青绿色
7: (0, 0, 0), # 黑色
8: (128, 128, 128)# 灰色
}
MINE_COLOR = (0, 0, 0)
MINE_BG_COLOR = (255, 0, 0)
FLAG_COLOR = (255, 255, 0)

创建游戏窗口

screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("扫雷游戏")
font = pygame.font.SysFont("Arial", 24)

class MineSweeper:
def init(self):
self.reset_game()

def reset_game(self):
    """重置游戏状态"""
    # 初始化网格
    self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
    self.covered = [[True for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
    self.flagged = [[False for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
    self.game_over = False
    self.game_won = False
    self.first_click = True
    
    # 随机放置地雷
    mines_placed = 0
    while mines_placed < MINE_COUNT:
        row = random.randint(0, GRID_HEIGHT - 1)
        col = random.randint(0, GRID_WIDTH - 1)
        if self.grid[row][col] != -1:
            self.grid[row][col] = -1  # -1表示地雷
            mines_placed += 1
    
    # 计算每个非地雷格子周围的地雷数
    for row in range(GRID_HEIGHT):
        for col in range(GRID_WIDTH):
            if self.grid[row][col] != -1:
                self.grid[row][col] = self.count_neighbor_mines(row, col)

def count_neighbor_mines(self, row, col):
    """计算指定格子周围的地雷数量"""
    count = 0
    for r in range(max(0, row - 1), min(GRID_HEIGHT, row + 2)):
        for c in range(max(0, col - 1), min(GRID_WIDTH, col + 2)):
            if self.grid[r][c] == -1:
                count += 1
    return count

def uncover_cell(self, row, col):
    """揭开格子,如果是空白格则递归揭开周围格子"""
    if (row < 0 or row >= GRID_HEIGHT or col < 0 or col >= GRID_WIDTH or 
        not self.covered[row][col] or self.flagged[row][col]):
        return
    
    self.covered[row][col] = False
    
    if self.grid[row][col] == -1:
        # 挖到地雷,游戏结束
        self.game_over = True
        return
    
    if self.grid[row][col] == 0:
        # 空白格,递归揭开周围格子
        for r in range(max(0, row - 1), min(GRID_HEIGHT, row + 2)):
            for c in range(max(0, col - 1), min(GRID_WIDTH, col + 2)):
                self.uncover_cell(r, c)
    
    # 检查是否获胜
    self.check_win()

def toggle_flag(self, row, col):
    """切换格子的标记状态"""
    if (row < 0 or row >= GRID_HEIGHT or col < 0 or col >= GRID_WIDTH or 
        not self.covered[row][col] or self.game_over):
        return
    
    self.flagged[row][col] = not self.flagged[row][col]

def check_win(self):
    """检查是否获胜"""
    for row in range(GRID_HEIGHT):
        for col in range(GRID_WIDTH):
            if self.grid[row][col] != -1 and self.covered[row][col]:
                return
    self.game_won = True

def draw(self):
    """绘制游戏界面"""
    # 绘制背景
    screen.fill(BG_COLOR)
    
    # 绘制剩余地雷数
    mines_left = MINE_COUNT - sum(row.count(True) for row in self.flagged)
    mines_text = font.render(f"剩余地雷: {mines_left}", True, (0, 0, 0))
    screen.blit(mines_text, (MARGIN, WINDOW_HEIGHT - 40))
    
    # 绘制游戏状态
    if self.game_over:
        status_text = font.render("游戏结束!", True, (255, 0, 0))
    elif self.game_won:
        status_text = font.render("恭喜获胜!", True, (0, 255, 0))
    else:
        status_text = font.render("游戏进行中...", True, (0, 0, 0))
    screen.blit(status_text, (WINDOW_WIDTH // 2 - 100, WINDOW_HEIGHT - 40))
    
    # 绘制网格
    for row in range(GRID_HEIGHT):
        for col in range(GRID_WIDTH):
            x = MARGIN + col * CELL_SIZE
            y = MARGIN + row * CELL_SIZE
            
            # 绘制格子边框
            pygame.draw.rect(screen, BORDER_COLOR, (x, y, CELL_SIZE, CELL_SIZE), 1)
            
            if self.covered[row][col]:
                # 未揭开的格子
                pygame.draw.rect(screen, COVERED_COLOR, (x + 1, y + 1, CELL_SIZE - 2, CELL_SIZE - 2))
                
                if self.flagged[row][col]:
                    # 标记的格子
                    pygame.draw.rect(screen, FLAG_COLOR, (x + 5, y + 5, CELL_SIZE - 10, CELL_SIZE - 10))
            else:
                # 已揭开的格子
                pygame.draw.rect(screen, CELL_COLOR, (x + 1, y + 1, CELL_SIZE - 2, CELL_SIZE - 2))
                
                if self.grid[row][col] == -1:
                    # 地雷格子
                    pygame.draw.circle(screen, MINE_BG_COLOR, (x + CELL_SIZE // 2, y + CELL_SIZE // 2), CELL_SIZE // 3)
                    pygame.draw.circle(screen, MINE_COLOR, (x + CELL_SIZE // 2, y + CELL_SIZE // 2), CELL_SIZE // 6)
                elif self.grid[row][col] > 0:
                    # 显示周围地雷数
                    num_text = font.render(str(self.grid[row][col]), True, TEXT_COLORS[self.grid[row][col]])
                    text_rect = num_text.get_rect(center=(x + CELL_SIZE // 2, y + CELL_SIZE // 2))
                    screen.blit(num_text, text_rect)
    
    pygame.display.flip()

def main():
game = MineSweeper()
clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if game.game_over or game.game_won:
                continue
            
            x, y = event.pos
            # 忽略状态显示区域
            if y >= WINDOW_HEIGHT - 50:
                continue
            
            col = (x - MARGIN) // CELL_SIZE
            row = (y - MARGIN) // CELL_SIZE
            
            if 0 <= row < GRID_HEIGHT and 0 <= col < GRID_WIDTH:
                if event.button == 1:  # 左键点击
                    if game.first_click:
                        # 确保第一次点击不会挖到地雷
                        if game.grid[row][col] == -1:
                            # 重新生成地雷
                            game.reset_game()
                            # 再次点击当前位置
                            game.uncover_cell(row, col)
                        game.first_click = False
                    else:
                        game.uncover_cell(row, col)
                
                elif event.button == 3:  # 右键点击
                    game.toggle_flag(row, col)
    
    game.draw()
    clock.tick(60)

if name == "main":
main()

posted @ 2025-06-22 22:02  无聊了多少人  阅读(19)  评论(0)    收藏  举报