/// <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); } }
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); }
/// <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); } }