private static AlphaBetaRootResult AlphaBetaRoot(Board _board, int _depth, List <Move> _sortedMoves, bool _ponderingMode, int alpha, int beta) { m_NodesSearched++; AlphaBetaRootResult result = new AlphaBetaRootResult { PV_Moves = new List <Move>(), Finished = true }; for (int i = 0; i < _sortedMoves.Count; i++) { //check if forced to quit if (_ponderingMode) { if (StopPondering) { result.Finished = false; } } else { if (Clock.TimesUp) { result.Finished = false; break; } } Move move = _sortedMoves[i]; Board clone = Board.Clone(_board); clone.ApplyMove(move); int childAlphaBeta = -AlphaBeta(clone, _depth - 1, -beta, -alpha); if (childAlphaBeta > alpha) { alpha = childAlphaBeta; result.BestMove = move; result.PV_Moves.Add(move); } if (childAlphaBeta == TIMES_UP) { result.Finished = false; break; } if (beta <= alpha) { break; } } result.Score = alpha; return(result); }
private static IterativeDeepeningResult IterativeDeepeningAlphaBeta(Board _board) { IterativeDeepeningResult result = new IterativeDeepeningResult(); //Move bestMove = null; //Move currentMove = null; var moves = MovesGenerator.GetMoves(_board, true); //iterative deepening current depth int depth; Move lastMove = _board.LastMove[1 - _board.CurrentPlayer]; if (lastMove != null && m_Pondering.Keys.Any(x => x.EqualMove(lastMove))) { Move lastMoveOnPondering = m_Pondering.Keys.First(x => x.EqualMove(lastMove)); IterativeDeepeningResult ponderingResult = m_Pondering[lastMoveOnPondering]; foreach (Move move in ponderingResult.PV_Moves) { Move moveToReorder = moves.First(x => x.EqualMove(move)); moves.Remove(moveToReorder); moves.Insert(0, moveToReorder); } depth = ponderingResult.DepthReeched + 1; } else { depth = 1; } int alpha = -31000, beta = 32000; //iterative deepening for (; !Clock.TimesUp && depth <= Depth; depth++) { _board.NullMoveOk = true; m_NodesSearched = 0; AlphaBetaRootResult alphaBetaResult = AlphaBetaRoot(_board, depth, moves, false, alpha, beta); if (!Clock.TimesUp && alphaBetaResult.BestMove != null && alphaBetaResult.Finished == true) { //used in case of researching bool isSearchOk = true; /*if (alphaBetaResult.Score <= alpha || alphaBetaResult.Score >= beta) * { * alpha = -31000; * beta = 32000; * alphaBetaResult = AlphaBetaRoot(_board, depth, moves, false, alpha, beta); * if (Clock.TimesUp || alphaBetaResult.BestMove == null && alphaBetaResult.Finished == false) * isSearchOk = false; ; * } * else * { * alpha = alphaBetaResult.Score - 50; * beta = alphaBetaResult.Score + 50; * }*/ if (isSearchOk) { result.BestMove = alphaBetaResult.BestMove; result.PV_Moves = alphaBetaResult.PV_Moves; result.DepthReeched = depth; } //order moves by the PV moves. foreach (Move move in alphaBetaResult.PV_Moves) { moves.Remove(move); moves.Insert(0, move); } } Global.WriteToLog(depth.ToString() + ' ' + "100" + ' ' + (Clock.CurrentMoveTimeElapsed.TotalMilliseconds) + ' ' + m_NodesSearched + ' ' + (alphaBetaResult.BestMove != null)); } return(result); }
private static void MakePondering(object _board) { Board board = _board as Board; m_Pondering = new Dictionary <Move, IterativeDeepeningResult>(); var moves = MovesGenerator.GetMoves(board, true); Dictionary <Move, List <Move> > responseMoves = new Dictionary <Move, List <Move> >(); bool finishedDepth = true; for (int depth = 1; finishedDepth && depth <= Depth; depth = depth + 1) { for (int i = 0; i < moves.Count; i++) { Move move = moves[i]; //order moves by the PV moves. if (depth > 1) { foreach (Move pvMove in m_Pondering[move].PV_Moves) { responseMoves[move].Remove(pvMove); responseMoves[move].Insert(0, pvMove); } } //now clone the game board (to avoid any changes) Board clone = Board.Clone(board); clone.ApplyMove(move); List <Move> response; if (responseMoves.ContainsKey(move)) { response = responseMoves[move]; } else { response = MovesGenerator.GetMoves(clone, true); if (response == null) { continue; } responseMoves.Add(move, response); } //launch alpha beta AlphaBetaRootResult alphaBetaResult = AlphaBetaRoot(clone, depth, response, true); if (alphaBetaResult.Finished == false) { finishedDepth = false; break; } IterativeDeepeningResult moveResult; if (m_Pondering.ContainsKey(move)) { moveResult = m_Pondering[move]; moveResult.BestMove = alphaBetaResult.BestMove; moveResult.PV_Moves = alphaBetaResult.PV_Moves; moveResult.DepthReeched++; } else { m_Pondering.Add(move, new IterativeDeepeningResult { BestMove = alphaBetaResult.BestMove, DepthReeched = 1, PV_Moves = alphaBetaResult.PV_Moves }); } } } m_PonderThread.Abort(); }