Пример #1
0
        //return Agent's decision
        public ActionFunction NextMove(Board state, int p)
        {
            ActionFunction bestAction = new ActionFunction();

            player_num = p;
            root       = new Node(p);
            board      = state;
            Stopwatch sw = new Stopwatch();

            try
            {
                sw.Start();
                do
                {
                    current_depth++;
                    bestAction = AlphaBeta.Search(board, root);
                } while (sw.ElapsedMilliseconds / 1000 < 5 && current_depth < MAX_DEPTH);
                sw.Stop();
                sw.Reset();
                current_depth = 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            return(bestAction);
        }
Пример #2
0
 public Node(ActionFunction move, ActionFunction undoMove, int player)
 {
     Move = move;
     Undo = undoMove;
     Player = player;
     Children = new List<Node>();
 }
Пример #3
0
 private IEnumerator AITurn(int playerNum) /// AI Controls
 {
     MessageText.text = "";
     //move or choose wall
     playerStatus[playerNum].currentTurn = true;
     playersTurnText.text = "Player " + (playerNum + 1) + "'s Turn!";
     Assets.Scripts.ActionFunction action = MyAgent.NextMove(MainBoard, playerNum); // <- currently has an issue
     if (action.function == null)
     {
         Debug.LogError("Agent action is null. Something is wrong. Agent just skip his move");
         yield break;
     }
     if (action.function.Method.Name == "MovePawn")
     {
         RenderPawnPosition(action.player, action.x, action.y);
     }
     else if (action.function.Method.Name == "PlaceHorizontalWall")
     {
         RenderWall(action.x, action.y, true);
     }
     else if (action.function.Method.Name == "PlaceVerticalWall")
     {
         RenderWall(action.x, action.y, false);
     }
     else
     {
         Debug.LogError("Agent returning a non-supported action");
     }
     MainBoard.ExecuteFunction(action);
     UpdateWallRemTxt(); //Update UI anyway because it doesn't matter
     yield return(null);
 }
Пример #4
0
        private static ValueAndAction MinValue(Board board, Node node, ref int alpha, ref int beta, int depth)
        {
            if (Agent.CutOff(depth))
            {
                node.Value = Agent.Evaluate(node);
                if (node.Value != 0)
                {
                    UnityEngine.Debug.Log(node.ToString() + " at depth= " + depth + " has value = " + node.Value);
                }
                return(new ValueAndAction(node.Value, node.Move));
            }
            int            tempVal    = int.MaxValue;
            ActionFunction tempAction = new ActionFunction();

            Agent.GenerateSuccessors(node);
            foreach (Node child in node.Children)
            {
                board.ExecuteFunction(child.Move);
                var retValAction = MaxValue(board, child, ref alpha, ref beta, depth + 1);
                board.ExecuteFunction(child.Undo);
                if (retValAction.value < tempVal)
                {
                    tempVal    = retValAction.value;
                    tempAction = child.Move;
                    if (retValAction.value <= alpha)
                    {
                        retValAction.action = child.Move;
                        return(retValAction);
                    }
                    beta = Math.Min(beta, retValAction.value);
                }
            }
            return(new ValueAndAction(tempVal, tempAction));
        }
Пример #5
0
        public void ExecuteFunction(ActionFunction actionFunction)
        {
            Action action = actionFunction.function;

            action.Invoke(this, actionFunction.player, actionFunction.x, actionFunction.y);
        }
Пример #6
0
        public static void GenerateSuccessors(Node node)
        {
            //Player 1 prioritizes moving up -> left or right -> Wall -> Down (tentative Move Ordering)
            PlayerInfo[]   playerStatus = board.playerStatus;
            int            p            = node.Player;
            int            nextPlayer   = (p + 1) % 2;
            ActionFunction undo         = new ActionFunction(Board.UndoMovePawn, p, playerStatus[p].x, playerStatus[p].y);

            #region Player 1's Successors
            if (node.Player == PLAYER1)  //first check in all if statemtents is the players position in relation to moving
            {
                //Move up
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 1, playerStatus[p].y))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 1, playerStatus[p].y), undo, nextPlayer));
                }
                else
                {
                    // going up jumping over 1 player directly
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 2, playerStatus[p].y))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 2, playerStatus[p].y), undo, nextPlayer));
                    }
                    // going Up by 1 and Right by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 1, playerStatus[p].y + 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 1, playerStatus[p].y + 1), undo, nextPlayer));
                    }
                    //going Left by 1 AND Up by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 1, playerStatus[p].y - 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 1, playerStatus[p].y - 1), undo, nextPlayer));
                    }
                }

                //Move Left
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y - 1))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y - 1), undo, nextPlayer));
                }
                // going Left jumping over 1 player directly
                else if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y - 2))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y - 2), undo, nextPlayer));
                }

                //Move Right
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y + 1))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y + 1), undo, nextPlayer));
                }
                //going Right by jumping over 1 player directly
                else if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y + 2))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y + 2), undo, nextPlayer));
                }

                //Move Down
                // going down by 1 (checks on location and for walls)
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x + 1, playerStatus[p].y))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x + 1, playerStatus[p].y), undo, nextPlayer));
                }
                else
                {
                    // going down jumping over 1 player directly
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x + 2, playerStatus[p].y))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x + 2, playerStatus[p].y), undo, nextPlayer));
                    }
                    // going Down by 1 AND to the Left by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x + 1, playerStatus[p].y - 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x + 1, playerStatus[p].y - 1), undo, nextPlayer));
                    }
                    // going Right by 1 AND Down by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 1, playerStatus[p].y + 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 1, playerStatus[p].y + 1), undo, nextPlayer));
                    }
                }
            }
            #endregion
            #region Player 2's Successors
            else
            {
                //Player 2 prioritizes moving down -> left or right -> Wall -> Up (tentative Move Ordering)
                //Move Down
                // going down by 1 (checks on location and for walls)
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x + 1, playerStatus[p].y))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x + 1, playerStatus[p].y), undo, nextPlayer));
                }
                else
                {
                    // going down jumping over 1 player directly
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x + 2, playerStatus[p].y))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x + 2, playerStatus[p].y), undo, nextPlayer));
                    }
                    // going Down by 1 AND to the Left by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x + 1, playerStatus[p].y - 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x + 1, playerStatus[p].y - 1), undo, nextPlayer));
                    }
                    // going Right by 1 AND Down by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x + 1, playerStatus[p].y + 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x + 1, playerStatus[p].y + 1), undo, nextPlayer));
                    }
                }


                //Move Left
                //   if (playerStatus[p].y - 1 >= 0)
                //  {
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y - 1))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y - 1), undo, nextPlayer));
                }
                // going Left jumping over 1 player directly
                else if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y - 2))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y - 2), undo, nextPlayer));
                }
                //}
                //Move Right
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y + 1))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y + 1), undo, nextPlayer));
                }
                //going Right jumping over 1 player directly
                else if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x, playerStatus[p].y + 2))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x, playerStatus[p].y + 2), undo, nextPlayer));
                }

                //Move up
                if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 1, playerStatus[p].y))
                {
                    node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 1, playerStatus[p].y), undo, nextPlayer));
                }
                else
                {
                    // going up jumping over 1 player directly
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 2, playerStatus[p].y))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 2, playerStatus[p].y), undo, nextPlayer));
                    }
                    // going Up by 1 and Right by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 1, playerStatus[p].y + 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 1, playerStatus[p].y + 1), undo, nextPlayer));
                    }
                    //going Left by 1 AND Up by 1
                    if (board.IsPawnMoveLegal(playerStatus[p].x, playerStatus[p].y, playerStatus[p].x - 1, playerStatus[p].y - 1))
                    {
                        node.Children.Add(new Node(new ActionFunction(Board.MovePawn, p, playerStatus[p].x - 1, playerStatus[p].y - 1), undo, nextPlayer));
                    }
                }
            }
            #endregion

            #region Wall Generation (for both players) taking too long
            if (playerStatus[p].wallsLeft == 0) // player has no wall left
            {
                return;
            }
            ActionFunction undoWall;
            for (int x = 0; x < Board.BOARD_SIZE - 1; x++)
            {
                for (int y = 0; y < Board.BOARD_SIZE - 1; y++)
                {
                    //Horizontal Wall
                    if (board.CheckWallH(x, y))
                    {
                        undoWall = new ActionFunction(Board.UndoPlaceHorizontalWall, p, x, y);
                        node.Children.Add(new Node(new ActionFunction(Board.PlaceHorizontalWall, p, x, y), undoWall, nextPlayer));
                    }
                    //Vertical Wall
                    if (board.CheckWallV(x, y))
                    {
                        undoWall = new ActionFunction(Board.UndoPlaceVerticalWall, p, x, y);
                        node.Children.Add(new Node(new ActionFunction(Board.PlaceVerticalWall, p, x, y), undoWall, nextPlayer));
                    }
                }
            }
            #endregion
        }
Пример #7
0
 public ValueAndAction(int val, ActionFunction act)
 {
     value  = val;
     action = act;
 }