Duplicate locations: across lists, not each array

BD/SP has Pokémon HOME as location 30018 and 40086; need to differentiate.
Revise the unit test to share the unique-check set across all location lists of that context

Ignore "empty" location values (dashes, empty). For deduplicating, ignore empty indexes as well.
This commit is contained in:
Kurt 2025-02-01 19:23:11 -06:00
parent e04ad2c6b2
commit 9dedd33694
2 changed files with 59 additions and 9 deletions

View File

@ -424,16 +424,21 @@ private void SanitizeMetGen4(LocationSet4 set)
private void SanitizeMetGen5(LocationSet6 set)
{
const string bw = " (B/W)";
set.Met0[36] = $"{set.Met0[84]}/{set.Met0[36]}"; // Cold Storage in B/W = PWT in B2/W2
set.Met0[40] += " (B/W)"; // Victory Road in B/W
set.Met0[40] += bw; // Victory Road in B/W
set.Met0[134] += " (B2/W2)"; // Victory Road in B2/W2
// B2/W2 Entries from 76 to 105 are for Entralink in B/W
for (int i = 76; i < 106; i++)
set.Met0[i] += "●";
set.Met0[i] += bw;
// Collision between 40002 (legal) and 00002 (illegal) "Faraway place"
if (set.Met0[2] == set.Met4[2])
set.Met0[2] += " (2)";
set.Met0[2] += " (-)";
// Collision between 00069 (legal) and 30014 (illegal) "Entralink"
if (set.Met3[14] == set.Met0[69])
set.Met3[14] += " (-)";
for (int i = 97; i < 109; i++)
set.Met4[i] += $" ({i - 97})";
@ -471,6 +476,10 @@ private void SanitizeMetGen6(LocationSet6 set)
set.Met3[1] += $" ({NPC})"; // Anything from an NPC
set.Met3[2] += $" ({EggName})"; // Egg From Link Trade
// Collision between 40002 (legal) and 00004 (illegal) "Faraway place"
if (set.Met0[4] == set.Met4[2])
set.Met0[4] += " (-)";
for (int i = 63; i <= 69; i++)
set.Met4[i] += $" ({i - 62})";
}
@ -491,6 +500,14 @@ private void SanitizeMetGen7(LocationSet6 set)
set.Met0[32] += " (2)";
set.Met0[102] += " (2)";
// Collision between 40002 (legal) and 00004 (illegal) "Faraway place"
if (set.Met0[4] == set.Met4[2])
set.Met0[4] += " (-)";
// Collision between 30012 (legal, in Gen8+) and 40084 (illegal) "Pokémon GO"
if (set.Met3[12] == set.Met4[84])
set.Met4[84] += " (-)";
set.Met3[1] += $" ({NPC})"; // Anything from an NPC
set.Met3[2] += $" ({EggName})"; // Egg From Link Trade
for (int i = 3; i <= 6; i++) // distinguish first set of regions (unused) from second (used)
@ -504,6 +521,12 @@ private static void SanitizeMetGen7b(LocationSet6 set)
{
for (int i = 48; i < 55; i++) // distinguish Event year duplicates
set.Met4[i] += " (-)";
// Collision between 40002 (legal) and 00002 (illegal) "Faraway place"
if (set.Met0[2] == set.Met4[2])
set.Met0[2] += " (-)";
set.Met4[73] += " (-)"; // Pokémon GO -- duplicate with 30000's entry
// set.Met3[12] += " (-)"; // Pokémon GO -- duplicate with 40000's entry
}
private void SanitizeMetGen8(LocationSet6 set)
@ -529,6 +552,9 @@ private void SanitizeMetGen8(LocationSet6 set)
set.Met4[30] += " (-)"; // a Video game Event (in spanish etc.) -- duplicate with line 39
set.Met4[53] += " (-)"; // a Pokémon event -- duplicate with line 37
// Collision between 40002 (legal) and 00004 (illegal) "Faraway place"
if (set.Met0[4] == set.Met4[2])
set.Met0[4] += " (-)";
set.Met4[81] += " (-)"; // Pokémon GO -- duplicate with 30000's entry
set.Met4[86] += " (-)"; // Pokémon HOME -- duplicate with 30000's entry
// set.Met3[12] += " (-)"; // Pokémon GO -- duplicate with 40000's entry
@ -544,6 +570,11 @@ private void SanitizeMetGen8b(LocationSet6 set)
Deduplicate(set.Met3, 30000);
Deduplicate(set.Met4, 40000);
Deduplicate(set.Met6, 60000);
set.Met4[81] += " (-)"; // Pokémon GO -- duplicate with 30000's entry
set.Met4[86] += " (-)"; // Pokémon HOME -- duplicate with 30000's entry
// set.Met3[12] += " (-)"; // Pokémon GO -- duplicate with 40000's entry
// set.Met3[18] += " (-)"; // Pokémon HOME -- duplicate with 40000's entry
}
private void SanitizeMetGen8a(LocationSet6 set)
@ -563,6 +594,9 @@ private void SanitizeMetGen8a(LocationSet6 set)
// set.Met3[12] += " (-)"; // Pokémon GO -- duplicate with 40000's entry
// set.Met3[18] += " (-)"; // Pokémon HOME -- duplicate with 40000's entry
// Collision between 40002 (legal) and 00004 (illegal) "Faraway place"
if (set.Met0[4] == set.Met4[2])
set.Met0[4] += " (-)";
for (int i = 55; i <= 60; i++) // distinguish second set of YYYY Event from the first
set.Met4[i] += " (-)";
@ -641,6 +675,9 @@ private void SanitizeMetGen9(LocationSet6 set)
set.Met4[27] += " (-)"; // a Video game Event (in spanish etc.) -- duplicate with line 36
set.Met4[48] += " (-)"; // a Pokémon event -- duplicate with line 34
// Collision between 40002 (legal) and 00004 (illegal) "Faraway place"
if (set.Met0[4] == set.Met4[2])
set.Met0[4] += " (-)";
set.Met4[73] += " (-)"; // Pokémon GO -- duplicate with 30000's entry
set.Met4[78] += " (-)"; // Pokémon HOME -- duplicate with 30000's entry
// set.Met3[12] += " (-)"; // Pokémon GO -- duplicate with 40000's entry
@ -653,6 +690,8 @@ private static void Deduplicate(Span<string> arr, int group)
foreach (var s in arr)
{
if (s.Length == 0)
continue;
counts.TryGetValue(s, out var value);
counts[s] = value + 1;
}
@ -666,6 +705,8 @@ private static void Deduplicate(Span<string> arr, int group)
arr[i] += $" ({group + i:00000})";
#else
var s = arr[i];
if (s.Length == 0)
continue;
var count = counts[s]--;
if (count == 1)
continue;

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
@ -95,10 +96,10 @@ private static void CheckMetLocations(string language)
var group = setField.GetValue(strings) as ILocationSet;
Assert.NotNull(group);
var dict = new Dictionary<string, (int Bank, int Index)>();
foreach (var (bank, mem) in group.GetAll())
{
var arr = mem.Span;
var hs = new HashSet<string>(arr.Length);
bool sm0 = bank == 0 && name == nameof(GameStrings.Gen7);
for (int index = 0; index < arr.Length; index++)
{
@ -108,14 +109,22 @@ private static void CheckMetLocations(string language)
if (sm0 && index % 2 != 0)
continue;
if (hs.Contains(line))
duplicates.Add($"{name}\t{index}\t{line}");
hs.Add(line);
if (line is "----------" or "" or "——————" or "")
continue; // don't care
if (dict.TryGetValue(line, out var other))
duplicates.Add($"{name}\t{other.Bank}-{other.Index}\t{bank}-{index}\t{line}");
else
dict.Add(line, (bank, index));
}
}
if (duplicates.Count != 0)
Assert.Fail($"Found duplicates for {name}. Debug this test to inspect the list of duplicate location IDs.");
if (duplicates.Count == 0)
continue;
// None of the location names displayed to the user should be exactly the same.
// This prevents a location list selection from being ambiguous/not what the user intended.
var result = string.Join(Environment.NewLine, duplicates);
Assert.Fail($"Disallowed - duplicate locations for {name}:{Environment.NewLine}{result}");
}
iterated.Should().BeTrue();