|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 pyzyd 于 2025-5-31 11:58 编辑
经典扫雷游戏
鼠标点击即玩
- import pygame
- import random
- import sys
- import traceback
- from tkinter import messagebox
- import time
- class SaoLei():
- def __init__(self):
- self.WIDTH = 10 # 宽
- self.HEIGHT = 10 # 高
- self.GRID_SIZE = 35 # 格子边长
- self.NUM = 10 # 雷的个数
- self.KEY_DATA = 20 # 加密层数
- self.map = [] # 地图,初始化
- self.is_easy = self.choose_difficulty()
- self.start = 0
- self.elapsed_time = 0
- for i in range(self.HEIGHT):
- self.map.append([])
- for j in range(self.WIDTH):
- self.map[i].append(0)
- self.images = [] # 加载图像
- for i in range(12):
- image = pygame.image.load(f'images/{i}.jpg')
- scaled_image = pygame.transform.scale(image, (self.GRID_SIZE, self.GRID_SIZE))
- self.images.append(scaled_image)
- self.is_over = False
- pygame.init()
- self.screen = pygame.display.set_mode((self.WIDTH * self.GRID_SIZE + 140, self.HEIGHT * self.GRID_SIZE))
- pygame.display.set_caption('扫雷')
- self.clock = pygame.time.Clock()
- self.font = pygame.font.SysFont('Microsoft YaHei', 20)
- self.init_map()
- self.update_map()
- def show_map(self):
- for i in range(self.HEIGHT):
- for j in range(self.WIDTH):
- print(f'{self.map[i][j]:4}', end=' ')
- print()
- def init_map(self):
- count = 0
- while count < self.NUM:
- j = random.randrange(self.WIDTH)
- i = random.randrange(self.HEIGHT)
- if self.map[i][j] == 0:
- self.map[i][j] = -1
- count += 1
- for i in range(self.HEIGHT):
- for j in range(self.WIDTH):
- if self.map[i][j] == 0:
- self.map[i][j] += self.search_lei(i,j)
- for i in range(self.HEIGHT):
- for j in range(self.WIDTH):
- self.map[i][j] += self.KEY_DATA
- def mask_num(self):
- num = 0
- for i in range(self.HEIGHT):
- for j in range(self.WIDTH):
- if self.map[i][j] >= -1 + 2 * self.KEY_DATA:
- num += 1
- return num
- def search_lei(self, x, y):
- count = 0
- for i in range(x-1, x+2):
- for j in range(y-1, y+2):
- if 0 <= i < self.HEIGHT and 0 <= j < self.WIDTH:
- if self.map[i][j] == -1:
- count += 1
- return count
- def over(self):
- for i in range(self.HEIGHT):
- for j in range(self.WIDTH):
- if self.map[i][j] == -1 + self.KEY_DATA or self.map[i][j] == -1 + 2 * self.KEY_DATA:
- self.map[i][j] = -1
- def is_win(self):
- count = 0
- t_count = 0
- r_count = 0
- for i in range(self.HEIGHT):
- for j in range(self.WIDTH):
- if self.map[i][j] >= -1 + 2 * self.KEY_DATA:
- count += 1
- if self.map[i][j] == -1 + 2 * self.KEY_DATA:
- t_count += 1
- if self.map[i][j] <= 8:
- r_count += 1
- if count == self.NUM and t_count == self.NUM and r_count == self.WIDTH * self.HEIGHT - self.NUM:
- return True
- def calc_time(self):
- # 计算经过的时间
- self.elapsed_time = time.time() - self.start
- minutes = int(self.elapsed_time // 60)
- seconds = int(self.elapsed_time % 60)
- text1 = "所用时间:"
- time_text = f"{minutes:02d}:{seconds:02d}" # 格式化为 "分:秒" 格式
- # 渲染文本
- text1_surface = self.font.render(text1, True, (0, 0, 0))
- text_surface = self.font.render(time_text, True, (0, 0, 0))
- best_time = 0
- file = ''
- if self.is_easy:
- file = r'record_easy.txt'
- else:
- file = r'record_difficult.txt'
- try:
- with open(file, 'r') as f:
- best_time = float(f.read())
- except FileNotFoundError:
- pass
- text2 = "最佳时间:"
- minutes = int(best_time // 60)
- seconds = int(best_time % 60)
- best_time_text = f"{minutes:02d}:{seconds:02d}"
- if best_time == 0:
- best_time_text = "暂无"
- text2_surface = self.font.render(text2, True, (235, 100, 0))
- best_time_surface = self.font.render(best_time_text, True, (0, 0, 0))
- num = self.mask_num()
- text3 = f"标记个数:{num}"
- text3_surface = self.font.render(text3, True, (0, 0, 0))
- # 绘制
- self.screen.fill((230, 235, 235))
- self.screen.blit(self.font.render(f"雷的个数:{self.NUM}", True, (255, 0, 0)),
- (self.WIDTH * self.GRID_SIZE + 10, 10))
- self.screen.blit(text1_surface, (self.WIDTH * self.GRID_SIZE + 10, 50))
- self.screen.blit(text_surface, (self.WIDTH * self.GRID_SIZE + 10, 90))
- self.screen.blit(text2_surface, (self.WIDTH * self.GRID_SIZE + 10, 130))
- self.screen.blit(best_time_surface, (self.WIDTH * self.GRID_SIZE + 10, 170))
- self.screen.blit(text3_surface, (self.WIDTH * self.GRID_SIZE + 10, 210))
- def game_over(self):
- title = 'Game Over'
- msg = ''
- if self.is_over == True:
- self.over()
- msg = '你踩到雷了,你输了,Fail T^T'
- elif self.is_win():
- msg = '你排掉了所有的雷,恭喜你,你赢了,Win!'
- best_time = 0
- file = ''
- if self.is_easy:
- file = r'record_easy.txt'
- else:
- file = r'record_difficult.txt'
- try:
- with open(file, 'r') as f:
- best_time = float(f.read())
- except FileNotFoundError:
- pass
- if best_time == 0 or best_time > self.elapsed_time:
- with open(file, 'w') as f:
- f.write(str(self.elapsed_time))
- if msg:
- self.over()
- res = messagebox.askretrycancel(title, msg, icon='question')
- if res == True:
- self.__init__()
- self.run()
- else:
- pygame.quit()
- sys.exit()
- def draw_map(self):
- for i in range(self.HEIGHT):
- for j in range(self.WIDTH):
- x = j * self.GRID_SIZE
- y = i * self.GRID_SIZE
- if self.map[i][j] == -1:
- self.screen.blit(self.images[9], (x, y))
- elif 0 <= self.map[i][j] <= 8:
- self.screen.blit(self.images[self.map[i][j]], (x, y))
- elif -1 + self.KEY_DATA <= self.map[i][j] <= 8 + self.KEY_DATA:
- self.screen.blit(self.images[10], (x, y))
- elif -1 + 2 * self.KEY_DATA <= self.map[i][j] <= 8 + 2 * self.KEY_DATA:
- self.screen.blit(self.images[11], (x, y))
- def open_null(self, x, y):
- for i in range(x-1, x+2):
- for j in range(y-1, y+2):
- if 0 <= i < self.HEIGHT and 0 <= j < self.WIDTH:
- if -1 + self.KEY_DATA < self.map[i][j] <= 8 + self.KEY_DATA:
- self.map[i][j] -= self.KEY_DATA
- if self.map[i][j] == 0:
- self.open_null(i, j)
- def run(self):
- self.start = time.time()
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- pygame.quit()
- sys.exit()
- elif event.type == pygame.MOUSEBUTTONDOWN:
- pos = pygame.mouse.get_pos()
- i = int(pos[1] / self.GRID_SIZE)
- j = int(pos[0] / self.GRID_SIZE)
- if 0 <= i < self.HEIGHT and 0 <= j < self.WIDTH:
- if pygame.mouse.get_pressed()[0] == 1:
- # 左键按下
- if -1 + self.KEY_DATA <= self.map[i][j] <= 8 + self.KEY_DATA:
- self.map[i][j] -= self.KEY_DATA
- if self.map[i][j] == -1:
- self.is_over = True
- elif self.map[i][j] == 0:
- self.open_null(i, j)
- elif pygame.mouse.get_pressed()[2] == 1:
- # 右键按下
- if -1 + self.KEY_DATA <= self.map[i][j] <= 8 + self.KEY_DATA:
- self.map[i][j] += self.KEY_DATA
- elif -1 + 2 * self.KEY_DATA <= self.map[i][j] <= 8 + 2 * self.KEY_DATA:
- self.map[i][j] -= self.KEY_DATA
- self.update_map()
- self.clock.tick(60)
- self.game_over()
- def update_map(self):
- self.calc_time()
- self.draw_map()
- pygame.display.update()
- def choose_difficulty(self):
- choice = ''
- choice = messagebox.askquestion("选择模式", "简单请选‘是’,困难请选‘否’", icon='question')
- if choice == 'yes':
- self.NUM = 10
- return True
- elif choice == 'no':
- self.NUM = 30
- self.WIDTH = 20
- return False
- else:
- sys.exit()
- if __name__ == '__main__':
- sl = SaoLei()
- try:
- sl.run()
- except SystemExit:
- pass
- except:
- traceback.print_exc()
- pygame.quit()
复制代码
saolei.zip
(73.35 KB, 下载次数: 1)
|
评分
-
查看全部评分
|