파이썬 행맨 게임

8408 단어
2021.07.08 16:38

행맨 게임



소개



Python의 기본 기능을 사용하여 명령줄 단어 추측 게임을 작성했습니다. codingnomads 의 Python 번들 - Python I 의 프로젝트입니다.

이 후속 기사를 학습 기록으로 작성했습니다.

1) 임의의 단어 생성



참조: Geeksforgeeks - pulling a random word or a string from a line in a text file

이전에 JavaScript에 대한 최소한의 경험이 있기 때문에 추가 마일을 걸을 수 있고 선택적인 부분을 수행할 수 있다고 믿습니다.

공백으로 구분된 단어 목록을 작성하여 .txt 파일에 저장했습니다.

hangman.txt
programming strong codingnomads rewarding frustrating


.txt 파일의 단어 목록은 목록처럼 취급됩니다. 무작위 정수는 목록에서 무작위로 한 단어를 선택하는 데 사용됩니다.

import random
with open(r"C:\Users\User\Desktop\codingnomads\Python-101\projects\hangman.txt", "r") as file:
    data = file.read()
    words = data.split()
    words_pos = random.randint(0, len(words) - 1)
    print(f"position: {words_pos}")
    print(f"word at position: {words[words_pos]}")


1.1) 경로 읽기에 대한 세부 정보



참조: stackoverflow - unicode escape

경로가 유니코드 이스케이프r"path"로 처리되지 않으면 오류가 발생합니다.

2) 단어를 문자 목록으로 분할



참조: stackoverflow - is there a function in python to split a word into a list

Python의 구문은 정말 직관적입니다. 단어를 문자 목록으로 분할하는 구문은 간단히 list(word) 입니다.

2.1) 왜 목록을 작성합니까? 빈 문자열이 아닌 이유는 무엇입니까?



Python의 문자열은 변경할 수 없으므로 빈 문자열의 내용을 변경할 수 없습니다. List는 항목 할당을 지원하는 간단한 구조입니다.

# container = "    "
# container[1] = "a"
# TypeError: 'str' object does not support item assignment


3) 입력 확인



사용자 입력을 확인하기 위해 기본 while 루프 내부에서 while 루프를 사용합니다.

