コード例 #1
0
        // MINIMAX FUNCTION
        public Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> > Minimax(GameBoard_SYSTST <counters> board, counters counter, int ply, Tuple <int, int> positions, bool mmax, GameBoard_SYSTST <int> scoreBoard, ref int cont, int alpha, int beta)
        {
            // decs
            counters us       = Flip(counter);
            int      ourindex = 1;
            List <Tuple <int, int> > availableMoves = getAvailableMoves(board, positions);
            // create new list of Tuple<int,int>
            List <Tuple <int, Tuple <int, int> > > result_list = new List <Tuple <int, Tuple <int, int> > >();
            int bestScore         = mmax ? -1001 : 1001;
            int score             = Consts.MIN_SCORE; // current score of move
            Tuple <int, int> Move = new Tuple <int, int>(6, 2);

            Tuple <int, int> bestMove = new Tuple <int, int>(7, 1); // best move with score// THRESHOLD <=============
                                                                    // add assertion here
                                                                    // decs for random move
            Random           rnd       = new Random();
            int              randMoveX = rnd.Next(1, 7);            // creates a number between 1 and 7
            int              randMoveY = rnd.Next(1, 7);            // creates a number between 1 and 7
            Tuple <int, int> randMove  = new Tuple <int, int>(randMoveX, randMoveY);

            // check win
            if (availableMoves.Count == 0)
            {
                return(new Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> >(10, positions, board, scoreBoard));
            }
            // if board no over 40
            if (Win(board, counter))
            {
                Game_SYSTST.cntr++;
                Game_SYSTST.nowcount++;
                //      Console.WriteLine(Game_SYSTST.cntr + "NOWCOUNT" + Game_SYSTST.nowcount);
                Console.WriteLine("✓ PASS on Board " + Game_SYSTST.cntr + " : Winning combination found");
                //        board.DisplayBoard();
                //  Console.ReadLine();
                var file  = @"C://Users//Lewis//Desktop//files_150819//ttt_csharp_270719//Minimax_SYSTST//SYSTST_report.csv";
                var date  = DateTime.Now.ToShortDateString();
                var time  = DateTime.Now.ToString("HH:mm:ss"); //result 22:11:45
                var csv   = new System.Text.StringBuilder();
                var title = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", "DATE", "TIME", "INT BOARD", "RESULT", "BOARD NO", "REASON", "SCORE", "X", "Y", "SIDE", "FIN BOARD", "SCORE BOARD", "POSITIONS VISTED", "DEPTH", "TIME ELAPSED", Environment.NewLine);
                csv.Append(title);
                File.AppendAllText(file, title.ToString());
                board.DisplayIntBoardToFile();
                board.DisplayFinBoardToFile();
                string status = "-";
                if (score == 1001 | score == -1001 | score == -1000 | score == -1000)
                {
                    status = "PASS";
                }
                else
                {
                    status = "FAIL";
                }
                string reason  = "Winning combination found";
                var    newLine = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", date, time, board, status.ToString(), "Board " + int.Parse(Game_SYSTST.cntr.ToString()), reason.ToString(), score.ToString(), positions.Item1.ToString(), positions.Item2.ToString(), counter, Game_SYSTST.board, Game_SYSTST.scoreBoard, cont, ply, stopwatch.Elapsed, Environment.NewLine);
                //var newLine = string.Format(Environment.NewLine + date + " " + time + "{0}", first, Environment.NewLine);
                csv.Append(newLine);
                File.AppendAllText(file, newLine);
                return(new Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> >(1000, positions, board, scoreBoard));
            }
            if (Win(board, this.otherCounter))
            {
                Game_SYSTST.cntr++;
                Game_SYSTST.nowcount++;
                Console.WriteLine(Game_SYSTST.cntr + "NOWCOUNT" + Game_SYSTST.nowcount);
                // Console.ReadLine();
                Console.WriteLine(Environment.NewLine + "✓ PASS on Board " + Game_SYSTST.cntr + " : Winning combination found");
                //    board.DisplayBoard();
                //   Console.ReadLine();
                var file  = @"C://Users//Lewis//Desktop//files_150819//ttt_csharp_270719//Minimax_SYSTST//SYSTST_report.csv";
                var date  = DateTime.Now.ToShortDateString();
                var time  = DateTime.Now.ToString("HH:mm:ss"); //result 22:11:45
                var csv   = new System.Text.StringBuilder();
                var title = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", "DATE", "TIME", "INT BOARD", "RESULT", "BOARD NO", "REASON", "SCORE", "X", "Y", "SIDE", "FIN BOARD", "SCORE BOARD", "POSITIONS VISTED", "DEPTH", "TIME ELAPSED", Environment.NewLine);
                csv.Append(title);
                File.AppendAllText(file, title.ToString());
                board.DisplayIntBoardToFile();
                board.DisplayFinBoardToFile();
                string status = "-";
                if (score == 1001 | score == -1001 | score == -1000 | score == -1000)
                {
                    status = "PASS";
                }
                else
                {
                    status = "FAIL";
                }
                string reason  = "Winning combination found";
                var    newLine = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", date, time, board, status.ToString(), "Board " + int.Parse(Game_SYSTST.cntr.ToString()), reason.ToString(), score.ToString(), positions.Item1.ToString(), positions.Item2.ToString(), counter, Game_SYSTST.board, Game_SYSTST.scoreBoard, cont, ply, stopwatch.Elapsed, Environment.NewLine);
                //var newLine = string.Format(Environment.NewLine + date + " " + time + "{0}", first, Environment.NewLine);
                csv.Append(newLine);
                File.AppendAllText(file, newLine.ToString());
                return(new Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> >(-1000, positions, board, scoreBoard));
            }
            else
            {
                if (FindTwoInARow(board, counter) && Two(board, counter) && board[Move.Item1, Move.Item2] == counters.e)
                {
                    // return new Tuple<int, Tuple<int, int>, GameBoard_SYSTST<counters>, GameBoard_SYSTST<int>>(100, positions, board, scoreBoard);
                }
                else if (FindTwoInARow(board, this.otherCounter) && Two(board, this.otherCounter) && board[Move.Item1, Move.Item2] == counters.e)
                {
                    //  return new Tuple<int, Tuple<int, int>, GameBoard_SYSTST<counters>, GameBoard_SYSTST<int>>(-100, positions, board, scoreBoard);
                }
                else if (FindOneInARow(board, ourindex, this.otherCounter) && One(board, counter) && board[Move.Item1, Move.Item2] == counters.e)
                {
                    // return new Tuple<int, Tuple<int, int>, GameBoard_SYSTST<counters>, GameBoard_SYSTST<int>>(100, positions, board, scoreBoard);
                }
                else if (FindOneInARow(board, ourindex, this.otherCounter) && One(board, this.otherCounter) && board[Move.Item1, Move.Item2] == counters.e)
                {
                    //    return new Tuple<int, Tuple<int, int>, GameBoard_SYSTST<counters>, GameBoard_SYSTST<int>>(-100, positions, board, scoreBoard);
                }
            }
            if (Game_SYSTST.cntr >= 40)
            {
                Environment.Exit(99);
            }
            // CHECK DEPTH
            if (ply > maxPly)
            {
                score = EvalCurrentBoard(board, scoreBoard, ourindex, us); // call stat evaluation func - takes board and player and gives score to that player
                return(new Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> >(score, positions, board, scoreBoard));
            }
            GameBoard_SYSTST <counters> copy;

            // make copy original board
            copy = board.Clone();     // make copy board
                                      // copy.DisplayBoard(); // display copy board
                                      // cell priority - favour centre and corners
            int iteration = 0;

            for (int i = 0; i < availableMoves.Count; i++)
            {
                Move = availableMoves[i];               // current move
                                                        // cell priority - favour centre and corners
                                                        // HWL: where do you actual place the piece for the position in Move? you don't do this here, just pass Move to the call of Minimax below; in the recursive call you then overwrite the input argument with a random move (see comment at start of Minimax; so you are actually not considering Move at all!
                                                        // HWL: try placing the piece here, and below just use the score
                copy[Move.Item1, Move.Item2] = counter; // place counter
                                                        // GameBoard_SYSTST board0 = MakeMove(board, move); // copies board - parallel ready

                // ************************************************************************************************
                // ************************************************************************************************
                // ************************************** MAIN MINIMAX WORK ***************************************
                // ************************************************************************************************
                // ************************************************************************************************

                // list defined in Minimax declarations
                Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> > result = Minimax(copy, Flip(counter), ply + 1, Move, !mmax, scoreBoard, ref cont, alpha, beta); /* swap player */ // RECURSIVE call

                // trying to prevent preventing cell overwrite
                copy[Move.Item1, Move.Item2] = counters.e; /*  counter; */     // HWL: remove counter that was tried in this iteration
                // GameBoard_SYSTST board0 = MakeMove(board, move); // copies board - parallel ready

                score     = -result.Item1; // assign score
                positions = result.Item2;  // present position (x,y)

                iteration++;

                // assign score to correct cell in score
                scoreBoard[result.Item2.Item1, result.Item2.Item2] = score;

                if (ply == 0)
                {
                    scoreBoard.DisplayBoard();
                    Console.WriteLine("Player move: " + counter + " which, returns: " + result.Item1 + result.Item2);
                    scoreBoard.DisplayScoreBoardToFile();
                }

                // if maximising
                if (/* true HWL || */ mmax)
                {
                    alpha = score;
                    if (score > bestScore)
                    {
                        bestMove  = Move;
                        bestScore = score;
                        Console.WriteLine("score board for fixed board no " + Game_SYSTST.cntr + ": ");
                        scoreBoard.DisplayBoard();
                    }
                    if (alpha > bestScore)
                    {
                        bestMove  = Move;
                        bestScore = alpha;
                        Console.WriteLine("score board for fixed board no " + Game_SYSTST.cntr + ": ");
                        scoreBoard.DisplayBoard();
                    }
                }
                // if minimising
                else
                {
                    if (bestScore > score)
                    {
                        bestMove  = Move;
                        bestScore = score;
                    }
                    if (beta <= alpha)
                    {
                        bestScore = alpha;
                    }
                    return(new Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> >(bestScore, positions, board, scoreBoard));
                }

                // ************************************************************************************************
                // ************************************************************************************************
                // ********************* END OF WHEN TO MAXIMISE, WHEN TO MINIMISE ********************************
                // ******************************* WITH ALPHA-BETA PRUNING ****************************************
                // ************************************************************************************************

                cont++;                                                                                                                              // increment positions visited
            }
            return(new Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> >(bestScore, bestMove, board, scoreBoard)); // return
        }
コード例 #2
0
        // GET MOVE
        public override Tuple <int, int> GetMove(GameBoard_SYSTST <counters> board, GameBoard_SYSTST <int> scoreBoard)
        {
            counters us = Flip(counter);

            // Begin timing.
            stopwatch.Start();
            // Do work
            List <Tuple <int, int> > availableMoves = getAvailableMoves(board, positions);
            Tuple <int, Tuple <int, int>, GameBoard_SYSTST <counters>, GameBoard_SYSTST <int> > result;

            result = Minimax(board, counter, ply, positions, true, scoreBoard, ref cont, alpha, beta); // 0,0
            Console.WriteLine("board " + Game_SYSTST.cntr + ":");
            board.DisplayBoard();
            Console.WriteLine("Player move: " + counter + " which, returns: " + result.Item1 + result.Item2);
            int score = result.Item1;
            var file  = @"C://Users//Lewis//Desktop//files_150819//ttt_csharp_270719//Minimax_SYSTST//SYSTST_Report.csv";
            var date  = DateTime.Now.ToShortDateString();
            var time  = DateTime.Now.ToString("HH:mm:ss"); //result 22:11:45
            var csv   = new System.Text.StringBuilder();
            var title = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", "DATE", "TIME", "INT BOARD", "RESULT", "BOARD NO", "REASON", "SCORE", "X", "Y", "SIDE", "FIN BOARD", "SCORE BOARD", "POSITIONS VISTED", "DEPTH", "TIME ELAPSED", Environment.NewLine);

            csv.Append(title);
            File.AppendAllText(file, title.ToString());
            board.DisplayIntBoardToFile();
            board.DisplayFinBoardToFile();
            //   Console.WriteLine(Game_SYSTST.cntr + "NOWCOUNT" + Game_SYSTST.nowcount);
            string status = "-";

            if (result.Item1 == 1001 | result.Item1 == -1001 | result.Item1 == -1000 | result.Item1 == -1000)
            {
                status = "PASS";
            }
            else
            {
                status = "FAIL";
            }
            string reason  = "Board combination missed";
            var    newLine = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", date, time, board, status.ToString(), "Board " + int.Parse(Game_SYSTST.cntr.ToString()), reason.ToString(), result.Item1.ToString(), result.Item2.Item1.ToString(), result.Item2.Item2.ToString(), counter, Game_SYSTST.board, Game_SYSTST.scoreBoard, cont, ply, stopwatch.Elapsed, Environment.NewLine);

            csv.Append(newLine);
            File.AppendAllText(file, newLine.ToString());
            // Console.ReadLine();
            if (result.Item1 == 1000 & result.Item2 == new Tuple <int, int>(1, 2))
            {
                //  Game_SYSTST.cntr++;
                //      Console.WriteLine(Game_SYSTST.cntr + "NOWCOUNT" + Game_SYSTST.nowcount);
                //        Console.ReadLine();
                error_confirm = 1;
                Console.Write("X ERROR on Board " + Game_SYSTST.cntr + " : Board combination missed" + Environment.NewLine);
                //          Console.ReadLine();
                board.DisplayBoard();
            }
            else if (result.Item1 == 100 || result.Item1 == -100 & result.Item2 == new Tuple <int, int>(2, 2))
            {
                //         Game_SYSTST.cntr++;
                //        Console.WriteLine(Game_SYSTST.cntr + "NOWCOUNT" + Game_SYSTST.nowcount);
                // Console.ReadLine();
                error_confirm = 1;
                Console.Write("X ERROR on Board " + Game_SYSTST.cntr + " : Board combination missed");
                // Console.ReadLine();
                board.DisplayBoard();
            }
            // Stop timing.
            stopwatch.Stop();
            // Return positions
            return(result.Item2);
        }