Python에서 명령줄용 행맨 게임 구축

2023. 12. 7. 21:40python/basic

 

프로젝트 개요

ㅇ 컴퓨터 게임의 공통 요소 알아보기 ㅇ 컴퓨터 게임의 상태추적 ㅇ 사용자 입력 가져오기 및 유효성 검사 ㅇ 게임을 위한 텍스트 기반 사용자 인터페이스(TUI) 만들기 ㅇ 언제 게임이 종료되고 누가 승자인지 예상하기

행맨 게임에 대한 설명

ㅇ 게임 설정: 행맨 게임은 두 명 이상의 플레이어가 참여하는 게임이며, 선택 플레이어와 한 명 이상의 추측하는 플레이어으로 구성됩니다. ㅇ 단어 선택: 선택 플레이어는 추측 플레이어가 추측할 단어를 선택합니다. - 선택한 단어는 전통적으로 단어의 각 문자에 대한 일련의 밑줄로 표시됩니다. - 선택 플레이어는 교수형 집행인 그림을 고정할 비계도 그립니다. ㅇ 추측: 추측하는 플레이어는 한 번에 하나씩 문자를 선택하여 단어를 추측하려고 시도합니다. ㅇ 피드백: 선택하는 플레이어는 추측한 각 문자가 단어에 나타나는지 여부를 나타냅니다. - 문자가 나타나면 선택 플레이어는 각 밑줄을 단어에 나타나는 문자로 바꿉니다. - 문자가 나타나지 않으면 선택 플레이어는 추측된 문자 목록에 문자를 씁니다. 그런 다음 매달린 남자의 다음 조각을 그립니다. 목매달린 남자를 그리기 위해서는 머리부터 시작해 몸통, 팔, 다리 총 6개의 부분을 그려야 한다. ㅇ 승리 조건: 6번의 잘못된 추측 후에 매달린 사람 그리기가 완료되면 선택한 플레이어가 승리하며, 이 경우 게임이 종료됩니다. 추측하는 플레이어가 단어를 추측하면 승리합니다. - 추측이 맞으면 게임이 종료되고 추측한 플레이어가 승리합니다. - 추측이 틀리면 게임은 계속됩니다.

Python으로 행맨 게임을 작성하기 위해 몇 가지 추가 디자인 결정을 내릴 것입니다.

  • 게임은 컴퓨터와 한 명의 인간 플레이어 사이에 있습니다.
  • 컴퓨터가 선택 플레이어 역할을 하며 선택 추측할 단어, 처리 사람의 입력 및 처리 모두 출력합니다.
  • 인간 플레이어가 추측 플레이어입니다. 간단히 플레이어라고 합니다. 플레이어가 단어를 알면 단어가 완성될 때까지 계속해서 올바른 문자를 추측합니다.

컴퓨터 게임의 공통 요소

ㅇ 초기 설정: 게임을 플레이할 준비가 되었습니다. 이는 체스판에 말을 놓거나, 카드를 나눠주거나, 누가 먼저 가는지 확인하기 위해 주사위를 굴리는 것을 의미할 수 있습니다. ㅇ 게임플레이: 사람들은 게임을 생각할 때 일반적으로 이렇게 생각합니다. 게임플레이 흐름은 게임 루프에 의해 제어됩니다. 게임 루프는 게임을 계속 움직이게 하며 게임이 끝날 때까지 끝나지 않습니다. 게임 루프는 다음을 보장합니다: - 사용자 입력이 수집되고 처리됩니다. - 게임 상태는 사용자 입력에 대한 반응에 따라 업데이트됩니다. 여기에는 게임 종료 조건 확인이 포함될 수 있습니다. - 필요한 모든 출력 변경은 새로운 게임 상태를 반영하기 위해 이루어집니다. - 게임 루프가 반복됩니다. ㅇ 게임 종료: 게임 종료 방법은 게임 자체에 따라 다릅니다. 체크메이트에서 적의 왕을 잡거나, 카드 게임에서 특정 점수를 달성하거나, 보드 게임에서 자신의 말이 선을 넘도록 하는 등 특정 조건에 따라 게임의 종료와 승자가 결정됩니다.

