PyGame做了一个扫雷
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()