상세 컨텐츠

본문 제목

숫자 야구 버전3 파이썬 게임 무료 다운로드: 파이썬 소스 코드, ChatGPT와의 제작 과정, 게임 규칙 등 공개

IT & Programming/파이썬 (Python) 공부

by 그림아이 2023. 5. 28. 11:00

본문

반응형

숫자 야구 버전3 파이썬 게임 무료 다운로드

 

□ 제목 : 숫자 야구 버전3 (Baseball With Numbers Version3)

 언어 : Python (파이썬)

 제작 : 알고리즘 작성 → ChatGPT에 제작 요청 → 디버깅 및 검토 → ChatGPT에 보완 요청 → 완성

 공개 : 2023년 5월 28일, 광고 없음

 형식 : EXE 파일

 파일 다운로드 : Baseball_with_numbers_Version3.exe

Baseball_with_numbers_Version3.exe
9.50MB

※ 만약 게임이 실행이 안 되시거나 문제가 있으시면, 이곳에 댓글을 남겨주시거나 grimeye.myw@gmail.com으로 메일 주시면 최선을 다해서 답변 드리겠습니다.

 

숫자 야구 버전3 파이썬 게임 무료 다운로드

 

반응형

 

숫자 야구 버전3 파이썬 게임을 개발하고 공개하며

 

사랑하는 딸아이가 중학교 수업시간에 숫자 야구게임을 했다는 얘기를 듣고 “ChatGPT와 파이썬으로 한 번 만들어볼까?” 하는 생각이 들어 만들게 된 게임 세번째 버전입니다.

 

하루에 한두시간 정도 들여서 3자리와 4자리 숫자야구 게임을 만들고 보니 욕심이 생겼습니다. “사용자가 맞히기만 하는 것이 아니라 반대로 컴퓨터가 맞히도록 하면 어떨까?”하는 궁금증과 호기심이 생겼습니다. 그래서 다시 도전해봤습니다. 컴퓨터가 얼마나 잘 맞히는지 딸아이에게 보여주고 싶기도 했고, 반대로 컴퓨터에게 볼과 스트라이크에 대한 피드백을 주는 연습도 시킬 겸 해서 만들었습니다. 그렇게 만든 프로그램을 모두에게 무료로 공개하고자 합니다. 게다가 광고도 없습니다.

 

만든 과정을 간단히 설명하면, 일단 숫자는 4자리로 정했고, ChatGPT에게 제시할 대화창 디자인부터 했으며, 가장 중요한 볼과 스트라이크에 대한 개념 정의를 제시했습니다. 아래 알고리즘은 맨 처음 ChatGPT에게 제시한 알고리즘입니다. 이후 약 4시간 가량 동안 수많은 보완 작업을 거쳐야 했습니다. 4자리 게임을 바로 전날 만들었는데도 ChatGPT는 대화창 디자인을 이해하지 못해서 한참 애를 먹었습니다. ChatGPT의 시행착오가 많았습니다. 거의 다 된 상태에서 작은 부분을 변경해달라고 했을 뿐인데 대화창의 디자인을 완전히 다 바꿔 버리기도 했습니다.

 

가장 오랜 시간이 소요된 부분은 대화창 디자인이 아니라 사용자의 정답을 컴퓨터가 추론하는 과정에 대한 알고리즘이었습니다. ChatGPT에게 아무리 설명을 해도 버그가 있었습니다. 처음에 잘 나가다가 엉뚱한 숫자들을 내놓기도 하고 사용자의 피드백을 거짓말이라고 답하고 끝내버리기도 했습니다. 설명을 반복했지만 역시 버그는 고쳐지지 않았습니다.

 

두어시간 정도 씨름하다가 대화창의 디자인이 완료되어 더 이상 손을 볼 필요가 없어졌을 때, 저는 고민을 했습니다. “만약 내가 직접 코딩했다면 어떻게 임의의 4자리 숫자를 맞혔을까?” 결국 저는 수학적으로 접근하기로 했습니다. 몇 가지 세부 전략이 있겠지만, 근본 원리는 교집합의 반복으로 풀기로 했습니다. 가장 원시적이지만, 동시에 가장 확실한 전략이기도 했습니다. 만약 첫번째 컴퓨터의 추측에 대해 사용자가 2B이라고 답하면 해당 4자리 숫자가 2B이 가능한 모든 4자리 숫자 조합을 Main 리스트로 저장해 둡니다. 그리고 그 리스트 중에서 하나를 추출해서 제시한 후 사용자가 다시 2B이라고 답하면 해당 4자리 숫자가 2B이 가능한 모든 4자리 숫자 조합을 리스트로 만들어 Main 리스트와의 교집합만을 남기고 나머지 Main 리스트를 삭제합니다. 이렇게 계속 반복하다 보면 Main 리스트에는 단 하나의 숫자만이 남을 수밖에 없습니다. 다만, 사용자는 실수를 할 수도 있고, 의도적으로 거짓말을 할 수도 있습니다. 이때는 Main 리스트를 줄여가는 과정에서 사용자의 피드백 조합과 교집합이 없는 순간이 올 수밖에 없습니다. 이때는 “I guess you made a mistake or lied to me.”라는 경고창을 출력하게 했습니다.

 