전제조건

  • 파일 및 with 문 작업
  • 내장된 input() 함수를 사용하여 사용자 입력 가져오기 및 처리
  • 자신만의 기능 정의함수
  • while 및 for 루프 작성하기
  • 작업조건문
  • Python 작업 문자열, 목록 및 세트

1단계: 행맨 프로젝트 설정

words.txt

prettiest close dog massive hollow cultured seashore explode dizzy minister competent thoughtful harbor tidy dance children zesty clean ball nostalgic plan week strap board slope bat steep mourn cat girl ancient street mice dare wasteful tub limping whimsical eager eggs detail experience beds train place cows admit rare respect loose group enjoy internal macabre imported superb crooked confused hug feigned unkempt coal meddle hapless country zealous sick pray lake tiny key empty labored delirious ants need omniscient onerous damp subtract sack connection toad gather record new trashy flow river sparkling kneel daughter glue allow raspy eminent weak wrong pretend receipt celery plain fire heal damaging honorable foot ignorant substance box crime giant learned itchy smoke likable station jaded innocent dead straw tray chin pack geese guess wealthy slippery book curly swing cure flowers rate ignore insidious necessary snakes entertaining rich comb lamentable fuel camera multiply army exist sulky brief worried third magical wary laborer end somber authority rainstorm anxious purpose agreeable spiky toe mixed waiting hungry lopsided flagrant windy ground slap please white hurry governor abandoned reject spiritual abrasive hunt weather endurable hobbies occur bake print tire juicy blush listen trousers daffy scarecrow rude stem bustling nail sneeze bellicose love

2단계: 추측할 단어 선택

# hangman.py

from random import choice

def select_word():
    with open("words.txt", mode="r") as words:
        word_list = words.readlines()
    return choice(word_list).strip()

귀하의 select_word() 작동 방식은 다음과 같습니다.

from hangman import select_word

select_word() ‘toad’ select_word() ‘daffy’ select_word() ‘insidious’

3단계: 플레이어의 입력 가져오기 및 유효성 검사

# hangman.py
# ...

def get_player_input(guessed_letters):
    while True:
        player_input = input("Guess a letter: ").lower()
        if _validate_input(player_input, guessed_letters):
            return player_input
# hangman.py

import string
# ...

def _validate_input(player_input, guessed_letters):
    return (
        len(player_input) == 1
        and player_input in string.ascii_lowercase
        and player_input not in guessed_letters
    )

from hangman import get_player_input

get_player_input({“a”, “b”}) Guess a letter: 3 Guess a letter: e ‘e’

get_player_input({“a”, “b”}) Guess a letter: a Guess a letter: f ‘f’

4단계: 추측한 글자와 단어 표시

# hangman.py
# ...

def join_guessed_letters(guessed_letters):
    return " ".join(sorted(guessed_letters))
# hangman.py
# ...

def build_guessed_word(target_word, guessed_letters):
    current_letters = []
    for letter in target_word:
        if letter in guessed_letters:
            current_letters.append(letter)
        else:
            current_letters.append("_")
    return " ".join(current_letters)

5단계: 매달린 사람 그리기

ASCII 문자를 사용하여 매달린 사람을 만들어 보겠습니다. 솔루션은 7개의 서로 다른 문자열을 포함하는 목록으로 구성됩니다. 첫 번째 줄은 비계를 나타내고 나머지 6개 부분은 매달린 사람의 신체 부위를 나타냅니다.

  • 머리
  • 몸통
  • 오른팔
  • 왼쪽 팔
  • 오른쪽 다리
  • 왼쪽 다리
# hangman.py
# ...

def draw_hanged_man(wrong_guesses):
    hanged_man = [
        r"""
  -----
  |   |
      |
      |
      |
      |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
      |
      |
      |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
  |   |
  |   |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ |   |
  |   |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ | \ |
  |   |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ | \ |
  |   |
 ---  |
/     |
|     |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ | \ |
  |   |
 ---  |
/   \ |
|   | |
      |
-------
""",
    ]

    print(hanged_man[wrong_guesses])
>>> from hangman import draw_hanged_man

