Skip to content

Instantly share code, notes, and snippets.

@shiracamus
Created April 22, 2019 16:07
Show Gist options
  • Save shiracamus/3c27e07866be6842dcc8f3835ffc543a to your computer and use it in GitHub Desktop.
Save shiracamus/3c27e07866be6842dcc8f3835ffc543a to your computer and use it in GitHub Desktop.
import tkinter as tk
import random
HANDS = ROCK, SCISSORS, PAPER = "グー", "チョキ", "パー"
WIN, LOSE, DRAW = "勝ち", "負け", "引き分け"
class Player:
STRONGER_THAN = {ROCK: PAPER, SCISSORS: ROCK, PAPER: SCISSORS}
def __init__(self, hand=None):
self.hand = hand
def select(self, hand=None):
self.hand = hand or random.choice(HANDS)
def is_selected(self):
return self.hand is not None
def reset(self):
self.hand = None
def judge(self, enemy):
if self.hand == self.STRONGER_THAN[enemy.hand]:
return WIN
elif enemy.hand == self.STRONGER_THAN[self.hand]:
return LOSE
else:
return DRAW
def load_image(name, scale=None, images={}):
if name not in images:
images[name] = tk.PhotoImage(file=f"素材/{name}.png")
if not scale:
return image[name]
if (name, scale) not in images:
images[name, scale] = images[name].subsample(scale)
return images[name, scale]
class View:
_PLAYER_PLACE = {ROCK: (25, 220), SCISSORS: (120, 205), PAPER: (200, 220)}
_ENEMY_PLACE = {ROCK: (100, 25), SCISSORS: (100, 15), PAPER: (100, 25)}
def __init__(self, master):
self._init_buttons(master)
self._init_hands(master)
self._init_judge(master)
def _init_buttons(self, master):
self.rock = tk.Button(master, text="グー")
self.rock.place(x=45, y=300)
self.scissors = tk.Button(master, text="チョキ")
self.scissors.place(x=130, y=300)
self.paper = tk.Button(master, text="パー")
self.paper.place(x=225, y=300)
self.retry = tk.Button(master, text="リトライ!")
self.retry.place(x=220, y=160)
def _init_hands(self, master):
def hand_image(hand, scale):
return tk.Label(master, image=load_image(hand, scale))
for hand in HANDS:
x, y = self._PLAYER_PLACE[hand]
hand_image(hand, 3).place(x=x, y=y)
self._enemy_hands = {hand: hand_image(hand, 2) for hand in HANDS}
self._enemy_hand = None
def _init_judge(self, master):
font = ("Impact", 20, "bold")
self._judges = {
WIN: tk.Label(master, text="勝ち!", fg="red", font=font),
LOSE: tk.Label(master, text="負け!", fg="black", font=font),
DRAW: tk.Label(master, text="引き分け!", fg="green", font=font)}
self._judge = None
def show_enemy_hand(self, hand):
enemy_hand = self._enemy_hands[hand]
if self._enemy_hand == enemy_hand:
return
if self._enemy_hand:
self._enemy_hand.place_forget()
x, y = self._ENEMY_PLACE[hand]
enemy_hand.place(x=x, y=y)
self._enemy_hand = enemy_hand
def show_judge(self, judge):
judge = self._judges[judge]
if judge != self._judge:
self.clear_judge()
judge.place(x=50, y=150)
self._judge = judge
def clear_judge(self):
if self._judge:
self._judge.place_forget()
self._judge = None
class Application(tk.Frame):
def __init__(self, master):
super().__init__(master)
master.geometry("300x350")
master.title("じゃんけんゲーム")
# Model
self.player = Player()
self.enemy = Player(ROCK)
# View
self.view = view = View(master)
self.pack()
# Controller
view.rock["command"] = lambda *args: self.player.select(ROCK)
view.scissors["command"] = lambda *args: self.player.select(SCISSORS)
view.paper["command"] = lambda *args: self.player.select(PAPER)
view.retry["command"] = lambda *args: self.player.reset()
master.after(50, self.update)
def update(self):
if self.player.is_selected():
self.view.show_judge(self.player.judge(self.enemy))
else:
self.enemy.select()
self.view.show_enemy_hand(self.enemy.hand)
self.master.after(50, self.update)
def main():
root = tk.Tk()
Application(root).mainloop()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment