コード例 #1
0
        protected Block1Node Create(Field field, BlockPath path, ApplyParameters pars)
        {
            var score = pars.Evaluator.GetScore(field, Depth, pars.Parameters);

            pars.Evaluations++;
            return(new Block1Node(field, path, score, pars.Next.BranchingFactor1));
        }
コード例 #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
        protected override BlockRndNode Create(Field field, ApplyParameters pars)
        {
            var score = pars.Evaluator.GetScore(field, Depth, pars.Parameters);

            pars.Evaluations++;
            return(new BlockRndNode(field, Depth, score));
        }
コード例 #4
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 void Apply(byte depth, ApplyParameters pars)
        {
            if (depth > Depth && depth <= pars.MaximumDepth && pars.HasTimeLeft)
            {
                if (Children == null)
                {
                    Children = new List <BlockNodes <BlockRndNode> >();

                    foreach (var block in pars.Blocks[Depth])
                    {
                        var nodes = new BlockNodes <BlockRndNode>(block);
                        foreach (var field in pars.Generator.GetFields(Field, block))
                        {
                            if (!pars.HasTimeLeft)
                            {
                                return;
                            }

                            var applied = BlockNode.Apply(field, Depth, pars);
                            if (!applied.IsNone)
                            {
                                var child = Create(applied, pars);
                                nodes.InsertSorted(child);
                            }
                        }
                        Children.Add(nodes);
                    }
                }
                else
                {
                    foreach (var nodes in Children)
                    {
                        nodes.Apply(depth, pars, BranchingFactor);
                    }
                }
                Score = 0;
                foreach (var nodes in Children)
                {
                    Score += nodes.GetScore(this);
                }
                if (Children.Count == 2)
                {
                    // Divide by 2.
                    Score >>= 1;
                }
                // We can not find valid responses. We will lose next turn.
                else if (Children.Count == 0)
                {
                    Score = Scores.Loses(Depth + 1);
                }
                else
                {
                    Score /= Children.Count;
                }
            }
        }
コード例 #5
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)
                {
                    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);
            }
        }
コード例 #6
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);
        }
コード例 #7
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);
            }
        }
コード例 #8
0
        /// <summary>Applies the search on the child nodes.</summary>
        /// <param name="depth">
        /// The maximum depth to search.
        /// </param>
        /// <param name="pars">
        /// The parameters needed to apply the search.
        /// </param>
        /// <param name="branchingFactor">
        /// The maximum branching factor.
        /// </param>
        public void Apply(byte depth, ApplyParameters pars, int branchingFactor)
        {
            if (Empty() || depth == 0)
            {
                return;
            }

            var threshold          = this[Math.Min(Count, branchingFactor) - 1].Score;
            var depthMin1          = (byte)(depth - 1);
            var dephtMin1Threshold = threshold - 100;

            foreach (var child in this)
            {
                // Only checks moves that are not worse than the threshold.
                if (child.Score < threshold)
                {
                    break;
                }

                if (child.Score > dephtMin1Threshold)
                {
                    child.Apply(depth, pars);
                }
                else
                {
                    child.Apply(depthMin1, pars);
                }

                // we find a lower move, look for others that are potentially better.
                if (child.Score < threshold)
                {
                    threshold = child.Score;
                }
            }
            base.Sort();
        }
コード例 #9
0
 protected override Block GetBlock(ApplyParameters pars)
 {
     return(pars.Current);
 }
コード例 #10
0
 protected override Block1Node Create(Field field, ApplyParameters pars)
 {
     throw new NotImplementedException();
 }
コード例 #11
0
 protected abstract Block GetBlock(ApplyParameters pars);
コード例 #12
0
 protected abstract T Create(Field field, ApplyParameters pars);
コード例 #13
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 abstract void Apply(byte depth, ApplyParameters pars);