Beispiel #1
0
        /// <summary>
        /// 削除できる可能性のあるスライムの分析する
        /// </summary>
        /// <param name="context">フィールド状態</param>
        /// <param name="player">プレイヤ</param>
        /// <param name="param">パラメータ</param>
        /// <returns>削除できる可能性のあるスライム数</returns>
        public int Analyze(FieldContext context, Player.Index player, Param param)
        {
            Debug.Assert(param.TargetSlime != Slime.None, "対象スライムがNoneはありえません");

            var _context = context.DeepCopy();

            // フィールドから削除対象のスライムを削除する
            foreach (var slime in param.ErasedSlimes)
            {
                if (slime == param.TargetSlime)
                {
                    continue;
                }
                _context.SlimeFields[(int)player][slime] = Enumerable.Range(0, FieldContextConfig.FieldUnitCount).Select(i => 0u).ToArray();
            }

            // 移動可能スライムも落下させたいので、情報のみ場外においやってしまう
            MovableSlime.ForEach(index =>
            {
                var movable      = _context.MovableSlimes[(int)player][(int)index];
                movable.Index    = 0;
                movable.Position = (int)index;
            });

            // 重力ですべて落下させる
            this.Gravity.Update(_context, player, GravityParam);

            // スライムを消済にマーキングする
            this.ErasingMarker.Update(_context, player, ErasingMarkerParam);

            // 消済スライム数をカウントする
            return(SlimeCountHelper.GetSlimeCount(_context, player, Slime.Erased));
        }
        /// <summary>
        /// フィールドの特徴を生成します。
        /// </summary>
        /// <param name="context"></param>
        /// <returns>フィールドの特徴</returns>
        public SparseVector <double> GetNext(FieldContext context)
        {
            var vector = new SparseVector <double>(0.0d);
            var param  = new ErasedPotentialSlimeAnalyzer.Param();

            param.ErasedSlimes = context.UsingSlimes;

            var players = new[] { Player.Index.First, Player.Index.Second };

            foreach (var player in players)
            {
                if (!this.OwnConfig.BothPlayer && player != context.OperationPlayer)
                {
                    continue;
                }

                var erasedPotentialCount = 0;
                var slimeCount           = 0;
                foreach (var slime in context.UsingSlimes)
                {
                    param.TargetSlime = slime;
                    if (this.OwnConfig.TargetFeatue[Feature.ErasedPotentialCount])
                    {
                        // 他の色を消すと消える個数
                        erasedPotentialCount += ErasedPotentialSlimeAnalyzer.Analyze(context, player, param);
                    }

                    if (this.OwnConfig.TargetFeatue[Feature.SlimeCount])
                    {
                        // フィールドのスライム数
                        slimeCount += SlimeCountHelper.GetSlimeCount(context, player, slime);
                    }
                }
                if (this.OwnConfig.TargetFeatue[Feature.ErasedPotentialCount])
                {
                    vector.Add(erasedPotentialCount);
                }

                if (this.OwnConfig.TargetFeatue[Feature.SlimeCount])
                {
                    vector.Add(slimeCount);
                }

                if (this.OwnConfig.TargetFeatue[Feature.ObstructionCount])
                {
                    // フィールドのおじゃまスライム数
                    var obstructionCount = SlimeCountHelper.GetSlimeCount(context, player, Slime.Obstruction);
                    vector.Add(obstructionCount);
                }

                if (this.OwnConfig.TargetFeatue[Feature.NoticeObstruction])
                {
                    // 予告おじゃまスライム数
                    var noticeObstruction = ObstructionSlimeHelper.ObstructionsToCount(context.ObstructionSlimes[(int)player]);
                    vector.Add(noticeObstruction);
                }

                if (this.OwnConfig.TargetFeatue[Feature.HeightDiff])
                {
                    // 高低差
                    var hDiff = DifferenceHeightAnalyzer.Analyze(context, player);
                    vector.Add(hDiff);
                }

                if (this.OwnConfig.TargetFeatue[Feature.UpperCount])
                {
                    // 上部スライム数
                    var upperCount = 0;
                    foreach (var u in UpperUnits)
                    {
                        foreach (var i in UpperIndexes)
                        {
                            upperCount += FieldContextHelper.ExistsSlime(context, player, FieldContextConfig.MaxHiddenUnitIndex + u, i) ? 1 : 0;
                        }
                    }
                    vector.Add(upperCount);
                }

                if (this.OwnConfig.TargetFeatue[Feature.DangerCount])
                {
                    // 左から3番目のスライム数
                    var dangerCount = 0;
                    foreach (var u in DangerUnits)
                    {
                        foreach (var i in DangerIndexes)
                        {
                            dangerCount += FieldContextHelper.ExistsSlime(context, player, FieldContextConfig.MaxHiddenUnitIndex + u, i) ? 1 : 0;
                        }
                    }
                    vector.Add(dangerCount);
                }

                if (this.OwnConfig.TargetFeatue[Feature.Chain])
                {
                    // 起こりうる最大連鎖数
                    var chain = 0;
                    if (player == context.OperationPlayer)
                    {
                        chain = this.ChainAnalyzer.Analyze(context, player);
                    }
                    vector.Add(chain);
                }
            }
            ;

            return(vector);
        }