Tips

【pythonゲーム作成】pythonでマインスイーパー作ってみるよ【その7】

【pythonゲーム作成】pythonでマインスイーパー作ってみるよ【その7】

【pythonゲーム作成】pythonでマインスイーパー作ってみるよ【その7】

今回はpythonでシンプルなマインスイーパーを作成してみたいと思います。
windowsに搭載されていた昔ながらのマインスイーパーを目指してみます!

おなじみのこんなやつ
↓↓↓

tkinterモジュールでは完全再現とまではいきませんが、なるべく似ているものを
作れるようにしていきたいと思います!

前回までのコード(コメント多くなりすぎたので、少なくしました)
↓↓↓

from tkinter import *
import random   #追加する

####メイン画面の生成####
root = Tk()
root.title("マインスイーパ")
root.resizable(0,0)

###メニュー作成###
menu_ROOT = Menu(root)
root.configure(menu = menu_ROOT)

menu_GAME = Menu(menu_ROOT, tearoff = False)
menu_ROOT.add_cascade(label = 'ゲーム(G)', under = 4, menu = menu_GAME)

menu_GAME.add_command(label = "初級(B)", under = 3)
menu_GAME.add_command(label = "中級(I)", under = 3)
menu_GAME.add_command(label = "上級(E)", under = 3)

menu_ROOT.add_command(label = "終了(X)", under = 3)

###フレームオブジェクト作成###
root_frame = Frame(root, relief = 'groove', borderwidth = 5, bg = 'LightGray')
status_frame = Frame(root_frame, height = 50, relief = 'sunken', borderwidth = 3, bg = 'LightGray')
game_frame = Frame(root_frame, relief = 'sunken', borderwidth = 3, bg = 'LightGray')
root_frame.pack()
status_frame.pack(pady = 5, padx = 5, fill = 'x')
game_frame.pack(pady = 5, padx = 5)

####マス目の作成####
bomb_list = []

def left_click(event):
    event.widget.configure(relief = 'ridge', bd = '1')
    except_num = event.widget.num
    if len(bomb_list) == 0:
        while len(bomb_list) != 10:
            bomb_num = random.randint(0,80)
            if bomb_num != except_num and (bomb_num in bomb_list) == False:
                bomb_list.append(bomb_num)
        for i in bomb_list:
            frame_list[i].configure(bg = 'red')
    bomb_count = search_bomb(bomb_list, event.widget.num)
    if  bomb_count == 9 :
        print('地雷')
    else:
        print(bomb_count)

i = 0
frame_list = []
for x in range(9):
    for y in range(9):
        frame = Frame(game_frame, width = 30, height = 30, bd = 3, relief = 'raised', bg = 'LightGray')
        frame.bind("<1>", left_click)
        frame.num = i
        frame_list.append(frame)
        frame.grid(row=x, column=y)
        i += 1

def search_bomb(list, num):
    around_list = []
    bomb_count = 0
    if num in list:
        return 9
    if num % 9 == 0:
        around_list.append(num-9)
        around_list.append(num-8)
        around_list.append(num+1)
        around_list.append(num+9)
        around_list.append(num+10)
    elif num % 9 == 8:
        around_list.append(num-10)
        around_list.append(num-9)
        around_list.append(num-1)
        around_list.append(num+8)    
        around_list.append(num+9)    
    elif num < 9:
        around_list.append(num-1)
        around_list.append(num+1)
        around_list.append(num+8)
        around_list.append(num+9)
        around_list.append(num+10)
    elif num > 72:
        around_list.append(num-10)
        around_list.append(num-9)
        around_list.append(num-8)
        around_list.append(num-1)
        around_list.append(num+1)
    else:
        around_list.append(num-10)
        around_list.append(num-9)
        around_list.append(num-8)
        around_list.append(num-1)
        around_list.append(num+1)
        around_list.append(num+8)
        around_list.append(num+9)
        around_list.append(num+10)
    for i in around_list:
        if i in list:
            bomb_count += 1
    return bomb_count

root.mainloop()

それでは、レッツスタート!!

【STEP7】一度クリックした箇所はクリックできないように&

地雷をクリックしたらそれ以降クリックできないようにする

さて、現状ではマス目をクリックするとそのマス目の周囲の地雷数が
printによってコンソール上に出力されます。

しかし上図のように、同じマス目を何度もクリックできてしまいます。
また、地雷となる赤色部分をクリックすると「地雷」と表示されますが、
それ以降もマス目をクリックし続けることができてしまいますね。

今回は、

・1度クリックしたマス目はクリックできないようにする
・地雷をクリックしたらすべてのマス目をクリックできないようにする

という2つを実装したいと思います。

44行目~47行目の部分を修正していきます。

    if  bomb_count == 9 :
        print('地雷')
        for i in frame_list:
            i.bind("<1>", stop)
    else:
        print(bomb_count)
        event.widget.bind("<1>", stop)

3行目4行目で地雷マスをクリックしてしまった場合、全てのマス目に対して左クリック時のイベントを
新しいイベントstopに割り当てなおしています。
7行目ではクリックしたマス目に対してだけ同様に新しいイベントstopを割り当てています。

また、新しい関数stopも定義してあげましょう。
上のコードの101行目と103行目の間に以下のコードを記述してください。

def stop(event):
    pass

関数定義のブロックには、何も処理を行わないことを表すpassを記述します。
これで左クリックしても何も処理が行われなくなるので、マス目は1回しかクリックできなく
なりますし、地雷をクリックした際にはゲームがストップしたように見せることができますね!

今回はこれで終わりです。
次回は、周囲の地雷の数をコンソール上ではなくマス目に表示するようにしたいと思います。

新連載はじまりました!独学で学ぶPython基礎 連載リンク

独学で学ぶ-Pythonプログラミング 連載

Recent News

Recent Tips

Tag Search