Example #1
0
    public override bool IsAvailable(APActionNode prevNode)
    {
        if (!_gameState.self.owner.HasAction(ActionType.Attack))
        {
            return(false);
        }

        if (prevNode.GetType() == typeof(ActionNode_Move))
        {
            return(false);
        }

        if (_gameState.self.actionPoint < _gameState.self.owner.GetActionSlot(ActionType.Move).cost)
        {
            return(false);
        }

        return(true);
    }
Example #2
0
    public IEnumerator Plan_Coroutine(Unit requester, Action <List <APActionNode> > OnPlanCompleted)
    {
        APGameState initialGameState = APGameState.Create(requester, TurnMgr.Instance.turns.ToList(), MapMgr.Instance.map.Cubes.ToList());

        List <APActionNode> leafNodes = new List <APActionNode>();

        // BFS Tree Construction
        Queue <APActionNode> queue = new Queue <APActionNode>();

        queue.Enqueue(new RootNode(initialGameState));

        while (queue.Count > 0)
        {
            APActionNode parentNode = queue.Dequeue();
            int          childCount = 0;

            //************** MOVE NODES **************//
            MovePlanner movePlanner = new MovePlanner(parentNode._gameState, parentNode._score, actionPointPanel);
            if (movePlanner.IsAvailable(parentNode))
            {
                // 시뮬레이션
                List <APActionNode> moveNodes;
                bool simulCompleted = false;
                movePlanner.Simulate(this, () => simulCompleted = true, out moveNodes);

                // // // // // // // // // // // // // // // // // // // // // // // //
                while (!simulCompleted)
                {
                    yield return(null);
                }
                // // // // // // // // // // // // // // // // // // // // // // // //

                // 부모노드 세팅 및 인큐
                foreach (var node in moveNodes)
                {
                    node._parent = parentNode;
                    childCount++;
                    queue.Enqueue(node);
                }
            }

            //************** ATTACK NODES **************//
            AttackPlanner attackPlanner = new AttackPlanner(parentNode._gameState, parentNode._score, actionPointPanel);
            if (attackPlanner.IsAvailable(parentNode))
            {
                // 시뮬레이션
                List <APActionNode> attackNodes;
                bool simulCompleted = false;
                attackPlanner.Simulate(this, () => simulCompleted = true, out attackNodes);

                // // // // // // // // // // // // // // // // // // // // // // // //
                while (!simulCompleted)
                {
                    yield return(null);
                }
                // // // // // // // // // // // // // // // // // // // // // // // //

                // 부모노드 세팅 및 인큐
                foreach (var node in attackNodes)
                {
                    node._parent = parentNode;
                    childCount++;
                    queue.Enqueue(node);
                }
            }


            //************** ITEM NODES **************//



            //************** SKILL NODES **************//



            //*** Leaf Check ***//
            if (childCount == 0)
            {
                leafNodes.Add(parentNode);
            }
            yield return(null);
        }

        //*** 마지막 위치에 따른 점수 계산 ***//



        //*** Construct Best Action List ***//
        List <APActionNode> bestSequence = new List <APActionNode>();;

        // 가장 높은 스코어 추출
        int bestScore = leafNodes.Aggregate((acc, curr) => curr._score > acc._score ? curr : acc)._score;

        // high score leaf들을 추출
        List <APActionNode> bestLeaves = leafNodes.FindAll(ln => ln._score == bestScore);

        // high score leaf들의 마지막 self 위치에 따른 점수변동
        CalcFinalPositionScore(bestLeaves, initialGameState);

        // 점수 변동한 leaf들로 다시 순위매김
        int secondBestScore = bestLeaves.Aggregate((acc, curr) => curr._score > acc._score ? curr : acc)._score;

        bestLeaves = bestLeaves.FindAll(ln => ln._score == secondBestScore);

        //// 추출한 leaf들중 랜덤하게 고르기위한 idx
        int randomIdx = UnityEngine.Random.Range(0, bestLeaves.Count);

        //// 결정한 시퀀스의 leaf노드
        APActionNode bestLeaf = bestLeaves[randomIdx];

        // 시퀀스 생성 perent를 따라올라감
        APActionNode currNode = bestLeaf;

        while (currNode.GetType() != typeof(RootNode)) // 미자막 RootNode는 안넣을겁니다.
        {
            bestSequence.Add(currNode);
            currNode = currNode._parent;
            yield return(null);
        }

        // leaf - {} - {} - {} - {}
        // 를
        // {} - {} - {} - {} - leaf
        // 순으로 뒤집기
        bestSequence.Reverse();
        OnPlanCompleted(bestSequence);
    }
 public override bool IsAvailable(APActionNode prevNode)
 => prevNode.GetType() != typeof(ActionNode_Move) && _gameState.self.actionPoint > 0;