Pythonアプリ(8):神経衰弱を作ろう
トランプゲームの神経衰弱を作ってみましょう。
ふたつの札(ふだ)をめくって、絵柄が同じだとめくった状態になり、間違えると元に戻ります。
まずは画像を使わないバージョンを作ってみます。
1. 札(ふだ)を並べよう
札はボタンで表現します。
電卓のときと同じ要領で4×4のタイル状に並べましょう。 b.grid(i % 4, i // 4)
の部分の意味がわからなかったら「Pythonアプリ(6):電卓を作ろう」を読んで下さい。
from tentoapp import *
app = App()
for i in range(16): b = Button(app) b.text = "オモテ" b.grid(i % 4, i // 4)
app.start()
2. 「ウラ」を作ろう
次に、札をクリックすると札がめくれて裏の数字が表示されるようにしましょう。 数字は、0から7とします。札が16枚あるので、裏の数字の種類は8個になります。
from tentoapp import *from random import shuffle
app = App()
def click(e): button = e.widget button.text = button.ura
ura_list = [0,1,2,3,4,5,6,7] * 2shuffle(ura_list)
for i in range(16): b = Button(app) b.text = "オモテ" b.ura = ura_list[i] b.onclick = click b.grid(i % 4, i // 4)
app.start()
2.1 裏の数字をランダムにする
裏の数字は、0~7ですが、それぞれ2個ずつ計16個になります。これをリスト ura_list
に入れます。 [0,1,2,3,4,5,6,7] * 2
は、リスト [0,1,2,3,4,5,6,7]
を2つ重ねるといういみです。毎回同じ順番ではゲームにならないので、 random
モジュールの shuffle()
(シャッフル)を使って中身をシャッフルしています。
ura_list = [0,1,2,3,4,5,6,7] * 2shuffle(ura_list)
次に、それぞれのボタンに ura_list
の数字を割り当てます。ここでは、 b.ura
として、ボタンに ura
という変数を新しく作ってそこに数字を代入しています。
for i in range(16): ... b.ura = ura_list[i]
2.2 クリックされたら文字を変える
ボタンがクリックされたら、数字を表示して札が「裏返った」ことを表現します。ここで先程設定したボタンの変数 ura
を用います。
def click(e): button = e.widget button.text = button.ura
3. 札を比べよう
次にいよいよ、神経衰弱の仕組みの部分を作ります。札をクリックしたとき、すでに裏返っている札があったらそれと比較するようにします。
from tentoapp import *from random import shuffle
app = App()
saisho = Nonedef click(e): global saisho button = e.widget button.text = button.ura if saisho == None: saisho = button else: if saisho.ura != button.ura: saisho.text = "オモテ" button.text = "オモテ" saisho = None
ura_list = [0,1,2,3,4,5,6,7] * 2shuffle(ura_list)
for i in range(16): b = Button(app) b.text = "オモテ" b.ura = ura_list[i] b.onclick = click b.grid(i % 4, i // 4)
app.start()
3.1 札をクリックした時の動作
札をクリックしたらこのような流れになります。
- まず札を裏返す
- 最初に裏返っている札があるかどうか調べる
- 最初に裏返っている札がなければ
- 今回の札を最初の札にする
- 最初に裏返っている札があったら
- 同じ数字だったらなにもしない(両方とも裏返ったままにする)
- 同じ数字ではなかったら両方とも元に戻す
- 最初に裏返っている札がなければ
saisho = Nonedef click(e): global saisho button = e.widget button.text = button.ura if saisho == None: saisho = button else: if saisho.ura != button.ura: saisho.text = "オモテ" button.text = "オモテ" saisho = None
saisho = None
ではすでに裏返っている札を代入するための saisho
という変数を作り、 None
を代入しています。 None(ナン) はなにもない、と言う意味です。 そのあとは、 saisho
が設定されていなければ今の札を代入し、設定されていれば今の札と比較します。設定されている場合は、次の比較に移るので saisho
をふたたびNoneにするのを忘れないでください。
4. 時間差をつけよう
ここまでで、二つの札の数字が同じだったらひっくり返すことはできるようになりましたが、二枚目の札が間違っていた場合すぐにもとに戻ってしまい、二枚目の札がなんなのか見ることができません。そこで、 app.after()
を使って、1秒後にもとに戻すようにします。
from tentoapp import *from random import shuffle
app = App()saisho = None
def click(e): global saisho button = e.widget button.text = button.ura if saisho == None: saisho = button else: if saisho.ura != button.ura: app.after(1000,clear,saisho) app.after(1000,clear,button) saisho = None
def clear(button): button.text = "オモテ"
ura_list = [0,1,2,3,4,5,6,7] * 2shuffle(ura_list)
for i in range(16): b = Button(app) b.text = "オモテ" b.ura = ura_list[i] b.onclick = click b.grid(i % 4, i // 4)
app.start()
4.1 click関数の修正
button.text = "オモテ"
を1秒後に実行するために、 clear()
関数を作って app.after()
から呼び出しています。
def click(e): global saisho button = e.widget button.text = button.ura if saisho == None: saisho = button else: if saisho.ura != button.ura: app.after(1000,clear,saisho) app.after(1000,clear,button) saisho = None
def clear(button): button.text = "オモテ"
やってみよう!
1. 裏返っている札のクリック☆
今のままでは、裏返っている札もクリックできてしまうので以下のような不具合が出てしまいます。裏返った札をクリックしても何も起こらないように修正して下さい。
(1) 同じ画像を連続でクリックすると裏返しのままになってしまう
(2) すでに正解した札もクリックできてしまう。(正解した札ももとに戻せてしまう)
2. 文字の代わりに画像を表示しよう☆☆
ボタンに文字ではなく、画像を表示して下さい。
オモテ用画像
ウラ用画像
3. 対戦できるようにしよう☆☆☆
二人で対戦できるようにして下さい。先手番か後手番かを表示し、また点数を表示して下さい。