사용자는 다음만 입력할 수 있습니다.
  • 알파벳guess.isalpha()
  • 단일 알파벳len(guess) == 1
  • 알파벳이 아직 정확하게 추측되지 않음guess in container

  • while container != word:
        guess = input("Guess an alphabet: ").lower()
        while not guess.isalpha() or len(guess) > 1:
            guess = input("We only allow single character input. Please guess again: ").lower()
      while guess.lower() in container:
            guess = input(f"{guess.upper()} is already guessed. Please guess another alphabet: ").lower()
    


    3.1) 들여쓰기 수준 기억



    들여쓰기 수준은 Python에서 중요합니다.
    guess in container 루프가 not guess.isalpha() or len(guess) > 1 루프 아래에 들여쓰기되어 있으면 Python은 길이가 1보다 길고 알파벳이 아닌 추측만 검사합니다. 결과는 Python이 컨테이너에 있는 잘못된 추측만 검사하고 답은 항상 아니오가 될 것입니다. 이렇게 하면 스니펫이 의미가 없습니다.

    4) 사용자가 시도한 횟수에 대한 카운터 생성



    위치가 중요합니다. Python에는 루프 내부에 선언된 변수가 루프 외부에서 액세스될 수 있다는 엄격한 네임스페이스 규칙이 없지만 변수를 선언하는 위치는 여전히 중요합니다.

    메인 while 루프 외부에서 카운터를 선언해야 함을 기억하십시오while container != word. 그렇지 않으면 카운터는 모든 루프에서 0 값을 다시 할당합니다. 이는 카운터가 0 다음 1 다음 0 만 표시하므로 의미가 없음을 의미합니다.

    5) 같은 값을 가진 모든 인덱스 반환



    참조: codegrepper - how to return all index with same value in list

    Codegrepper는 enumerate() 로 한 줄 솔루션을 제안합니다.
    indices = [i for i, x in enumerate(word) if x == guess]
    참조: stackoverflow - index of duplicate items in a python list

    Stackoverflow는 카운터를 인덱스로 사용하여 원하는 값을 가진 요소를 찾는 간단한 답변을 제안합니다.

    if elem in string_list:
         counter = 0
         elem_pos = []
         for i in string_list:
             if i == elem:
                 elem_pos.append(counter)
             counter = counter + 1
         print(elem_pos)
    


    6) 컨테이너 목록에 새 값 할당



    이제 변경할 수 없는 문자열이 아닌 변경 가능한 목록으로 작업하고 있습니다. 따라서 문자열의 요소 값을 다시 할당할 수 있습니다.

    for index in indices:
            if word[index] == guess:
                    container[index] = guess
    


    7) 디스플레이 용기


    print() 함수가 sep (분리)와 end (끝)의 인수를 취한다는 것을 아는 것이 편리합니다. 컨테이너의 모든 요소가 같은 줄에 배치되도록 기본 끝을 "\n"에서 ""로 변경합니다.

    for char in container:
        if char.isalpha():
            print(f" {char} ", sep=" ", end="")
        else:
            print(" _  ", sep=" ", end="")
    print("\n")
    


    8) 게임 종료 메시지



    파이썬은 list(str) 로 문자열을 쉽게 목록으로 바꿀 수 있고, "".join(list) 로 목록을 문자열로 바꿀 수 있습니다.

    출력을 더 예쁘게 만들기 위해 str.formatstr.upper() 메서드를 적용하고 싶기 때문에 여기에 문자열이 필요합니다.

    if container == word:
        print(f"""
                Congratulation! You made it!
                The word is {"".join(word).upper()!r}!
        """)
    
    else:
        print(f"""
                Your guesses are close.
                The word is {"".join(word).upper()!r}.
        """)
    


    전체 코드




    import random
    with open(r"C:\Users\User\Desktop\codingnomads\Python-101\projects\hangman.txt", "r") as file:
        data = file.read()
        words = data.split()
        words_pos = random.randint(0, len(words) - 1)
        # print(f"position: {words_pos}")
        # print(f"word at position: {words[words_pos]}")
    
    word = list(words[words_pos])
    container = list(len(word) * " ")
    limit = len(word) + 5
    counter = 0 
    # print(word)
    # print(container)
    
    print(f"""
            Welcome! Let's play Hangman, the word-guessing game.
            You will have {limit} chances to guess the word
            Let's begin! 
    """)
    
    for char in word:
        print(" _ ", sep=" ", end="")
    print("\n\n\n")
    
    while container != word:
        guess = input("Guess an alphabet: ").lower()
        while not guess.isalpha() or len(guess) > 1:
            guess = input("We only allow single character input. Please guess again: ").lower()
        while guess.lower() in container:
            guess = input(f"{guess.upper()} is already guessed. Please guess another alphabet: ").lower()
        counter += 1
        print(f"Number of guessess: {counter}")
    
            if counter > limit:
            print(f"You have already guessed {counter} times. You run out of time.")
            break
    
        for char in word:
            if guess == char:
                indices = [i for i, x in enumerate(word) if x == guess]
                # print(indices)
                for index in indices:
                    if word[index] == guess:
                        container[index] = guess
    
        for char in container:
            if char.isalpha():
                print(f" {char} ", sep=" ", end="")
            else:
                print(" _  ", sep=" ", end="")
        print("\n")
    
    if container == word:
        print(f"""
                Congratulation! You made it!
                The word is {"".join(word).upper()!r}!
        """)
        # how to join list into a string
        # https://www.simplilearn.com/tutorials/python-tutorial/list-to-string-in-python
    else:
        print(f"""
                Your guesses are close.
                The word is {"".join(word).upper()!r}.
        """)
    


    제 글을 읽어주셔서 감사합니다. 언제든지 의견을 남겨주세요.

    좋은 웹페이지 즐겨찾기