授業動画
Day 05th注意
課題注意
LUNAへ提出された課題には,ちゃんと意図通りに動いてないのがたくさんある.最後まできっちりしてください.
Pythonでは字下げ(indent, tab)に特別な意味がありますから注意ね.
- シフト選択で複数行を一括選択
- 複数行インデント挿入: Ctrl + ]
- 複数行インデント削除: Ctrl + [
見るところ
- 変数,配列,制御,method
- 何が読みやすいコードか?
1 def check_hit_and_blow(answer, trial):
2 print(answer, trial)
3 blow, hit = 0, 0
4 answer = answer[:] # 浅いコピー
5 for i in range(len(trial)):
6 if int(trial[i]) == answer[i]:
7 answer[i] = None
8 hit +=1
9 for i in range(len(trial)): # change this loop
10 for j in range(len(answer)):
11 if answer[i] is not None and int(trial[i]) == answer[j]:
12 answer[j] = -1
13 blow+=1
14 break
15 return hit, blow
Day 06th(5/31): c6(Tk版)
macのための準備
-
conda install tk
- tkinter.mainloop()をcodeの最後につける必要あり.
最初
まずはtkの表示からcodingしていきます.
import tkinter as tk
root = tk.Tk()
root.geometry("400x150")
root.title("数あてゲーム")
root.mainloop()
少し打ったら,すぐに結果を確認する癖をつけてください.そうすれば,間違いが混入してもすぐにその場所が特定できるから.
途中まで06-04
ゲームの雛形が出来上がった段階です.全体の流れを確認してください.この後は,ButtonClickに中身を書いていくだけです.
1 import tkinter as tk
2 import tkinter.messagebox as tmsg
3
4 def ButtonClick():
5 b = editbox1.get()
6 tmsg.showinfo("入力されたテキスト", b)
7
8 root = tk.Tk()
9 root.geometry("400x150")
10 root.title("数あてゲーム")
11
12 label1 = tk.Label(root, text="数を入力してね", font=("Helvetica", 14))
13 label1.place(x=20, y=20)
14
15 editbox1 = tk.Entry(width=4, font=("Helvetica", 28))
16 editbox1.place(x=120, y=60)
17
18 button1 = tk.Button(root, text="チェック", font=("Helvetica", 14), command=ButtonClick)
19 button1.place(x=220, y=60)
20
21 root.mainloop()
- 最初から順にTkの要素を増やしていきます
- place
- line:21 root.mainloopはいちばん下に.
- line:18 tk.Buttonでcommandを付けるのを忘れないように
コツですが,英語の綴りに自信がないときは,VSCodeのsuggestionから選択するのが正解.英語が上達してくると綴りミスに気がつくようになりますが,そこはNativeに負けるんで,エディターの補助機能を活用しましょう.
最終形
先週やったtext版のwhile-loopをButtonClickに入れます.ただし,printはtmsgに置き換えます.
1 import tkinter as tk
2 import tkinter.messagebox as tmsg
3
4 import random
5
6
7 def ButtonClick():
8 b = editbox1.get()
9 isok = False
10 while isok == False:
11 #b = input("数を入れてね>")
12 if len(b) != 4:
13 tmsg.showerror("エラー", "4桁の数字をいれてね")
14 else:
15 kazuok = True
16 for i in range(4):
17 if ((b[i] < "0") or (b[i] > "9")):
18 tmsg.showerror("b["+str(i)+"]は数字ではありません.")
19 kazuok = False
20 break
21 else:
22 isok = True
23
24 hit = 0
25 for i in range(4):
26 if a[i] == int(b[i]):
27 hit = hit + 1
28
29 blow = 0
30 for j in range(4):
31 for i in range(4):
32 if (int(b[j]) == a[i]) and (int(b[i]) != a[i]) and (int(b[j]) != a[j]):
33 blow = blow + 1
34 break
35
36 tmsg.showinfo("ヒント", "hit:"+str(hit)+"/blow:"+str(blow))
37
38 if hit == 4:
39 tmsg.showinfo("あたり", "おめでとうさん.あたりでっせ.")
40 # print("当たり")
41 root.destroy()
42
43
44 #random.seed(0)
45 a = [random.randint(0, 9),
46 random.randint(0, 9),
47 random.randint(0, 9),
48 random.randint(0, 9)]
49 print(a)
50 # print(str(a[0])+str(a[1])+str(a[2])+str(a[3]))
51
52 root = tk.Tk()
53 root.geometry("400x150")
54 root.title("数あてゲーム")
55
56 label1 = tk.Label(root, text="数を入力してね", font=("Helvetica", 14))
57 label1.place(x=20, y=20)
58
59 editbox1 = tk.Entry(width=4, font=("Helvetica", 28))
60 editbox1.place(x=120, y=60)
61
62 button1 = tk.Button(root, text="チェック", font=(
63 "Helvetica", 14), command=ButtonClick)
64 button1.place(x=220, y=60)
65 root.mainloop()
あ,これコピペしたらダメよ.だいぶテキストと違うんで,すぐバレるから.
動かしてみて,errorが出るlineを修正していってください.注意すべき箇所は,
- line:4のimport
- line:11のbは消す
- line:13のtmsg
- line:18のtmsg
- line:36のtmsg
- line:39のtmsg
- line:41のroot.destroy()
- lines:44-50の数の生成とprintのコメントアウト
さらに履歴表示
テキストにある履歴表示を加えています.
- line:59でrirekiboxを生成
- line:37でrirekiboxに情報をinsertしています.
1 import tkinter as tk
2 import tkinter.messagebox as tmsg
3
4 import random
5
6
7 def ButtonClick(event=None):
8 b = editbox1.get()
9 isok = False
10 while isok == False:
11 #b = input("数を入れてね>")
12 if len(b) != 4:
13 tmsg.showerror("エラー", "4桁の数字をいれてね")
14 return
15 else:
16 kazuok = True
17 for i in range(4):
18 if ((b[i] < "0") or (b[i] > "9")):
19 tmsg.showerror("b["+str(i)+"]は数字ではありません.")
20 kazuok = False
21 return
22 else:
23 isok = True
24
25 hit = 0
26 for i in range(4):
27 if a[i] == int(b[i]):
28 hit = hit + 1
29
30 blow = 0
31 for j in range(4):
32 for i in range(4):
33 if (int(b[j]) == a[i]) and (int(b[i]) != a[i]) and (int(b[j]) != a[j]):
34 blow = blow + 1
35 break
36
37 rirekibox.insert(tk.END, b + " h:"+str(hit)+"b:"+str(blow)+"\n")
38
39 if hit == 4:
40 tmsg.showinfo("あたり", "おめでとうさん.あたりでっせ.")
41 # print("当たり")
42 root.destroy()
43
44
45 # random.seed(0)
46 a = [random.randint(0, 9),
47 random.randint(0, 9),
48 random.randint(0, 9),
49 random.randint(0, 9)]
50 # print(a)
51 # print(str(a[0])+str(a[1])+str(a[2])+str(a[3]))
52
53 root = tk.Tk()
54 root.geometry("600x800")
55 root.title("数あてゲーム")
56 root.bind('<Return>', ButtonClick)
57
58 rirekibox = tk.Text(root, font=(("Helvetica", 14)))
59 rirekibox.place(x=400, y=0, width=200, height=800)
60
61 label1 = tk.Label(root, text="数を入力してね", font=("Helvetica", 14))
62 label1.place(x=20, y=20)
63
64 editbox1 = tk.Entry(width=4, font=("Helvetica", 28))
65 editbox1.place(x=120, y=60)
66
67 button1 = tk.Button(root, text="チェック", font=(
68 "Helvetica", 14), command=ButtonClick)
69 button1.place(x=220, y=60)
70 root.mainloop()
実際にゲームをやってみて,いちいちボタンをマウスで押すのが面倒になってきたので,root.bindでreturn keyに反応するように改良しています.
- How do I bind the enter key to a function in tkinter?
- line:7のdefに引数(event=None)をとってきてます
- line:56でbindしています.
- line:14, 21,数字の4桁判定の挙動をbreakではなく,returnにしています.
これは,違いをよく観察してください.これらは少し高度なデバッグなのでできてなくていいですよ.
提出課題
Tkinter版のhit and blowをLUNAに提出しなさい.
- source ~/Desktop/lecture_22s/CompAInfo/c6_hit_and_blow_tkinter.org