扫雷小游戏

import pygame as pg
import random,time
import sys
#import pygame.transform
from enum import Enum     #枚举
from pygame.locals import *
BLOCK_WIDTH=30
BLOCK_HEIGHT=20
SIZE=30
MINE_COUNT=99
SCREEN_WIDTH=BLOCK_WIDTH*SIZE
SCREEN_HEIGHT=(BLOCK_HEIGHT+2)*SIZE
pg.init()
screen=pg.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
pg.display.set_caption("扫雷")
bgcolor=(255,255,255)
font1=pg.font.Font("./resources/msyh.ttf",SIZE*2)
fwidth,fheight=font1.size('999')
class BlockStatus(Enum):
    normal=1   #normal 正常的
    opened=2   #打开的
    flag=3      #旗子🚩
    ask=4      #不确定❓
    mine=5    #Landmine地雷
    bomb=6   #爆炸,在此代表踩中地雷
class GameStatus(Enum):
    ready=1
    start=2
    win=3
    over=4

def load_image(file,size):
    img=pg.image.load(file).convert()
    return pg.transform.smoothscale(img,(size,size))
face_size=int(SIZE*2)
img_face_normal=load_image("./resources/face_normal.bmp",face_size)
img_face_fail  =load_image("./resources/face_fail.bmp",face_size)
img_face_win   =load_image("./resources/face_win.bmp",face_size)

face_pos_x=(SCREEN_WIDTH-face_size)//2
face_pos_y=(SIZE*2-face_size)//2
def print_text(screen,font,x,y,text,color=(255,0,0)):
    imgText=font.render(text,True,color)
    screen.blit(imgText,(x,y))

#screen.blit(img_face_normal,(face_pos_x,face_pos_y))
class Mine():
    def __init__(self,row,column,value=0):
        self.row=row
        self.column=column
        self.value=value
        self.pos=(self.column*SIZE,(self.row+2)*SIZE)
        self.status=BlockStatus.normal  # status状态
        self.arround_mine_count=-1
        self.image=load_image("resources/normal.jpg",SIZE)
        #self.image=pg.image.load("resources/normal.jpg").convert()
        #self.image=pygame.transform.smoothscale(self.image,(SIZE,SIZE))
class MineBlock():
    def __init__(self):
        self.blocks=[Mine(r,c) for r in range(BLOCK_HEIGHT) \
                     for c in range(BLOCK_WIDTH)]
        mines=random.sample(range(BLOCK_WIDTH*BLOCK_HEIGHT),MINE_COUNT)
        for i in mines:
            self.blocks[i].value=1
    def getMine(self,row,column):
        return self.blocks[row*BLOCK_WIDTH+column]
    def get_around(self,r,c):
        return [(i,j) for i in range(max(0,r-1),min(BLOCK_HEIGHT,r+2)) \
                for j in range(max(0,c-1),min(BLOCK_WIDTH,c+2)) \
                if not (i==row and j==column)]
    def open_mine(self,r,c):
        mine=self.getMine(r,c)
        if mine.value==1:
            mine.status=BlockStatus.bomb      #bomb 拟声,爆炸
            for i in block.blocks:            #block 街区,方块
                if i.value==1:
                    i.status=BlockStatus.mine
                    i.image=load_image("./resources/mine.bmp",SIZE)
            mine.image=load_image("./resources/bomb.bmp",SIZE)
            return False
        #统计周围雷的数量
        mine.status=BlockStatus.opened
        around=self.get_around(r,c)
        sum=0
        for i,j in around:
            if self.getMine(i,j).value==1:
                sum+=1
        mine.arround_mine_count=sum

        if sum==0:
            mine.image=load_image("./resources/blank.bmp",SIZE)
            for i,j in around:
                if self.getMine(i,j).arround_mine_count==-1:
                    self.open_mine(i,j)
        elif mine.arround_mine_count==-1:
            pass
        else:
            mine.image=load_image(f"./resources/{mine.arround_mine_count}.bmp",SIZE)
        return True

