파이썬으로 Wordle 코딩하기

치섭·2022년 2월 6일
0

안녕하세요 정말 오랜만의 포스팅입니다.
저는 그간 새로운 회사에 적응하느라 애를 많이 썼습니다ㅋㅋㅋ
너무 오랜만에 통근을 하다보니 체력적으로 많이 부치네요ㅠ

저는 요즘 Wordle 워들이라는 게임에 푹 빠져있습니다!

숫자야구와도 언뜻 비슷한 이 게임은 크로스워드 게임으로도 꽤 유명한
신문사 뉴욕타임즈에서 인수될 정도로 선풍적인 인기를 끈 게임입니다.

게임을 간단히 설명드리자면 하루에 단 한개의 5자짜리 단어를 전세계 사람들이 다함께 맞추는 게임입니다.
기회는 단 6번이고, 내가 입력한 글자가 단어 안에 있고 위치도 맞으면 초록색, 위치가 다르면 노란색, 아예 없으면 회색으로 표시됩니다.

공식 어플도 없는 웹게임인데도 제가 출퇴근시간에 틈틈히 플레이할 정도로 매우 재미있는 게임인데요,
문득 플레이를 하다보니 파이썬으로 워들을 만들어보면 재미있겠다는 생각이 들었습니다.
그럼 아래부터는 코드와 간단한 설명을 드리겠습니다.

1. 단어 랜덤 생성기

코드는 크게 두 부분으로 나뉘어져있습니다.
첫번째는 유효한 단어를 랜덤으로 생성해주는 단어 생성기 부분이고
두번째는 게임이 실행되는 워들부분입니다.

우선 라이브러리를 받아주겠습니다.

import enchant as en
import string
import random
from colorama import Fore, Style
from datetime import datetime

이번에는 저도 처음 써보는 라이브러리가 몇 개 있는데요,
enchant 는 단어의 철자를 체크해주는 파이썬 모듈이고,
string은 굳이 없어도 되긴 한데... 아래처럼 연속된 문자열을 간편하게 가져오기 위해 import 했습니다 ㅎㅎ 귀차니스트들에게 최적인 모듈입니다ㅋㅋㅋ

string.ascii_uppercase
> 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

colorama는 콘솔에 찍히는 텍스트에 색을 입혀주는 모듈입니다.
randomdatetime 함수는 익숙하시죠?
값을 랜덤으로 뽑아주고, 타임스탬프를 찍기위해 가져왔습니다.

단어 생성기 함수부터 보겠습니다.

dic = en.Dict("en_US")

def random_word_generator(num):
    while True:    
        letter = "".join(random.sample(string.ascii_uppercase, num))
        if dic.check(letter) == True:
            break
    return letter

우선 영어로 언어를 지정하여 사전을 생성하고 dic 변수에 담았습니다.
string 모듈의 string.ascii_uppercase를 이용해 대문자 알파벳을 모두 가져온 뒤,
그리고 sample() 함수를 이용해 랜덤으로 num개를 뽑고,
뽑힌 5자 짜리 단어가 유효한 단어인지를 enchant 모듈의 check() 함수를 통해 체크해주었습니다.

예를 들어 랜덤으로 생성된 단어가 SKDJE와 같이 없는 단어라면 False,
SPACE와 같이 있는 단어라면 True를 반환할 것입니다.
그리고 이 과정을 while문에 넣어 유효한 단어가 생성 될때 까지 돌리도록 코딩했습니다.

대문자만 가지고 단어를 만들어주기 때문에 경우의 수가 비교적 적어서 금방 단어가 만들어지더라구요!
이게 랜덤으로 단어를 생성하는 코드의 끝입니다. 아주 간단하죠?

2. 워들

while True:
        life = life+1
        user_input = input('단어 입력: ').upper()
        
        # 5글자 입력이 아닐경우 & 존재하지 않는 단어일 때 무한 질문
        while (len(user_input) != 5) or (dic.check(user_input) == False):
            user_input = input('유효하지 않은 단어입니다.\n단어 재입력: ').upper()

