From ffeae91b0ac33d3014c9a483d800d70a73a50bea Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Tue, 27 Feb 2024 14:28:08 +0200 Subject: [PATCH] Suggest corrections for misspelt conditionals; Better text similarity for strings with errors at the start --- .../models/ruleset/validation/TextSimilarity.kt | 11 +++++++++-- .../models/ruleset/validation/UniqueValidator.kt | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/src/com/unciv/models/ruleset/validation/TextSimilarity.kt b/core/src/com/unciv/models/ruleset/validation/TextSimilarity.kt index 4311a3d5c0..54ea68b7c4 100644 --- a/core/src/com/unciv/models/ruleset/validation/TextSimilarity.kt +++ b/core/src/com/unciv/models/ruleset/validation/TextSimilarity.kt @@ -1,5 +1,7 @@ package com.unciv.models.ruleset.validation +import kotlin.math.min + /** * Algorithm: * - Keep an index for each string. @@ -71,5 +73,10 @@ fun getTextDistance(text1: String, text2: String): Int { return dist } -/** @return the [getTextDistance] of two strings relative to their average length. */ -fun getRelativeTextDistance(text1: String, text2: String) = getTextDistance(text1, text2).toDouble() / (text1.length + text2.length) * 2.0 +/** @return the [getTextDistance] of two strings relative to their average length. + * The original algorithm is very weak to short strings with errors at the start (can't figure out that "on [] tiles" and "in [] tiles" are the same) + * So we run it twice, once with the string reversed */ +fun getRelativeTextDistance(text1: String, text2: String): Double{ + fun textDistance(a:String, b:String):Double = getTextDistance(a, b).toDouble() / (text1.length + text2.length) * 2.0 + return min(textDistance(text1, text2), textDistance(text1.reversed(), text2.reversed())) +} diff --git a/core/src/com/unciv/models/ruleset/validation/UniqueValidator.kt b/core/src/com/unciv/models/ruleset/validation/UniqueValidator.kt index 946754edf6..9db961c9eb 100644 --- a/core/src/com/unciv/models/ruleset/validation/UniqueValidator.kt +++ b/core/src/com/unciv/models/ruleset/validation/UniqueValidator.kt @@ -123,9 +123,19 @@ class UniqueValidator(val ruleset: Ruleset) { } if (conditional.type == null) { + var text = "$prefix contains the conditional \"${conditional.text}\"," + + " which is of an unknown type!" + + val similarConditionals = UniqueType.values().filter { + getRelativeTextDistance( + it.placeholderText, + conditional.placeholderText + ) <= RulesetCache.uniqueMisspellingThreshold + } + if (similarConditionals.isNotEmpty()) + text += " May be a misspelling of \""+ similarConditionals.joinToString("\", or \"") { it.text } +"\"" rulesetErrors.add( - "$prefix contains the conditional \"${conditional.text}\"," + - " which is of an unknown type!", + text, RulesetErrorSeverity.Warning, uniqueContainer ) return