Exemple #1
0
         protected Move[] getMoves()
         {
             //todo deal with moves with no pp/disabled
             Move[] moves = new Move[4];
            int waittime = 1;
            for (int i = 0; i < 4; i++)
            {
                if (!waitUntilElementExists(By.CssSelector("button[value='" + (i + 1).ToString() + "'][name='chooseMove']"), waittime))
                {
                    cwrite("Unavailable or bad move " + i.ToString(), "debug", COLOR_BOT);
                    Move defal = new Move("error", types["error"]);
                    moves[i] = defal;
                    continue;
                }
                IWebElement b = browser.FindElement(By.CssSelector("button[value='" + (i + 1).ToString() + "'][name='chooseMove']"));
                string htmla = (string)((IJavaScriptExecutor)browser).ExecuteScript("return arguments[0].outerHTML;", b);
                string[] html = htmla.Split(new string[] { "data-move=\"" }, StringSplitOptions.None);
                //string[] html = b.GetAttribute("innerhtml").Split(new string[]{"data-move=\""},StringSplitOptions.None);
                var nametag = Array.Find(html, s => s.StartsWith("data-move"));
                string[] name = html[1].Split('"');
                string[] temp = b.GetAttribute("class").Split('-');
                string type = temp[1];

                // moves [i] =

                Move m;
                //hidden power and frustration check
                if (name[0] == "Hidden Power")
                {
                    string nname = "Hidden Power " + type;
                    if (!Global.moves.ContainsKey(nname))
                    {
                        m = new Move(nname, types[type.ToLower()], 60);
                        m.group = "special";
                        Global.moves.Add(m.name, m);
                        moves[i] = m;
                        cwrite("Move " + i.ToString() + " " + m.name, COLOR_BOT);

                    }
                    else
                    {
                        m = Global.moveLookup("Hidden Power " + type);
                        moves[i] = m;
                    }


                }
                else if (Global.moveLookup(name[0]).type.value == "normal")
                {
                    string nname = name[0]+" (" + type + ")";
                    if (!Global.moves.ContainsKey(nname))
                    {
                        //This handles all normal type moves affected by -ate abilities.
                        //I think it also handles Normalize as well.
                        m = new Move(nname, types[type.ToLower()]);
                        Move analog = Global.moveLookup(name[0]);
                        m.group = analog.group;
                        /* Check for -ate abilities by comparing the original type to the one we have.
                         * Add the 30% boost to the base power so no need to calc it later. */
                        if(m.type != analog.type)
                            m.bp = analog.bp + (analog.bp * 0.3f);
                        Global.moves.Add(m.name, m);
                        moves[i] = m;
                        cwrite("Move " + i.ToString() + " " + m.name, COLOR_BOT);
                    }
                    else
                    {
                        m = Global.moveLookup(nname);
                        moves[i] = m;
                    }

                }
                else
                {
                    if (Global.moves.ContainsKey(name[0]))
                        m = Global.moves[name[0]];
                    else
                    {
                        cwrite("Unknown move " + name[0], COLOR_WARN);
                        m = new Move(name[0], Global.types[type.ToLower()]);
                    }
                    moves[i] = m;
                    cwrite("Move " + i.ToString() + " " + name[0], COLOR_BOT);
               }
             }
             return moves;
         }
Exemple #2
0
 /// <summary>
 /// Simply returns whether the move is super-effective or better (4x)
 /// </summary>
 /// <param name="m"></param>
 /// <param name="enemy"></param>
 /// <returns></returns>
 public bool isSuperEffective(Move m, BattlePokemon enemy)
 {
     float a = damageCalc(m.type, enemy.type1);
     float b = 1;
     if (enemy.type1 != enemy.type2)
         b = damageCalc(m.type, enemy.type2);
     return (a * b > 2f) ? true : false;
 }
