private void Execution() { do { lock (gm) { aiInfo = ai.NextControl(gm, out cx, out cr); lastInfo = gm.ForwardStep(cx, cr); } Trace.TraceInformation("{0}, CX {1}, CR {2}, {3}", gm.ToString(), cx, cr, lastInfo.ToString()); } while (lastInfo.AppraisalScore >= 0 && autoForward); }
public TurnInfo NextControl(GameModel gm, out int cx, out int cr) { long callCount = 0, boaderScore = 0; int nowLevel = 0, ci = 0; TurnInfo turnInfo = new TurnInfo(); try { while (!MaxToControl(out ci, boaderScore) && nowLevel++ < maxLevel) { if (!parallel) { SearchStorage ss = CreateLocalStorage(gm, nowLevel, boaderScore); turnInfo = SearchNode(rootNode, 0, ss); boaderScore = ss.MinimaxScore; callCount = ss.CallCount; } else { long minScore = long.MaxValue; long minimaxScore = 0; SpinLock sl = new SpinLock(); if (!rootNode.IsExistChild()) { rootNode.GenerateChild(W, T); } ParallelLoopResult plr = Parallel.For<SearchStorage>(0, rootNode.Length, () => CreateLocalStorage(gm, nowLevel, boaderScore), (index, state, local) => { local.MinimaxScore = long.MinValue; local.CallCount = 0; Debug.Assert(local.GMC.Level == 1); local.resultInfo = AppraiseNode(rootNode[index], 1, 0, local); return local; }, (local) => { bool lockTaken = false; while (!lockTaken) sl.Enter(ref lockTaken); if (turnInfo.AppraisalScore < local.resultInfo.AppraisalScore) { turnInfo = local.resultInfo; } if (local.resultInfo.AppraisalScore >= local.BoaderScore) { minScore = Math.Min(minScore, local.resultInfo.AppraisalScore); } minimaxScore = Math.Max(minimaxScore, local.MinimaxScore); callCount += local.CallCount; sl.Exit(); } ); Debug.Assert(plr.IsCompleted); if (minScore < long.MaxValue) { boaderScore = Math.Max(minimaxScore, minScore); } else { boaderScore = minimaxScore; } } Trace.TraceInformation("Turn {0}, Level {1}, CallCount {2}, BoaderScore {3}, {4}, {5}", gm.Turn + 1, nowLevel, callCount, boaderScore, turnInfo.ToString(), rootNode.ToString()); } } catch (OutOfMemoryException e) { Trace.TraceWarning("{0}", e.ToString()); } if (ci != -1) { rootNode = rootNode[ci]; cx = rootNode.CX; cr = rootNode.CR; } else { rootNode = new AppraisalTree(); cx = 0; cr = 0; } return turnInfo; }