feat: operator corrections injected into similar questions

This commit is contained in:
marcos
2026-08-06 03:09:11 +00:00
parent aee991bb7b
commit 5cfa580997
2 changed files with 128 additions and 0 deletions
@@ -0,0 +1,89 @@
package dev.marcospaulo.canalhandia;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
/**
* Operator corrections, injected when a new question resembles one that was
* answered wrongly before.
*
* <p>This is the cheap alternative to fine-tuning: a wrong answer becomes
* context, so the same mistake stops recurring.
*/
final class Corrections {
record Entry(String question, String answer) {
}
private final File file;
private final List<Entry> entries = new ArrayList<>();
Corrections(File file) {
this.file = file;
load();
}
void load() {
entries.clear();
if (!file.exists()) {
return;
}
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
for (String key : yaml.getKeys(false)) {
String question = yaml.getString(key + ".pergunta");
String answer = yaml.getString(key + ".resposta");
if (question != null && answer != null) {
entries.add(new Entry(question, answer));
}
}
}
void add(String question, String answer) {
entries.add(new Entry(question, answer));
YamlConfiguration yaml = new YamlConfiguration();
for (int i = 0; i < entries.size(); i++) {
yaml.set("c" + i + ".pergunta", entries.get(i).question());
yaml.set("c" + i + ".resposta", entries.get(i).answer());
}
try {
yaml.save(file);
} catch (Exception e) {
throw new IllegalStateException("não consegui gravar " + file, e);
}
}
List<Entry> all() {
return List.copyOf(entries);
}
/** Corrections sharing at least one significant word with the question. */
static List<Entry> matching(List<Entry> all, String question) {
Set<String> asked = significantWords(question);
List<Entry> out = new ArrayList<>();
for (Entry entry : all) {
Set<String> known = significantWords(entry.question());
known.retainAll(asked);
if (known.size() >= 1) {
out.add(entry);
}
}
return out;
}
private static Set<String> significantWords(String text) {
Set<String> words = new HashSet<>();
for (String word : text.toLowerCase(Locale.ROOT).split("[^\\p{L}0-9]+")) {
// Short words are almost all articles and prepositions in Portuguese.
if (word.length() > 4) {
words.add(word);
}
}
return words;
}
}