public TurnInfo FieldAssess(GameModel terget, IgnitionResultAppraise ira) { TurnInfo result = new TurnInfo(); MainField field = terget.Main; terget.CopyTo(gmCache); for (int x = 0; x < W; x++) { int top, bottom, maxNum; bottom = field.GetEarthPoint(x); top = bottom - 0; maxNum = S / 2; if (field.GetEarthPoint(x - 1) >= bottom || field.GetEarthPoint(x + 1) >= bottom) { //bottom++; //if (bottom >= field.Height) bottom = field.Height - 1; //maxNum = S; } for (int y = top; y <= bottom; y++) { for (int n = 1; n <= maxNum; n++) { TurnInfo now = gmCache.IgnitionPointForwardStep(n, x, y); terget.CopyTo(gmCache, now.ChangeRect); ira(ref result, now); } } } return result; }
private void ResultAppraise(ref TurnInfo result, TurnInfo now) { now.AppraisalScore = PartReckonAppraiseScore(now); if (result.AppraisalScore <= now.AppraisalScore) { result = now; } }
private long PartReckonAppraiseScore(TurnInfo info) { double e = (double)info.MaxEraseCount / targetErase; double c = (double)info.MaxEraseChain / targetChain; double b = (double)(H + T - info.MostBottom) / H; double w = (double)info.EraseWidth / W; double s = (double)info.MaxEraseCount / (info.TotalEraseCount + 1); return (long)(int.MaxValue * (e + c + b + w)); }
protected SearchStorage(GameModel gm, int nowLevel, long boaderScore) { GMC = new GameModelCache(nowLevel, gm); NowLevel = nowLevel; BoaderScore = boaderScore; MinimaxScore = long.MinValue; CallCount = 0; resultInfo = new TurnInfo(); }
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); }
private void ResultAppraise(ref TurnInfo result, TurnInfo now) { if (now.RawScore >= Th) { now.AppraisalScore = (long)Th * Th / now.EraseBlock; } else if (now.RawScore > 0) { now.AppraisalScore = now.RawScore / now.EraseBlock; } else { now.AppraisalScore = 0; } result.AppraisalScore += now.AppraisalScore; }
protected override TurnInfo ReckonAppraiseScore(TurnInfo forwardInfo, TurnInfo appraiseInfo) { if (forwardInfo.AppraisalScore < 0) { return forwardInfo; } double eb = (double)(forwardInfo.EraseBlock + forwardInfo.EraseObstacle) / FieldArea; if (eb >= 0.7) { forwardInfo.AppraisalScore = PartReckonAppraiseScore(forwardInfo); } else { forwardInfo.AppraisalScore = 0; } //appraiseInfo.AppraisalScore = (long)(appraiseInfo.AppraisalScore * (1 - eb)); return TurnInfo.MaxInfo(forwardInfo, appraiseInfo); }
public static TurnInfo MaxInfo(TurnInfo a, TurnInfo b) { a.AppraisalScore = Math.Max(a.AppraisalScore, b.AppraisalScore); a.RawScore = Math.Max(a.RawScore, b.RawScore); a.ExtraScore = Math.Max(a.ExtraScore, b.ExtraScore); a.Chain = Math.Max(a.Chain, b.Chain); a.TotalEraseCount = Math.Max(a.TotalEraseCount, b.TotalEraseCount); a.EraseBlock = Math.Max(a.EraseBlock, b.EraseBlock); a.EraseObstacle = Math.Max(a.EraseObstacle, b.EraseObstacle); a.EraseWidth = Math.Max(a.EraseWidth, b.EraseWidth); a.MaxEraseCount = Math.Max(a.MaxEraseCount, b.MaxEraseCount); a.MaxEraseChain = Math.Max(a.MaxEraseChain, b.MaxEraseChain); a.MostBottom = Math.Min(a.MostBottom, b.MostBottom); a.FieldSpace = Math.Min(a.FieldSpace, b.FieldSpace); a.FallingCount = Math.Max(a.FallingCount, b.FallingCount); a.ChangeRect.MaxRect(b.ChangeRect); return a; }
protected override TurnInfo ReckonAppraiseScore(TurnInfo forwardInfo, TurnInfo appraiseInfo) { if(forwardInfo.AppraisalScore < 0) { return forwardInfo; } TurnInfo nowInfo = TurnInfo.MaxInfo(forwardInfo, appraiseInfo); long score = appraiseInfo.AppraisalScore; if (forwardInfo.RawScore >= Th) { score += (long)Th * Th * Th / forwardInfo.EraseBlock; } else if (forwardInfo.EraseBlock > 0) { score /= forwardInfo.EraseBlock; } nowInfo.AppraisalScore = score; return nowInfo; }
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; }
protected abstract TurnInfo ReckonAppraiseScore(TurnInfo forwardInfo, TurnInfo assessInfo);
private TurnInfo AppraiseNode(AppraisalTree node, int level, long boader, SearchStorage ss) { TurnInfo nowInfo = node.Info; TurnInfo forwardInfo = new TurnInfo(); TurnInfo appraiseInfo = new TurnInfo(); if (nowInfo.AppraisalScore != long.MinValue) { if (nowInfo.AppraisalScore < boader) { node.ReleaseChild(); return nowInfo; } else if(level >= ss.NowLevel) { return nowInfo; } } forwardInfo = ss.GMC.ForwardStep(node.CX, node.CR); if (forwardInfo.AppraisalScore >= 0) { if (level >= ss.NowLevel) { appraiseInfo = AppraiseFunction(ss.GMC.GetCurrentGameModel(), ss); ss.CallCount++; } else { ss.GMC.NextLevel(); appraiseInfo = SearchNode(node, level, ss); ss.GMC.PreviousLevel(); } } ss.GMC.BackwardStep(); nowInfo = ReckonAppraiseScore(forwardInfo, appraiseInfo); node.Info = nowInfo; return nowInfo; }
private TurnInfo SearchNode(AppraisalTree node, int level, SearchStorage ss) { if (!node.IsExistChild()) { node.GenerateChild(W, T); } int length = node.Length; TurnInfo maxInfo = new TurnInfo { AppraisalScore = long.MinValue }; long minScore = long.MaxValue; //long boader = GetRankBoaderScore(node, level + 1); long boader = ss.BoaderScore; for (int i = 0; i < length; i++) { TurnInfo nextInfo = AppraiseNode(node[i], level + 1, boader, ss); if (maxInfo.AppraisalScore < nextInfo.AppraisalScore) { maxInfo = nextInfo; } if (nextInfo.AppraisalScore >= boader) { minScore = Math.Min(minScore, nextInfo.AppraisalScore); } } if (minScore < long.MaxValue) { ss.MinimaxScore = Math.Max(ss.MinimaxScore, minScore); } return maxInfo; }