block=MineBlock()
game_status=GameStatus.ready
flag_count=0                         #标记🚩数量
stat_time=spend_time=pause_time=0    #开始、花费、暂停时间归零


while True:
    screen.fill(bgcolor)
    screen.blit(img_face_normal, (face_pos_x, face_pos_y))
    #如果闯关成功,则显示笑脸和WIN!

    if game_status==GameStatus.win:
        screen.blit(img_face_win,(face_pos_x,face_pos_y))
        print_text(screen,font1,face_pos_x+face_size,-10,"WIN!")
    # 如果闯关失败,则显示哭脸和LOSE!

    elif game_status == GameStatus.over:
        screen.blit(img_face_fail, (face_pos_x, face_pos_y))
        print_text(screen, font1, face_pos_x + face_size, -10, "LOSE!")
    if game_status==GameStatus.start:
        spend_time=int(time.time()-start_time-pause_time)
        print_text(screen,font1,30,int((2*SIZE-fheight)/2),f"{spend_time}")
    elif game_status==GameStatus.ready and spend_time==0:
        print_text(screen, font1, 30, int((2 * SIZE - fheight) / 2), "0")
    else :
        print_text(screen, font1, 30, int((2 * SIZE - fheight) / 2), f"{spend_time}")
    flag_left=MINE_COUNT-flag_count
    print_text(screen,font1,SCREEN_WIDTH-fwidth,int((2*SIZE-fheight)/2), f"{flag_left}")
    open_count = 0

    for mine in block.blocks:
        screen.blit(mine.image,mine.pos)
        if mine.value==0 and mine.arround_mine_count!=-1:
            open_count+=1
    if open_count==BLOCK_HEIGHT*BLOCK_WIDTH-MINE_COUNT:
        game_status=GameStatus.win
    for event in pg.event.get():
        if event.type==QUIT:
            pg.quit()
            sys.exit()
        if event.type==MOUSEBUTTONDOWN:
            mouse_x,mouse_y=event.pos
            column=mouse_x//SIZE
            row=mouse_y//SIZE-2             #mouse🐀🖱
            b1,b2,b3=pg.mouse.get_pressed()  #press按,压
        if event.type==MOUSEBUTTONUP:
            if row>=0:
                mine=block.getMine(row,column)
                if game_status==GameStatus.ready:
                    game_status=GameStatus.start
                    start_time=time.time()
                elif game_status==GameStatus.start:
                    if b1 and not b3:
                        if not block.open_mine(row,column):
                            game_status=GameStatus.over
                    elif not b1 and b3:
                        if mine.status==BlockStatus.normal:
                            mine.status=BlockStatus.flag
                            mine.image=load_image("./resources/flag.bmp",SIZE)
                            flag_count+=1
                        elif mine.status==BlockStatus.flag:
                            mine.status=BlockStatus.ask
                            mine.image=load_image("./resources/ask.bmp",SIZE)
                            flag_count-=1
                        elif mine.status==BlockStatus.ask:
                            mine.status=BlockStatus.normal
                            mine.image=load_image("./resources/normal.jpg",SIZE)
            elif face_pos_x<mouse_x<face_pos_x+face_size and face_pos_y<mouse_y<face_pos_y+face_size:
                if game_status==GameStatus.start:
                    game_status=GameStatus.ready
                    pause_start=time.time()
                elif game_status==GameStatus.ready and spend_time!=0:
                    game_status=GameStatus.start
                    pause_end=time.time()
                    pause_time=int(pause_end-pause_start)
                elif game_status==GameStatus.win or game_status==GameStatus.over:
                    game_status=GameStatus.ready
                    block=MineBlock()
                    flag_count=0
                    start_time=spend_time=pause_time=0

    pg.display.flip()

python的扫雷游戏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值