Spaces:
Sleeping
Sleeping
# %% | |
import json | |
import random | |
from datetime import datetime | |
import numpy as np | |
from gensim.models import KeyedVectors | |
from hints import curiosity, hint | |
from tracking import ( | |
calculate_moving_average, | |
calculate_tendency_slope, | |
) | |
from sentence_transformers import SentenceTransformer | |
import warnings | |
warnings.filterwarnings(action="ignore", category=UserWarning, module="gensim") | |
class Semantrix: | |
model = KeyedVectors(768) | |
model_st = SentenceTransformer( | |
"sentence-transformers/paraphrase-multilingual-mpnet-base-v2" | |
) | |
config_file_path = "config/lang.json" | |
secret_file_path = "config/secret.json" | |
possible_words_file_path = "config/words.txt" | |
data_path = "data/" | |
class DictWrapper: | |
def __init__(self, data_dict): | |
self.__dict__.update(data_dict) | |
def __init__(self, lang=0): | |
self.embeddings_dict = {} | |
with open(self.config_file_path, "r") as file: | |
self.Config_full = json.load(file) | |
with open(self.secret_file_path, "r") as file: | |
self.secret = json.load(file) | |
self.lang = lang | |
if self.lang == 1: | |
self.Config = self.DictWrapper(self.Config_full["ENG"]["Game"]) | |
self.secret_dict = self.secret["ENG"] | |
else: | |
self.Config = self.DictWrapper(self.Config_full["SPA"]["Game"]) | |
self.secret_dict = self.secret["SPA"] | |
with open(self.data_path + "ranking.txt", "w+") as file: | |
file.write("---------------------------") | |
with open(self.possible_words_file_path, "r") as file: | |
data = file.read() | |
self.possible_words = data.split("\n") | |
def prepare_game(self, difficulty): | |
self.secret_list = ( | |
self.secret_dict["basic"] | |
if difficulty <= 2 | |
else self.secret_dict["advanced"] | |
) | |
self.secret = self.secret_list.pop(random.randint(0, len(self.secret_list) - 1)) | |
self.secret = self.secret.lower() | |
self.words = [self.Config.secret_word] | |
self.scores = [10] | |
if self.secret not in self.embeddings_dict.keys(): | |
self.embeddings_dict[self.secret] = self.model_st.encode( | |
self.secret, convert_to_tensor=True | |
) | |
self.model.add_vector( | |
self.secret, self.embeddings_dict[self.secret].tolist() | |
) | |
self.word_vect = [self.embeddings_dict[self.secret].tolist()] | |
self.win = False | |
self.n = 0 | |
self.recent_hint = 0 | |
self.f_dev_avg = 0 | |
self.last_hint = -1 | |
self.difficulty = difficulty | |
if self.difficulty == 1: | |
self.n = 3 | |
def preproc_vectors(self, repeated): | |
ascending_indices = np.argsort(self.scores) | |
descending_indices = list(ascending_indices[::-1]) | |
ranking_data = [] | |
k = len(self.words) - 1 | |
if repeated != -1: | |
k = repeated | |
ranking_data.append(["#" + str(k), self.words[k], self.scores[k]]) | |
ranking_data.append("---------------------------") | |
for i in descending_indices: | |
if i == 0: | |
continue | |
ranking_data.append(["#" + str(i), self.words[i], self.scores[i]]) | |
with open(self.data_path + "ranking.txt", "w+") as file: | |
for item in ranking_data: | |
file.write("%s\n" % item) | |
def play_game(self, word): | |
word = word.lower() | |
if word == "give_up": | |
text = ( | |
"[lose]" | |
+ self.Config.Feedback_9 | |
+ self.secret | |
+ "\n\n" | |
+ self.Config.Feedback_10 | |
) | |
return text | |
if word in self.words: | |
repeated = self.words.index(word) | |
else: | |
repeated = -1 | |
self.words.append(word) | |
if word not in self.embeddings_dict.keys(): | |
if word not in self.possible_words: | |
self.words.pop(len(self.words) - 1) | |
feedback = ( | |
"I don't know that word. Try again." | |
if self.lang == 1 | |
else "No conozco esa palabra. Inténtalo de nuevo." | |
) | |
feedback += ( | |
"[rank]" + open(self.data_path + "ranking.txt", "r").read() | |
if len(self.words) > 1 | |
else "\n\n" | |
) | |
return feedback | |
else: | |
embedding = self.model_st.encode(word, convert_to_tensor=True) | |
self.embeddings_dict[word] = embedding | |
self.model.add_vector(word, embedding.tolist()) | |
score = round( | |
np.interp( | |
np.log(self.model.similarity(self.secret, word) * 10), | |
[0, np.log(10)], | |
[0, 10], | |
), | |
2, | |
) | |
if repeated == -1: | |
self.word_vect.append(self.embeddings_dict[word].tolist()) | |
self.scores.append(score) | |
if score <= 2.5: | |
feedback = self.Config.Feedback_0 + str(score) | |
elif score > 2.5 and score <= 4.0: | |
feedback = self.Config.Feedback_1 + str(score) | |
elif score > 4.0 and score <= 6.0: | |
feedback = self.Config.Feedback_2 + str(score) | |
elif score > 6.0 and score <= 7.5: | |
feedback = self.Config.Feedback_3 + str(score) | |
elif score > 7.5 and score <= 8.0: | |
feedback = self.Config.Feedback_4 + str(score) | |
elif score > 8.0 and score < 10.0: | |
feedback = self.Config.Feedback_5 + str(score) | |
else: | |
self.win = True | |
feedback = "[win]" + self.Config.Feedback_8 | |
self.words[0] = self.secret | |
self.words.pop(len(self.words) - 1) | |
self.word_vect.pop(len(self.word_vect) - 1) | |
self.scores.pop(len(self.scores) - 1) | |
if score > self.scores[len(self.scores) - 2] and self.win == False: | |
feedback += "\n" + self.Config.Feedback_6 | |
elif score < self.scores[len(self.scores) - 2] and self.win == False: | |
feedback += "\n" + self.Config.Feedback_7 | |
if self.difficulty != 4: | |
mov_avg = calculate_moving_average(self.scores[1:], 5) | |
if len(mov_avg) > 1 and self.win == False: | |
f_dev = calculate_tendency_slope(mov_avg) | |
f_dev_avg = calculate_moving_average(f_dev, 3) | |
if f_dev_avg[len(f_dev_avg) - 1] < 0 and self.recent_hint == 0: | |
i = random.randint(0, len(self.Config.hint_intro) - 1) | |
feedback += "\n\n[hint]" + self.Config.hint_intro[i] | |
hint_text, self.n, self.last_hint = hint( | |
self.secret, | |
self.n, | |
self.model_st, | |
self.last_hint, | |
self.lang, | |
( | |
self.DictWrapper(self.Config_full["ENG"]["Hint"]) | |
if self.lang == 1 | |
else self.DictWrapper(self.Config_full["SPA"]["Hint"]) | |
), | |
) | |
feedback += "\n" + hint_text | |
self.recent_hint = 3 | |
if self.recent_hint != 0: | |
self.recent_hint -= 1 | |
self.preproc_vectors(repeated) | |
feedback += "[rank]" + open(self.data_path + "ranking.txt", "r").read() | |
if self.win: | |
bold_display = 0 | |
if self.win: | |
with open(self.data_path + "ranking.txt", "r") as original_file: | |
file_content = original_file.readlines() | |
new_file_name = self.secret + "_" + str(datetime.now()) + ".txt" | |
with open(self.data_path + "plays/" + new_file_name, "w+") as new_file: | |
new_file.writelines(file_content[2:]) | |
return feedback | |
def curiosity(self): | |
feedback = curiosity( | |
self.secret, | |
( | |
self.DictWrapper(self.Config_full["ENG"]["Hint"]) | |
if self.lang == 1 | |
else self.DictWrapper(self.Config_full["SPA"]["Hint"]) | |
), | |
) | |
return feedback | |