File size: 4,835 Bytes
1c56d55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Load our data
import os

def load_raw_text(corpus_directory: str, file_names=None) -> str:
    """Loads all the text files in a directory into one large string"""
    corpus = ""
    
    for file_name in os.listdir(corpus_directory):
        # Read the file as a string
        file_path = os.path.join(corpus_directory, file_name)
        if os.path.isdir(file_path):
            continue
            
        #  Make sure we only read text files
        if ".txt" not in file_name:
            continue
            
        with open(file_path, 'r') as file:
            file_contents = file.read()
            corpus += (file_contents + "\n")
    return corpus

# REPLACE WITH YOUR CORPUS DIRECTORY
corpus = load_raw_text(corpus_directory="./corpus")

import re
import util

# TODO: Strip accents using util.strip_accents


# TODO: Make corpus lowercase
corpus = corpus.lower()

# TODO: Split corpus into tokens using the following function
word_regex = r"[a-zïëñ]+"
def tokenize(text: str):
    return re.findall(word_regex, text)
s_tok = tokenize(corpus)

# TODO: Create a set named "lexicon" with all of the unique words
lexicon = set()
for word in s_tok:
    lexicon.add(word)

filtered_lexicon = set()

for word in lexicon:
    if 3 <= len(word) <= 7:
        filtered_lexicon.add(word)

import random

def random_scramble(lexicon: set):
    lexicon = list(lexicon)
    
    word = random.choice(lexicon)
    
    # Turn the word into a list of characters 
    word_chars = list(word)
    
    # Shuffle those characters
    random.shuffle(word_chars)
    
    # Re-join the characters into a string
    shuffled = ''.join(word_chars)
    
    return {'shuffled': shuffled, 'original': word}

import gradio as gr
from typing import Tuple

def create_hangman_clue(word, guessed_letters):
    """
    Given a word and a list of letters, create the correct clue. 
    
    For instance, if the word is 'apple' and the guessed letters are 'a' and 'l', the clue should be 'a _ _ l _'
    """
    clue = ''
    for letter in word:
        if letter in guessed_letters:
            clue += letter + ' '
        else:
            clue += '_ '
    return clue
    

def pick_new_word(lexicon):
    lexicon = list(lexicon)
    
    return {
        'word': random.choice(lexicon),
        'guessed_letters': set(),
        'remaining_chances': 6
    }


def hangman_game(current_state, guess):
    """Update the current state based on the guess."""
    
    
    if guess in current_state['guessed_letters'] or len(guess) > 1:
        # Illegal guess, do nothing
        return (current_state, 'Invalid guess')
    
    current_state['guessed_letters'].add(guess)
    
    if guess not in current_state['word']:
        # Wrong guess
        current_state['remaining_chances'] -= 1
        
        if current_state['remaining_chances'] == 0:
            # No more chances! New word
            current_state = pick_new_word(filtered_lexicon)
            return (current_state, 'You lose!')
        else:
            return (current_state, 'Wrong guess :(')
        
    else:
        # Right guess, check if there's any letters left
        for letter in current_state['word']:
            if letter not in current_state['guessed_letters']:
                # Still letters remaining
                return (current_state, 'Correct guess!')
        
        # If we made it here, there's no letters left.
        current_state = pick_new_word(filtered_lexicon)
        return (current_state, 'You win!')
    

def state_changed(current_state):
    clue = create_hangman_clue(current_state['word'], current_state['guessed_letters'])
    guessed_letters = current_state['guessed_letters']
    remaining_chances = current_state['remaining_chances']
    return (clue, guessed_letters, remaining_chances)


with gr.Blocks(theme=gr.themes.Soft(), title="karijona Hangman") as hangman:
    current_word = gr.State(pick_new_word(filtered_lexicon))
    
    gr.Markdown("# karijona Hangman")
    
    with gr.Row():
        current_word_textbox = gr.Textbox(label="Clue", interactive=False, value=create_hangman_clue(current_word.value['word'], current_word.value['guessed_letters']))
        guessed_letters_textbox = gr.Textbox(label="Guessed letters", interactive=False)
        remaining_chances_textbox = gr.Textbox(label="Remaining chances", interactive=False, value=6)
    
    guess_textbox = gr.Textbox(label="Guess")
    guess_button = gr.Button(value="Submit")
    
    output_textbox = gr.Textbox(label="Result", interactive=False)
    
    guess_button.click(fn=hangman_game, inputs=[current_word, guess_textbox], outputs=[current_word, output_textbox])\
                .then(fn=state_changed, inputs=[current_word], outputs=[current_word_textbox, guessed_letters_textbox, remaining_chances_textbox])
    
hangman.launch()