/// <summary>
        /// Recursive method to find the best move in a given position. Min-max algorithm alternates
        /// between black and white.
        /// </summary>
        /// <param name="board"></param>
        /// <param name="turn"></param>
        /// <param name="possibleMoves"></param>
        /// <param name="level">Number of half moves to look forward.</param>
        /// <param name="topLevel">True if this is the outermost call.</param>
        /// <param name="alpha"></param>
        /// <param name="beta"></param>
        /// <param name="bestMove"></param>
        /// <returns></returns>
        private int CalculateMove(ChessBoard board, ChessPieceColor turn, List <ChessMove> possibleMoves, int level, bool topLevel,
                                  int alpha, int beta, out ChessMove bestMove, int initialDepth)
        {
            int best_score = -INFINITY;

            bestMove = null;

            if (!Stop)
            {
                int i = 0;
                foreach (ChessMove possibleMove in possibleMoves)
                {
                    if (topLevel && ((depthToVisualize != 0 && initialDepth >= depthToVisualize) || (depthToVisualize == 0 && initialDepth > 2)))
                    {
                        RaiseConsideringMoveEvent(possibleMove);
                    }

                    i++;

                    ChessBoard resBoard = new ChessBoard(board);
                    resBoard.ApplyMove(turn, possibleMove, null);

                    int move_score = 0;
                    if (level == 0)
                    {
#if PROF
                        prof.Start("StaticEval");
#endif
                        move_score = StaticEvaluation(resBoard, turn);
#if PROF
                        prof.End("StaticEval");
#endif
                    }
                    else
                    {
                        ChessMove        m       = null;
                        ChessPieceColor  newTurn = ChessGame.InvertColor(turn);
                        List <ChessMove> moves   = ChessGame.GetPossibleMoves(resBoard, newTurn);
                        bool             abort   = false;

                        if (moves.Count == 0)
                        {
                            if (!ChessGame.IsInCheck(board, newTurn))
                            {
                                // Stale mate, good depending on piece value.
                                int whiteValue = 0;
                                int blackValue = 0;
                                board.GetPiecesValue(out whiteValue, out blackValue);

                                int delta = (turn == ChessPieceColor.White ? whiteValue - blackValue : blackValue - whiteValue);
                                if (delta > 0)
                                {
                                    move_score = -10000;
                                }
                                else
                                {
                                    move_score = 10000;
                                }
                            }
                            else
                            {
                                int checkMateScore = 50000 + level * 100; // Prioritize early check mate.

                                move_score = checkMateScore;              // Check mate.
                            }
                        }
                        else
                        {
                            move_score = -CalculateMove(resBoard, newTurn, moves, level - 1, false, -beta, -alpha, out m, initialDepth);
                            if (m == null)  // Abort
                            {
                                abort = true;
                            }
                        }

                        if (abort)  // Abort
                        {
                            bestMove   = null;
                            best_score = -INFINITY;
                            break;
                        }
                    }

                    if (topLevel)
                    {
                        // Decrease score for repetition moves.
                        if (Game.ChessMoves.Count >= 3)
                        {
                            ChessMove myLastMove     = Game.ChessMoves[Game.ChessMoves.Count - 2];
                            ChessMove oppLastMove    = Game.ChessMoves[Game.ChessMoves.Count - 1];
                            ChessMove oppSecLastMove = Game.ChessMoves[Game.ChessMoves.Count - 3];

                            if (myLastMove.FromIndex == possibleMove.ToIndex &&
                                myLastMove.ToIndex == possibleMove.FromIndex &&
                                !myLastMove.IsCapture &&
                                oppLastMove.FromIndex == oppSecLastMove.ToIndex &&
                                oppLastMove.ToIndex == oppSecLastMove.FromIndex &&
                                !oppLastMove.IsCapture && !oppSecLastMove.IsCapture)    // TODO: check for IsCapture in possibleMove
                            {
                                move_score -= 30;
                            }
                        }
                    }

#if LOGGING
                    Debug.WriteLine(string.Format("{0}Level {1} {2} {3} alpha {4} beta {5}", GetIndent(level), level, possibleMove.ToString(), move_score, alpha, beta));
#endif
                    if (move_score > best_score)
                    {
                        best_score = move_score;
                        bestMove   = possibleMove;
                    }

                    if (best_score > alpha)
                    {
                        alpha = best_score;
                    }

                    if (alpha >= beta)
                    {
                        return(alpha);   // This means the move is as good as or worse than a previous move.
                    }
                }
            }

            return(best_score);
        }
        private ChessMove GetNextMove()
        {
            int startTicks = (int)DateTime.Now.Ticks;

            ChessMove move = null;

            Progress = 0;
            Aborted  = false;
            Stop     = false;

            // Try opening book first.
            move = openingBook.GetNextMove(Game.ChessMoves);
            if (move != null && Game.MakeMove(move, true))
            {
#if !NETFX_CORE
                Thread.Sleep(200);
#endif
            }
            else
            {
#if LOGGING
                Debug.WriteLine(string.Format("Calc start"));
#endif

#if NETFX_CORE
                MyTimer timer = null;
                if (TimeLimit > 0)
                {
                    timer = new MyTimer(OutOfTime, null, TimeLimit, System.Threading.Timeout.Infinite);
                    Debug.WriteLine("Timer " + TimeLimit);
                }
#else
                Timer timer = null;
                if (TimeLimit > 0)
                {
                    timer = new Timer(OutOfTime, null, TimeLimit, System.Threading.Timeout.Infinite);
                    Debug.WriteLine("Timer " + TimeLimit);
                }
#endif

                List <ChessMove> possibleMoves = ChessGame.GetPossibleMoves(Game.Board, Game.Turn);
                // Iterative deepening.
                int depth = 0;
                while (true)
                {
                    ChessMove bestMove = null;

                    Game.AddLog(string.Format("lvl {0} start depth {1}", (int)DifficultyLevel, depth));

                    int calcStartTicks = (int)DateTime.Now.Ticks;
                    CalculateMove(Game.Board, Game.Turn, possibleMoves, depth, true, -INFINITY, INFINITY, out bestMove, depth);

                    int calcTimeTicks = (int)DateTime.Now.Ticks - calcStartTicks;
                    Game.AddLog(string.Format("end depth {0} ticks {1} bestMove {2}", depth, calcTimeTicks, (bestMove == null ? 0 :1)));

                    Debug.WriteLine(string.Format("dTV: {0} time: {1}", depthToVisualize, calcTimeTicks / TimeSpan.TicksPerSecond));
                    if (depthToVisualize == 0 && ((float)calcTimeTicks / (float)TimeSpan.TicksPerSecond) > 0.3f)
                    {
                        depthToVisualize = depth;
                    }

                    if (bestMove != null)
                    {
                        move = bestMove;
                    }

                    if (bestMove == null || DepthLimit > 0 && depth >= DepthLimit)
                    {
                        if (timer != null)
                        {
                            timer.Dispose();
                        }
                        break;
                    }
                    else
                    {
                        // Move the move to the beginning of the list.
                        if (possibleMoves.Remove(move))
                        {
                            possibleMoves.Insert(0, move);
                        }
                    }
                    depth++;
                }

#if LOGGING
                Debug.WriteLine(string.Format("Calc end."));
#endif
            }

            gameTicks += (int)DateTime.Now.Ticks - startTicks;

            return(move);
        }