파이썬 실습/게임 만들기

파이썬 GUI 영어단어맞추기 게임

파기차차 2022. 10. 18. 07:24
728x90
반응형
SMALL
728x90
ㅁ 개요
 
O 프로그램 소개
 

 - 이번 프로그램은 이전글(2022.08.09 - [파이썬 실습/게임 만들기] - 파이썬 단어 맞추기 게임 만들기) 파이썬 단어 맞추기 게임 만들기의 GUI 버전입니다.

게임의 규칙은 한글로 문제가 주어지고 해당 문제의 답을 영어로 답해서 많이 맞추면 되는 게임입니다.

(본 블로그의 내용은 유튜브 동영상(파이썬 GUI 영어 단어 맞추기 게임 프로그램 만들기)에서 더욱 자세히 보실 수 있습니다.)

 

 

O 완성된 프로그램 실행 화면

 

 - 최종 완성된 프로그램의 결과화면은 아래와 같습니다.
 
*처음 시작 시

 

*게임 종료 시

 

 

 - 위 프로그램 설명은 다음과 같습니다.(위의 그림을 보면서 설명 드리겠습니다.)

(1) 한글로 문제가 주어집니다.(예: '2. 호랑이')

(2) 흰색 입력박스에 영문으로 답을 입력합니다.(예: 'tiger')

(3) 문제를 모두 완료하면(여기서는 총 4문제) 총문제수, 맞춘 개수, 점수가 표시되고, 문제를 다시 출제할지를 물어 봅니다.

(4) 'Yes'를 누르면 문제가 다시 시작되고, 'No'를 누르면 게임이 종료됩니다.

 


 

ㅁ 세부 내용
 
O 완성된 소스

 

from PyQt5 import QtWidgets
from PyQt5 import QtCore

import random
import os

words_dict = {
    "사자" : "lion",
    "호랑이" : "tiger",
    "사과" : "apple",
    "비행기" : "airplane"
}
words = []
for word in words_dict:
    words.append(word)
print(words)

class MyWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        global current_index, k
        current_index = 0
        k = 0

        ######################################################
        # 2. 윈도우 폼 구성하기
        ######################################################
        self.setWindowTitle("파이썬 GUI영어단어맞추기게임")

        self.lb_info1 = QtWidgets.QLabel("다음 한글을 영어로 입력하세요.", self)
        self.lb_info1.setAlignment(QtCore.Qt.AlignLeft)
        self.lb_info1.setStyleSheet("font-family:맑은 고딕;color:gray; font-size:16px;")

        self.lb_quiz = QtWidgets.QLabel("현재 퀴즈 부분 입니다.", self)
        self.lb_quiz.setAlignment(QtCore.Qt.AlignLeft)
        self.lb_quiz.setStyleSheet("font-family:맑은 고딕;color:blue; font-size:20px;")

        self.lb_info2 = QtWidgets.QLabel("총 문제수: 0개<br>맞춘개수: 0개<br>최종점수: 00점", self)
        self.lb_info2.setAlignment(QtCore.Qt.AlignCenter)
        self.lb_info2.setStyleSheet("font-family:맑은 고딕;color:red; font-size:20px;")

        self.input = QtWidgets.QLineEdit(self)
        self.input.setFixedHeight(30)
        self.input.setStyleSheet("font-family:맑은 고딕;color:black; font-size:20px;")

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.lb_info1)
        layout.addWidget(self.lb_quiz)
        layout.addWidget(self.lb_info2)
        layout.addWidget(self.input)
        self.resize(650, 200)
        self.setLayout(layout)


        ######################################################
        # 3. enter_key 함수 호출 및 정의
        ######################################################
        self.input.returnPressed.connect(self.enter_key)



        ######################################################
        # 7. 최초 게임 시작 시 동일한 문제가 출제되지 않고 시작시 마다
        # 다르게 출제하게 하기 위해서 초기화(섞어주고)하고, 
        ######################################################
        self.init_quiz()
        self.next_word()
       

        self.show()


    ######################################################
    # 3. enter_key 함수 호출 및 정의
    ######################################################
    def enter_key(self):
        global current_index, k

        if current_index < len(words):
            q = words[current_index]
            print(q, current_index)
        else:
            current_index = 0
            q = words[current_index]
        
        user_input = self.input.text()

        dictionary = words_dict[q]

        if user_input == dictionary:

            k = k + 1
            print("정답입니다.")
            self.lb_info2.setText("정답입니다. <br>현재까지 맞춘개수는 '"+str(k)+"'개 입니다.")
            self.input.setText("")
            current_index = current_index + 1

        else:
            print("틀렸습니다.")
            self.lb_info2.setText("틀렸습니다. <br>현재까지 맞춘개수는 '"+str(k)+"'개 입니다.")
            current_index = current_index + 1
            self.input.setText("")


        
        ######################################################
        # 4. 다음 문제 출제 함수 호출 및 실행
        ######################################################
        self.next_word()


    ######################################################
    # 5. 게임 초기화 함수 호출 및 실행
    ######################################################
    def init_quiz(self):
        global k
        random.shuffle(words)
        print(words)
        self.current_index = 0
        k = 0



    ######################################################
    # 4. 다음 문제 출제 함수 호출 및 실행
    ######################################################
    def next_word(self):
        global next_question
        if self.current_index < len(words):
            question = words[self.current_index]
            question = str(self.current_index+1)+". "+question
            if self.current_index + 1 < len(words):
                next_question = words[self.current_index + 1]
            else:
                pass

            self.lb_quiz.setText(question)
            self.current_index = self.current_index + 1
        else:
            self.lb_info2.setText("총 문제수: "+str(self.current_index)+"개<br>맞춘 개수: "+str(k)+"개<br>점수: "+str(k/self.current_index * 100)+"점")
            reply = QtWidgets.QMessageBox.question(self, 'GUI영어단어맞추기게임', '모든 문제를 출제했습니다.\n다시 하시겠습니까?',
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes)
            if reply == QtWidgets.QMessageBox.Yes:

                ######################################################
                # 5. 게임 초기화 함수 호출 및 실행
                ######################################################
                self.init_quiz()
                self.next_word()
                self.lb_info2.setText("")
            else:
                exit(0)

