Remove old GeneratePKMs api methods

Use the GenerateEncounters methods instead, just a single line extra for each consumer.

PokemonGenerationReturnsLegalPokemon now works for all Gen1-7 encounters->PKM (except for Korean WC6 Arceus form mismatch), still disabled from auto-test due to it taking about a minute to generate everything. Future updates can add special methods for SW/SH, PLA, BD/SP, and S/V if the species/form exists in the game.
This commit is contained in:
Kurt 2023-09-11 18:20:22 -07:00
parent fe7012c3eb
commit 3a28eee2e9
3 changed files with 15 additions and 60 deletions

View File

@ -64,13 +64,14 @@ public static List<PKM> GetLivingDex(this ITrainerInfo tr, IEnumerable<ushort> s
var memory = moves.AsMemory(0, 4);
var span = memory.Span;
template.GetMoves(span);
var f = EncounterMovesetGenerator.GeneratePKMs(template, tr, memory).FirstOrDefault();
var first = EncounterMovesetGenerator.GenerateEncounters(template, tr, memory).FirstOrDefault();
span.Clear();
ArrayPool<ushort>.Shared.Return(moves);
if (f == null)
if (first == null)
return null;
var result = EntityConverter.ConvertToType(f, destType, out _);
var pk = first.ConvertToPKM(tr);
var result = EntityConverter.ConvertToType(pk, destType, out _);
if (result == null)
return null;

View File

@ -1,4 +1,3 @@
//#define VERIFY_GEN
using System;
using System.Buffers;
using System.Collections.Generic;
@ -23,38 +22,6 @@ public static class EncounterMovesetGenerator
/// </summary>
public static void ResetFilters() => PriorityList = (EncounterTypeGroup[])Enum.GetValues(typeof(EncounterTypeGroup));
/// <summary>
/// Gets possible <see cref="PKM"/> objects that allow all moves requested to be learned.
/// </summary>
/// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
/// <param name="info">Trainer information of the receiver.</param>
/// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param>
/// <param name="versions">Any specific version(s) to iterate for. If left blank, all will be checked.</param>
/// <returns>A consumable <see cref="PKM"/> list of possible results.</returns>
/// <remarks>When updating, update the sister <see cref="GenerateEncounters(PKM,ITrainerInfo,ReadOnlyMemory{ushort},GameVersion[])"/> method.</remarks>
public static IEnumerable<PKM> GeneratePKMs(PKM pk, ITrainerInfo info, ReadOnlyMemory<ushort> moves, params GameVersion[] versions)
{
if (!IsSane(pk, moves.Span))
yield break;
OptimizeCriteria(pk, info);
var vers = versions.Length >= 1 ? versions : GameUtil.GetVersionsWithinRange(pk, pk.Format);
foreach (var ver in vers)
{
var encounters = GenerateVersionEncounters(pk, moves, ver);
foreach (var enc in encounters)
{
var result = enc.ConvertToPKM(info);
#if VERIFY_GEN
var la = new LegalityAnalysis(result);
if (!la.Valid)
throw new Exception("Legality analysis of generated Pokémon is invalid");
#endif
yield return result;
}
}
}
/// <summary>
/// Gets possible <see cref="IEncounterable"/> objects that allow all moves requested to be learned.
/// </summary>
@ -63,7 +30,6 @@ public static IEnumerable<PKM> GeneratePKMs(PKM pk, ITrainerInfo info, ReadOnlyM
/// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param>
/// <param name="versions">Any specific version(s) to iterate for. If left blank, all will be checked.</param>
/// <returns>A consumable <see cref="IEncounterable"/> list of possible results.</returns>
/// <remarks>When updating, update the sister <see cref="GeneratePKMs(PKM,ITrainerInfo,ReadOnlyMemory{ushort},GameVersion[])"/> method.</remarks>
public static IEnumerable<IEncounterable> GenerateEncounters(PKM pk, ITrainerInfo info, ReadOnlyMemory<ushort> moves, params GameVersion[] versions)
{
if (!IsSane(pk, moves.Span))
@ -92,19 +58,6 @@ public static void OptimizeCriteria(PKM pk, ITrainerID32 info)
htTrash[0] = 1; // Fake Trash to indicate trading.
}
/// <summary>
/// Gets possible <see cref="PKM"/> objects that allow all moves requested to be learned within a specific generation.
/// </summary>
/// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
/// <param name="info">Trainer information of the receiver.</param>
/// <param name="generation">Specific generation to iterate versions for.</param>
/// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param>
public static IEnumerable<PKM> GeneratePKMs(PKM pk, ITrainerInfo info, int generation, ReadOnlyMemory<ushort> moves)
{
var vers = GameUtil.GetVersionsInGeneration(generation, pk.Version);
return GeneratePKMs(pk, info, moves, vers);
}
/// <summary>
/// Gets possible encounters that allow all moves requested to be learned.
/// </summary>

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace PKHeX.Core.Tests.Simulator;
@ -10,26 +12,25 @@ public class GeneratorTests
public static IEnumerable<object[]> PokemonGenerationTestData()
{
for (int i = 1; i <= 807; i++)
{
yield return new object[] { i };
}
}
[Theory(Skip = "Feature not ready yet")]
[Theory(Skip = "Long duration test, run manually & very infrequently.")]
[MemberData(nameof(PokemonGenerationTestData))]
public void PokemonGenerationReturnsLegalPokemon(ushort species)
{
int count = 0;
var tr = new SimpleTrainerInfo(GameVersion.SN);
var pk = new PK7 { Species = species };
pk.Gender = pk.GetSaneGender();
var ez = EncounterMovesetGenerator.GeneratePKMs(pk, tr, pk.Moves);
foreach (var e in ez)
var template = new PK7 { Species = species };
template.Gender = template.PersonalInfo.RandomGender();
var encounters = EncounterMovesetGenerator.GenerateEncounters(template, tr, Array.Empty<ushort>());
foreach (var enc in encounters)
{
var la = new LegalityAnalysis(e);
la.Valid.Should().BeTrue($"Because generated Pokemon {count} for {species:000} should be valid");
Assert.True(la.Valid);
var pk = enc.ConvertToPKM(tr);
var la = new LegalityAnalysis(pk);
la.Valid.Should().BeTrue($"Because encounter #{count} for {(Species)species} ({species:000}) should be valid, {Environment.NewLine}{la.Report()}");
count++;
}
}