1 # 这是一个示例 Python 脚本。
2
3 # 按 ⌃R 执行或将其替换为您的代码。
4 # 按 双击 ⇧ 在所有地方搜索类、文件、工具窗口、操作和设置。
5 import sys
6 import pygame
7 import random
8
9 game = None
10 BOMB_COUNT = 1
11
12 # 空间
13 class Button(object):
14 pass
15
16 class Game(object):
17 screen = None
18 row_count = 0
19 bomb_location = []
20 squares_list = []
21 squares_val_dict = {}
22 win = False
23
24 def __init__(self, count):
25 pygame.init()
26 total_width = count * 18 + 100 * 2
27 total_height = count * 18 + 100 * 2
28 self.row_count = count
29 self.screen = pygame.display.set_mode((total_width, total_height))
30 self.win = False
31 self.bomb_location = []
32 self.squares_list = []
33 self.squares_val_dict = {}
34
35 def __del__(self):
36 print('del game')
37 pygame.display.quit()
38
39 def is_over(self):
40 return self.win
41
42 def get_screen(self):
43 return self.screen
44
45 def random_bomb(self):
46 # 随机产生炸弹
47 for i in range(BOMB_COUNT):
48 while 1:
49 x = random.randint(0, 29)
50 y = random.randint(0, 29)
51 if (x, y) in self.bomb_location:
52 continue
53 else:
54 self.bomb_location.append((x, y))
55 break
56
57 # 计算某个位置范围的数字
58 for x in range(self.row_count):
59 for y in range(self.row_count):
60 count = 0
61 if (x - 1, y) in self.bomb_location:
62 count += 1
63 if (x - 1, y - 1) in self.bomb_location:
64 count += 1
65 if (x - 1, y + 1) in self.bomb_location:
66 count += 1
67
68 if (x , y - 1) in self.bomb_location:
69 count += 1
70 if (x , y) in self.bomb_location:
71 count += 1
72 if (x , y + 1) in self.bomb_location:
73 count += 1
74
75 if (x + 1 , y - 1) in self.bomb_location:
76 count += 1
77 if (x + 1 , y) in self.bomb_location:
78 count += 1
79 if (x + 1, y + 1) in self.bomb_location:
80 count += 1
81
82 # print('%s,%s %d' % (x, y, count))
83 self.squares_val_dict[(x, y)] = count
84
85 def init_square(self):
86 for i in range(self.row_count):
87 self.squares_list.append([])
88 top = 100 + i * 18
89 for j in range(self.row_count):
90 left = 100 + j * 18
91 width = 18
92 height = 18
93 exist = False
94 if (i, j) in self.bomb_location:
95 # print('%s,%s exists' % (j, i))
96 exist = True
97
98 # 周围的炸弹数量
99 around_count = self.squares_val_dict.get((i, j), 0)
100 # print('init square %s,%s %d' % (i, j, around_count))
101 self.squares_list[i].append(Square(exist, around_count, self.screen, left, top, width, height))
102 self.squares_list[i][j].draw()
103 pygame.display.update()
104
105 def start_game(self):
106 pass
107
108 def display_win(self):
109 font = pygame.font.SysFont("Andale Mono", 32)
110 txt = font.render("Winner Winner Winner", True, 'Red')
111 self.get_screen().blit(txt, (200, 0))
112
113 font = pygame.font.SysFont("Andale Mono", 16)
114 txt = font.render("uploading to dashboard...", True, 'green')
115 self.get_screen().blit(txt, (260, 40))
116
117 font = pygame.font.SysFont("Andale Mono", 16)
118 txt = font.render("click to continue...", True, 'gray')
119 self.get_screen().blit(txt, (280, 60))
120
121 self.win = True
122
123 def display_flag(self):
124 for (x, y) in self.bomb_location:
125 square = self.squares_list[x][y]
126 square.right_click()
127 square.draw()
128
129 # 根据所有的旗帜来判断胜利
130 def check_win_by_flag(self):
131 for (x, y) in self.bomb_location:
132 square = self.squares_list[x][y]
133 if square.state == 'flag' and square.exist:
134 continue
135 return False
136 self.display_win()
137 return True
138
139 # 根据已经没有格子点击了来判断胜利
140 def check_win_by_click(self):
141 # print('check by click')
142 for x in range(self.row_count):
143 for y in range(self.row_count):
144 square = self.squares_list[x][y]
145 if square.state == 'blank' or square.exist:
146 # print(1)
147 continue
148 return False
149 self.display_flag()
150 self.display_win()
151 return True
152
153 def right_clicked(self, pos):
154 left = pos[0]
155 top = pos[1]
156 x = int((top - 100) / 18)
157 y = int((left - 100) / 18)
158
159 # print('right clicked %s, %s' % (x, y))
160 if x in range(0, self.row_count) and y in range(0, self.row_count):
161 square = self.squares_list[x][y]
162 if not square.right_click():
163 return
164 # 表示右键生效
165 square.draw()
166
167 if square.state == 'flag' and square.exist:
168 # 只有当前标记是正确的时候才判断
169 # 判断是否已经将所有的炸弹标记出来
170 self.check_win_by_flag()
171 pygame.display.update()
172
173 def clicked(self, pos):
174 left = pos[0]
175 top = pos[1]
176 x = int((top - 100) / 18)
177 y = int((left - 100) / 18)
178
179 def click_square(self, x, y):
180 if x not in range(0, self.row_count) or y not in range(0, self.row_count):
181 return False
182
183 square = self.squares_list[x][y]
184 if square.state != 'new':
185 return False
186
187 if not square.click():
188 return False
189
190 square.draw()
191 if square.around_count == 0:
192 # print('around is 0')
193 for (x1, y1) in [
194 (x - 1, y), (x - 1, y - 1), (x - 1, y + 1),
195 (x, y - 1), (x, y), (x, y + 1),
196 (x + 1, y - 1), (x + 1, y), (x + 1, y + 1),
197
198 ]:
199 click_square(self, x1, y1)
200 return True
201
202 if x in range(0, self.row_count) and y in range(0, self.row_count):
203 if click_square(self, x, y):
204 # 判断是否成功
205 self.check_win_by_click()
206 pygame.display.update()
207
208 def refresh(self):
209 pygame.display.update()
210
211
212 class Square(object):
213 exist = False
214 surface = None
215 rect = None
216 state = '' # new, blank, flag, bomed
217 face = None
218 around_count = 0
219
220 def __init__(self, exist, around_count, surface, left, top, width, height):
221 self.rect = pygame.Rect(left, top, width, height)
222 self.exist = exist
223 self.surface = surface
224 self.state = 'new'
225 self.around_count = around_count
226 # print('%s' % (self.around_count))
227
228 def exists(self):
229 return self.exist
230
231 def draw(self):
232 global game
233 if self.state == 'new':
234 self.face = pygame.Surface((self.rect.width, self.rect.height))
235 self.face.fill('white')
236 game.get_screen().blit(self.face, (self.rect.left, self.rect.top))
237 pygame.draw.rect(self.surface, 'gray', self.rect, 1)
238
239 elif self.state == 'blank':
240 self.face.fill('gray')
241 game.get_screen().blit(self.face, (self.rect.left, self.rect.top))
242 pygame.draw.rect(self.surface, 'white', self.rect, 1)
243
244 # 在格子中间画上数字
245 font = pygame.font.SysFont("Andale Mono", 16)
246 txt = font.render("%s" % (self.around_count if self.around_count > 0 else ''), True, 'blue')
247 # print('%s, %s' % (txt.get_rect(), self.around_count))
248 game.get_screen().blit(txt, (self.rect.left + 4, self.rect.top))
249
250 pass
251 elif self.state == 'flag':
252 # 在格子中间画上 F
253 font = pygame.font.SysFont("Andale Mono", 16)
254 txt = font.render("F", True, 'green')
255 # print('%s, %s' % (txt.get_rect(), self.around_count))
256 game.get_screen().blit(txt, (self.rect.left + 4, self.rect.top))
257
258 elif self.state == 'boom':
259 self.face.fill('red')
260 game.get_screen().blit(self.face, (self.rect.left, self.rect.top))
261 pygame.draw.rect(self.surface, 'white', self.rect, 1)
262 pass
263
264 def click(self):
265 need_update = False
266 if self.state == 'new':
267 if self.exist:
268 self.state = 'boom'
269 need_update = True
270 else:
271 self.state = 'blank'
272 need_update = True
273 return need_update
274
275 def right_click(self):
276 need_update = False
277 if self.state == 'new':
278 self.state = 'flag'
279 need_update = True
280 elif self.state == 'flag':
281 self.state = 'new'
282 need_update = True
283 return need_update
284
285
286 def init_game(count, x=18, y=18):
287 global game
288 if game:
289 del game
290 game = Game(count)
291 game.random_bomb()
292 game.init_square()
293
294
295 # 按间距中的绿色按钮以运行脚本。
296 if __name__ == '__main__':
297 init_game(30)
298
299 while True:
300 for event in pygame.event.get():
301 if event.type == pygame.MOUSEBUTTONUP:
302 if game.is_over():
303 init_game(30)
304 continue
305 pos = event.pos
306 if event.button == 1:
307 game.clicked(pos)
308 elif event.button == 3:
309 game.right_clicked(pos)
310 # 获取当前那个格子被点击了
311 if event.type == pygame.QUIT:
312 sys.exit(0)
313 pygame.display.update()