######################################################
# 1. 윈도우 창 띄우기
######################################################
if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    win = MyWindow()
    app.exec_()

 

O 소스 다운로드
 
 

GUI_englishWordQuizGame.py
0.01MB

 
 
 

 

O 핵심 내용
 

1. app=QtWidgets.QApplication([]) : app객체 생성

2. win = MyWindow() : 생성자의 self는 win를 전달받음, 여기서 self는 MyWindow 클래스 그 자신을 의미

3. app.exec_() : app객체를 실행, exec_()함수의 내장 루프로 계속 창이 뜨게 만듦

4. words_dict = {} : 키/벨류구조의 딕셔너리 생성

5. words = [] : 순서대로 저장하기 위해 리스트 생성

6. self.lb_info1 = QtWidgets.QLabel("", self) : self.lb_info1으로 레이블 생성
7. self.lb_info1.setAlignment(QtCore.Qt.AlignLeft) : self.lb_info1 레이블의 위치 정렬(왼쪽)
8. self.lb_info1.setStyleSheet("font-family:맑은 고딕;color:gray; font-size:16px;") : self.lb_info1 레이블의 폰트설정

9. layout = QtWidgets.QVBoxLayout() : 레이아웃 객체 생성
10. layout.addWidget(self.lb_info1) : 레이아웃에 위에서 만든 구성요소를 추가(여기서는 self.lb_info1)
11. self.setLayout(layout) : 레이아웃을 최종적으로 설정함

12. if current_index < len(words) :   : 현재 인덱스가 words리스트의 길이보다 작으면, 즉 문제가 아직 끝나지 않았으면

 

 


 

O 기본 내용

-문제목록을 딕셔너리로 만들고, 순서를 정하기 위해 words리스트에 딕셔너리의 키를 넣어 둡니다.(딕셔너리는 순서 정렬이 안되므로 리스트를 사용함)

-그리고 윈도우 창을 띄우기 위해 app.exec_()를 사용하여 윈도우 창을 띄웁니다.

 

 

- 윈도우의 폼을 생성합니다.

>안내 문구 부분 : '다음 한글을 영어로 입력하세요'

>문제 부분 : 현재 퀴즈 부분 입니다.

>결과부분 : 총문제수, 맞춘개수, 최종점수

>input 박스 부분 : 흰 박스에 답을 입력하는 부분

 

 

-엔터키를 누르면 작동하는 부분의 소스입니다.

>엔터키를 누르면 'self.input.returnPressed.connect(self.enter_key)'에 의해 'enter_key()'함수가 호출됩니다.

>컴퓨터가 랜덤하게 생성한 딕셔너리의 퀴즈(dictionary)와 내가 입력한 답변(user_input)을 비교 후

>> 같으면 맞춘개수(k)와 총문제수(current_index)를 1개 증가시키고, 결과부분(lb_info2)에 '정답입니다.'로 표시합니다.

>> 다르면 총문제수(current_index)만 1개 증가시키고, 결과부분(lb_info2)에 '틀렸습니다.'로 표시합니다.

 

 

- 아래는 엔터입력 후 다음문제가 출제되도록 구현한 소스 코드 입니다.

>현재 문제가 마지막이 아니면(if self.current_index < len(words):) 문제부분(lb_quiz)의 레이블에 현재문제를 보여주고,  다음문제를 위해 current_index를 1개 증가 시킵니다.

 

 

- 만약 current_index가 words리스트의 길이보다 작지 않다면, 즉 현재문제가 마지막이라면, 결과화면(lb_info2)에 총문제수, 맞춘개수, 점수를 보여주고, 다시 시작할지를 묻는 메시지박스를 보여줍니다.

>여기서 'Yes'를 누르면 게임을 다시 초기화(문제를 섞고, current_index와 k를 0으로 초기화)하고, next_word()함수를 호출하여 문제를 처음부터 다시 시작합니다.

 


 

ㅁ 정리
 
O 우리가 배운 내용
 
 - 파이썬 단어 맞추기 게임을 만들기를 GUI환경에서 만들어 보았습니다.
 - 이번 프로그램은 소스 하나 하나는 크게 어려운 부분이 없으나, 전체적으로 어떻게 프로그램이 돌아가는지 단계별 로직을 생각하는 부분(아래)이 중요한 것 같습니다.
 > 1. 윈도우 창 띄우기
 > 2. 윈도우 창에 폼 구성하기
 > 3. 엔터를 눌렀을때 동작하는 로직 구현하기
 > 4. 이어지는 다음문제가 출력되도록 로직 구현하기
> 5. 문제가 끝났을때 초기화(다시 처음부터 실행) 또는 종료 부분 구현하기
> 6. 최초 게임 시작시 마다 동일한 문제가 출제되지 않고, 다르게 출제하는 방법에 대한 고민 등
 

 

위의 내용이 유익하셨다면, 좋아요와 구독 부탁드립니다.

 

 

감사합니다.

 

728x90
반응형
LIST