이렇게 ChatGPT에게 추론하는 방법을 구체적으로 제시해주니 단 한 번에 해결되어 코딩이 완료되었습니다. 그래도 제가 코딩했으면 미천한 제 실력에 3일 정도 걸렸을 텐데 4시간 만에 완성했으니 불평 하나 없이 대신 코딩해주는 조수로서는 훌륭하다고 생각합니다. 참고로 여기에서는 한글로 알고리즘을 썼지만 ChatGPT에게는 구글 번역기를 통해 영어로만 코딩을 요청했습니다.

 

본 글의 순서는 제가 ChatGPT에게 요청했던 알고리즘, 수많은 보완을 거쳐 완성된 최종 파이썬 소스코드 전문, 최종 숫자 야구 게임 다운로드의 순서로 진행됩니다. 다른 건 모르겠고 게임의 다운로드가 필요하다 하시는 분들은 본문 맨 위로 스크롤 하시면 다운로드 받으실 수 있습니다.

 

즐겜하세요!!!

 

 

ChatGPT에게 요청한 파이썬 알고리즘 및 게임의 규칙

 

1. 게임의 타이틀은 “Baseball with Numbers”이다.

2. 사용자가 숫자를 임의로 추출해서 정답을 가지고 있고, 파이썬이 정답을 추측하고 맞히는 게임이다.

3. 0부터 9까지 숫자들 중 중복되지 않은 4자리 숫자를 사용자가 가지고 있고 컴퓨터가 중복되지않은 임의의 4자리 숫자를 사용자에게 보여주면, 사용자는 결과값을 “2B 0S”와 같이 숫자만 입력한다.

4. 컴퓨터가 추측한 숫자와 위치가 일치하면 “S”, 숫자만 일치하면 “B”로 나타낸다. 만약 일치하는 숫자가 하나도 없으면 “0B 0S”라고 사용자가 입력할 것이다. 사용자가 “0B 4S”라고 입력하면 “Computer won!!!”이라는 경고창을 출력한다.

5. 총 20번 시도할 수 있고, 20번의 시도에도 불구하고 맞히지 못한다면 “Computer lost.”라는 경고창을 출력한다.

6. 사용자가 입력한 결과값에 따라 컴퓨터가 추측할 때, 논리적으로 4자리 숫자의 추측이 불가능한 순간이 오면 사용자가 결과값을 실수로 잘못 입력했을 가능성이 크므로 “I guess you made a mistake or you lied to me.”라는 경고창을 출력한다.

7. 게임의 dialogue box는 다음과 같다.

a. 컴퓨터가 추측한 숫자를 보여주는 4열 및 20행의 타일이 있고 사용자는 편집할 수 없다.

b. 타일의 오른쪽에 사용자가 입력 가능한 타일과 “B”라는 텍스트, 또 그 오른쪽에 사용자가 입력 가능한 타일과 “S”라는 텍스트를 배치한다.

c. 맨 오른쪽에 “Submit”이라는 버튼을 1열 및 20행으로 배치하여 사용자가 “B”값과 “S”값 입력이 완료된 경우 컴퓨터에게 결과값을 제공하고 다음 추측을 할 수 있도록 한다.

8. 20행의 타일들 아래에 "New Game", "Quit", "How to Play" 버튼을 같은 행으로 나란히 배치한다.

9. 타일의 맨 아래에는 studyingengineer.tistory.com 이라는 링크를 삽입하고 마우스로 누를 경우 인터넷 브라우저 새창이 열리면서 이동할 수 있도록 한다.”

 

 

완성된 파이썬 소스 코드

 

#Baseball_with_numbers_Version3.py

import tkinter as tk
import random
import itertools
from tkinter import messagebox
import webbrowser
 
class NumberBaseballGame:
    def __init__(self, master):
        self.master = master
        self.master.title('Baseball with Numbers Version3')
        self.entries = []
        self.answers = [''.join(p) for p in itertools.permutations('0123456789', 4)]
        random.shuffle(self.answers)
        first_guess = self.answers.pop(random.randint(0, len(self.answers) - 1))
 
        for i in range(20):
            row_entries = [tk.Entry(master, width=2, font=("Helvetica", 20), justify='center', state='disabled') for _ in range(4)]
            for j in range(4):
                row_entries[j].grid(row=i, column=j, padx=(0, 20) if j == 3 else 0)
                if i == 0:
                    row_entries[j].config(state='normal')
                    row_entries[j].insert(0, first_guess[j])
                    row_entries[j].config(state='disabled')
                row_entries[j].bind("<KeyRelease>", lambda e, i=i, j=j: self.auto_advance(e, i, j))
 
            row_entries.append(tk.Entry(master, width=2, font=("Helvetica", 20), justify='center', state='disabled' if i > 0 else 'normal'))
            row_entries[4].grid(row=i, column=5, padx=(20, 0))
            row_entries[4].bind("<KeyRelease>", lambda e, i=i: self.auto_advance(e, i, 4))
 
            tk.Label(master, text="B", font=("Helvetica", 20)).grid(row=i, column=6)
 
            row_entries.append(tk.Entry(master, width=2, font=("Helvetica", 20), justify='center', state='disabled' if i > 0 else 'normal'))
            row_entries[5].grid(row=i, column=7)
            row_entries[5].bind("<KeyRelease>", lambda e, i=i: self.auto_advance(e, i, 5))
 
            tk.Label(master, text="S", font=("Helvetica", 20)).grid(row=i, column=8)
 
            row_entries.append(tk.Button(master, text='Submit', state='disabled' if i > 0 else 'normal', command=lambda i=i: self.check(i))) # type: ignore
            row_entries[6].grid(row=i, column=9)
            self.entries.append(row_entries)
 
        self.buttons = self.create_buttons()
 
    def create_buttons(self):
        button_frame = tk.Frame(self.master)
        button_frame.grid(row=21, column=0, columnspan=10)
 
        new_game_button = tk.Button(button_frame, text='New Game', command=self.new_game)
        new_game_button.pack(side='left', expand=True)
 
        quit_button = tk.Button(button_frame, text='Quit', command=self.master.quit)
        quit_button.pack(side='left', expand=True)
 
        how_to_play_button = tk.Button(button_frame, text='How to Play', command=self.how_to_play)
        how_to_play_button.pack(side='left', expand=True)
 
        link_frame = tk.Frame(self.master)
        link_frame.grid(row=22, column=0, columnspan=10)
 
        link = tk.Label(link_frame, text="studyingengineer.tistory.com", font=("Helvetica", 10), cursor="hand2")
        link.pack(expand=True)
        link.bind("<Button-1>", self.open_url)
 
        return new_game_button, quit_button, how_to_play_button, link
 
    def open_url(self, event):
        webbrowser.open_new('http://studyingengineer.tistory.com/1304')
 
    def auto_advance(self, event, i, j):
        if len(self.entries[i][j].get()) > 0:
            if j < 3:
                self.entries[i][j+1].focus()
            elif i < 19 and j == 3:
                self.entries[i+1][0].focus()
            elif j == 4:
                self.entries[i][5].focus()
 
    def check(self, row):
        try:
            b = int(self.entries[row][4].get())
            s = int(self.entries[row][5].get())
        except ValueError:
            messagebox.showwarning("Warning", "Please enter a valid number of balls and strikes.")
            return
        if b < 0 or b > 4 or s < 0 or s > 4 or b + s > 4:
            messagebox.showwarning("Warning", "Please enter a valid number of balls and strikes.")
            return
 
        if s == 4:
            messagebox.showinfo("Computer won!!!", "The computer has guessed your number!")
            self.disable_all()
            return
 
        self.answers = [a for a in self.answers if self.matches(self.entries[row][0:4], a, b, s)]
        if len(self.answers) == 0:
            messagebox.showwarning("Warning", "I guess you made a mistake or you lied to me.")
            self.disable_all()
            return
 
        next_guess = self.answers.pop(random.randint(0, len(self.answers) - 1))
        if row < 19:
            for i in range(4):
                self.entries[row + 1][i].config(state='normal')
                self.entries[row + 1][i].insert(0, next_guess[i])
                self.entries[row + 1][i].config(state='disabled')
            self.entries[row + 1][4].config(state='normal')
            self.entries[row + 1][5].config(state='normal')
            self.entries[row + 1][6].config(state='normal')
        else:
            messagebox.showwarning("Computer lost.", "The computer could not guess your number in 20 attempts.")
 
        self.entries[row][4].config(state='disabled')
        self.entries[row][5].config(state='disabled')
        self.entries[row][6].config(state='disabled')
 
    def matches(self, entries, answer, b, s):
        guessed_number = [e.get() for e in entries]
        user_s = sum(1 for i, e in enumerate(guessed_number) if e == answer[i])
        user_b = sum(1 for e in guessed_number if e in answer) - user_s
        return user_b == b and user_s == s
 
    def disable_all(self):
        for row in self.entries:
            for entry in row:
                entry.config(state='disabled')
 
    def new_game(self):
        self.master.destroy()
        root = tk.Tk()
        game = NumberBaseballGame(root)
        root.mainloop()
 
    def how_to_play(self):
        webbrowser.open_new('http://studyingengineer.tistory.com/1304')
 