>>> draw_hanged_man(0)

  -----
  |   |
      |
      |
      |
      |
      |
      |
      |
      |
-------

>>> draw_hanged_man(6)

  -----
  |   |
  O   |
 ---  |
/ | \ |
  |   |

 ---  |
/   \ |
|   | |
      |
-------

6단계: 게임이 언제 끝나는지 알아내기

행맨 게임은 다음 두 가지 이벤트 중 하나가 발생하면 종료됩니다.

  1. 플레이어는 6번의 잘못된 추측을 했습니다.
  2. 플레이어는 단어를 정확하게 추측합니다.
# hangman.py
# ...

MAX_INCORRECT_GUESSES = 6
# ...

def game_over(wrong_guesses, target_word, guessed_letters):
    if wrong_guesses == MAX_INCORRECT_GUESSES:
        return True
    if set(target_word) <= guessed_letters:
        return True
    return False

참고: 가독성을 위해 에서 여러 if 문을 사용했습니다. 이 함수를 다음과 같이 작성할 수도 있습니다:game_over()

hangman.py

def game_over(guesses_taken, target_word, letters_guessed): return ( guesses_taken == MAX_INCORRECT_GUESSES or set(target_word) <= letters_guessed )

7단계: 게임 루프 실행

  • 추측할 단어를 무작위로 선택하기
  • 플레이어의 입력 수집 및 처리
  • 추측할 수 없는 문자가 숨겨진 단어 표시
  • 매달린 남자 그림을 보여주는 중
  • 추측한 문자와 추측한 문자 추적
  • 게임이 끝났는지 확인하기
# hangman.py
# ...

if __name__ == "__main__":
    # Initial setup
    target_word = select_word()
    guessed_letters = set()
    guessed_word = build_guessed_word(target_word, guessed_letters)
    wrong_guesses = 0
    print("Welcome to Hangman!")

게임 루프를 작성하는 한 가지 방법은 다음과 같습니다.

# hangman.py
# ...

if __name__ == "__main__":
    # ...

    # Game loop
    while not game_over(wrong_guesses, target_word, guessed_letters):
        draw_hanged_man(wrong_guesses)
        print(f"Your word is: {guessed_word}")
        print(
            "Current guessed letters: "
            f"{join_guessed_letters(guessed_letters)}\n"
        )

        player_guess = get_player_input(guessed_letters)
        if player_guess in target_word:
            print("Great guess!")
        else:
            print("Sorry, it's not there.")
            wrong_guesses += 1

        guessed_letters.add(player_guess)
        guessed_word = build_guessed_word(target_word, guessed_letters)
# hangman.py
# ...

if __name__ == "__main__":
    # ...

    # Game over
    draw_hanged_man(wrong_guesses)
    if wrong_guesses == MAX_INCORRECT_GUESSES:
        print("Sorry, you lost!")
    else:
        print("Congrats! You did it!")
    print(f"Your word was: {target_word}")

$ python hangman.py Welcome to Hangman!

| |
|
|
|
|
|
|
|
|

Your word is: _ _ _ _ _ Current guessed letters:

Guess a letter: e Sorry, it’s not there.

| |
O |
|
|
|
|
|
|
|

Your word is: _ _ _ _ _ Current guessed letters: e

Guess a letter:

다음 단계

