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


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

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

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

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

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

from tkinter import *

####メイン画面の生成####
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)

####マス目の作成####
def left_click(event):
    event.widget.configure(relief = 'ridge', bd = '1')
    print(event.widget.num)

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

root.mainloop()

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

【STEP5】地雷を配置する場所を決める

次はゲームの要でもある、地雷の配置場所を決めていきましょう。
以下のルールを実装していきます。

・最初にクリックしたところは絶対地雷ではない
・それ以外の場所からランダムに決める

という感じですね。実際のマインスイーパーも最初のマスは必ず開くことができます。
また今はとりあえず初級編を作成したいので、9×9=81マスの中から10ヶ所ランダムで
地雷を配置したいと思います。

ランダムな値を生成するために、まずrandomモジュールをインポートする必要がありますね!
一番上に書いておきましょう

from tkinter import *
import random   #追加する

それでは地雷の配置を行うコードを書いていきましょう!
一つ目のマスをクリックした際に地雷の位置を決定しますので、上のコードの30行目
周辺を変更していきます。

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

def left_click(event):
    event.widget.configure(relief = 'ridge', bd = '1')
    except_num = event.widget.num
    #地雷が配置されていない最初のクリックの時に呼ばれる
    if len(bomb_list) == 0:
        #地雷の個数が10コになるまで繰り返し呼ばれる
        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')

2行目で、まず地雷の配置場所を格納するリストを作成しておきます。
4行目~5行目は今までと変化ナシで、その次にあったprint文はいらないので消しました。
代わりに6行目でクリックしたマス目の番号を新しくexcept_numという変数で取得しています。

8行目以降に条件if文を追加しています。
8行目の条件からbomb_listが空の時、つまり地雷の配置場所が決まっていない
時にだけこの条件文が呼ばれます。つまり最初のクリックの時だけになりますね。

10行目からの繰り返しwhile文は、bomb_listに10コ数値が格納されるまで反復されます。
11行目でrandomモジュールのrandintメソッドを使ってランダムな整数値を生成しています。
randintメソッドは2つの引数を取り、その間の値をランダムで生成します。
上記例では0から80までの値を取ります。マス目の番号と同じになるようにします。

13行目でまた条件if文です。
条件が少し複雑ですが、andの前の条件(bomb_num != except_num)で、生成したランダムな
値がクリックしたマスとは違う判定をしています。
andの後ろの条件((bomb_num in bomb_list) == False)で、地雷がすでにappendされてbomb_list
に格納されていないかの判定をしています。重複した値が格納されないようにするためですね。

15行目~16行目の繰り返しfor文は確認のためです。
iにはbomb_listに格納されている数値、つまり地雷の位置が繰り返し代入され、
そのマス目の背景色を赤色に変えてくれます。

これで実際に実行して確認してみましょう。

どこか1つのマスをクリックすると(下の例ではframe_list[12]をクリックしています)、

このように10ヶ所赤色に変化しました!
地雷の位置をランダムに生成しているため、実行するたびに赤色になる部分が変わるはずです。
ぜひ何度も試してみてください。

今回はこれでおしまいです。
次回は周りに何個の地雷があるのか判定する機能を追加しましょう。

  • このエントリーをはてなブックマークに追加

PAGE TOP