Source code for literate_wordle.game

"""Wordle game's state and playing rounds"""


from dataclasses import dataclass
from enum import Enum
from typing import Optional

from literate_wordle.guess import CharacterScore, score_guess
from literate_wordle.words import check_valid_word


[docs]class WordleMoveOutcome(Enum): """Outcome of a single move"""
[docs] GAME_OVER_LOST = 1
[docs] GAME_WON = 2
[docs] GUESS_SCORED_CONTINUE = 3
[docs] GUESS_NOTVALID_CONTINUE = 4
@dataclass
[docs]class WordleGame: """A Wordle game's internal state, before a move is played"""
[docs] answer: str
[docs] guess_number: int
@dataclass
[docs]class WordleMove: """A Wordle game state once a move is played"""
[docs] game: WordleGame
[docs] outcome: WordleMoveOutcome
[docs] message: str
[docs] score: Optional[str]
[docs]def play_round(guess: str, game: WordleGame) -> WordleMove: """Use guess on the given game, resulting in WordleMove""" if game.guess_number >= 7: message = f"Too many guesses: Game Over. Answer was: {game.answer}" outcome = WordleMoveOutcome.GAME_OVER_LOST return WordleMove(game=game, outcome=outcome, message=message, score=None) valid, validity_msg = check_valid_word(guess) if not valid and validity_msg is not None: outcome = WordleMoveOutcome.GUESS_NOTVALID_CONTINUE return WordleMove(game=game, outcome=outcome, message=validity_msg, score=None) # Guess now guaranteed to be valid: count it game.guess_number += 1 score = score_guess(guess, game.answer) if score == CharacterScore.perfect_score: outcome = WordleMoveOutcome.GAME_WON message = f"Correct! Game won in {game.guess_number - 1} guesses" return WordleMove(game=game, outcome=outcome, message=message, score=score) # Only case left is "try another guess" outcome = WordleMoveOutcome.GUESS_SCORED_CONTINUE message = f"Try again! Guess number {game.guess_number - 1}. Score is: {score}" return WordleMove(game=game, outcome=outcome, message=message, score=score)