| | |
| | |
| |
|
| | |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | 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: |
| |
|
| | |
| | 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, model_type="SentenceTransformer"): |
| |
|
| | |
| | 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 |
| |
|
| | |
| | self.model_type = model_type |
| |
|
| | 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"] |
| |
|
| | |
| | if self.model_type == "SentenceTransformer": |
| | self.model_trans = KeyedVectors(768) |
| |
|
| | self.model_st = SentenceTransformer( |
| | "sentence-transformers/paraphrase-multilingual-mpnet-base-v2" |
| | ) |
| |
|
| | |
| | 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.model_type == "SentenceTransformer": |
| | |
| | |
| | if self.secret not in self.model_trans.key_to_index.keys(): |
| | self.model_trans.add_vector( |
| | self.secret, |
| | self.model_st.encode(self.secret, convert_to_tensor=True).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 gen_rank(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.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 |
| |
|
| | |
| | if ( |
| | self.model_type == "SentenceTransformer" |
| | and word not in self.model_trans.key_to_index.keys() |
| | ): |
| | self.model_trans.add_vector( |
| | word, self.model_st.encode(word, convert_to_tensor=True).tolist() |
| | ) |
| |
|
| | |
| | if self.model_type == "word2vec": |
| | similarity = self.model.similarity(self.secret, word) |
| | else: |
| | similarity = self.model_trans.similarity(self.secret, word) |
| |
|
| | log_similarity = np.log10(similarity * 10) if similarity > 0 else 0 |
| | score = round( |
| | np.interp( |
| | log_similarity, |
| | [0, np.log10(10)], |
| | [0, 10], |
| | ), |
| | 2, |
| | ) |
| |
|
| | |
| | if repeated == -1: |
| | 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.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.gen_rank(repeated) |
| |
|
| | |
| | feedback += "[rank]" + open(self.data_path + "ranking.txt", "r").read() |
| |
|
| | |
| | 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 |
| |
|