728x90
반응형

alphago.png
0.08MB

저번에는 tkinter(window, label, button, canvas)에 대해 알아보고 간단한 제비뽑기 프로그램을 만들었는데

https://jinho-study.tistory.com/1077

 

파이썬 GUI 기초 1(Tkinter )

1 GUI란? GUI: 소프트웨어의 조작 방법을 직관적으로 알 수 있게 해주는 인터페이스 1.1 윈도우 표시하기 import tkinter root = tkinter.Tk() # 윈도우 요소(객체) 생성 root.mainloop() # 윈도우 표시 tkinter.T..

jinho-study.tistory.com

 

이번에는 배운걸 좀 더 활용해서 가위바위보 게임을 만들어봤다.

기존 제비뽑기 프로그램에서 배경화면을 변경, 라벨과 버튼을 추가, 가위바위보 승패 판별 및 출력 기능을 추가했다. 

맨 위에 첨부한 이미지 파일이 코드와 같은 경로에 있어야 한다!!

 

아래 이미지는 코드를 실행하고 플레이해본 결과와 전체 코드이다!

가위바위보 프로그램

import tkinter
import random
# from functools import partial
from PIL import ImageTk

def click_btn(user_choice):
    # 가위, 바위, 보 중 랜덤으로 하나 선택하고 com_rps_label에 출력
    computer_choice = random.choice(["가위", "바위", "보"])
    com_rps_label["text"] = computer_choice
    com_rps_label.update()
    
    # 사용자가 선택한 것을 user_rps_label에 출력
    user_rps_label["text"] = user_choice
    user_rps_label.update()
    
    # 승패를 판별하고 result_label에 출력
    res = ""
    if computer_choice == user_choice:
        res = "비김!" 
    else:
        if user_choice == "가위":
            res = "승리!" if computer_choice == "보" else "패배!"
        elif user_choice == "바위":
            res = "승리!" if computer_choice == "가위" else "패배!"
        elif user_choice == "보":
            res = "승리!" if computer_choice == "바위" else "패배!"
    result_label["text"] = res
    result_label.update()
    
        
root = tkinter.Tk() 
root.title("가위바위보 프로그램")
root.resizable(False, False) 
canvas = tkinter.Canvas(root, width=800, height=480)
canvas.pack()

# 이미지 파일 타입에 따라 tkinter.PhotoImage가 잘 작동하지 않는 것 같다.
# ImageTk.PhotoImage 명령을 대신 사용했다.
# gazou = tkinter.PhotoImage(file="alphago.png")
gazou = ImageTk.PhotoImage(file="alphago.png")
canvas.create_image(400, 240, image=gazou)

# 컴퓨터, 사용자 라벨
com_label = tkinter.Label(root, text="컴퓨터", font=("Times New Roman", 55),
                        bg="white")
user_label = tkinter.Label(root, text="사용자", font=("Times New Roman", 55),
                        bg="white")
# 컴퓨터 가위, 바위, 보 라벨
com_rps_label = tkinter.Label(root, text="??", font=("Times New Roman", 55),
                        bg="white")
# 사용자 가위, 바위, 보 라벨
user_rps_label = tkinter.Label(root, text="??", font=("Times New Roman", 55),
                        bg="white")
# 승패 결과 라벨
result_label = tkinter.Label(root, text="승패", font=("Times New Roman", 60),
                        bg="white")
com_label.place(x=350, y=25)
com_rps_label.place(x=600, y=25)
user_label.place(x=350, y=145)
user_rps_label.place(x=600, y=145)
result_label.place(x=470, y=250)

# 가위, 바위, 보 버튼 3개
# 버튼 명령에 인수를 전달하기 위해 lambda를 사용했다.
# partial(clict_btn, "가위") 같은 방식으로도 사용할 수 있다.
s_button = tkinter.Button(root, text="가위", font=("Times New Roman", 36),
                        fg="skyblue", command=lambda: click_btn("가위"))
r_button = tkinter.Button(root, text="바위", font=("Times New Roman", 36),
                        fg="skyblue", command=lambda: click_btn("바위"))
p_button = tkinter.Button(root, text="보", font=("Times New Roman", 36),
                        fg="skyblue", command=lambda: click_btn("보"))
s_button.place(x=350, y=365)
r_button.place(x=520, y=365)
p_button.place(x=690, y=365)

root.mainloop() 

 

주석으로도 설명이 되어있긴 하다만 추가한 라벨과 버튼, 수정된 부분을 정리하자면 아래와 같다. 

라벨 

com_label, user_label

  • "컴퓨터"와 "사용자"를 출력해주는 라벨

