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. Web 前端实战:Gitee 贡献图

    前言 这次要做的 Web 前端实战是一个 Gitee 个人主页下的贡献图(在线 Demo),偶尔做一两个,熟悉熟悉 JS 以及 jQ.整体来说这个案例并不难,主要是控制第一个节点以及最后一个节点处于星 ...

  2. HTML(下)

    (一)表格标签 1.表格的作用 用于显示.展示数据,让数据更加规整,可读性更好,把繁琐的数据表现得很有条理,表格不是用来布局页面的,而是用来展示数据的 2.表格标签基本语法 table--table ...

  3. 聊天机器人框架Rasa资源整理

      Rasa是一个主流的构建对话机器人的开源框架,它的优点是几乎覆盖了对话系统的所有功能,并且每个模块都有很好的可扩展性.参考文献收集了一些Rasa相关的开源项目和优质文章. 一.Rasa介绍 1.R ...

  4. 「题解报告」CF1067A Array Without Local Maximums

    大佬们的题解都太深奥了,直接把转移方程放出来让其他大佬们感性理解,蒟蒻们很难理解,所以我就写了一篇让像我一样的蒟蒻能看懂的题解 原题传送门 动态规划三部曲:确定状态,转移方程,初始状态和答案. --神 ...

  5. MAC上PKG打包

    pkg是Mac平台上非常常见的一种安装包格式,如果你想要快速将软件制作为pkg文件,就千万不要错过Packages Mac版,Packages Mac版是Mac平台上能够快速为您生成pkg程序包的一款 ...

  6. Html飞机大战(五):主角登场(英雄类编辑)

    好家伙, 遇到了一些非常奇怪的bug index.html:179 Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRender ...

  7. 第七十四篇:Vue组件父子传值

    好家伙, 1.组件之间的关系 在项目开发中,组件之间的最常见关系分为如下两种: (1)父子关系 (2)兄弟关系 2.父子之间的数据共享 (1)父->子共享数据 父组件向子组件共享数据需要使用自定 ...

  8. 03 最小CMake项目

    03 最小CMake项目 所有CMake项目都从一个CMakeLists.txt文件开始,此文件应该放在源代码树的最顶层目录下.可以将CMakeLists.txt想象成CMake项目文件,定义了从源和 ...

  9. Windows 2012 R2 iSCSI server

     Windows 2012 R2可以充当一台简单的SAN,提供iSCSI方式的连接,供客户端使用.不确定是否有人会这么使用,但至少在做实验的时候我觉得挺方便的.不用再像以前专门安装windows ...

  10. 永恒之蓝(MS17-010)漏洞复现

    1. 漏洞介绍 永恒之蓝: 恒之蓝是指2017年4月14日晚,黑客团体Shadow Brokers(影子经纪人)公布一大批网络攻击工具,其中包含"永恒之蓝"工具,"永恒之 ...