鱼C论坛

 找回密码
 立即注册
查看: 139|回复: 12

[作品展示] 扫雷(python)

[复制链接]
回帖奖励 56 鱼币 回复本帖可获得 7 鱼币奖励! 每人限 1 次
发表于 3 天前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 pyzyd 于 2025-5-31 11:58 编辑

经典扫雷游戏

鼠标点击即玩
屏幕截图 2025-05-31 115251.png
屏幕截图 2025-05-31 115344.png
屏幕截图 2025-05-31 115446.png
屏幕截图 2025-05-31 115536.png


  1. import pygame
  2. import random
  3. import sys
  4. import traceback
  5. from tkinter import messagebox
  6. import time

  7. class SaoLei():
  8.     def __init__(self):
  9.         self.WIDTH = 10         # 宽
  10.         self.HEIGHT = 10        # 高
  11.         self.GRID_SIZE = 35     # 格子边长
  12.         self.NUM = 10           # 雷的个数
  13.         self.KEY_DATA = 20      # 加密层数
  14.         self.map = []           # 地图,初始化
  15.         self.is_easy = self.choose_difficulty()
  16.         self.start = 0
  17.         self.elapsed_time = 0
  18.         for i in range(self.HEIGHT):
  19.             self.map.append([])
  20.             for j in range(self.WIDTH):
  21.                 self.map[i].append(0)
  22.         self.images = []        # 加载图像
  23.         for i in range(12):
  24.             image = pygame.image.load(f'images/{i}.jpg')
  25.             scaled_image = pygame.transform.scale(image, (self.GRID_SIZE, self.GRID_SIZE))
  26.             self.images.append(scaled_image)
  27.         self.is_over = False

  28.         pygame.init()
  29.         self.screen = pygame.display.set_mode((self.WIDTH * self.GRID_SIZE + 140, self.HEIGHT * self.GRID_SIZE))
  30.         pygame.display.set_caption('扫雷')
  31.         self.clock = pygame.time.Clock()
  32.         self.font = pygame.font.SysFont('Microsoft YaHei', 20)

  33.         self.init_map()
  34.         self.update_map()

  35.     def show_map(self):
  36.         for i in range(self.HEIGHT):
  37.             for j in range(self.WIDTH):
  38.                 print(f'{self.map[i][j]:4}', end='  ')
  39.             print()

  40.     def init_map(self):
  41.         count = 0
  42.         while count < self.NUM:
  43.             j = random.randrange(self.WIDTH)
  44.             i = random.randrange(self.HEIGHT)
  45.             if self.map[i][j] == 0:
  46.                 self.map[i][j] = -1
  47.                 count += 1

  48.         for i in range(self.HEIGHT):
  49.             for j in range(self.WIDTH):
  50.                 if self.map[i][j] == 0:
  51.                     self.map[i][j] += self.search_lei(i,j)

  52.         for i in range(self.HEIGHT):
  53.             for j in range(self.WIDTH):
  54.                 self.map[i][j] += self.KEY_DATA

  55.     def mask_num(self):
  56.         num = 0
  57.         for i in range(self.HEIGHT):
  58.             for j in range(self.WIDTH):
  59.                 if self.map[i][j] >= -1 + 2 * self.KEY_DATA:
  60.                     num += 1
  61.         return num

  62.     def search_lei(self, x, y):
  63.         count = 0
  64.         for i in range(x-1, x+2):
  65.             for j in range(y-1, y+2):
  66.                 if 0 <= i < self.HEIGHT and 0 <= j < self.WIDTH:
  67.                     if self.map[i][j] == -1:
  68.                         count += 1
  69.         return count

  70.     def over(self):
  71.         for i in range(self.HEIGHT):
  72.             for j in range(self.WIDTH):
  73.                 if self.map[i][j] == -1 + self.KEY_DATA or self.map[i][j] == -1 + 2 * self.KEY_DATA:
  74.                     self.map[i][j] = -1

  75.     def is_win(self):
  76.         count = 0
  77.         t_count = 0
  78.         r_count = 0
  79.         for i in range(self.HEIGHT):
  80.             for j in range(self.WIDTH):
  81.                 if self.map[i][j] >= -1 + 2 * self.KEY_DATA:
  82.                     count += 1
  83.                     if self.map[i][j] == -1 + 2 * self.KEY_DATA:
  84.                         t_count += 1
  85.                 if self.map[i][j] <= 8:
  86.                     r_count += 1
  87.         if count == self.NUM and t_count == self.NUM and r_count == self.WIDTH * self.HEIGHT - self.NUM:
  88.             return True

  89.     def calc_time(self):
  90.         # 计算经过的时间
  91.         self.elapsed_time = time.time() - self.start
  92.         minutes = int(self.elapsed_time // 60)
  93.         seconds = int(self.elapsed_time % 60)
  94.         text1 = "所用时间:"
  95.         time_text = f"{minutes:02d}:{seconds:02d}"  # 格式化为 "分:秒" 格式
  96.         # 渲染文本
  97.         text1_surface = self.font.render(text1, True, (0, 0, 0))
  98.         text_surface = self.font.render(time_text, True, (0, 0, 0))

  99.         best_time = 0
  100.         file = ''
  101.         if self.is_easy:
  102.             file = r'record_easy.txt'
  103.         else:
  104.             file = r'record_difficult.txt'
  105.         try:
  106.             with open(file, 'r') as f:
  107.                 best_time = float(f.read())
  108.         except FileNotFoundError:
  109.             pass

  110.         text2 = "最佳时间:"
  111.         minutes = int(best_time // 60)
  112.         seconds = int(best_time % 60)
  113.         best_time_text = f"{minutes:02d}:{seconds:02d}"
  114.         if best_time == 0:
  115.             best_time_text = "暂无"
  116.         text2_surface = self.font.render(text2, True, (235, 100, 0))
  117.         best_time_surface = self.font.render(best_time_text, True, (0, 0, 0))


  118.         num = self.mask_num()
  119.         text3 = f"标记个数:{num}"
  120.         text3_surface = self.font.render(text3, True, (0, 0, 0))

  121.         # 绘制
  122.         self.screen.fill((230, 235, 235))
  123.         self.screen.blit(self.font.render(f"雷的个数:{self.NUM}", True, (255, 0, 0)),
  124.                          (self.WIDTH * self.GRID_SIZE + 10, 10))
  125.         self.screen.blit(text1_surface, (self.WIDTH * self.GRID_SIZE + 10, 50))
  126.         self.screen.blit(text_surface, (self.WIDTH * self.GRID_SIZE + 10, 90))
  127.         self.screen.blit(text2_surface, (self.WIDTH * self.GRID_SIZE + 10, 130))
  128.         self.screen.blit(best_time_surface, (self.WIDTH * self.GRID_SIZE + 10, 170))

  129.         self.screen.blit(text3_surface, (self.WIDTH * self.GRID_SIZE + 10, 210))

  130.     def game_over(self):
  131.         title = 'Game Over'
  132.         msg = ''
  133.         if self.is_over == True:
  134.             self.over()
  135.             msg = '你踩到雷了,你输了,Fail T^T'

  136.         elif self.is_win():
  137.             msg = '你排掉了所有的雷,恭喜你,你赢了,Win!'
  138.             best_time = 0
  139.             file = ''
  140.             if self.is_easy:
  141.                 file = r'record_easy.txt'
  142.             else:
  143.                 file = r'record_difficult.txt'
  144.             try:
  145.                 with open(file, 'r') as f:
  146.                     best_time = float(f.read())
  147.             except FileNotFoundError:
  148.                 pass

  149.             if best_time == 0 or best_time > self.elapsed_time:
  150.                 with open(file, 'w') as f:
  151.                     f.write(str(self.elapsed_time))


  152.         if msg:
  153.             self.over()
  154.             res = messagebox.askretrycancel(title, msg, icon='question')
  155.             if res == True:
  156.                 self.__init__()
  157.                 self.run()
  158.             else:
  159.                 pygame.quit()
  160.                 sys.exit()

  161.     def draw_map(self):
  162.         for i in range(self.HEIGHT):
  163.             for j in range(self.WIDTH):
  164.                 x = j * self.GRID_SIZE
  165.                 y = i * self.GRID_SIZE
  166.                 if self.map[i][j] == -1:
  167.                     self.screen.blit(self.images[9], (x, y))
  168.                 elif 0 <= self.map[i][j] <= 8:
  169.                     self.screen.blit(self.images[self.map[i][j]], (x, y))
  170.                 elif -1 + self.KEY_DATA <= self.map[i][j] <= 8 + self.KEY_DATA:
  171.                     self.screen.blit(self.images[10], (x, y))
  172.                 elif -1 + 2 * self.KEY_DATA <= self.map[i][j] <= 8 + 2 * self.KEY_DATA:
  173.                     self.screen.blit(self.images[11], (x, y))

  174.     def open_null(self, x, y):
  175.         for i in range(x-1, x+2):
  176.             for j in range(y-1, y+2):
  177.                 if 0 <= i < self.HEIGHT and 0 <= j < self.WIDTH:
  178.                     if -1 + self.KEY_DATA < self.map[i][j] <= 8 + self.KEY_DATA:
  179.                             self.map[i][j] -= self.KEY_DATA
  180.                             if self.map[i][j] == 0:
  181.                                 self.open_null(i, j)

  182.     def run(self):
  183.         self.start = time.time()
  184.         while True:
  185.             for event in pygame.event.get():
  186.                 if event.type == pygame.QUIT:
  187.                     pygame.quit()
  188.                     sys.exit()
  189.                 elif event.type == pygame.MOUSEBUTTONDOWN:
  190.                     pos = pygame.mouse.get_pos()
  191.                     i = int(pos[1] / self.GRID_SIZE)
  192.                     j = int(pos[0] / self.GRID_SIZE)
  193.                     if 0 <= i < self.HEIGHT and 0 <= j < self.WIDTH:
  194.                         if pygame.mouse.get_pressed()[0] == 1:
  195.                             # 左键按下
  196.                             if -1 + self.KEY_DATA <= self.map[i][j] <= 8 + self.KEY_DATA:
  197.                                 self.map[i][j] -= self.KEY_DATA
  198.                                 if self.map[i][j] == -1:
  199.                                     self.is_over = True
  200.                                 elif self.map[i][j] == 0:
  201.                                     self.open_null(i, j)
  202.                         elif pygame.mouse.get_pressed()[2] == 1:
  203.                             # 右键按下
  204.                             if -1 + self.KEY_DATA <= self.map[i][j] <= 8 + self.KEY_DATA:
  205.                                 self.map[i][j] += self.KEY_DATA
  206.                             elif -1 + 2 * self.KEY_DATA <= self.map[i][j] <= 8 + 2 * self.KEY_DATA:
  207.                                 self.map[i][j] -= self.KEY_DATA

  208.             self.update_map()
  209.             self.clock.tick(60)
  210.             self.game_over()

  211.     def update_map(self):
  212.         self.calc_time()
  213.         self.draw_map()
  214.         pygame.display.update()

  215.     def choose_difficulty(self):
  216.         choice = ''
  217.         choice = messagebox.askquestion("选择模式", "简单请选‘是’,困难请选‘否’", icon='question')
  218.         if choice == 'yes':
  219.             self.NUM = 10
  220.             return True
  221.         elif choice == 'no':
  222.             self.NUM = 30
  223.             self.WIDTH = 20
  224.             return False
  225.         else:
  226.             sys.exit()


  227. if __name__ == '__main__':
  228.     sl = SaoLei()
  229.     try:
  230.         sl.run()
  231.     except SystemExit:
  232.         pass
  233.     except:
  234.         traceback.print_exc()
  235.         pygame.quit()
复制代码


saolei.zip (73.35 KB, 下载次数: 1)

评分

参与人数 7荣誉 +22 鱼币 +18 贡献 +12 C币 +3 收起 理由
sfqxx_小 + 5 + 3
sfqxx + 5 + 1 + 3
tommyyu + 5 + 5 + 3
player-none + 2 + 2
ydwb + 2 + 2 鱼C有你更精彩^_^
小甲鱼 + 3 + 3 + 3 + 3 鱼C有你更精彩^_^
某一个“天” + 5 秒坐沙发

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层

回帖奖励 +7 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层

回帖奖励 +7 鱼币

加个程序截图就更好啦~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 天前 | 显示全部楼层

回帖奖励 +7 鱼币

口含明珠,进退自如
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 天前 From FishC Mobile | 显示全部楼层

回帖奖励 +7 鱼币

好!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层

回帖奖励 +7 鱼币

6
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 08:13 | 显示全部楼层

回帖奖励 +7 鱼币

优质贴值得有 C 币
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 08:13 | 显示全部楼层

回帖奖励 +7 鱼币

感谢
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 09:49 | 显示全部楼层

回帖奖励 +7 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 15:25 | 显示全部楼层

回帖奖励 +7 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 23:11 | 显示全部楼层

回帖奖励 +7 鱼币


好!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 10:51 | 显示全部楼层

回帖奖励 +7 鱼币

好好学习 天天向上
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 19:57 | 显示全部楼层

回帖奖励 +7 鱼币

牛哇牛哇
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-3 02:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表