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;
 }
        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;
        }
        /// <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;
        }
        //, 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;
        }