002.07  MineSweeper - PySimleGUI 的应用 
                                                    
                        
                    
                    
  
                    
                    建檔日期: 2019/12/07
更新日期: None
相关软件信息:
| Win 10 | Python 3.7.2 | PySimpleGUI 4.6.0 | 
说明:所有内容欢迎引用,只需注明来源及作者,本文内容如有错误或用词不当,敬请指正.
主题: 002.07 MineSweeper - PsSimleGUI 的应用
还是用PySimpleGU来写一个常见的游戏MineSweeper, 其中PySimpleGUI Button没有提供鼠标右键功能下, 自己加了个event handler来处理, 其他没啥好说, 请见下文.
鼠标右键Event Handler
def right_click(self, event): # Right_click handler
 if self.state == 1:
 self.update(3)
 elif self.state == 3:
 self.update(1)
window[b[x][y].key].Widget.bind('<Button-3>', b[x][y].right_click)游戏方法:
- 鼠标左键点选, 显示数字或炸弹, 数字的意义为’周围有多少颗炸弹’.
- 鼠标右键点选, 以旗子标记自己认为是炸弹的格子, 鼠标左键不可点选显示, 再点选则去除标记.
- 上方记录炸弹总数, 已点到炸弹总数, 以及旗子总数, 后两者数目等于前者时, 游戏结束
游戏目标:
游戏画面:

代码:
import PySimpleGUI as sg
import random
import sys
'''
Source code of MineSweeper Game
'''
font        = 'Courier 16 bold'
width       = 25
height      = 14
all         = 80
new_start   = True
size        = (30,30)
# 0: 0, 1: hidden card, 2: bomb card, 3: flag card, 4: shown card
im          = ['', 'blank.png', 'bomb.png', 'flag.png', '']
color       = [('grey', 'grey'), ('black', 'green'),
               ('black', 'green'), ('black', 'green'), ('black', 'grey')]
def binding_all():                  # Bind right button of mouse to cell object
    for x in range(width):
        for y in range(height):
            window[b[x][y].key].Widget.bind(
                '<Button-3>', b[x][y].right_click)
# Setting for top buttons
def button1(text, key=None, disabled=False, button_color=('white', 'green')):
    return sg.Button(text, pad=(10, 10), font=font, focus=False, key=key,
            disabled=disabled, button_color=button_color)
def button2(x, y):                  # define cell as instance of button and
    b[x][y] = button(x,y)           # bulid Button
    return b[x][y].button
def check_blank(x, y):              # Check if cell near 0-bomb cel
    if b[x][y].num==0: return False
    for i in [-1, 0, 1]:
        for j in [-1, 0, 1]:
            if i==0 and j==0: continue
            if ((0<=x+i<width) and (0<=y+j<height) and
                (b[x+i][y+j].num==0)): return True
    return False
def check_num():                    # check number of bombs, flags and hides
    bomb_count = flag_count = hide_count = 0
    for x in range(width):
        for y in range(height):
            if b[x][y].state == 1:
                hide_count += 1
            elif b[x][y].state == 2:
                bomb_count += 1
            elif b[x][y].state == 3:
                flag_count += 1
    return bomb_count, flag_count, hide_count
# Count number of bombs about cell
def count_bomb(x, y):
    global bomb
    if bomb[x][y]==10: return 10
    count = 0
    for i in [-1, 0, 1]:
        for j in [-1, 0, 1]:
            if i==0 and j==0: continue
            if ((0<=x+i<width) and (0<=y+j<height) and
                (bomb[x+i][y+j]==10)):
                count += 1
    return count
# set position for all boms
def deal():
    global bomb
    bomb_list   = random.sample(range(width*height), all)
    bomb        = [[0 for y in range(height)] for x in range(width)]
    for x in range(width):
        for y in range(height):
            if x*height+y in bomb_list: bomb[x][y]=10
    for x in range(width):
        for y in range(height):
            bomb[x][y] = count_bomb(x, y)
    return
