From 549737d3fcfc4644002ec6f0713bc974614c33d3 Mon Sep 17 00:00:00 2001 From: hnu202210040101 <639595606@qq.com> Date: Wed, 24 May 2023 23:50:09 +0800 Subject: [PATCH] ADD file via upload --- minesweep.py | 261 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 minesweep.py diff --git a/minesweep.py b/minesweep.py new file mode 100644 index 0000000..f9c8496 --- /dev/null +++ b/minesweep.py @@ -0,0 +1,261 @@ +import sys +import time +import random +import pygame +from pygame.locals import * +#游戏基本设定 +M = 15 #行数 +N = 15 #列数 +MINE_COUNT = 50 #雷数 + +class Mine: + def __init__(self, x, y, value=0): + self._x = x + self._y = y + self._value = 0 #咱先得创造一块空地嘛 + self._around_mine_count = -1 #表示周围的雷数 + self._status = 'normal' #格子状态, normal表示未被挖开. + self.set_value(value) + + def get_x(self): + return self._x + def set_x(self, x): + self._x = x + x = property(fget=get_x, fset=set_x) + def get_y(self): + return self._y + def set_y(self, y): + self._y = y + y = property(fget=get_y, fset=set_y) + + def get_value(self): + return self._value + def set_value(self, value): + if value: + self._value = 1 + else: + self._value = 0 + value = property(fget=get_value, fset=set_value) + + def get_around_mine_count(self): #周围雷数 + return self._around_mine_count + def set_around_mine_count(self, around_mine_count): + self._around_mine_count = around_mine_count + around_mine_count = property(fget=get_around_mine_count, fset=set_around_mine_count) + + def get_status(self): #格子状态(没挖, 挖了, 标记了等) + return self._status + def set_status(self, value): + self._status = value + status = property(fget=get_status, fset=set_status) +def _get_around(x, y): + return [(i, j) for i in range(max(0, x - 1), min(N - 1, x + 1) + 1) + for j in range(max(0, y - 1), min(M - 1, y + 1) + 1) if i != x or j != y] + #max()和min()应对边界的格子. + +class MineBlock: + def __init__(self): + self._block = [[Mine(i, j) for i in range(N)] for j in range(M)] + #用前面的Mine()类生成的列表和网格同构 + for i in random.sample(range(N * M), MINE_COUNT): # 进行一个雷的埋 + self._block[i // N][i % N].value = 1 #注意雷被赋值为1 + def get_block(self): + return self._block + block = property(fget=get_block) + + def getmine(self, x, y): #返回是0还是1 + return self._block[y][x] + def open_mine(self, x, y): #为了返回是否挖到雷, 挖到就饭后False, #悄悄催更某鸽子的爆炸电台, Bomb! + if self._block[y][x].value: + self._block[y][x].status = 'bomb' #标记为寄 + return False #1就会执行到这里, 这里是灵魂的终点 + self._block[y][x].status = 'opened' #否则咱先标记为open + around = _get_around(x, y) #前面定义的函数哈 + _sum = 0 #开始数雷 + for i, j in around: + if self._block[j][i].value: + _sum += 1 + self._block[y][x].around_mine_count = _sum + if _sum == 0: #周围都没雷要把一片都打开 + for i, j in around: + if self._block[j][i].around_mine_count == -1: + self.open_mine(i, j) #游戏开始最渴望的情况. + return True + def double_mouse_button_down(self, x, y): #左右鼠标同时按下 + if self._block[y][x].around_mine_count == 0: #是0就周围一圈都处理下 + return True + self._block[y][x].status = 'double' #状态设为双击ing + around = _get_around(x, y) + # 准备计算周围被标记的雷数量 + sumflag = 0 + for i, j in _get_around(x, y): + if self._block[j][i].status == 'flag': + sumflag += 1 + # 周边的雷已经全部被标记 + result = True + if sumflag == self._block[y][x].around_mine_count: + for i, j in around: + if self._block[j][i].status == 'normal': + if not self.open_mine(i, j): + result = False + else: #没标记完毕就闪烁一下 + for i, j in around: + if self._block[j][i].status == 'normal': #完成闪烁 + self._block[j][i].status = 'hint' + return result + def double_mouse_button_up(self, x, y): + self._block[y][x].status = 'opened' + for i, j in _get_around(x, y): + if self._block[j][i].status == 'hint': + self._block[j][i].status = 'normal' + +SIZE = 30 #每个方块的像素大小 +SCREEN_WIDTH = N * SIZE +SCREEN_HEIGHT = (M + 2) * SIZE + +def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)): + imgText = font.render(text, True, fcolor) + screen.blit(imgText, (x, y)) + +def main(): + pygame.init() + screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) + pygame.display.set_caption('扫雷') + #得分的字体 + font1 = pygame.font.Font('F:/Work/Python_Work/minesweeper-main/resources/a.TTF', SIZE * 2) + fwidth, fheight = font1.size('999') + red = (200, 40, 40) + #你也不想你的图片有大有小吧 + img0 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/0.bmp').convert() + img0 = pygame.transform.smoothscale(img0, (SIZE, SIZE)) + img1 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/1.bmp').convert() + img1 = pygame.transform.smoothscale(img1, (SIZE, SIZE)) + img2 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/2.bmp').convert() + img2 = pygame.transform.smoothscale(img2, (SIZE, SIZE)) + img3 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/3.bmp').convert() + img3 = pygame.transform.smoothscale(img3, (SIZE, SIZE)) + img4 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/4.bmp').convert() + img4 = pygame.transform.smoothscale(img4, (SIZE, SIZE)) + img5 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/5.bmp').convert() + img5 = pygame.transform.smoothscale(img5, (SIZE, SIZE)) + img6 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/6.bmp').convert() + img6 = pygame.transform.smoothscale(img6, (SIZE, SIZE)) + img7 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/7.bmp').convert() + img7 = pygame.transform.smoothscale(img7, (SIZE, SIZE)) + img8 = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/8.bmp').convert() + img8 = pygame.transform.smoothscale(img8, (SIZE, SIZE)) + img_blank = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/blank.bmp').convert() + img_blank = pygame.transform.smoothscale(img_blank, (SIZE, SIZE)) + img_flag = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/flag.bmp').convert() + img_flag = pygame.transform.smoothscale(img_flag, (SIZE, SIZE)) + img_ask = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/ask.bmp').convert() + img_ask = pygame.transform.smoothscale(img_ask, (SIZE, SIZE)) + img_mine = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/mine.bmp').convert() + img_mine = pygame.transform.smoothscale(img_mine, (SIZE, SIZE)) + img_blood = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/blood.bmp').convert() + img_blood = pygame.transform.smoothscale(img_blood, (SIZE, SIZE)) + img_error = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/error.bmp').convert() + img_error = pygame.transform.smoothscale(img_error, (SIZE, SIZE)) + face_size = int(SIZE * 1.25) + img_face_fail = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/face_fail.bmp').convert() + img_face_fail = pygame.transform.smoothscale(img_face_fail, (face_size, face_size)) + img_face_normal = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/face_normal.bmp').convert() + img_face_normal = pygame.transform.smoothscale(img_face_normal, (face_size, face_size)) + img_face_success = pygame.image.load('F:/Work/Python_Work/minesweeper-main/resources/face_success.bmp').convert() + img_face_success = pygame.transform.smoothscale(img_face_success, (face_size, face_size)) + + face_pos_x = (SCREEN_WIDTH - face_size) // 2 + face_pos_y = (SIZE * 2 - face_size) // 2 + img_dict = {0: img0, 1: img1, 2: img2, 3: img3, 4: img4, 5: img5, 6: img6, 7: img7, 8: img8} + bgcolor = (225, 225, 225) + block = MineBlock() + game_status = 'readied' + start_time = None + elapsed_time = 0 + while True: + screen.fill(bgcolor) + for event in pygame.event.get(): + if event.type == QUIT: + sys.exit() + elif event.type == MOUSEBUTTONDOWN: + mouse_x, mouse_y = event.pos + x = mouse_x // SIZE + y = mouse_y // SIZE - 2 + b1, b2, b3 = pygame.mouse.get_pressed() + if game_status == 'started': + if b1 and b3: + mine = block.getmine(x, y) + if mine.status == 'opened': + if not block.double_mouse_button_down(x, y): + game_status = 'over' + elif event.type == MOUSEBUTTONUP: + if y < 0: + if face_pos_x <= mouse_x <= face_pos_x + face_size \ + and face_pos_y <= mouse_y <= face_pos_y + face_size: + block = MineBlock() + start_time = time.time() + game_status = 'readied' + elapsed_time = 0 + continue + if game_status == 'readied': + game_status = 'started' + start_time = time.time() + elapsed_time = 0 + if game_status == 'started': + mine = block.getmine(x, y) + if b1 and not b3: + if mine.status == 'normal': + if not block.open_mine(x, y): + game_status = 'over' + elif not b1 and b3: + if mine.status == 'normal': + mine.status = 'flag' + elif mine.status == 'flag': + mine.status = 'ask' + elif mine.status == 'ask': + mine.status = 'normal' + elif b1 and b3: + if mine.status == 'double': + block.double_mouse_button_up(x, y) + flag_count = 0 + opened_count = 0 + for row in block.block: + for mine in row: + pos = (mine.x * SIZE, (mine.y + 2) * SIZE) + if mine.status == 'opened': + screen.blit(img_dict[mine.around_mine_count], pos) + opened_count += 1 + elif mine.status == 'double': + screen.blit(img_dict[mine.around_mine_count], pos) + elif mine.status == 'bomb': + screen.blit(img_blood, pos) + elif mine.status == 'flag': + screen.blit(img_flag, pos) + flag_count += 1 + elif mine.status == 'ask': + screen.blit(img_ask, pos) + elif mine.status == 'hint': + screen.blit(img0, pos) + elif game_status == 'over' and mine.value: + screen.blit(img_mine, pos) + elif mine.value == 0 and mine.status == 'flag': + screen.blit(img_error, pos) + elif mine.status == 'normal': + screen.blit(img_blank, pos) + print_text(screen, font1, 30, (SIZE * 2 - fheight) // 2 - 2, '%02d' % (MINE_COUNT - flag_count), red) + if game_status == 'started': + elapsed_time = int(time.time() - start_time) + print_text(screen, font1, SCREEN_WIDTH - fwidth - 30, (SIZE * 2 - fheight) // 2 - 2, '%03d' % elapsed_time, red) + if flag_count + opened_count == M*N: + game_status = 'win' + #给你脸了 + if game_status == 'over': + screen.blit(img_face_fail, (face_pos_x, face_pos_y)) + elif game_status == 'win': + screen.blit(img_face_success, (face_pos_x, face_pos_y)) + else: + screen.blit(img_face_normal, (face_pos_x, face_pos_y)) + pygame.display.update() + +if __name__ == '__main__': + main() \ No newline at end of file