Files
ai-game-2/addons/transition_configurator/fuzzy_search.gd
Bryce 4954732552 Add Transition Configurator plugin for easy exit configuration
Features:
- Fuzzy search for finding destination rooms
- Lists all TransitionPieces in selected room as arrival points
- Bidirectional wiring - updates return transition automatically
- Auto-reloads destination scene in editor
- UndoRedo support for source scene changes

Files added:
- addons/transition_configurator/plugin.cfg
- addons/transition_configurator/transition_configurator.gd
- addons/transition_configurator/transition_inspector_plugin.gd
- addons/transition_configurator/config_dialog.gd
- addons/transition_configurator/fuzzy_search.gd
- addons/transition_configurator/README.md
2026-03-16 09:26:03 -07:00

65 lines
1.8 KiB
GDScript

extends RefCounted
class_name FuzzySearch
## Simple fuzzy matching algorithm for text search
## Returns a score between 0 (no match) and 1 (perfect match)
static func match(query: String, target: String) -> float:
if query.is_empty():
return 1.0
query = query.to_lower()
target = target.to_lower()
# Exact match
if target == query:
return 1.0
# Contains query as substring
if target.find(query) != -1:
return 0.9
# Fuzzy match - all characters in query must appear in order in target
var query_idx: int = 0
var target_idx: int = 0
var matches: int = 0
var consecutive_bonus: float = 0.0
var last_match_idx: int = -1
while query_idx < query.length() and target_idx < target.length():
if query[query_idx] == target[target_idx]:
matches += 1
if last_match_idx != -1 and target_idx == last_match_idx + 1:
consecutive_bonus += 0.1
last_match_idx = target_idx
query_idx += 1
target_idx += 1
# All characters matched
if query_idx == query.length():
var base_score: float = float(matches) / float(query.length())
var bonus: float = min(consecutive_bonus, 0.3) # Cap bonus at 0.3
return base_score * 0.7 + bonus
return 0.0
## Sort an array of items by fuzzy match score
## items should be Dictionary with at least a "name" or specified key field
static func sort_by_match(query: String, items: Array, key: String = "name") -> Array:
if query.is_empty():
return items.duplicate()
var scored: Array[Dictionary] = []
for item in items:
var item_name: String = item.get(key, "")
var score: float = match(query, item_name)
if score > 0:
scored.append({"item": item, "score": score})
# Sort by score descending
scored.sort_custom(func(a: Dictionary, b: Dictionary) -> bool:
return a["score"] > b["score"]
)
return scored.map(func(s): return s["item"])