示例#1
0
        public void rotateLines()
        {
            //-Here we rotate towers and locking for nearest threat
            int i = ownTowers.Count;

            if (i < 1)
            {
                return;
            }
            List <attackDef> attackersList = new List <attackDef>();
            List <attackDef> tmp;
            attackDef        near = new attackDef();

            foreach (BoardObj t in this.ownTowers)
            {
                tmp = t.getImmediateAttackers(this);
                if (tmp.Count > 0 && (near.empty || near.time > tmp[0].time))
                {
                    near = tmp[0];
                }
            }
            if (!near.empty)
            {
                Playfield p     = new Playfield(this, near.time);
                BoardObj  myObj = near.attacker.own ? near.attacker : near.target;
                opposite  opp   = KnowledgeBase.Instance.getOppositeToAll(p, myObj);

                if (opp != null)
                {
                    if (opp.hc != null)
                    {
                        int callTime = near.time - opp.hc.card.DeployTime;
                        if (callTime < 0)
                        {
                            callTime = 0;
                        }
                        p = new Playfield(p, callTime);
                        VectorAI position = new VectorAI(0, 0);
                        //VectorAI position = p.getDeployPosition(opp); //TODO: this decision takes a behavior or a time machine

                        bestCast = new Cast(opp.hc.name, position, opp.hc);
                    }
                    else if (opp.bo != null)
                    {
                        if (opp.bo.TargetType == targetType.GROUND)
                        {
                            //TODO
                        }
                    }
                    else
                    {
                        //TODO automatic creation opposite list in getOppositeToAll or do something else
                    }
                }
            }
        }
示例#2
0
        private VectorAI getDeployPosition(opposite opp)
        {
            VectorAI retval = new VectorAI(0, 0);

            //TODO:

            /*
             * 1.Исходя из Радиуса атаки высчитываем точку его призыва.
             * а)учесть, он дамагер или отвлекатель
             * если дамагер - то так что бы сразу был на линии своей атаки
             * если отвлекатель - то так чтобы башни или другие минионы дамажили как можно дольше + подальше от других вражеских
             * distractor
             * */

            if (noEnemiesOnMySide())
            {
                return(getBackPosition(opp.hc));
            }

            BoardObj enemy         = opp.target;
            bool     enemyMelee    = (opp.target.Range < 1000) ? true : false;          //TODO: set real value
            bool     defenderMelee = (opp.target.attacker.Range < 1000) ? true : false; //TODO: set real value
            bool     attackerMelee = (opp.hc.card.MaxRange < 3) ? true : false;         //TODO: set real value

            VectorAI centerPos = new VectorAI(0, 0);
            int      kingLine  = 0;

            foreach (BoardObj tower in this.ownTowers)
            {
                if (tower.Tower < 10)
                {
                    continue;
                }
                kingLine  = tower.Line;
                centerPos = tower.Position;
                break;
            }

            if (enemyMelee)
            {
                if (attackerMelee)
                {
                    if (enemy.attacked)
                    {
                        if (defenderMelee)
                        {
                            retval = enemy.Position;
                        }
                        else
                        {
                            //0.TODO: ставить так что бы сагрился именно на оппозит + максимально увести вбок под башни
                            //или других юнитов с радиусом атаки и не вывести из под текущего дефендера(того кто ща атакует)
                            retval = centerPos;
                        }
                    }
                    else if (enemy.attacking)
                    {
                        retval = enemy.Position;
                    }
                    else
                    {
                        //1.TODO: выбрать:
                        //а)если на линии есть R атакер - то поближе к нему
                        //б)прям на врага
                        //с)если отвлекатель - то увести вбок меж башен
                        retval = enemy.Position;
                    }
                }
                else
                {
                    if (enemy.attacked)
                    {
                        if (defenderMelee)
                        {
                            //2.TODO: max R + под башни если не сдержит или поближе (но не слишком близко на случай аое) и
                            //в бок паралельно 1 башне что бы она доставала если сдержит (что бы потом войска настакались)
                            retval = centerPos;
                        }
                        else
                        {
                            //3.TODO: выбрать кто ценнее - дефендер или атакер и поставить на max R + под башни
                            //если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                            //что бы потом войска настакались но небыли слишком близко на случай аое
                            retval = centerPos;
                        }
                    }
                    else if (enemy.attacking)
                    {
                        //2.TODO: max R + под башни если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                        //что бы потом войска настакались но небыли слишком близко на случай аое
                        retval = centerPos;
                    }
                    else
                    {
                        //6.TODO: выбрать:
                        //а)если есть рэндж атакер на поле который сможет его атаковать - выбрать кто ценнее и поставить
                        //так что бы сагрился на менее ценного (не забываем уводить под башни и max R)
                        //б) //2.
                        retval = centerPos;
                    }
                }
            }
            else
            {
                if (attackerMelee)
                {
                    if (enemy.attacked)
                    {
                        retval = enemy.Position;
                    }
                    else if (enemy.attacking)
                    {
                        retval = enemy.Position;
                    }
                    else
                    {
                        //4.TODO: выбрать:
                        //а)если есть рэндж атакер на поле который сможет его атаковать и сам не будет атакован
                        //то выбать что лучше подставить под дефендера и позволить врагу атаковать юнитов пока они
                        //топают к нему (отвлекатель, нельзя дамагера) или поставить сразу на врага (дамагер или отвлекатель)
                        //б)поставить сразу на врага
                        retval = enemy.Position;
                    }
                }
                else
                {
                    if (enemy.attacked)
                    {
                        if (defenderMelee)
                        {
                            //2.TODO: max R + под башни если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                            //что бы потом войска настакались но небыли слишком близко на случай аое
                            retval = centerPos;
                        }
                        else
                        {
                            //3.TODO: выбрать кто ценнее - дефендер или атакер и поставить на max R + под башни
                            //если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                            //что бы потом войска настакались но небыли слишком близко на случай аое
                            retval = centerPos;
                        }
                    }
                    else if (enemy.attacking)
                    {
                        //2.TODO: max R + под башни если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                        //что бы потом войска настакались но небыли слишком близко на случай аое
                        retval = centerPos;
                    }
                    else
                    {
                        //5.TODO: выбрать:
                        //а)если ток башня - выбрать кто ценнее и поставить на max R
                        //б) //2.
                        retval = centerPos;
                    }
                }
            }

            return(retval);
        }
