private ulong InternalPerftWithHash(int depth, int p, PerfResults res, ITranspositionTable table) { ulong count = 0; if (table.ProbeMovesCount(ZKey, out count, depth)) { res.HashHit++; return(count); } bool inCheck = TestInCheck(ToMove); int moveCount = GetMoves(p, prftMoves); if (depth == 1) { table.StoreMovesCount(ZKey, (ulong)moveCount, 1); return((ulong)moveCount); } if (depth == 0) { return(1); } for (int i = p; i < p + moveCount; ++i) { Side moving = ToMove; Move(prftMoves[i]); count += InternalPerftWithHash(depth - 1, p + moveCount, res, table); UndoMove(); } table.StoreMovesCount(ZKey, count, depth); return(count); }
public PerfResults Perft(int depth, bool useHash, ITranspositionTable table) { if (useHash == false) { prftMoves = new int[1000]; Stopwatch sw = new Stopwatch(); PerfResults perft = new PerfResults(); sw.Start(); perft.MovesCount = InternalPerft(depth, 0); sw.Stop(); perft.Elapsed = (ulong)sw.ElapsedMilliseconds; return(perft); } else { prftMoves = new int[1000]; Stopwatch sw = new Stopwatch(); PerfResults perft = new PerfResults(); sw.Start(); perft.MovesCount = InternalPerftWithHash(depth, 0, perft, table); sw.Stop(); perft.Elapsed = (ulong)sw.ElapsedMilliseconds; return(perft); } }
private void DoPerftTest(string line, ITranspositionTable tt) { string[] chunks = line.Split(';'); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Testing position:" + chunks[0]); Console.ForegroundColor = ConsoleColor.White; OX88Chessboard board = new OX88Chessboard(chunks[0]); for (int i = 1; i < chunks.Length; ++i) { int level; ulong expected; string[] items = chunks[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); level = int.Parse(items[0].Substring(1)); expected = ulong.Parse(items[1]); Console.Write("Performing perft {0}. Expected:{1}\t", level, expected); PerfResults res = board.Perft(level, true, tt); Console.ForegroundColor = res.MovesCount == expected ? ConsoleColor.DarkGreen : ConsoleColor.Red; Console.WriteLine("Found:{0}\t\t\t{1}", res.MovesCount, res.MovesCount == expected ? "SUCCESS!" : "*ERROR*"); Console.ForegroundColor = ConsoleColor.White; } }
private int RunMtdf(MutState root, CancellationToken ct, out ImmutableArray <Move> pv) { _tt = (ITranspositionTable <TtEntry>)Tt; _ct = ct; _nodesSearched = 0; _nodesRemaining = MaxNodes; _pvt = new PvTable(Depth); _kt = new KillerTable(Depth); int guess = FirstGuess; var(lowerBound, upperBound) = (Evaluation.MinScore, Evaluation.MaxScore); do { int beta = guess == lowerBound ? (guess + 1) : guess; Log.Debug("Starting null-window search for state {0} with beta={1}", root, beta); guess = NullWindowSearch(root, beta, Depth); Log.Debug("Null-window search for state {0} with beta={1} returned {2}", root, beta, guess); if (guess < beta) // the real value is <= guess { upperBound = guess; } else // beta-cutoff: the real value is >= guess { lowerBound = guess; } // EXPERIMENTAL: trying binary search guess = (int)(((long)lowerBound + (long)upperBound) / 2); }while (lowerBound < upperBound && _nodesRemaining > 0); pv = _pvt.GetTopPv().ToImmutableArray(); return(guess); }
public FullEngine(int maxdepth, ITranspositionTable tt) { this.maxDepth = maxdepth; ttable = tt; }
void UciNewGame() { _root = null; _tt = null; }
void Go(Stack <string> tokens) { if (_root == null) { Error.WriteLine("Position not set, use the 'position' command to set it"); return; } var settings = new GoSettings(); while (tokens.TryPop(out var paramName)) { switch (paramName) { case "searchmoves": // needs to be the last command on the line var searchMoves = new List <Move>(); while (tokens.TryPop(out var move)) { searchMoves.Add(Move.ParseLong(move)); } settings.SearchMoves = searchMoves.ToImmutableArray(); break; case "ponder": _ponder = true; break; case "depth": settings.Depth = int.Parse(tokens.Pop()); break; case "nodes": settings.Nodes = int.Parse(tokens.Pop()); break; case "mate": // todo settings.Mate = int.Parse(tokens.Pop()); break; case "movetime": // todo settings.MoveTime = TimeSpan.FromMilliseconds(int.Parse(tokens.Pop())); break; case "infinite": settings.Infinite = true; break; } } // go ahead with the search var searcher = new MtdfIds(); searcher.Depth = settings.Depth ?? ((settings.Infinite || settings.Nodes != null) ? int.MaxValue : DefaultSearchDepth); searcher.MaxNodes = settings.Nodes ?? int.MaxValue; int ttCapacity = _options.Get <int>("Hash") * EntriesPerMb; if (_tt == null || _tt.Capacity != ttCapacity) { _tt = searcher.MakeTt(ttCapacity); } searcher.Tt = _tt; _ponder = false; var cts = new CancellationTokenSource(); // define the task and either run it straight away, or add it to the queue if there's one in progress var rootCopy = _root; // if a new search is requested before this one is started, we don't want to pick up on a new position var searchTask = new Task(() => { try { _cts = cts; Search(rootCopy, searcher, settings, this, cts.Token); } // exceptions don't propagate to the main thread unless they are explicitly handled like this catch (Exception e) { Error.WriteLine(e); } finally { cts.Dispose(); _cts = null; // run the next task if one is queued if (_searchQueue.TryDequeue(out var nextTask)) { nextTask.Start(); } else { _searchInProgress = false; } } }); if (!_searchInProgress) { Debug.Assert(_searchQueue.IsEmpty); _searchInProgress = true; searchTask.Start(); } else { _searchQueue.Enqueue(searchTask); } }
public WinBoardAdapter(IChessBoard board, IEngine engine, ITranspositionTable hashTable) { this.board = board; this.engine = engine; }