코드가 무지막지하게 길진 않지만 한번에 보기엔 헷갈릴 것 같아 메인인 워들 부분은 끊어서 보도록 하겠습니다.
우선 아무 글자나 입력하거나 5자 이상의 단어를 입력하는 것을 방지해주기 위해서
while문을 이용하여 위의 두가지 조건을 충족하지 못한다면 단어를 무한 재입력하도록 했습니다.

abt = list(string.ascii_uppercase)
answer = []
for idx, val in enumerate(user_input):
    is_there = word.find(val)
    # 단어안에 해당 글자가 있을 경우
    if is_there != -1:
        # 위치까지 동일하면 초록
        if idx == is_there:
            char = Fore.GREEN + val + Style.RESET_ALL
        # 있지만 위치는 다르다면 노랑
        else:
            char = Fore.YELLOW + val + Style.RESET_ALL
        answer.append(char)
    # 단어안에 해당 글자가 아예 없으면 빨강
    elif is_there == -1:
        char = Fore.RED + val + Style.RESET_ALL
        for abt_idx, abt_val in enumerate(abt):
            if val in abt_val:
                abt[abt_idx] = char
        answer.append(char)

이 부분은 사용자가 입력한 단어인 user_input의 글자를 검증하는 부분입니다.
여기서 colorama 모듈의 함수를 사용하게 되는데요,
간단히 설명드리면 Fore.색깔 + str + Style.RESET_ALL 의 형식으로 작성하고
print()하면 콘솔에 색이 입혀진 텍스트로 출력됩니다.

예) Fore.GREEN + str + Style.RESET_ALL

위와 같이 작성하면 초록색 글씨가 출력되고 RED, YELLOW 등 다양한 색이 가능합니다.
Style.RESET_ALL을 작성하지 않으면
처음 초록색으로 입력된 글자 뒤의 모든 단어가 초록색이 되므로 꼭 스타일 리셋을 해주어야합니다.

리스트 abt는 A-Z까지의 알파벳 중 어떤 단어를 입력했고, 어떤 결과가 나왔었는지 출력해주기 위해 선언해줬고,
이 정답지와 별개로 맞으면 초록|노랑, 틀리면 빨간색으로 user_input을 칠해주기 위해서
answer 변수에 append 해주었습니다.

answer = " ".join(answer)
print(f"\n{ life }번째 시도: { user_input }")  
print(f"결과: {answer}")
print(' '.join(abt))

if answer.count('32') == 5:
            print(f'\n축하합니다! {life}번만에 맞추셨습니다!')
            break
        elif life == 6:
            print('\n6번의 기회를 모두 사용했지만 정답을 맞추는 것에 실패했습니다.')
            print(f'오늘의 단어는 {word}입니다.')
            break


헷갈리실 것 같아 결과물을 첨부해드리면 여기서 n번째 시도 옆에 표시된 것이 user_input,
결과: 옆에 표시된 것이 answer, 그리고 그 아래가 abt입니다.
놀랍게도 이게 코드의 거의 전부입니다.
변수에 결과를 다 담아주었으니 나머지는 이제 결과를 출력해줄일만 남았습니다.

32는 나중에 출력해보시면 아시겠지만
초록색으로 입력 되었을 때 colorama에 의해 추가되는 문자의 일부입니다.
따라서 32가 5개라는건 곧 정답을 의미합니다.

3. 플레이하기

자 코드가 완성이 되었으니 플레이해볼까요?

wordle(random_word_generator(5))

이런식으로 함수를 실행시켜주면 인풋창이 뜨게됩니다.
거기에 단어를 입력하고 6번 내에 단어를 맞춰보세요!!!

저는 실제 워들처럼 공유용 status 등등 사소한 부분을 약간 추가해보았습니다.
풀코드는 제 깃헙에서 확인하실 수 있습니다.

소감

퇴근하고 짬짬히 작성해본 코든데 꽤 재미있었습니다 ㅎㅎ
UI도 붙여서 말 그대로 클론코딩을 해볼까도 했는데 이정도로도 충분히 플레이가능한 것 같아서
거기까진 가지 않았습니다 ㅋㅋㅋ

다음으로 하고싶은건 이제 워들을 만들었으니 정답을 맞추는 크래커도 한번 만들어보고싶네요!
다음 포스팅은 크래커와 함께 돌아와보도록 하겠습니다.
읽어주셔서 감사합니다!

profile
주니어 웹개발자

0개의 댓글