Spaces:
Sleeping
Sleeping
| import random | |
| import streamlit as st | |
| from a3c.play import get_play_model_path, suggest | |
| from wordle_env.wordle import get_env | |
| from wordle_env.words import complete_vocabulary, target_vocabulary | |
| def initial_config() -> None: | |
| """ | |
| Function to configure the app | |
| """ | |
| st.title("Wordle Game 🔠") | |
| if "secret_word" not in st.session_state: | |
| st.session_state["secret_word"] = random.choice(target_vocabulary) | |
| if "guesses" not in st.session_state: | |
| st.session_state["guesses"] = [] | |
| if "won" not in st.session_state: | |
| st.session_state["won"] = False | |
| def reset_state() -> None: | |
| """ | |
| Deletes all the game state to start again | |
| """ | |
| for key in st.session_state.keys(): | |
| del st.session_state[key] | |
| def game_not_finished() -> bool: | |
| """ | |
| Condition that tells if the game is finished or not | |
| It could because there are not more attempts or because the user won | |
| """ | |
| return not st.session_state.get("won") and len(st.session_state.guesses) < 6 | |
| def get_ai_guess() -> str: | |
| """ | |
| Call the AI to make a guess based on the game state | |
| """ | |
| env = get_env() | |
| model_path = get_play_model_path() | |
| words = list(map(lambda guess: guess[0], st.session_state.get("guesses"))) | |
| states = list(map(lambda guess: guess[2], st.session_state.get("guesses"))) | |
| ai_guess = suggest(env, words, states, model_path) | |
| return ai_guess | |
| def render() -> None: | |
| """ | |
| Function to render the app | |
| """ | |
| st.markdown( | |
| "<style>.big-font {font-size:30px; display: inline-block; margin: 2px; padding: 10px; border-radius: 5px; text-align: center;}</style>", | |
| unsafe_allow_html=True, | |
| ) | |
| if game_not_finished(): | |
| guess_input = st.text_input("Enter your guess:", key="guess_input") | |
| col1, col2 = st.columns([0.2, 1]) | |
| with col1: | |
| st.button("Submit", on_click=lambda: process_guess(guess_input)) | |
| with col2: | |
| st.button("Ask AI ✨", on_click=lambda: process_guess(get_ai_guess())) | |
| elif st.session_state.get("won"): | |
| st.success("Congratulations! You guessed the word!") | |
| else: | |
| st.error("Game Over! The word was: " + st.session_state.secret_word) | |
| # Display guesses and feedback centered | |
| display_guesses() | |
| def process_guess(guess: str) -> None: | |
| """ | |
| Process the user guess and sets if the user won or not | |
| """ | |
| guess = guess.upper() | |
| if not len(guess) == 5 or not guess.isalpha(): | |
| st.warning("Please enter a valid 5-letter word.") | |
| elif guess not in complete_vocabulary: | |
| st.warning("That is not a valid word.") | |
| else: | |
| if guess == st.session_state.secret_word: | |
| st.session_state["won"] = True | |
| feedback, state = check_guess(guess) | |
| st.session_state.guesses.append((guess, feedback, state)) | |
| def display_guesses() -> None: | |
| """ | |
| Display the user guesses with the feedback in a pretty format | |
| """ | |
| for guess, feedback, _ in st.session_state.guesses: | |
| guess_display = '<div style="text-align: center;">' | |
| for i, letter in enumerate(guess): | |
| color = feedback[i] | |
| guess_display += f'<span class="big-font" style="background-color: {color};">{letter}</span>' | |
| guess_display += "</div>" | |
| st.markdown(guess_display, unsafe_allow_html=True) | |
| if game_not_finished(): | |
| st.write("You have {} guesses left.".format(6 - len(st.session_state.guesses))) | |
| else: | |
| if st.button("Reset game"): | |
| reset_state() | |
| st.rerun() | |
| def check_guess(guess: str) -> tuple[list[str], list[str]]: | |
| """ | |
| Takes a guess and returns the guess feedback | |
| depending if the letters are in the right place or not | |
| """ | |
| feedback = ["grey"] * 5 | |
| word_list = list(st.session_state.secret_word) | |
| processed_letters = [] | |
| state = ["0"] * 5 | |
| # Check for correct position (green) | |
| for i, letter in enumerate(guess): | |
| if letter == word_list[i]: | |
| feedback[i] = "green" | |
| state[i] = "2" | |
| processed_letters.append(letter) | |
| # Check for correct letter but wrong position (yellow) | |
| for i, letter in enumerate(guess): | |
| if ( | |
| feedback[i] == "grey" | |
| and letter in word_list | |
| and word_list.count(letter) > processed_letters.count(letter) | |
| ): | |
| feedback[i] = "yellow" | |
| state[i] = "1" | |
| processed_letters.append(letter) | |
| return feedback, state | |
| # Main function | |
| if __name__ == "__main__": | |
| initial_config() | |
| render() | |