public IEnumerable <CalcBackCell> GetGeneratableCell(GCSlot slot)
        {
            var seed = this.seed;
            var tsv  = this.tsvCondition;

            var fixedNature = (uint)slot.FixedNature;
            var fixedGender = slot.FixedGender;

            // PIDのチェック.
            // PIDが条件を満たしていなければyield break.
            {
                var lid = seed >> 16;
                var hid = seed.Back() >> 16;
                var pid = hid << 16 | lid;
                var psv = hid ^ lid;

                if ((pid % 25) != fixedNature)
                {
                    yield break;                            // 性格不一致
                }
                if (pid.GetGender(slot.Pokemon.GenderRatio) != fixedGender)
                {
                    yield break;                                                         // 性別不一致
                }
                if (tsv < 0x10000 && (psv ^ tsv) < 8)
                {
                    yield break;                                   // TSVに条件がついているが, そのTSVだと色回避に引っかかってしまう場合
                }
                this.psvCondition = psv;
            }

            // 逆算
            var currentCondition = this.tsvCondition;

            while (true)
            {
                // 条件を満たすPIDに当たるまで, seedを返し続ける.
                yield return(new CalcBackCell(this, seed.PrevSeed(6), currentCondition));

                var lid = seed.Back() >> 16;
                var hid = seed.Back() >> 16;
                var pid = hid << 16 | lid;
                if (pid % 25 == fixedNature && pid.GetGender(slot.Pokemon.GenderRatio) == fixedGender)
                {
                    // 性格・性別が一致するPIDに当たったら
                    if (currentCondition < 0x10000 && (lid ^ hid ^ currentCondition) >= 8)
                    {
                        yield break;                                                                    // TSV指定済みで色回避が発生しないなら終了.
                    }
                    if (currentCondition == 0x10000)
                    {
                        currentCondition = lid ^ hid; // TSVが指定されていない場合はTSVを指定して続行. (色回避を発生させた場合のみ出現する個体を探す)
                        if (!CheckPSV(currentCondition))
                        {
                            yield break;                              // prevCellを全部遡って判定する. 既に固定されているPIDが光ってしまうTSVはアウト
                        }
                    }
                }
            }
        }
 private CalcBackCell(GCSlot slot, uint seed)
 {
     this.prevCell     = RootCell.Instance;
     this.core         = new CalcBackCore(seed, slot);
     this.seed         = seed;
     this.tsvCondition = 0x10000;
 }
            public CalcBackCore(uint seed, GCSlot slot)
            {
                this.slot          = slot;
                representativeSeed = seed;

                seed.Advance(2);
                ivs          = seed.GetIVs();
                abilityIndex = seed.GetRand() & 1;
                var hid = seed.GetRand();
                var lid = seed.GetRand();
                var psv = lid ^ hid;

                pid1 = lid | (hid << 16);
                do
                {
                    hid  = seed.GetRand();
                    lid  = seed.GetRand();
                    pid2 = lid | (hid << 16);
                } while ((hid ^ lid ^ psv) >= 8);
            }
 /// <summary>
 /// 逆算対象のポケモンのSlotと、対象ポケモンの生成開始seedを渡して、Cellを生成します。
 /// </summary>
 /// <param name="slot"></param>
 /// <param name="seed"></param>
 /// <returns></returns>
 public static CalcBackCell CreateCell(GCSlot slot, uint seed) => new CalcBackCell(slot, seed);
 private CoDarkPokemon(string name, uint lv, GCSlot[] preGenerate)
 {
     slot = new GCSlot(name, lv);
     preGeneratePokemons = preGenerate;
 }
 private CoDarkPokemon(string name, uint lv)
 {
     slot = new GCSlot(name, lv);
     preGeneratePokemons = new GCSlot[0];
 }