Probability Machines

As you can tell in Screenshot, there isn't really any order to the different battle states. So, what determines whether you're attacking, dodging, or running away? Sometimes you want the decision between different states to occur purely on deterministic reasoning. For example, you might want to dodge only if you detect projectiles heading your way. Sometimes, though, you just want to randomly select one of these states, giving preference to one state or the other. Check out Screenshot as an example.

Screenshot Each bot could have a different probability of performing each battle state.

Java graphics 13fig05.gif


This figure shows three different types of bots, with different probabilities of each state occurring. Note that the sum of the probabilities equals 100%. You might be used to observing probability as a percentage—for example, when you flip a coin, there's a 50% chance of the coin turning up heads. You also might have thought of probability as a fraction, such as a 1/6 chance of rolling a certain number with a die or a one-in-a-million chance of winning a lottery. In this chapter, we use the decimal representation of probability that's common in statistics textbooks. In this representation, the probability of an event occurring is between 0 and 1. A probability of 1 means the event always occurs, 0 means the event never occurs, and 0.5 means the event has a 50% chance of occurring. Screenshot could easily have been a described as a pie chart, but laying it out in this way shows how you can determine which state is chosen. For example, a random number generator returns a number between 0 and 1. With an average bot, if the result is between 0 and 0.5, the state could be attack; between 0.5 and 0.9 would be dodge; and between 0.9 and 1.0 would be run away. You can keep track of these probabilities like this:

// probability of each battle state
// (the sum should be 1)
float attackProbability;
float dodgeProbability;
float runAwayProbability;


Notice that the sum of these is assumed to be 1.0, just like in Screenshot—that way, at least one of these events will always occur. You can randomly choose a state as in Listing 13.6.

Listing 13.6 AIBot.chooseBattleState()
/**
 Randomly choose one of the three battle states (attack, dodge,
 or run away).
*/
public int chooseBattleState() {
 float p = (float)Math.random();
 if (p <= attackProbability) {
 return BATTLE_STATE_ATTACK;
 }
 else if (p <= attackProbability + dodgeProbability) {
 return BATTLE_STATE_DODGE;
 }
 else {
 return BATTLE_STATE_RUN_AWAY;
 }
}


Because you assume the sum of the probabilities is 1.0, you can assume that if attack or dodge isn't chosen, then run away is the resulting state.

Some Useful Random Functions

Using Math.random() in the chooseBattleState() method was fine because the random function returns a number from 0 to 1, but you're going to be using random numbers a lot on this chapter, and you'll often want more flexibility than just a range from 0 to 1. Now is a good time to introduce some handy random functions. You'll add them to the MoreMath class, shown here in Listing 13.7.

Listing 13.7 Random Functions of MoreMath.java
/**
 Returns a random integer from 0 to max (inclusive).
*/
public static int random(int max) {
 return (int)Math.round(Math.random() * max);
}
/**
 Returns a random integer from min to max (inclusive).
*/
public static int random(int min, int max) {
 return min + random(max-min);
}
/**
 Returns a random float from 0 to max (inclusive).
*/
public static float random(float max) {
 return (float)Math.random()*max;
}
/**
 Returns a random float from min to max (inclusive).
*/
public static float random(float min, float max) {
 return min + random(max-min);
}
/**
 Returns a random object from a List.
*/
public static Object random(List list) {
 return list.get(random(list.size() - 1));
}
/**
 Returns true if a random "event" occurs. The specified
 value, p, is the probability (0 to 1) that the random
 "event" occurs.
*/
public static boolean chance(float p) {
 return (Math.random() <= p);
}


The first four functions return a random number between certain ranges. The next function returns a random object from a list of objects. Finally, the last function returns true if a random "event" occurs, with the probability of the event occurring between 0 and 1.



   
Comments