def new_card():                     # refresh all cells to hidden card
    for x in range(width):
        for y in range(height):
            b[x][y].state = 1
            b[x][y].num = bomb[x][y]
            b[x][y].color = color[1]
            b[x][y].update(1)
def show_blank():                   # Show all cell not around by any bomb
    for x in range(width):
        for y in range(height):
            if b[x][y].num == 0:
                b[x][y].update(0)
            elif check_blank(x, y):
                b[x][y].update(4)
# Class for each button object
class button():
    def __init__(self, x, y):
        self.x          = x
        self.y          = y
        self.state      = 1
        self.color      = color[self.state]
        self.disabled   = False
        self.key        = 'Button{:0>2d}{:0>2d}'.format(x, y)
        self.num        = bomb[x][y]
        self.button     = sg.Button(' ',
            auto_size_button=False,
            border_width=2,
            button_color=self.color,
            disabled=self.disabled,
            focus=False,
            font=font,
            image_size=size,
            image_filename=im[self.state],
            key=self.key,
            pad=(1,1))
    def right_click(self, event):   # Right_click handler
        if self.state == 1:
            self.update(3)
        elif self.state == 3:
            self.update(1)
    def update(self, state):        # update state of cell
        self.state = state
        if state == 0:
            self.disabled = True
            text = ' '
        elif state in [1,2,3]:
            self.disabled = False
            text = ' '
        elif state == 4:
            self.disabled = True
            text = str(self.num)
        self.color = color[self.state]
        window[self.key].TKButton['disabledforeground'] = 'white'
        self.button.Update(text=text, disabled=self.disabled,
            image_filename=im[self.state], image_size=size,
            button_color=self.color)
# Check platform, only for Windows. Maybe wrok on other platform
if not sys.platform.startswith('win'):
    sg.popup_error('Sorry, you gotta be on Windows')
    sys.exit(0)
# set theme for window
sg.change_look_and_feel('DarkGreen')
deal()  # Initial position of bombs
b = [[0 for j in range(height)] for i in range(width)]
layout  = [[button1('New Game', key='-New Game-'),  # Layout of window
            button1('Game Over', key='-Game Over-'),
            button1('Target:'+str(all), key='-Target-'),
            button1('Bomb:0', key='-Count-Bomb-'),
            button1('Flag:0', key='-Count-Flag-')]]+[
            [button2(x, y) for x in range(width)] for y in range(height)]
window = sg.Window('MineSweeper', layout=layout).Finalize() # Create window
binding_all()       # Binding right button event handler of all cells
show_blank()        # Show all cells near no-bomb cell
new_start   = True  # Flag for new game
message     = False # Flag for game over message sent
while True:
    if new_start:   # Actions for new game
        deal()
        new_card()
        show_blank()
        message = False
        new_start = False
        pass
    event, values = window.read(timeout=100)    # read window event
    if event==None or event=='-Game Over-':     # Window close / Game over
        break
    elif event == '-New Game-':                 # New Game, set the flag
        new_start = True
    elif event[:6] == 'Button':                 # Left button clicked
        x, y = int(event[6:8]), int(event[8:10])
        if b[x][y].state == 1:
            if b[x][y].num == 10:
                b[x][y].update(2)
            else:
                b[x][y].update(4)
    # Update number onf bombs, flags
    bomb_num, flag_num, hide_num = check_num()
    window['-Count-Bomb-'].Update(text='Bomb:'+str(bomb_num))
    window['-Count-Flag-'].Update(text='Flag:'+str(flag_num))
    # Check if game over
    if hide_num==0 and (bomb_num+flag_num==all) and (not message):
        message = True
        sg.popup('Game Over', title='Note')
window.close()链结
drive.google.com/open?id=1J9i_tUK3...
本作品采用《CC 协议》,转载必须注明作者和本文链接
 
           Jason990420 的个人博客
 Jason990420 的个人博客
         
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: