見出し画像

Pythonのtkinterで画面込みでじゃんけんゲームを作成する

Pythonの標準モジュールtkinterを利用して、じゃんけんゲームをゲーム画面つきで作ってしまおうという回です。

1. 完成イメージ

画面は以下のとおりです。なお、イラストはフリー素材を利用させていただいています。(自分で写真とって利用してもいいかもですね!)

・トップ画面

画像1

・STARTボタン押下後

画像2

・ボタン押下で結果表示、再度やる場合は「もう一度」ボタンを押下

画像3

2. 画面の概要

画面は、最上部にtkinterのCanvasウィジェットを配置。
真ん中にボタン用のFrameウィジェットをおいて、最下部にメッセージ表示のためのFrameウィジェットをおいています。

画像切替は、Canvasのitemconfigureメソッドでコントロールしています。

canvasオブジェクト.itemconfigure(タグ名, image = 〇〇)

という処理をボタンに紐づけた機能の中で実施しています。

#スタートを押したら、トップ画像を消してじゃんけん画面を表示
def start_func(*arg):
   global image_think
   global hand_frame
   lb.delete(0,END)
       
   image_think = PhotoImage(file="janken_think.png")
   hand_canvas.itemconfigure("top_image", image = image_think)
   hand_canvas.create_text(200,50, text="", font=("MSゴシック", 20), tag="image_message")
   hand_canvas.itemconfigure("image_message", text = "")
   hand_button_style = ttk.Style()
   hand_button_style.configure(
                               "hand_button.TButton",
                               font = ("MSゴシック", 14)
                                                   )
   hand_frame = ttk.Frame(root, style="menu_frame.TFrame")
   hand_frame.grid(row=2, column=0, sticky=(W,E))
   button_rock= ttk.Button(hand_frame,
                                text = "グー",
                                style = "hand_button.TButton",
                                padding = [7.5],
                                command = rock
                                )
   button_rock.grid(row=0, column= 0,sticky=(W,E))
   button_scissors = ttk.Button(hand_frame,
                                text = "チョキ",
                                style = "hand_button.TButton",
                                padding = [7.5],
                                command = scissors
                                )
   button_scissors.grid(row=0, column = 1,sticky=(W,E))
   button_paper = ttk.Button(hand_frame,
                                text ="パー",
                                style = "hand_button.TButton",
                                padding = [7.5],
                                command = paper
                                )
   button_paper.grid(row=0, column = 2, sticky=(W,E))
   lb.insert(END, "自分の手を選んでください")
   
   #スタートフレームを削除
   start_frame.destroy()

スタ―トボタンを押下した際の機能は、上記のように作成しています。
以下の部分でCanvasのimageを切り替えています。

予めimage変数に格納した、イメージファイル(この場合はjanken_think.pngというファイル)を設定しています。

hand_canvas.itemconfigure("top_image", image = image_think)

同時にhand_frameを作成し、グー・チョキ・パーのボタンを作成・配置しています。

3. じゃんけん機能

じゃんけん部分は、以下のような機能で作成しています。

まずは手の形として、グー・チョキ・パーの文字列を格納したリストを用意し、コンピュータ側の手を選ぶpc_hand関数を定義しています。

最下部はグーボタンを押した場合のプログラムです。(lb.insertについては後述します。)チョキ・パーそれぞれに機能を用意しています。

#handsリストを定義(global変数)
global hands
hands = ['グー', 'チョキ', 'パー']

#cpu_hand変数を定義(global変数)
global cpu_hand

#じゃんけんの手の画像定義
global image_rock
image_rock = PhotoImage(file="janken_rock.png")
global image_scissors
image_scissors = PhotoImage(file="janken_scissors.png")
global image_paper
image_paper = PhotoImage(file="janken_paper.png")
global cpu_hand_images
cpu_hand_images = {"グー" : image_rock, "チョキ" : image_scissors, "パー" : image_paper}

#コンピュータの手を選ぶ
def  pc_hand(*arg):
   cpu_hand = random.choice(hands)
   return cpu_hand

#グーボタン機能
def rock(*arg):
   player_hand = "グー"
   lb.insert(END, "あなたはグーを出しました!")
   cpu_hand = pc_hand()
   cpu_hand_image = cpu_hand_images[cpu_hand]
   hand_canvas.itemconfigure("top_image", image = cpu_hand_image)
   hand_canvas.itemconfigure("image_message", text = "相手の手は・・・")
   time.sleep(0.3)
   if cpu_hand == "グー":
       lb.insert(END, "あいこです")
   elif cpu_hand == "チョキ":
       lb.insert(END, "勝ちました!")
   else:
       lb.insert(END, "残念、負けました!")
   hand_canvas.create_window(200,350,window=restart_button)
   hand_frame.grid_forget()

(1) 手を選択した際の、Canvasへの画像表示切替

コンピュータの手を画像として、Canvasに表示。
予め、辞書形式で用意しておいたグー・チョキ・パーのイメージファイルを格納したものをもとに、表示画像を選んでいます。

cpu_hand = pc_hand
cpu_hand_image = cpu_hand_images[cpu_hand]
hand_canvas.itemconfigure("top_image", image = cpu_hand_image)

(2) 勝敗判定とメッセージ表示

プレイヤーの手とコンピュータの手で、勝敗を判定。

if cpu_hand == "グー":
   lb.insert(END, "あいこです")
elif cpu_hand == "チョキ":
   lb.insert(END, "勝ちました!")
else:
   lb.insert(END, "残念、負けました!")
hand_canvas.create_window(200,350,window=restart_button)
hand_frame.grid_forget()

なお、グー・チョキ・パーボタンを表示している、hand_frameはgrid_forgetメソッドで非表示にしています。

4. メッセージ表示方法

今回、ゲームに関するメッセージは、ListBoxウィジェットに表示しています。

Listboxは以下のように作成・配置しています。

#messagesリストを定義(global変数)
global messages
messages = ['STARTボタンを押してください']

#メッセージフレーム作成・配置
message_frame=ttk.Frame(root, style="menu_frame.TFrame")
message_frame.grid(row=3, column=0, sticky=(W,E))

#Listboxを作成
global lb
global message_v
message_v = StringVar(value=messages)
lb = Listbox(message_frame, listvariable=message_v, height=20,width=66)
lb.grid(row=0, column=0,sticky=(W,E,N,S))

リスト形式で、messages変数を定義。用意したmessage_frameの子要素としてListboxを作成・配置。

lbという変数に、Listboxを格納しグローバル変数とすることで他の機能(関数)からもアクセスできるようにしています。

4. コード全文

以下がコード全文です。まずは写経して、自分でプログラムを動かしながら習得したいよ、という方にオススメします。

但し、ドキュメントやブログ等複数のWebページを自分で参照してまとめれば実装できる内容かと思いますので、あくまでその手間を省いて効率的に学習したい方が対象です。

ここから先は

6,490字

¥ 300

この記事が気に入ったらサポートをしてみませんか?