Esempio n. 1
0
        private static void MCRollout(Node leaf)
        {
            Con4Board  board  = leaf.state;
            int        player = leaf.playerToMove;
            int        value  = 0;
            BoardState bs     = leaf.bs;

            while (true)
            {
                //BoardState bs = board.EvaluateBoard();
                //checkEqualityOfEval(board, bs);

                if (bs != BoardState.ongoing)
                {
                    value = BoardStateToValue(bs);
                    break;
                }
                else
                {
                    List <int> possMoves = board.GetPossibleMoves();
                    board = board.SimulateMove(player, possMoves[rnd.Next(possMoves.Count)]);
                    simulations++;
                    bs = Evaluate.EvaluateBoard(board);
                    evaluations++;
                    player *= -1;
                }
            }
            Backpropagate(leaf, value);
        }
Esempio n. 2
0
        public override bool Equals(object obj)
        {
            /*Con4Board other = obj as Con4Board;
             * if (other == null)
             *  return false;
             */
            if (obj.GetType() != GetType())
            {
                return(false);
            }
            Con4Board other = obj as Con4Board;

            /*for (int x = 0; x < WIDTH; x++)
             *  for (int y = 0; y < HEIGHT; y++)
             *      if (other.grid[x, y] != grid[x, y])
             *          return false;*/

            // Iteration order to find differences early
            for (int y = HEIGHT - 1; y >= 0; y--)
            {
                for (int x = 0; x < WIDTH; x++)
                {
                    if (other.grid[x, y] != grid[x, y])
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Esempio n. 3
0
        public static BoardState EvaluateBoard(Con4Board board)
        {
            BoardState bs;

            bs = CheckRows(board);
            if (bs != BoardState.ongoing)
            {
                return(bs);
            }

            bs = CheckColumns(board);
            if (bs != BoardState.ongoing)
            {
                return(bs);
            }

            bs = CheckDiagonals(board);
            if (bs != BoardState.ongoing)
            {
                return(bs);
            }

            if (IsDraw(board))
            {
                return(BoardState.draw);
            }

            return(BoardState.ongoing);
        }
Esempio n. 4
0
        private static void HandleLeafNode(Node leaf)
        {
            if (leaf.totalVisits == 0)
            {
                MCRollout(leaf);
            }
            else
            {
                // EXPAND
                Con4Board board = leaf.state;
                //BoardState bs = board.EvaluateBoard();
                //checkEqualityOfEval(board, bs);
                //BoardState bs = Evaluate.EvaluateBoard(board);
                BoardState bs = leaf.bs;
                //evaluations++;
                if (bs != BoardState.ongoing)   // Terminal node, do not expand, just backprop
                {
                    Backpropagate(leaf, BoardStateToValue(bs));
                }
                else     // Not terminal, expand
                {
                    List <int> possMoves = board.GetPossibleMoves();
                    foreach (int move in possMoves)
                    {
                        leaf.children.Add(new Node(leaf, board.SimulateMove(leaf.playerToMove, move),
                                                   leaf.playerToMove * -1, move));
                        simulations++;
                    }

                    Node firstChild = leaf.children[0];
                    MCRollout(firstChild);
                }
            }
        }
Esempio n. 5
0
        public Con4Board SimulateMove(int player, int move)
        {
            simulations++;
            Con4Board deepCopy = new Con4Board(grid);

            deepCopy.PlayMove(player, move);
            return(deepCopy);
        }
Esempio n. 6
0
 /*public Node(Node parent, Con4Board state, int playerToMove) {
  *  this.parent = parent;
  *  this.state = state;
  *  this.playerToMove = playerToMove;
  *  this.bs = Evaluate.EvaluateBoard(state);
  * }*/
 public Node(Node parent, Con4Board state, int playerToMove, int previousMove)
 {
     this.parent       = parent;
     this.state        = state;
     this.playerToMove = playerToMove;
     this.previousMove = previousMove;
     this.bs           = Evaluate.EvaluateBoard(state);
 }
Esempio n. 7
0
        private static BoardState CheckDiagonals(Con4Board board)
        {
            List <int> seq;
            BoardState bs;

            // Positive line slopes
            for (int i = 0; i < 4; i++)
            {
                seq = GenerateDiagonalSequence(board, i, boardHeight - 1, true);
                bs  = CheckSequence(seq);
                if (bs != BoardState.ongoing)
                {
                    return(bs);
                }
            }

            seq = GenerateDiagonalSequence(board, 0, boardHeight - 2, true);
            bs  = CheckSequence(seq);
            if (bs != BoardState.ongoing)
            {
                return(bs);
            }

            seq = GenerateDiagonalSequence(board, 0, boardHeight - 3, true);
            bs  = CheckSequence(seq);
            if (bs != BoardState.ongoing)
            {
                return(bs);
            }

            // Negative line slopes
            for (int i = 0; i < 4; i++)
            {
                seq = GenerateDiagonalSequence(board, i, 0, false);
                bs  = CheckSequence(seq);
                if (bs != BoardState.ongoing)
                {
                    return(bs);
                }
            }

            seq = GenerateDiagonalSequence(board, 0, 1, false);
            bs  = CheckSequence(seq);
            if (bs != BoardState.ongoing)
            {
                return(bs);
            }

            seq = GenerateDiagonalSequence(board, 0, 2, false);
            bs  = CheckSequence(seq);
            if (bs != BoardState.ongoing)
            {
                return(bs);
            }

            return(BoardState.ongoing);
        }
Esempio n. 8
0
 private static bool IsDraw(Con4Board board)
 {
     for (int x = 0; x < boardWidth; x++)
     {
         if (board.grid[x, 0] == 0)
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 9
0
        private static List <int> GenerateDiagonalSequence(Con4Board board, int x, int y, bool positiveSlope)
        {
            List <int> seq = new List <int>();

            while (LegalPos(x, y))
            {
                seq.Add(board.grid[x, y]);
                x++;
                y += positiveSlope ? -1 : 1;
            }
            return(seq);
        }
Esempio n. 10
0
        private static void checkEqualityOfEval(Con4Board board, BoardState bs)
        {
            BoardState localBs = Evaluate.EvaluateBoard(board);

            if (bs != localBs)
            {
                Albot.Connect4.Connect4Board albotBoard = new Albot.Connect4.Connect4Board(board.grid);
                albotBoard.PrintBoard("Board which gave error:");
                Console.WriteLine("Albot implementation evaluates to: " + bs.ToString() + "\n" +
                                  "Local implementation evaluates to: " + localBs.ToString());
                throw new Exception("LOCAL EVALUATION NOT SAME AS ALBOTS!");
            }
        }
Esempio n. 11
0
 private static BoardState CheckRows(Con4Board board)
 {
     for (int y = 0; y < boardHeight; y++)
     {
         List <int> seq = new List <int>(boardWidth);
         for (int x = 0; x < boardWidth; x++)
         {
             seq.Add(board.grid[x, y]);
         }
         BoardState bs = CheckSequence(seq);
         if (bs != BoardState.ongoing)
         {
             return(bs);
         }
     }
     return(BoardState.ongoing);
 }
Esempio n. 12
0
        private static int DecideMove(Connect4Board board)
        {
            Con4Board con4Board = new Con4Board(board);

            return(MCTS.FindMove(con4Board, 9000));
        }
Esempio n. 13
0
        public static int FindMove(Con4Board board, long searchTimeMs)
        {
            simulations = 0;
            evaluations = 0;
            if (root == null)
            {
                // New tree
                root = new Node(null, board, 1, -1);
                List <int> possMoves = board.GetPossibleMoves();
                foreach (int move in possMoves)
                {
                    root.children.Add(new Node(root, board.SimulateMove(root.playerToMove, move),
                                               root.playerToMove * -1, move));
                    simulations++;
                }
            }
            else
            {
                // Continue from last tree
                // Set root to child which matches opponents move
                foreach (Node node in root.children)
                {
                    if (node.state.Equals(board))
                    {
                        root        = node;
                        root.parent = null; // Let GC remove rest of tree
                        Console.WriteLine("Found root, continuing where we left off!");
                        break;
                    }
                }
            }

            stopwatch.Restart();
            while (stopwatch.ElapsedMilliseconds < searchTimeMs)
            {
                //stopwatch.Restart();
                for (int i = 0; i < 100; i++)
                {
                    MCTSIteration();
                }
                //stopwatch.Stop();
                //Console.WriteLine(stopwatch.ElapsedMilliseconds);
                //searchTimeMs -= stopwatch.ElapsedMilliseconds;
            }

            List <Node> children  = root.children;
            int         bestMove  = children[0].previousMove;
            double      bestValue = children[0].totalValue;
            Node        nextRoot  = children[0]; // To continue on same tree next move

            Console.Write("Move values {m, v}: ");
            Console.Write("{" + children[0].previousMove + ", " + children[0].totalValue + "} ");
            for (int i = 1; i < children.Count; i++)
            {
                Node   child  = children[i];
                double totVal = child.totalValue;
                Console.Write("{" + child.previousMove + ", " + totVal + "}");
                if (totVal > bestValue)
                {
                    bestValue = totVal;
                    bestMove  = child.previousMove;
                    nextRoot  = child;
                }
            }
            Console.WriteLine(" => Playing move: " + bestMove);
            Console.WriteLine("Simulations: " + simulations + ", Evaluations: " + evaluations);
            root = nextRoot;
            return(bestMove);
        }