com_rps_label

  • 컴퓨터가 가위, 바위, 보 중 랜덤으로 고른 것을 출력해주는 라벨
  • 처음엔 "??"가 출력되고 나중엔 "가위", "바위", "보" 중 하나가 출력되는 식이다.
  • s_button, r_button, p_button 중 하나가 눌릴 때마다 업데이트된다. 

user_rps_label

  • 사용자가 선택한 버튼에 따라서 "가위", "바위", "보" 중 하나를 출력해주는 라벨
  • s_button, r_button, p_button 중 하나가 눌릴 때마다 업데이트된다.

result_label

  • 가위바위보 승패 결과를 출력해주는 라벨
  • 처음엔 "승패"가 출력되고 나중엔 "승리!", "패배!", "비김!" 중 하나가 출력되는 식이다.
  • s_button, r_button, p_button 중 하나가 눌릴 때마다 업데이트된다.

 

버튼

s_button, r_button, p_button

  • 순서대로 "가위", "바위", "보" 중 하나를 사용자가 선택할 수 있도록 하기 위해 만든 버튼들이다. 
  • 이 중 하나를 누르면 click_btn 함수가 실행되는데 이때 인자(user_choice)로 각 함수에 맞는 값이 전달된다.
  • s_button -> "가위", r_button -> "바위", p_button -> "보"

 

tkinter.PhotoImage -> ImageTk.PhotoImage

tkinter.PhotoImage는 이미지 파일 타입에 따라 오류가 날 때가 있는 것 같아 ImageTk.PhotoImage를 대신 사용했다.

만약 ImageTk.PhotoImage 부분에서 오류가 난다면 pillow를 설치해보자! -> pip install pillow

 

# 이미지 파일 타입에 따라 tkinter.PhotoImage가 잘 작동하지 않는 것 같다.
# ImageTk.PhotoImage 명령을 대신 사용했다.
# gazou = tkinter.PhotoImage(file="alphago.png")
gazou = ImageTk.PhotoImage(file="alphago.png")
canvas.create_image(400, 240, image=gazou)

 

click_btn 함수 수정

  • 컴퓨터가 가위, 바위, 보 중 랜덤으로 하나를 선택하게 하고 선택한 것을 com_rps_label에 업데이트
  • 인자로 받은 user_choice(사용자가 선택한 버튼 -> "가위", "바위", "보")를 user_rps_label에 업데이트
  • 컴퓨터와 사용자의 선택을 비교하여 승패를 판결하고 그 결과를 result_label에 업데이트

위의 3개의 기능을 구현했다.

def click_btn(user_choice):
    # 가위, 바위, 보 중 랜덤으로 하나 선택하고 com_rps_label에 출력
    computer_choice = random.choice(["가위", "바위", "보"])
    com_rps_label["text"] = computer_choice
    com_rps_label.update()
    
    # 사용자가 선택한 것을 user_rps_label에 출력
    user_rps_label["text"] = user_choice
    user_rps_label.update()
    
    # 승패를 판별하고 result_label에 출력
    res = ""
    if computer_choice == user_choice:
        res = "비김!" 
    else:
        if user_choice == "가위":
            res = "승리!" if computer_choice == "보" else "패배!"
        elif user_choice == "바위":
            res = "승리!" if computer_choice == "가위" else "패배!"
        elif user_choice == "보":
            res = "승리!" if computer_choice == "바위" else "패배!"
    result_label["text"] = res
    result_label.update()

 

command에 인자가 있는 함수 넘겨주기

command로 인자가 있는 함수를 넘겨줄 때는 제비뽑기 프로그램처럼 그냥 command=click_btn 같은 식으로

하면 안되고 lambda나 partial를 사용해서 처리해줘야 하는 것 같다. 예를 들면

lambda -> command=lambda: click_btn("가위") 

partial -> command=partial(clict_btn, "가위") 같은 식이다.

# 버튼 명령에 인수를 전달하기 위해 lambda를 사용했다.
# partial(clict_btn, "가위") 같은 방식으로도 사용할 수 있다.
s_button = tkinter.Button(root, text="가위", font=("Times New Roman", 36),
                        fg="skyblue", command=lambda: click_btn("가위"))
r_button = tkinter.Button(root, text="바위", font=("Times New Roman", 36),
                        fg="skyblue", command=lambda: click_btn("바위"))
p_button = tkinter.Button(root, text="보", font=("Times New Roman", 36),
                        fg="skyblue", command=lambda: click_btn("보"))

 

 

코드 github 주소: https://github.com/kimjinho1/Python-Game/blob/main/GUI%20%EA%B8%B0%EC%B4%88%201(tkinter)/%EA%B0%80%EC%9C%84%EB%B0%94%EC%9C%84%EB%B3%B4.ipynb 

 

kimjinho1/Python-Game

Contribute to kimjinho1/Python-Game development by creating an account on GitHub.

github.com

728x90
반응형

+ Recent posts