if __name__ == "__main__":
    root = tk.Tk()
    game = NumberBaseballGame(root)
    root.mainloop()

 

 

참고할만한 다른 자료들

 

숫자 야구 버전1 파이썬 게임 무료 다운로드: 파이썬 소스 코드, ChatGPT와의 제작 과정, 게임 규칙 등 공개 (tistory.com)

 

숫자 야구 버전1 파이썬 게임 무료 다운로드: 파이썬 소스 코드, ChatGPT와의 제작 과정, 게임 규칙

숫자 야구 버전1 파이썬 게임 무료 다운로드 □ 제목 : 숫자 야구 버전1 (Baseball With Numbers Version1) □ 언어 : Python (파이썬) □ 제작 : 알고리즘 작성 → ChatGPT에 제작 요청 → 디버깅 및 검토 → ChatGP

studyingengineer.tistory.com

숫자 야구 버전2 파이썬 게임 무료 다운로드: 파이썬 소스 코드, ChatGPT와의 제작 과정, 게임 규칙 등 공개 (tistory.com)

 

숫자 야구 버전2 파이썬 게임 무료 다운로드: 파이썬 소스 코드, ChatGPT와의 제작 과정, 게임 규칙

숫자 야구 버전2 파이썬 게임 무료 다운로드 □ 제목 : 숫자 야구 버전2 (Baseball With Numbers Version2) □ 언어 : Python (파이썬) □ 제작 : 알고리즘 작성 → ChatGPT에 제작 요청 → 디버깅 및 검토 → ChatGP

studyingengineer.tistory.com

Wordle (워들) 파이썬 게임 무료 공개 (광고 없음): 파이썬 소스 코드, ChatGPT와의 제작 과정, 게임 규칙 등 공개 (tistory.com)

 

Wordle (워들) 파이썬 게임 무료 공개 (광고 없음): 파이썬 소스 코드, ChatGPT와의 제작 과정, 게임 규

Wordle (워들) 게임 무료 공개 제목 : Wordle 게임 언어 : Python (파이썬) 제작 : 알고리즘 작성 → ChatGPT에 제작 요청 → 디버깅 및 검토 → ChatGPT에 보완 요청 → 완성 공개 : 2023년 5월 14일, 광고 없음

studyingengineer.tistory.com

[Python] 구구단 출력하기 파이썬 프로그램 예제 (tistory.com)

 

[Python] 구구단 출력하기 파이썬 프로그램 예제

이번 시간에는 파이썬으로 구구단을 출력해주는 프로그램을 만들어 보겠습니다. 구구단은 보통 1~9까지 숫자를 각각 1~9까지 곱해서 곱셈을 외우고 공부하기 쉽게 만든 것을 의미합니다. 그런데

studyingengineer.tistory.com

[Python] 윤년인지 여부 확인 파이썬 프로그램 예제 (tistory.com)

 

[Python] 윤년인지 여부 확인 파이썬 프로그램 예제

오늘은 입력한 연도가 윤년인지 아닌지 확인해주는 프로그램을 만들어 보겠습니다. 먼저 윤년에 대해 정확히 알고 있어야 합니다. 프로그램 언어를 공부하면서 질문을 받아 보면 많은 분들이

studyingengineer.tistory.com

[Python] 파이썬으로 각종 단위 변환 프로그램 예제 (tistory.com)

 

[Python] 파이썬으로 각종 단위 변환 프로그램 예제

미국과 영국은 독특한 단위 체계를 사용하는 것으로 유명합니다. 전세계가 공용으로 사용하고 있는 SI (International System of Units) 단위 체계, 즉 미터법을 받아들이지 않고 버티는 것으로 유명합니

studyingengineer.tistory.com

[Python] 1에서 100까지 숫자들 중 소수 (Prime Number)만 찾아서 출력하기 파이썬 프로그램 예제 (tistory.com)

 

[Python] 1에서 100까지 숫자들 중 소수 (Prime Number)만 찾아서 출력하기 파이썬 프로그램 예제

무한히 많은 숫자들 중 가장 신비로운 수 중의 하나가 바로 소수입니다. 영어로 Prime Number라고 하고, 1과 자기 자신을 제외한 어떤 수로도 나눠지지 않는 수를 말합니다. 심지어 세상 모든 수는

studyingengineer.tistory.com

 

728x90
반응형

관련글 더보기

댓글 영역