private static object threadProc(Object data)
 {
     Individual[] weights = data as Individual[];
     Algorithms alg = new Algorithms(new CheckersPlayer(1));
     CheckersBoard whiteBoard = new CheckersBoard(0, weights[0].Weights);
     CheckersBoard blackBoard = new CheckersBoard(0, weights[1].Weights);
     whiteBoard.GameMaxLength = 150;
     blackBoard.GameMaxLength = 150;
     while (!blackBoard.GameIsOver())
     {
         CheckersMove move = alg.ABNegamax(blackBoard, weights[1].SearchDepth, 0, double.MinValue, double.MaxValue) as CheckersMove;
         whiteBoard.MakeMove(move);
         blackBoard.MakeMove(move);
         if (blackBoard.GameIsOver())
             break;
         else
         {
             move = alg.ABNegamax(whiteBoard, weights[0].SearchDepth, 0, double.MinValue, double.MaxValue) as CheckersMove;
             whiteBoard.MakeMove(move);
             blackBoard.MakeMove(move);
         }
     }
     switch (whiteBoard.Winner)
     {
         case 0:
             weights[0].Draws += 1;
             weights[1].Draws += 1;
             break;
         case 1:
             weights[0].TotalWhiteWins += 1;
             weights[1].Loses += 1;
             break;
         case -1:
             weights[1].TotalBlackWins += 1;
             weights[0].Loses += 1;
             break;
     }
     return weights as object;
 }
 public IBoardGame TestMove(IMove move)
 {
     CheckersBoard board = new CheckersBoard(this, false);
     board.MakeMove(move);
     return board;
 }
        /// <summary>
        ///  This procedure takes two individuals and makes them play against each other
        /// </summary>
        /// <param name="data">Should be an array of doubles representing two individuals</param>
        /// <returns>The individuals after playing against each other</returns>
        static object ThreadProc(Object data)
        {
            Individaul[] weights = data as Individaul[];
            GameAI.Algorithms alg = new Algorithms(new CheckersPlayer(1));
            CheckersBoard whiteBoard = new CheckersBoard(0, weights[0].Weights);
            CheckersBoard blackBoard = new CheckersBoard(0, weights[1].Weights);
            whiteBoard.GameMaxLength = 200;
            blackBoard.GameMaxLength = 200;
            while (!blackBoard.GameIsOver())
            {
                CheckersMove move = alg.ABNegamax(blackBoard, 4, 0, double.MinValue, double.MaxValue) as CheckersMove;
                whiteBoard.MakeMove(move);
                blackBoard.MakeMove(move);
                if (blackBoard.GameIsOver())
                    break;
                else
                {

                    move = alg.ABNegamax(whiteBoard, 4, 0, double.MinValue, double.MaxValue) as CheckersMove;
                    whiteBoard.MakeMove(move);
                    blackBoard.MakeMove(move);
                }
            }
            switch (whiteBoard.Winner)
            {
                case 0:
                    weights[0].AddToFitness(1);
                    weights[1].AddToFitness(1);
                    break;
                case 1:
                    weights[0].AddToFitness(3);
                    break;
                case -1:
                    weights[1].AddToFitness(3);
                    break;
            }
            return weights as object;
        }
        static object ThreadProcAdaptive(Object data)
        {
            Individual[] weights = data as Individual[];
            GameAI.Algorithms alg = new Algorithms(new CheckersPlayer(1));
            CheckersBoard whiteBoard = new CheckersBoard(0, weights[0].Weights);
            CheckersBoard blackScore = new CheckersBoard(0, weights[0].Weights);
            CheckersBoard blackBoard = new CheckersBoard(0, weights[1].Weights);
            whiteBoard.GameMaxLength = 200;
            blackBoard.GameMaxLength = 200;
            while (!blackBoard.GameIsOver())
            {
                CheckersMove move = alg.ABNegamax(blackBoard, weights[1].SearchDepth, 0, double.MinValue, double.MaxValue) as CheckersMove;
                List<IMove> opponentsMoves = alg.EvaluateMoves(blackScore, weights[0].SearchDepth, 0, double.MinValue, double.MaxValue);
                whiteBoard.MakeMove(move);
                blackScore.MakeMove(move);
                blackBoard.MakeMove(move);
                if (blackBoard.GameIsOver())
                    break;
                else
                {

                    move = alg.AdaptiveABNegamax(whiteBoard, weights[0].SearchDepth, 0, double.MinValue, double.MaxValue, opponentsMoves, move) as CheckersMove;
                    whiteBoard.MakeMove(move);
                    blackScore.MakeMove(move);
                    blackBoard.MakeMove(move);
                }
            }

            switch (whiteBoard.Winner)
            {
                case 0:
                    weights[0].Draws += 1;
                    weights[1].Draws += 1;
                    break;
                case 1:
                    weights[0].TotalWhiteWins += 1;
                    weights[1].Loses += 1;
                    break;
                case -1:
                    weights[1].TotalBlackWins += 1;
                    weights[0].Loses += 1;
                    break;
            }
            return weights as object;
        }
        //, GameAI.Algorithms alg)
        static object ThreadProc(Object data, string path)
        {
            Individual[] weights = data as Individual[];
            GameAI.Algorithms alg = new Algorithms(new CheckersPlayer(1));
            CheckersBoard whiteBoard = new CheckersBoard(0, weights[0].Weights);
            CheckersBoard blackBoard = new CheckersBoard(0, weights[1].Weights);
            whiteBoard.GameMaxLength = 200;
            blackBoard.GameMaxLength = 200;
            while (!blackBoard.GameIsOver())
            {
                CheckersMove move = alg.ABNegamax(blackBoard, weights[1].SearchDepth, 0, double.MinValue, double.MaxValue) as CheckersMove;
                whiteBoard.MakeMove(move);
                blackBoard.MakeMove(move);
                if (blackBoard.GameIsOver())
                    break;
                else
                {

                    //move = alg.ABNegamax(whiteBoard, weights[0].SearchDepth, 0, double.MinValue, double.MaxValue) as CheckersMove;
                    move = alg.POSM(whiteBoard, 0.5) as CheckersMove;
                    // writer.WriteLine(move.GetMoveScore().ToString());
                    whiteBoard.MakeMove(move);
                    blackBoard.MakeMove(move);
                }
            }
            FileStream file = new FileStream(path, FileMode.Append, FileAccess.Write);
            StreamWriter wr = new StreamWriter(file);
            switch (whiteBoard.Winner)
            {
                case 0:
                    weights[0].Draws += 1;
                    weights[1].Draws += 1;
                    wr.WriteLine("Draw");
                    wr.WriteLine(alg.ToString());
                    break;
                case 1:
                    weights[0].TotalWhiteWins += 1;
                    weights[1].Loses += 1;
                    wr.WriteLine("Win for Adaptive");
                    alg.GameObervationUpdate(1);
                    wr.WriteLine(alg.ToString());
                    break;
                case -1:
                    weights[1].TotalBlackWins += 1;
                    weights[0].Loses += 1;
                    wr.WriteLine("Los for Adaptive");
                    alg.GameObervationUpdate(-1);
                    wr.WriteLine(alg.ToString());
                    break;
            }
            wr.Close();
            file.Close();
            return weights as object;
        }
        private void moveList_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListView list = sender as ListView;
            if (list != null)
            {
                if (list.SelectedIndex != -1)
                {
                    MessageBoxResult result = MessageBox.Show("Do you wish to restore the game from this position? ",
                        "Restore",
                        MessageBoxButton.YesNo,
                        MessageBoxImage.Exclamation,
                        MessageBoxResult.No);
                    if (result == MessageBoxResult.Yes)
                    {

                        List<CheckersMove> moves = moveList.Tag as List<CheckersMove>;
                        int selectedIndex = list.SelectedIndex;
                        for (int index = list.Items.Count - 1; index > selectedIndex; --index)
                        {

                            list.Items.RemoveAt(index);
                            moves.RemoveAt(index);
                        }
                        board = new CheckersBoard(0, x);
                        board.GameOver += new CheckersBoard.EndGame(board_GameOver);
                        board.GameMaxLength = 200;
                        foreach (var move in moves)
                        {
                            board.MakeMove(move);
                            StringBuilder builder = new StringBuilder(move.PlayerID.ToString() == "1" ? "White: " : "Black: ");
                            foreach (var item in move.GetPath())
                            {
                                builder.Append(Convert.ToChar(65 + item.Y));
                                builder.Append((item.X + 1).ToString());
                                builder.Append('-');
                            }
                            // builder.Remove(builder.Length - 1, 1);
                            builder.Append(move.Duration.TotalSeconds.ToString());

                        }
                        moveList.ScrollIntoView(moveList.Items[moveList.Items.Count - 1]);
                        this.repaint(null);
                        if (alg.ComputerPlayerID == board.GetCurrentPlayer().GetPlayerID())
                        {
                            computerThread = new Thread(this.computerMove);
                            computerThread.Start();
                        }
                    }

                }

            }
            e.Handled = true;
        }
        private void load_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog fileDiag = new System.Windows.Forms.OpenFileDialog();
            System.Windows.Forms.DialogResult result = fileDiag.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                FileStream file = new FileStream(fileDiag.FileName, FileMode.Open, FileAccess.Read);
                StreamReader reader = new StreamReader(file);
                string currentString = reader.ReadLine();
                List<CheckersMove> list = new List<CheckersMove>();
                try
                {
                    while (currentString != null)
                    {
                        string[] parseData = currentString.Split(' ');
                        int pathLength = int.Parse(parseData[0]);
                        List<CheckersGame.Point> pathPoints = new List<CheckersGame.Point>();
                        for (int index = 0; index < pathLength; ++index)
                        {
                            pathPoints.Add(new CheckersGame.Point(int.Parse(parseData[index * 2 + 1]), int.Parse(parseData[(index + 1) * 2])));
                        }
                        bool isJump = false;
                        if (parseData[pathLength * 2 + 1] == "True")
                            isJump = true;
                        int playerID = int.Parse(parseData[parseData.Length - 1]);
                        list.Add(new CheckersMove(pathPoints, isJump, playerID));
                        currentString = reader.ReadLine();
                    }
                }
                catch
                {

                    MessageBox.Show("This is not a valid document");
                    return;
                }
                moveList.Tag = list;
                moveList.Items.Clear();

                board = new CheckersBoard(0, x);
                board.GameOver += new CheckersBoard.EndGame(board_GameOver);
                board.GameMaxLength = 200;
                foreach (var move in list)
                {
                    board.MakeMove(move);

                    StringBuilder builder = new StringBuilder(move.PlayerID.ToString() == "1" ? "White: " : "Black: ");
                    foreach (var item in move.GetPath())
                    {
                        builder.Append(Convert.ToChar(65 + item.Y));
                        builder.Append((item.X + 1).ToString());
                        builder.Append('-');
                    }
                    builder.Remove(builder.Length - 1, 1);
                    moveList.Items.Add(builder.ToString());

                }
                moveList.ScrollIntoView(moveList.Items[moveList.Items.Count - 1]);
                this.repaint(null);
                if (board.GetCurrentPlayer().GetPlayerID() == alg.ComputerPlayerID)
                {
                    computerThread = new Thread(computerMove);
                    computerThread.Start();

                }

                reader.Close();
                file.Close();
            }
        }