diff --git a/version-rust/src/main.rs b/version-rust/src/main.rs index 2add3bc..71cc3c5 100644 --- a/version-rust/src/main.rs +++ b/version-rust/src/main.rs @@ -538,7 +538,7 @@ fn cmd_sorter(args: &SorterArgs) -> anyhow::Result<()> { "subfaction": i.subfaction, "class": i.klass, "unit": i.unit, - "score": (i.match_score * 1000.0).round() / 1000.0, + "score": (i.match_score * 1000.0).round_ties_even() / 1000.0, "kind": i.match_kind, "inner_count": i.inner_names.len(), "target": i.target diff --git a/version-rust/src/sorter.rs b/version-rust/src/sorter.rs index 5db6389..7091a58 100644 --- a/version-rust/src/sorter.rs +++ b/version-rust/src/sorter.rs @@ -906,16 +906,22 @@ fn compute_match_name( } } let cands: Vec<(f64, usize, bool)> = [same, other].into_iter().flatten().collect(); - if !cands.is_empty() { - let normals: Vec<&(f64, usize, bool)> = cands.iter().filter(|c| !c.2).collect(); - let winner = if normals.is_empty() { - cands.iter().max_by(|a, b| a.0.total_cmp(&b.0)).unwrap() - } else { - normals.iter().max_by(|a, b| a.0.total_cmp(&b.0)).unwrap() - }; - return Some(winner.clone()); + if cands.is_empty() { + return None; } - None + // python `max(normals or cands, key=score)` keeps the FIRST + // maximum; a normal (non-weak) candidate always beats a weak one. + let has_normal = cands.iter().any(|c| !c.2); + let mut winner: Option<(f64, usize, bool)> = None; + for c in &cands { + if has_normal && c.2 { + continue; + } + if winner.as_ref().is_none_or(|w| c.0 > w.0) { + winner = Some(c.clone()); + } + } + return winner; } else { pool_best(clean, &pool, ctx, threshold, cache) }