PyGame做了一个扫雷的更多相关文章

  1. 我用Bash编写了一个扫雷游戏

    我在编程教学方面不是专家,但当我想更好掌握某一样东西时,会试着找出让自己乐在其中的方法.比方说,当我想在 shell 编程方面更进一步时,我决定用 Bash 编写一个扫雷游戏来加以练习. 我在编程教学 ...

  2. 做了一个sublime text插件

    做了一个sublime text插件,可以方便地查看C++/python的调用图.插件的演示视频在这里: http://list.youku.com/albumlist/show?id=2820226 ...

  3. 做为一个前端工程师,是往node方面转,还是往HTML5方面转

    文章背景:问题本身来自于知乎,但是我感觉这个问题很典型,有必要把问题在整理一下,重新分享出来. 当看到这个问题之前,我也碰到过很多有同样疑惑的同学,他们都有一个共同的疑问该学php还是nodejs,包 ...

  4. bootstrap做了一个表格

    花了一下午做了一个表格: 大致是这样: 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf ...

  5. PHP MVC简单介绍,对PHP当前主流的MVC做了一个总结

    东抄西抄,对PHP当前主流的MVC做了一个总结PPT. 希望对初学者有点帮助! PHP MVC初步.ppt

  6. 用MVVM做了一个保存网页的工具-上篇

    前言: 你是否有过收藏了别人博客或文章,当想用的时候却找不到?你是否有过收藏了别人博客或文章,却因为没有网络而打不开网页?OK,下面是我做的一个工具,有兴趣的同学们可以download 玩下,哈哈^. ...

  7. php大力力 [042节] 今天做了一个删除功能

    php大力力 [042节] 今天做了一个删除功能 if(isset($_GET['action'])){ if($_GET['action']=="del"){ $sql = &q ...

  8. 做了一个简易的git 代码自动部署脚本

    做了一个简易的git 代码自动部署脚本 http://my.oschina.net/caomenglong/blog/472665 发表于2个月前(2015-06-30 21:08)   阅读(200 ...

  9. 用原生javascript做的一个打地鼠的小游戏

    学习javascript也有一段时间了,一直以来分享的都是一些概念型的知识,今天有空做了一个打地鼠的小游戏,来跟大家分享一下,大家也可以下载来增加一些生活的乐趣,下面P出代码:首先是HTML部分代码: ...

随机推荐

  1. 论文翻译:2020_Lightweight Online Noise Reduction on Embedded Devices using Hierarchical Recurrent Neural Networks

    论文地址:基于分层递归神经网络的嵌入式设备轻量化在线降噪 引用格式:Schröter H, Rosenkranz T, Zobel P, et al. Lightweight Online Noise ...

  2. 常用类--String

    一.String 1.1 String是不可变对象 String的底层是一个 char类型字符数组 String类是final修饰的,不能被继承,不能改变,但引用可以重新赋值 String采用的编码方 ...

  3. 部署前后端为独立的 Docker 节点

    在『服务器部署 Vue 和 Django 项目的全记录』一文中,介绍了在服务器中使用 Nginx 部署前后端项目的过程.然而,当 Web 应用流量增多时,需要考虑负载均衡.流量分发.容灾等情况,原生的 ...

  4. 调用 StatefulWidget 组件的参数时(widget.xxx)报 Invalid Constant Value

    一个 Flutter 组件(Widget)在很多情况下都需要接收一些参数.Flutter 插件通常提示使用 const 关键字包裹某 Widget(很多人接受建议且执行),导致通过 widget.xx ...

  5. 套接字传输(TCP简单使用)

  6. 分库分表之ShardingSphere

    目录 分库分表诞生的前景 分库分表的方式(垂直拆分,水平复制) 1.垂直拆分 1.1 垂直分库 1.2 垂直分表 2.水平拆分 2.1 水平分库 2.2 水平分表 分库分库中间件 ShardingSp ...

  7. PerfView专题 (第十篇):洞察 C# 终结队列引发的内存泄漏

    一:背景 C# 程序内存泄漏的诱发因素有很多,但从顶层原理上来说,就是该销毁的 用户根 对象没有被销毁,从而导致内存中意料之外的对象无限堆积,导致内存暴涨,最终崩溃,这其中的一个用户根就是 终结器队列 ...

  8. iOS白嫖系列Testflight

    1.Picsart 白嫖一年会员 使用 Picsart 照片编辑器和视频编辑器,您可以将您的创意变为现实.制作专业级拼贴画.设计和添加贴纸.快速移除和交换背景.尝试热门编辑,如黄金时段.镜子自拍和复古 ...

  9. Think PHP框架基础安装6.0

    第一步:点击基础安装tp框架composer create-project topthink/think tp 第二步:点击架构多应用模式 拓展composer require topthink/th ...

  10. 面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)

    一.JVM内存结构 ▷ 谈及内存结构各个部分的数据交互过程:还可以再谈及生命周期.数据共享:是否GC.是否OOM 答:jvm 内存结构包括程序计数器.虚拟机栈.本地方法栈.堆.方法区:它是字节码运行时 ...