コード例 #1
0
    public bool GetNode(NodeType type, out APActionNode newNode)
    {
        // 첫 접근
        if (pool.Count == 0)
        {
            pool.Add(NodeType.Move, new Dictionary <APActionNode, bool>());
            pool.Add(NodeType.Attack, new Dictionary <APActionNode, bool>());
            pool.Add(NodeType.Item, new Dictionary <APActionNode, bool>());
            pool.Add(NodeType.Skill, new Dictionary <APActionNode, bool>());
        }


        Dictionary <APActionNode, bool> dic = pool[type];

        foreach (var node in dic.Keys)
        {
            if (dic[node] == false)
            {
                dic[node] = true;
                newNode   = node;
                return(true);
            }
        }

        newNode = null;
        return(false);
    }
コード例 #2
0
 public override bool IsAvailable(APActionNode prevNode)
 {
     if (_gameState.self.actionPoint < _gameState.self.owner.GetActionSlot(ActionType.Attack).cost)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
コード例 #3
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);
    }
コード例 #4
0
    public void AddNode(APActionNode newNode)
    {
        if (newNode is ActionNode_Move)
        {
            pool[NodeType.Move].Add(newNode, false);
        }
        else if (newNode is ActionNode_Attack)
        {
            pool[NodeType.Attack].Add(newNode, false);
        }

        // TODO
        //else if (newNode is ActionNode_Item)
        //{
        //pool[NodeType.Item].Add(newNode, false);
        //}
        //else if (newNode is ActionNode_Skill)
        //{
        //pool[NodeType.Skill].Add(newNode, false);
        //}
    }
コード例 #5
0
    private IEnumerator ExecuteAction()
    {
        if (_actions.Count <= 0)
        {
            yield break;
        }

        float sec = UnityEngine.Random.Range(0.5f, 1.5f);

        yield return(new WaitForSeconds(sec));

        // 다음 액션
        _currAction = _actions.Dequeue();

        // 액션 실행
        unit.EnqueueCommand(_currAction.Command);

        // 커맨드의 성공여부이벤트를 wait
        List <KeyValuePair <Predicate <EventParam>, TurnMgr_State_> > branches
            = new List <KeyValuePair <Predicate <EventParam>, TurnMgr_State_> >();

        // Command가 성공했을 경우 유닛의 Action의 끝을 Wait
        TurnMgr_State_ waitIdleEnterState = new TurnMgr_WaitSingleEvent_(
            owner, unit, EventMgr.Instance.onUnitIdleEnter, this, WaitUnitIdleEnterPredicate,
            _currAction.OnWaitEnter, _currAction.OnWaitExecute, _currAction.OnWaitExit);
        var successBranch = new KeyValuePair <Predicate <EventParam>, TurnMgr_State_>((param) => CommandResultPredicate(param), waitIdleEnterState);

        branches.Add(successBranch);
        // Command가 실패했을 경우 Replan으로 State전환
        var failBranch = new KeyValuePair <Predicate <EventParam>, TurnMgr_State_>((param) => !CommandResultPredicate(param), new TurnMgr_AIPlan_(owner, unit));

        branches.Add(failBranch);


        // BranchSingleEvent
        owner.stateMachine.ChangeState(
            new TurnMgr_BranchSingleEvent_(owner, unit, EventMgr.Instance.onUnitCommandResult, branches,
                                           (param) => ((CommandResultParam)param)._subject != unit),
            StateMachine <TurnMgr> .StateTransitionMethod.PopNPush);
    }
コード例 #6
0
 public abstract bool IsAvailable(APActionNode prevNode);
コード例 #7
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);
    }
コード例 #8
0
 public override bool IsAvailable(APActionNode prevNode)
 => prevNode.GetType() != typeof(ActionNode_Move) && _gameState.self.actionPoint > 0;