/// <summary>Applies the search on the current node.</summary>
        /// <param name="depth">
        /// The maximum depth to search.
        /// </param>
        /// <param name="pars">
        /// The parameters needed to apply the search.
        /// </param>
        public override void Apply(byte depth, ApplyParameters pars)
        {
            if (depth > Depth && depth <= pars.MaximumDepth && pars.HasTimeLeft)
            {
                if (Children == null)
                {
                    var block = GetBlock(pars);
                    Children = new BlockNodes <BlockRndNode>(block);

                    var applied = BlockNode.Apply(Field, Depth, pars);
                    if (!applied.IsNone)
                    {
                        foreach (var field in pars.Generator.GetFields(applied, block))
                        {
                            if (!pars.HasTimeLeft)
                            {
                                return;
                            }
                            var child = Create(field, pars);

                            // We can kill our opponent.
                            if (child.Field.Points > Field.Points)
                            {
                                var garbageNew = child.Field.Points / 3;
                                if (garbageNew - pars.Garbage > pars.Opponent.FirstFilled2)
                                {
                                    child.SetFinalScore(Scores.Wins(2));
                                }
                            }
                            Children.InsertSorted(child);
                        }
                    }
                }
                else
                {
                    if (Children.Empty())
                    {
                        return;
                    }
                    Children.Apply(depth, pars, BranchingFactor);
                }
                Score = Children.GetScore(this);
            }
        }
示例#2
0
        public virtual BlockPath GetMove(Field field, Field opponent, Block current, Block next, int round)
        {
            Logs.Clear();
            Pars = new ApplyParameters(Rnd)
            {
                Garbage         = field.Points / 3,
                Round           = round,
                MaximumDuration = MaximumDuration,
                MaximumDepth    = MaximumDepth,
                Evaluator       = Evaluator,
                Generator       = Generator,
                Current         = current,
                Next            = next,
                FirstFilled     = field.FirstFilled,
                Parameters      = DefaultEvaluation,
            };
            var oppo = new OpponentEvaluator()
            {
                Generator = Pars.Generator
            };

            Pars.Opponent = oppo.Evaluate(opponent, current, next);

            var move = BlockPath.None;

            Root = new BlockRootNode(field);

            // search at least two ply deep.
            while ((Pars.Depth < 2 || (Pars.Depth < Pars.MaximumDepth && Pars.Elapsed < MinimumDuration))
                   // Cut if we have a win in 1 or two.
                   && Root.Score != Scores.Wins(Pars.Depth))
            {
                Root.Apply(++Pars.Depth, Pars);
                Logs.Add(new PlyLog(Pars.Round, Root.BestMove, Root.Score, Pars.Depth, Pars.Elapsed, Pars.Evaluations));
            }
            BestField = Root.BestField;
            return(Root.BestMove);
        }
示例#3
0
        /// <summary>Applies the search on the current node.</summary>
        /// <param name="depth">
        /// The maximum depth to search.
        /// </param>
        /// <param name="pars">
        /// The parameters needed to apply the search.
        /// </param>
        public override void Apply(byte depth, ApplyParameters pars)
        {
            if (depth > Depth && depth <= pars.MaximumDepth && pars.HasTimeLeft)
            {
                if (Children == null)
                {
                    BranchingFactor = pars.Current.BranchingFactor0;
                    var block = GetBlock(pars);
                    Children = new BlockNodes <Block1Node>(block);

                    foreach (var candidate in pars.Generator.GetMoves(Field, block))
                    {
                        if (!pars.HasTimeLeft)
                        {
                            return;
                        }
                        Block1Node child = Create(candidate.Field, candidate.Path, pars);

                        // We can kill our opponent.
                        if (child.Field.Points > Field.Points)
                        {
                            var garbageNew = child.Field.Points / 3;
                            if (garbageNew - pars.Garbage > pars.Opponent.FirstFilled1)
                            {
                                child.SetFinalScore(Scores.Wins(1));
                            }
                        }
                        Children.InsertSorted(child);
                    }
                }
                else
                {
                    Children.Apply(depth, pars, BranchingFactor);
                }
                Score = Children.GetScore(this);
            }
        }