public AttackPlanner(APGameState gameState, int prevScore, ActionPointPanel actionPointPanel)
     : base(gameState, prevScore, actionPointPanel)
 {
     _gameState        = gameState.Clone();
     _prevScore        = prevScore;
     _actionPointPanel = actionPointPanel;
 }
Beispiel #2
0
    public void RequestAsync(APGameState gameState, Action <List <PFPath> > OnServe)
    {
        List <INavable>       navables    = new List <INavable>(gameState._cubes);
        APUnit                unit        = gameState.self;
        int                   maxDistance = unit.actionPoint / unit.owner.GetActionSlot(ActionType.Move).cost;
        Cube                  start       = gameState._unitPos[unit];
        Func <INavable, bool> cubeIgnore  = (cube) =>
        {
            return(cube.IsAccupied() == true);
        };

        StartCoroutine(BFSPathfinding(start, navables, unit.actionPoint, OnServe, cubeIgnore));
    }
    public void GetState(out APGameState newState)
    {
        foreach (var state in pool.Keys)
        {
            if (pool[state] == false)
            {
                pool[state] = true;
                newState    = state;
                return;
            }
        }

        newState = new APGameState();
        pool.Add(newState, true);
    }
Beispiel #4
0
    private void CalcFinalPositionScore(List <APActionNode> leaves, APGameState initialGameState)
    {
        foreach (var leaf in leaves)
        {
            APGameState finalGameState = leaf._gameState;

            // 적 유닛들 중에
            List <APUnit> eUnitCanAttackMe = new List <APUnit>();
            foreach (var unit in finalGameState._units)
            {
                if (unit.isSelf)
                {
                    continue;
                }
                if (!finalGameState.self.owner.team.enemyTeams.Contains(unit.owner.team))
                {
                    continue;
                }

                Cube        unitPos      = finalGameState._unitPos[unit];
                Range       attackRange  = unit.owner.basicAttackRange;
                List <Cube> cubesInRange = MapMgr.Instance.GetCubes(
                    attackRange.range,
                    attackRange.centerX,
                    attackRange.centerZ,
                    unitPos);


                // 만약 일반공격 사정거리가 닿는 적이 있다면 우선 모아놓기
                Cube selfPos = finalGameState._unitPos[finalGameState.self];
                if (cubesInRange.Contains(selfPos))
                {
                    eUnitCanAttackMe.Add(unit);
                }
            }

            // 그리고 적의 기본공격 몇방에 죽을수 있는지에 따라 점수 차감
            // 적이 많을수록 조금만 깎기
            foreach (var unit in eUnitCanAttackMe)
            {
                int attackDmg  = unit.owner.BasicAttackDamageAvg;
                int howManyHit = Mathf.Max(finalGameState.self.health / attackDmg, 1);
                int scoreToSub = (500 / howManyHit) / eUnitCanAttackMe.Count;

                leaf._score -= scoreToSub;
            }
        }
    }
Beispiel #5
0
    public override int GetScoreToAdd(List <APUnit> splashUnits, APGameState prevState, APGameState gameState)
    {
        int score = 0;

        // 체력이 많은 적보다
        // 체력이 조금 남은 적을 공격하기 (+ 4000 * (자신의공격력/적의체력))
        if (splashUnits.Where(unit => gameState.self.owner.team.enemyTeams.Contains(unit.owner.team)).Count() > 0)
        {
            score += (int)(7000 * (
                               splashUnits
                               .Where(unit => gameState.self.owner.team.enemyTeams.Contains(unit.owner.team))
                               .Select(unit => (float)unit.health)
                               .Aggregate((accum, health) => accum + gameState.self.owner.skill.amountAvg / health)
                               ));
        }

        // 아군에 사용했으면 점수를 깎습니다.
        // (+ 1500 * (자신의공격력/아군의체력))
        if (splashUnits.Where(unit => gameState.self.owner.team == unit.owner.team).Count() > 0)
        {
            score -= (int)(1500 * (
                               splashUnits
                               //.Where(unit => gameState.self.owner.team == unit.owner.team)
                               .Select(unit => (float)unit.health)
                               .Aggregate((accum, health) => accum + gameState.self.owner.skill.amountAvg / health)
                               ));
        }

        // 적을 죽이는 plan이면 죽인 유닛당 +2000
        if (prevState._units.Where(unit => gameState.self.owner.team.enemyTeams.Contains(unit.owner.team)).Count()     // 이전 상태의 적군 유닛 갯수
            != gameState._units.Where(unit => gameState.self.owner.team.enemyTeams.Contains(unit.owner.team)).Count()) // 현재 상태의 적군 유닛 갯수
        {
            score += 2000 * (Mathf.Abs(gameState._units.Count - prevState._units.Count));
        }


        return(score);
    }
Beispiel #6
0
 public abstract int GetScoreToAdd(APGameState prevState);
Beispiel #7
0
 protected void SetNode(APGameState prevGameState, int prevScore, ActionPointPanel actionPointPanel)
 {
     _gameState        = prevGameState.Clone();
     _score            = prevScore;
     _actionPointPanel = actionPointPanel;
 }
Beispiel #8
0
 protected APActionNode(APGameState prevGameState, int prevScore, ActionPointPanel actionPointPanel)
 {
     SetNode(prevGameState, prevScore, actionPointPanel);
 }
Beispiel #9
0
 public AttackPlanner(APGameState gameState, int prevScore)
     : base(gameState, prevScore)
 {
     _gameState = gameState.Clone();
     _prevScore = prevScore;
 }
Beispiel #10
0
 public MovePlanner(APGameState gameState, int prevScore)
     : base(gameState, prevScore)
 {
 }
Beispiel #11
0
 public APPlanner(APGameState gameState, int prevScore)
 {
     _gameState = gameState.Clone();
     _prevScore = prevScore;
 }
Beispiel #12
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);
    }
 protected void SetNode(APGameState prevGameState, int prevScore)
 {
     _gameState = prevGameState.Clone();
     _score     = prevScore;
 }
 protected APActionNode(APGameState prevGameState, int prevScore)
 {
     SetNode(prevGameState, prevScore);
 }
 public MovePlanner(APGameState gameState, int prevScore, ActionPointPanel actionPointPanel)
     : base(gameState, prevScore, actionPointPanel)
 {
     _actionPointPanel = actionPointPanel;
 }
Beispiel #16
0
 public virtual int GetScoreToAdd(List <APUnit> splashUnits, APGameState prevState, APGameState gameState)
 {
     return(0);
 }