|18th December 2013, 02:40 AM||#1|
Join Date: Nov 2013
Before we start, find a way to get the effects of a move without actually using the move. For example, if the move is an attack, it'll be important to know how much HP the foe will have left after the move is used.
Generally, each possible move the pokemon can make will receive a "score" based on its power, effects, etc. An attack that does more damage will receive a higher score than an attack that does less damage, for instance.
First make a list containing all the moves pokemon can make that turn. Should you desire, the list could also contain special moves such as using items or switching out. Remember to not add illegal moves, like moves that have ran out of PP.
Each move in this list will be assigned a score. A score starts at 0, and will increase/decrease based on its effects. For example, if a move inflicts the foe with poison, add 20 points to the score.
For effects like causing a pokemon to lose HP, a formula needs to be used. The more damage the move would do, the higher the move's score should be. Getting a pokemon to faint, the goal of the battle, should result in a hefty score bonus too.
Here are some scores for various effects.
Damage foe: 100 * (damage done / foe's max HP)
Faint foe: 100
Recoil damage: -100 * (recoil damage done / user's max HP)
Faint self: -100
Inflicting paralysis: 20
Inflicting poison: 20
Inflicting a burn: 25
Move goes first: 20
Raising or lowering stats require more thought, however. If a pokemon raised its attack last turn, it should be less likely to raise its attack this turn. Not only is this important for strategy, but battles where a trainer repeatedly raises a single stat are boring. Here are formulas I devised for stat mods:
Raising a stat: 40 * (stat's next modifier / stat's current modifier - 1)
Lowering a foe's stat: 30 * (stat's current modifier / stat's next modifier - 1)
For instance, raising attack by 1 (multiplier goes from 1 to 1.5) gets a score of 20, because 40 * (1.5/1 - 1) = 20. But raising attack by 1 again (multiplier goes from 1.5 to 2) only gets a score of 13.33, because 40 * (2/1.5 - 1) = 13.33. Remember the formula for lowering a foe's stat is slightly different. For example, if a foe's defense is currently down 1 stage (multiplier is .67), and the move lowers its defense by 2 (multiplier goes from .67 to .33), then the move's score is 30 * (.67 / .33 - 1) = 30.
(Under closer inspection I've found these formulas are actually wrong and don't work as intended for all cases. Will try to fix soon!)
Moves that have alternate effects can have their own custom scores. If you want the AI to get more advanced, scores can also be dependent on the foe pokemon as well. Say, a move that lowers a pokemon's attack will get a lower score if the pokemon is clearly a special attacker.
And if you want to get really advanced, you can change the score based on predicting on what move the foe will use or what it will do in response. But this approach can involve messy recursion and knowing prematurely what moves a foe can use, which shouldn't be possible at the beginning of the battle. Personally I'm avoiding that territory for now.
Once the score for each move is determined, sort the moves by their score from highest to lowest. For a weak AI, randomly pick a move from the entire list. For a better AI, randomly pick the first or second move on the list. Just picking the highest scoring move on the list may not be the best option, since it could be predictable.
So those are my ideas for trainer AI. I've implemented these concepts in my game, and so far tests are doing alright. Thoughts, suggestions, criticisms are welcome!
|26th March 2014, 04:15 AM||#2|
Join Date: Mar 2014
Nice. One way of approaching the problem would be to assign a score to the whole match - HP, number of pokes still alive, status effects etc and then evaluate the resultant score for all combinations of AI and player moves (including switches). The best move would then be the one which maximises the lowest score the players move can achieve (if that makes sense - minimax algorithm used in chess computers)
There's no need for "prediction" here, just assuming the player makes the best possible response. To make the AI smarter you could then extend the search to the second turn, although this could slow things down considerably due to extensive branching.
Out of curiosity, have you found where the current AI is called in order to implement your own in its stead. If so, what is the approach the game currently takes?
|pokemon, trainer, [Ongoing]|