/// <summary> /// /// </summary> /// <param name="board"></param> /// <param name="protocol">Protocol will be used to write output of bestline</param> public Engine(Board board, IProtocol protocol) { Exit = false; Board = board; Protocol = protocol; elapsedTime = new Stopwatch(); historyMoves = new HistoryMoves(); killerMoves = new KillerMoves(); }
/// <summary> /// Calculates best line in given depth /// </summary> /// <param name="maxDepth"></param> /// <param name="timeLimit">Time limit in millisecond</param> /// <returns></returns> public Result Search(long timeLimit) { this.timeLimit = timeLimit; int infinity = int.MaxValue; int alpha = -infinity, beta = infinity, depth = 0, nodesCount = 0; Result previousResult = null; elapsedTime.Restart(); Result result; var pv = new List<Move>(); Exit = false; historyMoves = new HistoryMoves(); killerMoves = new KillerMoves(); for (iterationPly = 1; ; ) { var score = AlphaBeta(alpha, beta, iterationPly, depth, pv, NullMove.Disabled, ref nodesCount); if (score <= alpha || score >= beta) { //Aspiration window failed so make full window search again. alpha = -infinity; beta = infinity; continue; } if ((!HaveTime() || Exit) && iterationPly > 1) //time control and stop mode { return previousResult; } alpha = score - Pawn.Piecevalue / 4; //Narrow Aspiration window beta = score + Pawn.Piecevalue / 4; //Save principal variation for next iteration previousPV = new List<Move>(); previousPV.AddRange(pv); result = new Result(iterationPly, score, elapsedTime.ElapsedMilliseconds, nodesCount, pv); previousResult = new Result(iterationPly, score, elapsedTime.ElapsedMilliseconds, nodesCount, previousPV); if (result.BestLine.Count > 0) Protocol.WriteOutput(result); if (Math.Abs(score) == Board.CheckMateValue || Exit || iterationPly>30) break; iterationPly++; nodesCount = 0; } return result; }