示例#3
0
        public opposite getOppositeToAll(Playfield p, BoardObj defender, int canWaitMissingMana = 3)
        {
            opposite         bestOpposite  = null;
            List <attackDef> attackersList = defender.getPossibleAttackers(p);

            if (attackersList.Count < 1)
            {
                return(bestOpposite);
            }

            List <attackDef> defendersList;

            CardDB.cardName aName;
            CardDB.cardName dName;
            Dictionary <CardDB.cardName, int> aopp;

            Dictionary <CardDB.cardName, opposite> allOpposite = new Dictionary <CardDB.cardName, opposite>();

            foreach (attackDef ad in attackersList)
            {
                if (OppositeDB.ContainsKey(ad.attacker.Name))
                {
                    aopp = OppositeDB[ad.attacker.Name];
                    //-1.Get all obj on board
                    defendersList = ad.attacker.getPossibleAttackers(p);
                    foreach (var def in defendersList)
                    {
                        dName = def.attacker.Name;
                        if (aopp.ContainsKey(dName))
                        {
                            if (!allOpposite.ContainsKey(dName))
                            {
                                allOpposite.Add(dName, new opposite(dName, aopp[dName], def.attacker, ad.attacker));
                            }
                            else
                            {
                                allOpposite[dName].value += aopp[dName];
                            }
                        }
                    }

                    //-2.Get all cards
                    //TODO - enemy have opposite - it depends on his mana
                    if (defender.own)
                    {
                        foreach (Handcard hc in p.ownHandCards)
                        {
                            dName = hc.card.name;
                            if (canWaitMissingMana >= hc.manacost - p.ownMana && aopp.ContainsKey(dName))
                            {
                                hc.missingMana = hc.manacost - p.ownMana;
                                if (!allOpposite.ContainsKey(dName))
                                {
                                    allOpposite.Add(dName, new opposite(dName, aopp[dName], hc, ad.attacker));
                                }
                                else
                                {
                                    allOpposite[dName].value += aopp[dName];
                                }
                            }
                        }
                    }
                }
                else
                {
                    Handcard tmp   = null;
                    int      count = p.ownHandCards.Count;
                    //TODO automatic creation opposite list
                    if (ad.attacker.Transport == transportType.AIR)
                    {
                        foreach (Handcard hc in p.ownHandCards)
                        {
                            if (canWaitMissingMana >= hc.manacost - p.ownMana)
                            {
                                if (hc.card.TargetType == targetType.ALL)
                                {
                                    if (ad.attacker.card.DamageRadius > 1000)
                                    {
                                        if (hc.card.MaxHP > ad.attacker.Atk)
                                        {
                                            if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP)
                                            {
                                                tmp = hc;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3)
                                        {
                                            tmp = hc;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (ad.attacker.TargetType == targetType.ALL)
                        {
                            foreach (Handcard hc in p.ownHandCards)
                            {
                                if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                {
                                    if (ad.attacker.card.DamageRadius > 1000 && hc.card.MaxHP > ad.attacker.Atk)
                                    {
                                        if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP)
                                        {
                                            tmp = hc;
                                        }
                                    }
                                    else
                                    {
                                        if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3)
                                        {
                                            tmp = hc;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        else if (ad.attacker.TargetType == targetType.BUILDINGS)
                        {
                            foreach (Handcard hc in p.ownHandCards)
                            {
                                if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                {
                                    if (hc.card.Atk > ad.attacker.HP * 5 || hc.card.SpawnNumber > 3)
                                    {
                                        tmp = hc;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            foreach (Handcard hc in p.ownHandCards)
                            {
                                if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                {
                                    if (hc.card.Transport == transportType.AIR)
                                    {
                                        if (tmp == null || tmp.card.SpawnNumber < hc.card.SpawnNumber || tmp.card.SummonNumber < hc.card.SummonNumber)
                                        {
                                            tmp = hc;
                                        }
                                    }
                                }
                            }
                            if (tmp == null)
                            {
                                foreach (Handcard hc in p.ownHandCards)
                                {
                                    if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                    {
                                        if (ad.attacker.card.DamageRadius > 1000)
                                        {
                                            if (hc.card.MaxHP > ad.attacker.Atk)
                                            {
                                                if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP)
                                                {
                                                    tmp = hc;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3)
                                            {
                                                tmp = hc;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (tmp == null)
                    {
                        foreach (Handcard hc in p.ownHandCards)
                        {
                            if (hc.card.type == boardObjType.PROJECTILE)
                            {
                                if (tmp == null || tmp.card.Atk < hc.card.Atk)
                                {
                                    tmp = hc;
                                }
                            }
                        }
                    }
                    if (tmp == null && p.ownMana >= 9)
                    {
                        tmp = p.getCheapestCard(boardObjType.NONE, targetType.NONE);
                    }
                    if (tmp != null && !allOpposite.ContainsKey(tmp.card.name))
                    {
                        tmp.missingMana = tmp.manacost - p.ownMana;
                        allOpposite.Add(tmp.card.name, new opposite(tmp.card.name, 10, tmp, ad.attacker));
                    }
                }
            }

            int oppCount = allOpposite.Count;

            if (oppCount > 0)
            {
                foreach (opposite opp in allOpposite.Values)
                {
                    if (OppositeDB.ContainsKey(opp.name))
                    {
                        aopp = OppositeDB[opp.name];
                        foreach (attackDef ad in attackersList)
                        {
                            aName = ad.attacker.Name;
                            if (aopp.ContainsKey(aName))
                            {
                                opp.value -= aopp[aName];
                                //TODO: test - repeat for each or break;
                            }
                        }
                    }
                    else
                    {
                        Logger.Debug("!OppositeDB.ContainsKey");
                    }
                    if (bestOpposite != null)
                    {
                        if (bestOpposite.value < opp.value)
                        {
                            bestOpposite = opp;
                        }
                    }
                    else
                    {
                        bestOpposite = opp;
                    }
                }

                if (bestOpposite != null && bestOpposite.target != null && bestOpposite.hc != null && bestOpposite.hc.card != null)
                {
                    bestOpposite.target.attacker = new BoardObj(bestOpposite.hc.card.name, bestOpposite.hc.lvl);
                }
            }
            return(bestOpposite);
        }