# %% 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_st = SentenceTransformer( "sentence-transformers/paraphrase-multilingual-mpnet-base-v2" ) config_file_path = "config/lang.json" secret_file_path = "config/secret.json" data_path = "data/" class DictWrapper: def __init__(self, data_dict): self.__dict__.update(data_dict) def __init__(self, lang=0): self.lang = lang 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) if self.lang == 1: self.model = KeyedVectors.load("config/w2v_models/eng_w2v_model", mmap="r") self.Config = self.DictWrapper(self.Config_full["ENG"]["Game"]) self.secret_dict = self.secret["ENG"] else: self.model = KeyedVectors.load("config/w2v_models/esp_w2v_model", mmap="r") 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("---------------------------") 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[self.secret] 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.model.key_to_index.keys(): 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 embedding = self.model[word] self.embeddings_dict[word] = embedding score = round(self.model.similarity(self.secret, word) * 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