이제 행맨 게임 제작을 마쳤으므로 한 단계 더 나아가 계속해서 게임을 개선할 수 있습니다. 또는 방향을 바꿔 다른 멋진 프로젝트에 뛰어들 수도 있습니다. Python을 계속 배우고 프로젝트를 구축하기 위한 몇 가지 훌륭한 다음 단계는 다음과 같습니다.

  • Python과 Rich를 사용하여 Wordle 복제본 구축: 이 단계별 프로젝트에서는 Python을 사용하여 자신만의 Wordle 복제본을 구축하게 됩니다. 게임은 터미널에서 실행되며, 단어 추측 앱이 보기 좋게 보이도록 Rich를 사용하게 됩니다. 명령줄 애플리케이션을 처음부터 구축하는 방법을 배우고 친구들과 경쟁을 벌이세요!
  • Python으로 퀴즈 애플리케이션 구축: 이 단계별 프로젝트에서는 터미널용 Python 퀴즈 애플리케이션을 구축하게 됩니다. 귀하의 앱은 귀하의 지식을 강화하거나 친구들에게 그들의 지식을 테스트하도록 도전하는 데 사용할 수 있는 객관식 질문을 할 것입니다.
  • Python을 사용하여 주사위 굴리기 애플리케이션 구축: 이 단계별 프로젝트에서는 최소한의 텍스트 기반 사용자 인터페이스를 사용하여 주사위 굴리기 시뮬레이터 앱을 구축합니다. 파이썬을 사용하여. 앱은 최대 6개의 주사위 굴리기를 시뮬레이션합니다. 각 주사위에는 6개의 면이 있습니다. 밖에 비가 오나요?
  • Python을 사용하여 날씨 CLI 앱 구축: 이 튜토리얼에서는 이름을 제공하는 모든 도시의 현재 날씨에 대한 정보를 표시하는 멋진 형식의 Python CLI 앱을 작성합니다.
  • 명령줄용 Python 디렉터리 트리 생성기 구축: 이 단계별 프로젝트에서는 명령줄용 Python 디렉터리 트리 생성기 애플리케이션을 만듭니다. argparse를 사용하여 명령줄 인터페이스를 코딩하고 pathlib를 사용하여 파일 시스템을 탐색합니다.

첨부 : hangman.py 전체 source

import string
from random import choice

MAX_INCORRECT_GUESSES = 6


def select_word():
    with open("words.txt", mode="r") as words:
        word_list = words.readlines()
    return choice(word_list).strip()


def get_player_input(guessed_letters):
    while True:
        player_input = input("Guess a letter: ").lower()
        if _validate_input(player_input, guessed_letters):
            return player_input


def _validate_input(player_input, guessed_letters):
    return (
        len(player_input) == 1
        and player_input in string.ascii_lowercase
        and player_input not in guessed_letters
    )


def join_guessed_letters(guessed_letters):
    return " ".join(sorted(guessed_letters))


def build_guessed_word(target_word, guessed_letters):
    current_letters = []
    for letter in target_word:
        if letter in guessed_letters:
            current_letters.append(letter)
        else:
            current_letters.append("_")
    return " ".join(current_letters)


def draw_hanged_man(wrong_guesses):
    hanged_man = [
        r"""
  -----
  |   |
      |
      |
      |
      |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
      |
      |
      |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
  |   |
  |   |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ |   |
  |   |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ | \ |
  |   |
      |
      |
      |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ | \ |
  |   |
 ---  |
/     |
|     |
      |
-------
""",
        r"""
  -----
  |   |
  O   |
 ---  |
/ | \ |
  |   |
 ---  |
/   \ |
|   | |
      |
-------
""",
    ]

    print(hanged_man[wrong_guesses])


def game_over(wrong_guesses, target_word, guessed_letters):
    if wrong_guesses == MAX_INCORRECT_GUESSES:
        return True
    if set(target_word) <= guessed_letters:
        return True
    return False


if __name__ == "__main__":
    # Initial setup
    target_word = select_word()
    guessed_letters = set()
    guessed_word = build_guessed_word(target_word, guessed_letters)
    wrong_guesses = 0
    print("Welcome to Hangman!")

    # Game loop
    while not game_over(wrong_guesses, target_word, guessed_letters):
        draw_hanged_man(wrong_guesses)
        print(f"Your word is: {guessed_word}")
        print(
            "Current guessed letters: "
            f"{join_guessed_letters(guessed_letters)}\n"
        )

        player_guess = get_player_input(guessed_letters)
        if player_guess in target_word:
            print("Great guess!")
        else:
            print("Sorry, it's not there.")
            wrong_guesses += 1

        guessed_letters.add(player_guess)
        guessed_word = build_guessed_word(target_word, guessed_letters)

    # Game over
    draw_hanged_man(wrong_guesses)
    if wrong_guesses == MAX_INCORRECT_GUESSES:
        print("Sorry, you lost!")
    else:
        print("Congrats! You did it!")
    print(f"Your word was: {target_word}")