mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 22:10:21 +00:00
Refactoring
Add in frametype, rename classes for more coherent structure
This commit is contained in:
parent
9380ca25d9
commit
6c6b3ae4b6
10 changed files with 177 additions and 137 deletions
21
PKHeX.Core/Legality/RNG/Frame/Frame.cs
Normal file
21
PKHeX.Core/Legality/RNG/Frame/Frame.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public class Frame
|
||||
{
|
||||
public readonly FrameType FrameType;
|
||||
|
||||
public uint Seed { get; set; }
|
||||
public readonly LeadRequired Lead;
|
||||
public bool CuteCharm { get; set; }
|
||||
|
||||
public uint ESV { get; set; }
|
||||
public bool SuctionCups { get; set; }
|
||||
|
||||
public Frame(uint seed, FrameType type, LeadRequired lead)
|
||||
{
|
||||
Seed = seed;
|
||||
Lead = lead;
|
||||
FrameType = type;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,24 +2,26 @@
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public static class SlotFinder
|
||||
public static class FrameFinder
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks a <see cref="PIDIV"/> to see if any encounter frames can generate the spread. Requires further filtering against matched Encounter Slots and generation patterns.
|
||||
/// </summary>
|
||||
/// <param name="pidiv">Matched <see cref="PIDIV"/> containing <see cref="PIDIV.RNG"/> info and <see cref="PIDIV.OriginSeed"/>.</param>
|
||||
/// <param name="pk"><see cref="PKM"/> object containing various accessible information required for the encounter.</param>
|
||||
/// <returns><see cref="IEnumerable{SlotResult}"/> to yield possible encounter details for further filtering</returns>
|
||||
public static IEnumerable<SlotResult> getSlotSeeds(PIDIV pidiv, PKM pk)
|
||||
/// <returns><see cref="IEnumerable{Frame}"/> to yield possible encounter details for further filtering</returns>
|
||||
public static IEnumerable<Frame> getFrames(PIDIV pidiv, PKM pk)
|
||||
{
|
||||
// gather possible nature determination seeds until a same-nature PID breaks the unrolling
|
||||
SearchCriteria criteria = SearchCriteria.getSearchCriteria(pk);
|
||||
if (criteria == null)
|
||||
FrameGenerator criteria = new FrameGenerator(pk, pidiv.Type);
|
||||
if (criteria.FrameType == FrameType.None)
|
||||
yield break;
|
||||
|
||||
criteria.Nature = pk.EncryptionConstant % 25;
|
||||
|
||||
IEnumerable<SeedInfo> seeds = SeedInfo.getSeedsUntilNature(pidiv, criteria);
|
||||
// get game generation criteria
|
||||
IEnumerable<SlotResult> info;
|
||||
IEnumerable<Frame> info;
|
||||
switch (pidiv.Type)
|
||||
{
|
||||
case PIDType.CuteCharm:
|
||||
|
@ -43,7 +45,7 @@ namespace PKHeX.Core
|
|||
/// <param name="pidiv">PIDIV Info for the frame</param>
|
||||
/// <param name="info">Search Info for the frame</param>
|
||||
/// <returns>Possible matches to the Nature Lock frame generation pattern</returns>
|
||||
private static IEnumerable<SlotResult> filterNatureSync(IEnumerable<SeedInfo> seeds, PIDIV pidiv, SearchCriteria info)
|
||||
private static IEnumerable<Frame> filterNatureSync(IEnumerable<SeedInfo> seeds, PIDIV pidiv, FrameGenerator info)
|
||||
{
|
||||
foreach (var seed in seeds)
|
||||
{
|
||||
|
@ -59,12 +61,17 @@ namespace PKHeX.Core
|
|||
{
|
||||
var failsync = (info.DPPt ? prev >> 31 : (prev >> 16) & 1) != 1;
|
||||
if (failsync)
|
||||
yield return new SlotResult {Seed = pidiv.RNG.Prev(prev), Sync = true, FailedSync = true};
|
||||
yield return info.GetFrame(pidiv.RNG.Prev(prev), LeadRequired.SynchronizeFail);
|
||||
}
|
||||
if (sync)
|
||||
yield return new SlotResult {Seed = prev, Sync = true};
|
||||
yield return info.GetFrame(prev, LeadRequired.Synchronize);
|
||||
if (reg)
|
||||
yield return new SlotResult {Seed = prev, Sync = false, CuteCharm = seed.Charm3};
|
||||
{
|
||||
if (seed.Charm3)
|
||||
yield return info.GetFrame(prev, LeadRequired.CuteCharm);
|
||||
else
|
||||
yield return info.GetFrame(prev, LeadRequired.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +82,7 @@ namespace PKHeX.Core
|
|||
/// <param name="pidiv">PIDIV Info for the frame</param>
|
||||
/// <param name="info">Search Info for the frame</param>
|
||||
/// <returns>Possible matches to the Cute Charm frame generation pattern</returns>
|
||||
private static IEnumerable<SlotResult> filterCuteCharm(IEnumerable<SeedInfo> seeds, PIDIV pidiv, SearchCriteria info)
|
||||
private static IEnumerable<Frame> filterCuteCharm(IEnumerable<SeedInfo> seeds, PIDIV pidiv, FrameGenerator info)
|
||||
{
|
||||
foreach (var seed in seeds)
|
||||
{
|
||||
|
@ -92,7 +99,7 @@ namespace PKHeX.Core
|
|||
if (!charmProc)
|
||||
continue;
|
||||
|
||||
yield return new SlotResult {Seed = prev, CuteCharm = true};
|
||||
yield return info.GetFrame(prev, LeadRequired.CuteCharm);
|
||||
}
|
||||
}
|
||||
}
|
106
PKHeX.Core/Legality/RNG/Frame/FrameGenerator.cs
Normal file
106
PKHeX.Core/Legality/RNG/Frame/FrameGenerator.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public class FrameGenerator
|
||||
{
|
||||
public uint Nature;
|
||||
public readonly bool Gendered;
|
||||
public readonly int GenderHigh;
|
||||
public readonly int GenderLow;
|
||||
public readonly bool DPPt;
|
||||
public readonly bool CanSync;
|
||||
public readonly FrameType FrameType = FrameType.None;
|
||||
public Frame GetFrame(uint seed, LeadRequired lead) => new Frame(seed, FrameType, lead);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Search Criteria parameters necessary for generating <see cref="SeedInfo"/> and <see cref="Frame"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="pk"><see cref="PKM"/> object containing various accessible information required for the encounter.</param>
|
||||
/// <param name="type">Type info used to determine the <see cref="FrameType"/>.</param>
|
||||
/// <returns>Object containing search criteria to be passed by reference to search/filter methods.</returns>
|
||||
public FrameGenerator(PKM pk, PIDType type)
|
||||
{
|
||||
var ver = (GameVersion)pk.Version;
|
||||
switch (ver)
|
||||
{
|
||||
// Method H
|
||||
case GameVersion.R:
|
||||
case GameVersion.S:
|
||||
case GameVersion.FR:
|
||||
case GameVersion.LG:
|
||||
case GameVersion.E:
|
||||
DPPt = false;
|
||||
FrameType = getFrameType(type);
|
||||
|
||||
if (ver != GameVersion.E)
|
||||
return;
|
||||
|
||||
CanSync = true;
|
||||
|
||||
// Cute Charm waits for gender too!
|
||||
var gender = pk.Gender;
|
||||
bool gendered = gender != 2;
|
||||
if (!gendered)
|
||||
return;
|
||||
|
||||
var gr = pk.PersonalInfo.Gender;
|
||||
Gendered = true;
|
||||
GenderLow = getGenderMinMax(gender, gr, false);
|
||||
GenderHigh = getGenderMinMax(gender, gr, true);
|
||||
return;
|
||||
|
||||
// Method J
|
||||
case GameVersion.D:
|
||||
case GameVersion.P:
|
||||
case GameVersion.Pt:
|
||||
DPPt = true;
|
||||
CanSync = true;
|
||||
FrameType = FrameType.MethodJ;
|
||||
return;
|
||||
|
||||
// Method K
|
||||
case GameVersion.HG:
|
||||
case GameVersion.SS:
|
||||
DPPt = false;
|
||||
CanSync = true;
|
||||
FrameType = FrameType.MethodK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the span of values for a given Gender
|
||||
/// </summary>
|
||||
/// <param name="gender">Gender</param>
|
||||
/// <param name="ratio">Gender Ratio</param>
|
||||
/// <param name="max">Return Max (or Min)</param>
|
||||
/// <returns>Returns the maximum or minimum gender value that corresponds to the input gender ratio.</returns>
|
||||
private static int getGenderMinMax(int gender, int ratio, bool max)
|
||||
{
|
||||
if (ratio == 0 || ratio == 0xFE || ratio == 0xFF)
|
||||
gender = 2;
|
||||
switch (gender)
|
||||
{
|
||||
case 0: return max ? 255 : ratio; // male
|
||||
case 1: return max ? ratio - 1 : 0; // female
|
||||
default: return max ? 255 : 0; // fixed/genderless
|
||||
}
|
||||
}
|
||||
|
||||
private static FrameType getFrameType(PIDType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PIDType.Method_1:
|
||||
case PIDType.Method_1_Unown:
|
||||
return FrameType.MethodH1;
|
||||
case PIDType.Method_2:
|
||||
case PIDType.Method_2_Unown:
|
||||
return FrameType.MethodH2;
|
||||
case PIDType.Method_4:
|
||||
case PIDType.Method_4_Unown:
|
||||
return FrameType.MethodH4;
|
||||
}
|
||||
return FrameType.None;
|
||||
}
|
||||
}
|
||||
}
|
13
PKHeX.Core/Legality/RNG/Frame/FrameType.cs
Normal file
13
PKHeX.Core/Legality/RNG/Frame/FrameType.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public enum FrameType
|
||||
{
|
||||
None,
|
||||
MethodH1,
|
||||
MethodH2,
|
||||
MethodH4,
|
||||
|
||||
MethodJ,
|
||||
MethodK,
|
||||
}
|
||||
}
|
10
PKHeX.Core/Legality/RNG/Frame/LeadRequired.cs
Normal file
10
PKHeX.Core/Legality/RNG/Frame/LeadRequired.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public enum LeadRequired
|
||||
{
|
||||
None,
|
||||
CuteCharm,
|
||||
Synchronize,
|
||||
SynchronizeFail,
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
public uint Seed;
|
||||
public bool Charm3;
|
||||
public static IEnumerable<SeedInfo> getSeedsUntilNature(PIDIV pidiv, SearchCriteria info)
|
||||
public static IEnumerable<SeedInfo> getSeedsUntilNature(PIDIV pidiv, FrameGenerator info)
|
||||
{
|
||||
bool reverse = pidiv.Type.IsReversedPID();
|
||||
bool charm3 = false;
|
||||
|
@ -40,7 +40,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
private static LockInfo verifyPIDCriteria(uint pid, SearchCriteria info)
|
||||
private static LockInfo verifyPIDCriteria(uint pid, FrameGenerator info)
|
||||
{
|
||||
// Nature locks are always a given
|
||||
var nval = pid % 25;
|
|
@ -1,103 +0,0 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public class SearchCriteria
|
||||
{
|
||||
public uint Nature;
|
||||
public bool Gendered;
|
||||
public int GenderHigh;
|
||||
public int GenderLow;
|
||||
public bool DPPt;
|
||||
public bool CanSync;
|
||||
public bool MethodH;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Search Criteria parameters necessary for generating <see cref="SeedInfo"/> and <see cref="SlotResult"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="pk"><see cref="PKM"/> object containing various accessible information required for the encounter.</param>
|
||||
/// <returns>Object containing search criteria to be passed by reference to search/filter methods.</returns>
|
||||
public static SearchCriteria getSearchCriteria(PKM pk)
|
||||
{
|
||||
var ver = (GameVersion)pk.Version;
|
||||
switch (ver)
|
||||
{
|
||||
// Method H
|
||||
case GameVersion.R:
|
||||
case GameVersion.S:
|
||||
case GameVersion.FR:
|
||||
case GameVersion.LG:
|
||||
return new SearchCriteria
|
||||
{
|
||||
Nature = pk.EncryptionConstant % 25,
|
||||
DPPt = false,
|
||||
MethodH = true,
|
||||
};
|
||||
|
||||
// Method H with Emerald Features
|
||||
case GameVersion.E:
|
||||
|
||||
// Cute Charm waits for gender too!
|
||||
var gender = pk.Gender;
|
||||
bool gendered = ver == GameVersion.E && gender != 2;
|
||||
|
||||
var criteria = new SearchCriteria
|
||||
{
|
||||
Nature = pk.EncryptionConstant % 25,
|
||||
DPPt = false,
|
||||
CanSync = true,
|
||||
MethodH = true,
|
||||
};
|
||||
if (gendered)
|
||||
{
|
||||
var gr = pk.PersonalInfo.Gender;
|
||||
criteria.Gendered = true;
|
||||
criteria.GenderLow = getGenderMinMax(gender, gr, false);
|
||||
criteria.GenderHigh = getGenderMinMax(gender, gr, true);
|
||||
}
|
||||
return criteria;
|
||||
|
||||
// Method J
|
||||
case GameVersion.D:
|
||||
case GameVersion.P:
|
||||
case GameVersion.Pt:
|
||||
return new SearchCriteria
|
||||
{
|
||||
Nature = pk.EncryptionConstant % 25,
|
||||
DPPt = true,
|
||||
CanSync = true,
|
||||
};
|
||||
|
||||
// Method K
|
||||
case GameVersion.HG:
|
||||
case GameVersion.SS:
|
||||
return new SearchCriteria
|
||||
{
|
||||
Nature = pk.EncryptionConstant % 25,
|
||||
DPPt = false,
|
||||
CanSync = true,
|
||||
};
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the span of values for a given Gender
|
||||
/// </summary>
|
||||
/// <param name="gender">Gender</param>
|
||||
/// <param name="ratio">Gender Ratio</param>
|
||||
/// <param name="max">Return Max (or Min)</param>
|
||||
/// <returns>Returns the maximum or minimum gender value that corresponds to the input gender ratio.</returns>
|
||||
private static int getGenderMinMax(int gender, int ratio, bool max)
|
||||
{
|
||||
if (ratio == 0 || ratio == 0xFE || ratio == 0xFF)
|
||||
gender = 2;
|
||||
switch (gender)
|
||||
{
|
||||
case 0: return max ? 255 : ratio; // male
|
||||
case 1: return max ? ratio - 1 : 0; // female
|
||||
default: return max ? 255 : 0; // fixed/genderless
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public class SlotResult
|
||||
{
|
||||
public uint Seed { get; set; }
|
||||
public bool Sync { get; set; }
|
||||
public bool FailedSync { get; set; }
|
||||
public bool CuteCharm { get; set; }
|
||||
|
||||
public bool SuctionCups { get; set; }
|
||||
|
||||
public uint ESV { get; set; }
|
||||
}
|
||||
}
|
|
@ -118,18 +118,18 @@ namespace PKHeX.Tests.PKM
|
|||
{
|
||||
// Pearl
|
||||
pk.Version = (int) GameVersion.P;
|
||||
var results = SlotFinder.getSlotSeeds(pidiv, pk);
|
||||
var results = FrameFinder.getFrames(pidiv, pk);
|
||||
const int failSyncCount = 1;
|
||||
const int noSyncCount = 2;
|
||||
const int SyncCount = 37;
|
||||
var r2 = results.ToArray();
|
||||
var failSync = r2.Where(z => z.FailedSync);
|
||||
var noSync = r2.Where(z => !z.Sync);
|
||||
var sync = r2.Where(z => z.Sync && !z.FailedSync);
|
||||
var failSync = r2.Where(z => z.Lead == LeadRequired.SynchronizeFail);
|
||||
var noSync = r2.Where(z => z.Lead == LeadRequired.None);
|
||||
var sync = r2.Where(z => z.Lead == LeadRequired.Synchronize);
|
||||
|
||||
Assert.AreEqual(failSync.Count(), failSyncCount, "Failed Sync count mismatch.");
|
||||
Assert.AreEqual(sync.Count(), SyncCount, "Sync count mismatch.");
|
||||
Assert.AreEqual(noSync.Count(z => !z.Sync), noSyncCount, "Non-Sync count mismatch.");
|
||||
Assert.AreEqual(noSync.Count(), noSyncCount, "Non-Sync count mismatch.");
|
||||
|
||||
// var slots = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 9 };
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ namespace PKHeX.Tests.PKM
|
|||
{
|
||||
// Sapphire
|
||||
// pk.Version = (int)GameVersion.S;
|
||||
// var results = SlotFinder.getSlotSeeds(pidiv, pk);
|
||||
// var results = FrameFinder.getFrames(pidiv, pk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue