mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-21 17:48:28 -05:00
Split shadow team tests from shadow test
Use TheoryData to wrap instead of `object`
This commit is contained in:
parent
416e519073
commit
422a082f98
112
Tests/PKHeX.Core.Tests/Legality/RNG/ShadowTeamTests.cs
Normal file
112
Tests/PKHeX.Core.Tests/Legality/RNG/ShadowTeamTests.cs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
using FluentAssertions;
|
||||
using System;
|
||||
using Xunit;
|
||||
using static PKHeX.Core.Encounters3XDTeams;
|
||||
|
||||
namespace PKHeX.Core.Tests.Legality.Shadow;
|
||||
|
||||
#pragma warning disable IDE0079 // Remove unnecessary suppression
|
||||
#pragma warning disable xUnit1044
|
||||
|
||||
public static class ShadowTeamTests
|
||||
{
|
||||
public static TheoryData<ReadOnlyMemory<TeamLock>, uint[]> DelcattyTestData => new()
|
||||
{
|
||||
{ Delcatty, [0xD118BA52, 0xA3127782, 0x16D95FA5, 0x31538B48] },
|
||||
{ Delcatty, [0x7D5FFE3E, 0x1D5720ED, 0xE0D89C99, 0x3494CDA1] },
|
||||
{ Delcatty, [0xAEB0C3A6, 0x956DC2FD, 0x3C11DCE8, 0xC93DF897] },
|
||||
{ Delcatty, [0xACCE2655, 0xFF2BA0A2, 0x22A8A7E6, 0x5F5380F4] },
|
||||
{ Delcatty, [0xDC1D1894, 0xFC0F75E2, 0x97BFAEBC, 0x38DDE117] },
|
||||
{ Delcatty, [0xDE278967, 0xFD86C9F7, 0x3E16FCFD, 0x1956D8B5] },
|
||||
{ Delcatty, [0xF8CB4CAE, 0x42DE628B, 0x48796CDA, 0xF6EAD3E2] },
|
||||
{ Delcatty, [0x56548F49, 0xA308E7DA, 0x28CB8ADF, 0xBEADBDC3] },
|
||||
{ Delcatty, [0xF2AC8419, 0xADA208E3, 0xDB3A0BA6, 0x5EEF1076] },
|
||||
{ Delcatty, [0x9D28899D, 0xA3ECC9F0, 0x606EC6F0, 0x451FAE3C] },
|
||||
};
|
||||
|
||||
public static TheoryData<ReadOnlyMemory<TeamLock>, uint[]> ButterfreeTestData => new()
|
||||
{
|
||||
{ Butterfree, [0x4D6BE487, 0xBB3EFBFB, 0x6FD7EE06, 0x289D435F, 0x0EC25CE5] },
|
||||
{ Butterfree, [0xB04DF5B3, 0x661E499C, 0x94EB752D, 0xC5FA9DE5, 0x0A8C9738] },
|
||||
{ Butterfree, [0xCBB9A3B0, 0x9AC1A0B8, 0xCA3CAD46, 0x54FFCA27, 0x1D5AEC4F] },
|
||||
{ Butterfree, [0xB2AF145E, 0x455155C9, 0xB5CE4932, 0x4B8C6554, 0x55CE5E4B] },
|
||||
{ Butterfree, [0x193A0F3B, 0xE1474ECF, 0x4C30D215, 0x72262B89, 0x9B2F5B53] },
|
||||
{ Butterfree, [0xB73010B9, 0x361F1DB1, 0x2C65320A, 0x329A4A1E, 0x9334337E] },
|
||||
{ Butterfree, [0xFB6A6770, 0xE0068ECC, 0xB99B326E, 0x08A18311, 0x92D31CC2] },
|
||||
{ Butterfree, [0x5B1214BC, 0xB82FDDA9, 0x606D3D18, 0xA142F730, 0xCBA7A0C3] },
|
||||
{ Butterfree, [0xC7315E32, 0x76566AA1, 0xC0CE436E, 0x98C45DA8, 0x9D1BDC4A] },
|
||||
{ Butterfree, [0xB687F0AF, 0xC01DB6C6, 0xAD6DEC75, 0xDB041314, 0x0D949325] },
|
||||
};
|
||||
|
||||
public static TheoryData<ReadOnlyMemory<TeamLock>, ushort, ushort, int[], uint[]> MawileAntiShinyTestData => new()
|
||||
{
|
||||
{ Mawile, 12345, 51882, [31, 30, 29, 31, 23, 27], [0x4C3005E8, 0xD28DE40E, 0x049F2F05] },
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(DelcattyTestData))]
|
||||
[MemberData(nameof(ButterfreeTestData))]
|
||||
public static void VerifyResults(ReadOnlyMemory<TeamLock> locks, uint[] team)
|
||||
{
|
||||
var pk = new PK3();
|
||||
Span<uint> seeds = stackalloc uint[XDRNG.MaxCountSeedsPID];
|
||||
var pid = team[^1];
|
||||
int count = XDRNG.GetSeeds(seeds, pid);
|
||||
var reg = seeds[..count];
|
||||
var match = IsAnySeedMatch(locks.Span, reg, pk);
|
||||
match.Should().BeTrue($"because the lock conditions for team's {(Species)locks.Span[0].Species} should have been verified");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(MawileAntiShinyTestData))]
|
||||
public static void VerifyMawileAntishiny(ReadOnlyMemory<TeamLock> team, ushort tid, ushort sid, int[] ivs, uint[] resultPIDs)
|
||||
{
|
||||
VerifyResultsAntiShiny(resultPIDs, team.Span, tid, sid, ivs);
|
||||
}
|
||||
|
||||
private static bool IsAnySeedMatch(ReadOnlySpan<TeamLock> team, Span<uint> seeds, PK3 template)
|
||||
{
|
||||
foreach (var s in seeds)
|
||||
{
|
||||
var origin = XDRNG.Prev3(s);
|
||||
var seed = origin;
|
||||
|
||||
var iv1 = XDRNG.Next15(ref seed); // IV1
|
||||
var iv2 = XDRNG.Next15(ref seed); // IV2
|
||||
_ = XDRNG.Next16(ref seed); // Ability
|
||||
var d16 = XDRNG.Next16(ref seed); // PID
|
||||
var e16 = XDRNG.Next16(ref seed); // PID
|
||||
|
||||
template.IV32 = (iv2 << 15) | iv1;
|
||||
template.PID = (d16 << 16) | e16;
|
||||
|
||||
var info = MethodFinder.Analyze(template);
|
||||
info.OriginSeed.Should().Be(origin);
|
||||
info.Type.Should().Be(PIDType.CXD, "because the PID should have matched the CXD spread");
|
||||
|
||||
if (LockFinder.IsAllShadowLockValid(team, origin))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void VerifyResultsAntiShiny(ReadOnlySpan<uint> resultPIDs, ReadOnlySpan<TeamLock> team, ushort tid, ushort sid, ReadOnlySpan<int> ivs)
|
||||
{
|
||||
var pk3 = new PK3
|
||||
{
|
||||
PID = resultPIDs[^1],
|
||||
TID16 = tid,
|
||||
SID16 = sid,
|
||||
};
|
||||
pk3.SetIVs(ivs);
|
||||
|
||||
var info = MethodFinder.Analyze(pk3);
|
||||
info.Type.Should().Be(PIDType.CXD, "because the PID should have matched the CXD spread");
|
||||
bool result = LockFinder.IsAllShadowLockValid(team, info.OriginSeed, pk3.TSV);
|
||||
result.Should().BeTrue();
|
||||
|
||||
// if you're here inspecting what's so special about this method,
|
||||
// double check that the Team's PIDs exactly match what's in the expected result array.
|
||||
// as of this test's date, the methods/fields aren't exposed for viewing.
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
using static PKHeX.Core.Encounters3XDTeams;
|
||||
|
|
@ -7,209 +6,43 @@
|
|||
|
||||
namespace PKHeX.Core.Tests.Legality.Shadow;
|
||||
|
||||
public static class ValidityTests
|
||||
#pragma warning disable IDE0079 // Remove unnecessary suppression
|
||||
#pragma warning disable xUnit1044
|
||||
|
||||
public static class ShadowTests
|
||||
{
|
||||
public static IEnumerable<object[]> Lock1()
|
||||
public static TheoryData<uint, int[], ReadOnlyMemory<TeamLock>> LockData => new()
|
||||
{
|
||||
// Zubat (F) (Serious)
|
||||
yield return [Poochyena, 0xAF4E3161, new[] { 11, 29, 25, 6, 23, 10 }];
|
||||
|
||||
// Murkrow (M) (Docile)
|
||||
yield return [Pineco, 0xC3A0F1E5, new[] { 30, 3, 9, 10, 27, 30 }];
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> Lock2()
|
||||
{
|
||||
// Goldeen (F) (Serious)
|
||||
// Horsea (M) (Quirky)
|
||||
yield return [Spheal, 0xA459BF44, new[] { 0, 11, 4, 28, 6, 13 }];
|
||||
|
||||
// Kirlia (M) (Hardy)
|
||||
// Linoone (F) (Hardy)
|
||||
yield return [Natu, 0x8E14DAB6, new[] { 29, 24, 30, 16, 3, 18 }];
|
||||
|
||||
// Remoraid (M) (Docile) -- 73DB58CC
|
||||
// Golbat (M) (Bashful) -- F6B04390
|
||||
yield return [Roselia, 0x30E87CC7, new[] { 22, 11, 8, 26, 4, 29 }];
|
||||
|
||||
// 519AEF0E
|
||||
// Duskull (M) (Quirky) -- 45BE3B97
|
||||
// Spinarak (F) (Hardy) -- E18F5A3E
|
||||
yield return [ColoMakuhita, 0xC252FEBA, new[] { 15, 9, 17, 16, 24, 22 }];
|
||||
|
||||
// 559C5F72 -- Quirky F => skip
|
||||
// Duskull (M) (Quirky) -- A5AC2CCB
|
||||
// Spinarak (F) (Hardy) -- D08FF135
|
||||
yield return [ColoMakuhita, 0x61C676FC, new[] { 20, 28, 21, 18, 9, 1 }];
|
||||
|
||||
// 3CCB97BA -- Quirky F => skip * 2, Hardy Skip
|
||||
// Duskull (M) (Quirky) -- 7F0D6783 @ 161
|
||||
// Spinarak (F) (Hardy) -- 6C03F545 @ 182
|
||||
yield return [ColoMakuhita, 0x3B27608D, new[] { 7, 12, 5, 19, 3, 7 }];
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> Lock3()
|
||||
{
|
||||
// Luvdisc (F) (Docile)
|
||||
// Beautifly (M) (Hardy)
|
||||
// Roselia (M) (Quirky)
|
||||
yield return [Delcatty, 0x9BECA2A6, new[] { 31, 31, 25, 13, 22, 1 }];
|
||||
|
||||
// Kadabra (M) (Docile)
|
||||
// Sneasel (F) (Hardy)
|
||||
// Misdreavus (F) (Bashful)
|
||||
yield return [Meowth, 0x77D87601, new[] { 10, 27, 26, 13, 30, 19 }];
|
||||
|
||||
// Ralts (M) (Docile)
|
||||
// Voltorb (-) (Hardy)
|
||||
// Bagon (F) (Quirky)
|
||||
yield return [Numel, 0x37F95B26, new[] { 11, 8, 5, 10, 28, 14 }];
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> Lock4()
|
||||
{
|
||||
// Ninetales (F) (Serious)
|
||||
// Jumpluff (M) (Docile)
|
||||
// Azumarill (F) (Hardy)
|
||||
// Shadow Tangela
|
||||
yield return [Butterfree, 0x2E49AC34, new[] { 15, 24, 7, 2, 11, 2 }];
|
||||
|
||||
// Huntail (M) (Docile)
|
||||
// Cacturne (F) (Hardy)
|
||||
// Weezing (F) (Serious)
|
||||
// Ursaring (F) (Bashful)
|
||||
yield return [Arbok, 0x1973FD07, new[] { 13, 30, 3, 16, 20, 9 }];
|
||||
|
||||
// Lairon (F) (Bashful)
|
||||
// Sealeo (F) (Serious)
|
||||
// Slowking (F) (Docile)
|
||||
// Ursaring (M) (Quirky)
|
||||
yield return [Primeape, 0x33893D4C, new[] { 26, 25, 24, 28, 29, 30 }];
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> Lock5()
|
||||
{
|
||||
// many prior, all non-shadow
|
||||
yield return [Seedot, 0x8CBD29DB, new[] { 19, 29, 30, 0, 7, 2 }];
|
||||
}
|
||||
// 1 Lock
|
||||
{ 0xAF4E3161, [11, 29, 25, 06, 23, 10], Poochyena },
|
||||
{ 0xC3A0F1E5, [30, 03, 09, 10, 27, 30], Pineco },
|
||||
// 2 Locks
|
||||
{ 0xA459BF44, [00, 11, 04, 28, 06, 13], Spheal },
|
||||
{ 0x8E14DAB6, [29, 24, 30, 16, 03, 18], Natu },
|
||||
{ 0x30E87CC7, [22, 11, 08, 26, 04, 29], Roselia },
|
||||
{ 0xC252FEBA, [15, 09, 17, 16, 24, 22], ColoMakuhita },
|
||||
{ 0x61C676FC, [20, 28, 21, 18, 09, 01], ColoMakuhita },
|
||||
{ 0x3B27608D, [07, 12, 05, 19, 03, 07], ColoMakuhita },
|
||||
// 3 Locks
|
||||
{ 0x9BECA2A6, [31, 31, 25, 13, 22, 01], Delcatty },
|
||||
{ 0x77D87601, [10, 27, 26, 13, 30, 19], Meowth },
|
||||
{ 0x37F95B26, [11, 08, 05, 10, 28, 14], Numel },
|
||||
// 4 Locks
|
||||
{ 0x2E49AC34, [15, 24, 07, 02, 11, 02], Butterfree },
|
||||
{ 0x1973FD07, [13, 30, 03, 16, 20, 09], Arbok },
|
||||
{ 0x33893D4C, [26, 25, 24, 28, 29, 30], Primeape },
|
||||
// 5 Locks
|
||||
{ 0x8CBD29DB, [19, 29, 30, 00, 07, 02], Seedot },
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(Lock1))]
|
||||
[MemberData(nameof(Lock2))]
|
||||
[MemberData(nameof(Lock3))]
|
||||
[MemberData(nameof(Lock4))]
|
||||
[MemberData(nameof(Lock5))]
|
||||
public static void Verify(TeamLock[] teams, uint pid, int[] ivs)
|
||||
[MemberData(nameof(LockData))]
|
||||
public static void Verify(uint pid, int[] ivs, ReadOnlyMemory<TeamLock> teams)
|
||||
{
|
||||
var pk3 = new PK3 { PID = pid, IVs = ivs };
|
||||
var info = MethodFinder.Analyze(pk3);
|
||||
info.Type.Should().Be(PIDType.CXD, "because the PID should match the CXD spread");
|
||||
bool match = LockFinder.IsAllShadowLockValid(teams, info.OriginSeed);
|
||||
match.Should().BeTrue($"because the lock conditions for {teams[0].Species} should have been verified");
|
||||
}
|
||||
}
|
||||
|
||||
public static class PIDTests
|
||||
{
|
||||
public static IEnumerable<object[]> TestData()
|
||||
{
|
||||
yield return
|
||||
[
|
||||
new uint[][]
|
||||
{
|
||||
[0xD118BA52, 0xA3127782, 0x16D95FA5, 0x31538B48],
|
||||
[0x7D5FFE3E, 0x1D5720ED, 0xE0D89C99, 0x3494CDA1],
|
||||
[0xAEB0C3A6, 0x956DC2FD, 0x3C11DCE8, 0xC93DF897],
|
||||
[0xACCE2655, 0xFF2BA0A2, 0x22A8A7E6, 0x5F5380F4],
|
||||
[0xDC1D1894, 0xFC0F75E2, 0x97BFAEBC, 0x38DDE117],
|
||||
[0xDE278967, 0xFD86C9F7, 0x3E16FCFD, 0x1956D8B5],
|
||||
[0xF8CB4CAE, 0x42DE628B, 0x48796CDA, 0xF6EAD3E2],
|
||||
[0x56548F49, 0xA308E7DA, 0x28CB8ADF, 0xBEADBDC3],
|
||||
[0xF2AC8419, 0xADA208E3, 0xDB3A0BA6, 0x5EEF1076],
|
||||
[0x9D28899D, 0xA3ECC9F0, 0x606EC6F0, 0x451FAE3C],
|
||||
},
|
||||
Delcatty,
|
||||
];
|
||||
yield return
|
||||
[
|
||||
new uint[][]
|
||||
{
|
||||
[0x4D6BE487, 0xBB3EFBFB, 0x6FD7EE06, 0x289D435F, 0x0EC25CE5],
|
||||
[0xB04DF5B3, 0x661E499C, 0x94EB752D, 0xC5FA9DE5, 0x0A8C9738],
|
||||
[0xCBB9A3B0, 0x9AC1A0B8, 0xCA3CAD46, 0x54FFCA27, 0x1D5AEC4F],
|
||||
[0xB2AF145E, 0x455155C9, 0xB5CE4932, 0x4B8C6554, 0x55CE5E4B],
|
||||
[0x193A0F3B, 0xE1474ECF, 0x4C30D215, 0x72262B89, 0x9B2F5B53],
|
||||
[0xB73010B9, 0x361F1DB1, 0x2C65320A, 0x329A4A1E, 0x9334337E],
|
||||
[0xFB6A6770, 0xE0068ECC, 0xB99B326E, 0x08A18311, 0x92D31CC2],
|
||||
[0x5B1214BC, 0xB82FDDA9, 0x606D3D18, 0xA142F730, 0xCBA7A0C3],
|
||||
[0xC7315E32, 0x76566AA1, 0xC0CE436E, 0x98C45DA8, 0x9D1BDC4A],
|
||||
[0xB687F0AF, 0xC01DB6C6, 0xAD6DEC75, 0xDB041314, 0x0D949325],
|
||||
},
|
||||
Butterfree,
|
||||
];
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TestData))]
|
||||
public static void VerifyResults(IReadOnlyList<uint[]> results, TeamLock[] team)
|
||||
{
|
||||
var pk = new PK3();
|
||||
Span<uint> seeds = stackalloc uint[XDRNG.MaxCountSeedsPID];
|
||||
for (int i = 0; i < results.Count; i++)
|
||||
{
|
||||
var result = results[i];
|
||||
var pid = result[^1];
|
||||
int count = XDRNG.GetSeeds(seeds, pid);
|
||||
var reg = seeds[..count];
|
||||
bool match = false;
|
||||
foreach (var s in reg)
|
||||
{
|
||||
var seed = XDRNG.Prev3(s);
|
||||
PIDGenerator.SetValuesFromSeed(pk, PIDType.CXD, seed);
|
||||
var info = MethodFinder.Analyze(pk);
|
||||
info.OriginSeed.Should().Be(seed);
|
||||
info.Type.Should().Be(PIDType.CXD, "because the PID should have matched the CXD spread");
|
||||
if (!LockFinder.IsAllShadowLockValid(team, info.OriginSeed))
|
||||
continue;
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
match.Should().BeTrue($"because the lock conditions for result {i} and species {team[0].Species} should have been verified");
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<uint> MawileTeamPIDs =>
|
||||
[
|
||||
0x4C3005E8, // Loudred
|
||||
0xD28DE40E, // Girafarig (re - rolled 64 times to next viable match)
|
||||
0x049F2F05, // Mawile
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<int> MawileIVs => [31, 30, 29, 31, 23, 27];
|
||||
|
||||
[Fact]
|
||||
public static void VerifyMawileAntishiny()
|
||||
{
|
||||
VerifyResultsAntiShiny(MawileTeamPIDs, Mawile, 12345, 51882, MawileIVs);
|
||||
}
|
||||
|
||||
private static void VerifyResultsAntiShiny(ReadOnlySpan<uint> resultPIDs, TeamLock[] team, ushort tid, ushort sid, ReadOnlySpan<int> ivs)
|
||||
{
|
||||
var pk3 = new PK3
|
||||
{
|
||||
PID = resultPIDs[^1],
|
||||
TID16 = tid,
|
||||
SID16 = sid,
|
||||
};
|
||||
pk3.SetIVs(ivs);
|
||||
|
||||
var info = MethodFinder.Analyze(pk3);
|
||||
info.Type.Should().Be(PIDType.CXD, "because the PID should have matched the CXD spread");
|
||||
bool result = LockFinder.IsAllShadowLockValid(team, info.OriginSeed, pk3.TSV);
|
||||
result.Should().BeTrue();
|
||||
|
||||
// if you're here inspecting what's so special about this method,
|
||||
// double check that the Team's PIDs exactly match what's in the expected result array.
|
||||
// as of this test's date, the methods/fields aren't exposed for viewing.
|
||||
bool match = LockFinder.IsAllShadowLockValid(teams.Span, info.OriginSeed);
|
||||
match.Should().BeTrue($"because the lock conditions for {teams.Span[0].Species} should have been verified");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user