Exemple #3
0
 private void readJson()
 {
     if (!File.Exists(path))
     {
         cwrite("Could not open movelist.txt", "error", COLOR_ERR);
         cwrite("Analytic mode will not work properly.", "[!]", COLOR_WARN);
         cwrite("Attempting to continue", COLOR_OK);
         return;
     }
     using (var reader = new StreamReader(path))
     {
         string json;
         json = reader.ReadToEnd();
         JObject jo = JsonConvert.DeserializeObject<JObject>(json);
         string allmoves = jo.First.ToString();
         var current = jo.First;
         for (int i = 0; i< jo.Count;i++)
         {
             MoveJSONObj mv = JsonConvert.DeserializeObject<MoveJSONObj>(current.First.ToString());
             Move move = new Move(mv);
             Global.moves.Add(move.name, move);
             current = current.Next;
   
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Used to handle moves whose BP is unknown or varies.
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        private float getRealBP(Move m, BattlePokemon enemy)
        {
            if (m.bp > -1)
                return m.bp;
               
            else if (m.bp == -2)
            {
                if (m.name == "Gyro Ball")
                {
                    float np = 25 * (enemy.getStat("spe") / this.getStat("spe"));
                }
            }

            return 20; //assume default
        }
Exemple #5
0
 public float heuristic(Move m, BattlePokemon p)
 {
     return heuristic(m.type, p, true);
 }
Exemple #6
0
        /// <summary>
        /// Calculates the total damage a move will do to a particular pokemon,
        /// with respect to abilities, types, STAB, common items, etc.
        /// </summary>
        /// <param name="m">Move used by (this) pokemon.</param>
        /// <param name="enemy"></param>
        /// <returns></returns>
        public float damageCalcTotal(Move m, BattlePokemon enemy)
        {
            float mult = damageCalc(m.type, enemy.type1);
            mult = mult * damageCalc(m.type, enemy.type2);
            float dmg = getRealBP(m,enemy);
            float stab = 1;
            float ability = 1;
            float immunity = 1;
            if (immunityCheck(m.type, enemy))
                immunity = 0;
            if (m.type == this.type1 || m.type == this.type2)
            {
                stab = 1.5f;
            }
            //do ability calculations

            float additional = itemDamageMod(m, enemy);
            

            return (dmg * mult * stab * ability * additional * immunity);
        }
Exemple #7
0
        /// <summary>
        /// Returns the damage modifier for the held item.
        /// </summary>
        /// <returns></returns>
        private float itemDamageMod(Move m, BattlePokemon enemy)
        {
            if (item == "none")
                return 1;
            if (item == "choiceband" && m.group == "physical")
                return 1.5f;
            if (item == "choicespecs" && m.group == "special")
                return 1.5f;
            if (item == "lifeorb")
                return 1.3f;
            if (item == "expertbelt" && this.isSuperEffective(m, enemy))
                return 1.2f;

            return 1;
        }
Exemple #8
0
        private int getBoostChance(BattlePokemon you, BattlePokemon e, Move m, LastBattleAction lastAction)
        {
            int chance = 0;
            int minHP = 30;
            float enemyTolerance = 0.5f;

            List<String> boosts = m.whatBoosts();
            //lower rank if already maxed out.
            foreach (string s in boosts)
            {
                if (this.getBoostModifier(s) == 4f)
                    chance -= 1;
            }
            if (you.getHPPercentage() <= minHP) chance -= 2; //too weak, should focus efforts elsewhere

            if (e.checkKOChance(you) < enemyTolerance) chance += 2; //enemy does not threaten us
            else if (e.checkKOChance(you) - 0.2f < enemyTolerance) chance += 2; //if boosting will make us survive, do it.
            else chance -= 2; //otherwise too risky

            if (you.mon.getRole().setup) chance += 4; //if the mon is a setup sweeper, etc, 
            if (lastAction == LastBattleAction.ACTION_BOOST) chance -= 1; //Be careful not to boost forever.
            return chance;
        }
Exemple #9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="you"></param>
        /// <param name="e"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        private int getStatusChance(BattlePokemon you, BattlePokemon e, Move m, List<BattlePokemon> enemyTeam)
        {
            int max = GlobalConstants.MAX_MOVE_RANK;
            if (e.status != Status.STATE_HEALTHY)
                return -max;
            if (e.mon.hasAbility("magic bounce"))
                return -max;
            if (e.mon.hasAbility("poison heal") && m.statuseffect == "tox")
                return -max;
            if (e.mon.hasAbility("limber") && m.statuseffect == "par")
                return -max;
            if (m.statuseffect == "tox" && (e.hasType(types["poison"]) || e.hasType(types["steel"])))
                return -max;
            if (m.statuseffect == "par" && (e.hasType(types["ground"]) || e.hasType(types["electric"])))
                return -max;

            int chance = 0;
            if (m.statuseffect == "brn" && e.mon.getRole().physical)
                chance += 2;
            else if (m.statuseffect == "par" && (e.getStat("spe") >= you.getStat("spe")))
                chance += 2;
            else if (m.statuseffect == "slp" && (you.getStat("spe") >= e.getStat("spe")))
            {
                foreach (BattlePokemon bp in enemyTeam)
                {
                    if (bp.status == Status.STATE_SLP)
                        return -max; //abide by sleep clause
                }
                chance += 2;
            }

            chance += (int)Math.Round(10 * e.checkKOChance(you)); //Increase chance if enemy is too strong and needs to be weakened.

            return chance;
        }
Exemple #10
0
        /// <summary>
        /// The damage formula used by the games / PS!
        /// This returns a fairly accurate representation of
        /// how much damage this pokemon will do to enemy with move m.
        /// Ignores critical chance and variance.
        /// </summary>
        /// <param name="m"></param>
        /// <param name="enemy"></param>
        /// <returns></returns>
        private int damageFormula(Move m, BattlePokemon enemy)
        {
            float first = (2f * this.level + 10f) / 250f;
            float second = 0;
            if (m.group == "physical")
            {
                second = (float)this.getStat("atk") / (float)enemy.getStat("def");
            }
            else
            {
                second = (float)this.getStat("spa") / (float)enemy.getStat("spd");
            }
            float third = getRealBP(m, enemy);
            float totaldmg = first * second * third + 2;

            //Calculate modifier.
            //We will assume no critical hit and disregard the random variance.
            float itemmod = 1;
            float stab = 1;
            float immunity = 1;

            float type = damageCalc(m.type, enemy.type1);
            if(enemy.type1 != enemy.type2)
                type = type * damageCalc(m.type, enemy.type2);

            if (m.type == this.type1 || m.type == this.type2)
            {
                stab = 1.5f;
            }
            itemmod = itemDamageMod(m, enemy);
            if (immunityCheck(m.type, enemy))
                immunity = 0;
            float multiplier = type * stab * itemmod * immunity;
            return (int)Math.Floor(totaldmg * multiplier);
        }
Exemple #11
0
 /// <summary>
 /// Returns how many times this pokemon will
 /// have to use move m to KO enemy.
 /// </summary>
 /// <param name="m"></param>
 /// <param name="enemy"></param>
 /// <returns></returns>
 public int hitsToKill(Move m, BattlePokemon enemy)
 {
     int totalDamage = damageFormula(m, enemy);
     //Compare the damage we will deal to the health of the enemy.
     int times = 0; //number of times it takes to use this move to KO the opponent.
     int health = enemy.getHealth();
     for (;(health > 0); times++)
     {
         if (times > GlobalConstants.MAX_HKO)
             break;
         health -= totalDamage;
     }
     return times;
 }
Exemple #12
0
 /// <summary>
 /// Ranks a given move.
 /// Returns a rank >= 1
 /// </summary>
 /// <param name="m"></param>
 /// <param name="enemy"></param>
 /// <returns></returns>
 public int rankMove(Move m, BattlePokemon enemy,List<BattlePokemon> enemyTeam, LastBattleAction lba)
 {
     int DEFAULT_RANK = 11; //(15 - 4)
     int rank = DEFAULT_RANK; // rank of move m
     if (m.group != "status")
     {
         rank = hitsToKill(m, enemy);
         //discourage the use of low accuracy moves if they're overkill
         if (m.accuracy != 1 && enemy.getHPPercentage() < 20)
             ++rank;
         if (m.priority > 0)
             rank -= m.priority;
         //To rank in ascending order (ie 1 is a poor rank) subtract the rank from the max.
         if (rank > GlobalConstants.MAX_MOVE_RANK) rank = GlobalConstants.MAX_MOVE_RANK;
         rank = GlobalConstants.MAX_MOVE_RANK - rank;
        
     }
     else
     {
        if (m.heal)
         {
             rank = getRecoverChance(enemy, lba);
             rank += ((100-getHPPercentage())/10);
         }
        else if (m.status)
         {
             rank += getStatusChance(this, enemy, m, enemyTeam);
             /* add the status rank to the default rank, meaning a good
              * status move will rank around the same as a 2HKO. This
              * will prevent cases where an easy OHKO is available, but
              * a turn is wasted on status. However it may need more
              * balancing.
              */
         }
        else if (m.isBoost)
         {
             rank += getBoostChance(this, enemy, m, lba);
         }
     }
     return rank;
 }