Technically the game is actually good enough as it is, however it can be improved upon.
Currently, the AI is coded to aim perfectly for the center of the paddle.
The issue is that humans do not aim perfectly for the center 100% of the time, nor are most of them
aiming for the center since the edges speed up the ball.
Basically our current AI does not act or feel human.
Solution to non-human AI
The solution is quite simple; all we need to do is add randomness to where the AI paddles is aiming for
and simulate the behaviour of a beginner which most likely is aiming the paddle for the center.
Mathematical Randomness
There are generally two types of randomness is mathematics:
Uniform Randomness
Discrete Uniform Distribution
Non-Uniform Randomness
Normal Distribution
Gamma Distribution
Beta Distribution
Discrete Uniform Distribution
Discrete uniform distribution is a symmetric probability distribution where a finite
set of values are equally likely to be observed.
Basically everything has an equal chance of happening.
1/n (where n is the set of values)
The benefit of discrete uniform randomness is that it is unpredictable.
A real world example of this is a die roll.
A single die has six side labeled 1-6, every number has a 1/6 chance of happening.
An example of this in Godot GDScript is:
# discrete uniform distribution
randomize()
randi_range(1,10)
All numbers have a 10% chance of happening (1/10).
Discrete uniform distribution is great when you need pure randomness, like a game of poker where everyone has an equal chance
of getting any two pair of cards.
What if you need something more than “pure randomness”?
Then what you need is a non-uniform distribution randomness.
Normal Distribution
Normal distribution (Gaussian) is symmetric around the mean (you can think of it like the middle, sort of).
Basically all occurrences closer to the mean are more frequent than occurrences further away from the mean.
Benefits of using a normal distribution randomness is that it feels more human.
This is because as humans we experience this in everyday life.
Normal Distribution can be found in:
Heights in adults
Colors in flowers
Hours of sleep
Out of the box working products (laptops, tvs, cellphones)
Two six-sided dice games (such as Monopoly)
A real world example is a two six-sided dice roll that can be found in many board games.
The numbers 2-12 are possible outcomes; the result of 7 has a 6/36 (16.66%) chance of happening, while a result of 2 has a 1/36 (2.77%)
chance of happening.
In game like Monopoly, plan out your moves as though you will roll numbers from 5-9 rather than the numbers closer to the fringes.
An example of normal distribution in the Godot Game Engine:
# discrete uniform distributionvar result: float=0.0var iterate: float=6
randomize()
for i in iterate:
result += randf()
return result /float(iterate)
Reasons to use normal distribution randomness in uyour games is to give the feeling
of randomness, but with results that feel consistent.
In a sense it feels “more human”.
An AI opponent that can target the center with near 100% accuracy is not “human”.
However, an AI that tries to aim for the center of the paddle will feel “more human”, especially
a human that is a beginner at the pong game.
With all game features, iteration will be needed to flesh out the “feel” of our AI.
Transcript
Godot Tutorials is not sponsored by or affiliated with the Godot game engine. So right now, our game is basically complete. It's got all the elements that you would expect from a simple pong game. However, there is one issue, and that is with our current A.I. In this case, it perfectly aims for the center of the paddle. Humans do not aim perfectly for anything and in this case, especially for the center of the paddle.
And so in the case
of our A.I., because it's always perfect, it does not feel human and that is an issue and I should feel human. The solution to this is to add randomness to where the paddle is aiming for. We have two types of mathematical randomness. The first is uniform randomness, or in this case, a discrete uniform distribution among the range. And the second type of mathematical randomness is non-uniform randomness.
And this would include basically every other type of distribution, including normal distribution, gamma distribution and beta distribution. In this episode, I will only deal with normal distribution. First, let's get started with discrete uniform distribution. The discrete uniform distribution is a symmetric probability distribution where a finite set of values are equally likely to be observed.
Basically, this is your typical ratio of
one divided by NP and is the set of
values. The benefit
of using discrete uniform randomness
is that it is
unpredictable.
In this case, the game
engine does provide a c# discrete uniform distribution.
This is, for example,
the random integer range function. In this case, if we set the random integer range between the values of one and 10, the randomness of getting a one or a ten and everything in between is the same. We have a one in 10 chance of getting any of the integers, which is a 10 percent chance.
A real
world example would be a single diro or a single six sided diro in this case, because
it is uniform, the
probability of rolling any values between one and six are equal, one divided by
NP. And to summarise
the discrete uniform distribution randomness is great when you want pure randomness, unpredictable randomness. However, what if we want something more predictable?
In this case,
what we can do is use a normal distribution, random generator. Normal distribution is a
symmetric probability
around the mean. Or in this case you can think of it as
the middle sort of.
And basically all occurrences closer to the mean are more frequent than occurrences further away
from the mean.
The benefit of using normal distribution randomness is that it feels more human. And this is simply because as humans, we experience normal distribution in our everyday life. Let's take a moment to think about it. We can find normal distribution in the heights of Adults',
the
color in
flowers, for example.
Not all roses are equally red. Not all white roses are equally white.
On top of
that, the hours of
sleep, the average
tends to be six to eight, and it is abnormal to be under or above that depending on your age range. We also have quality control
in products that
we purchase, for example, laptops, TVs, cell phones. And on top of that we have games such as Monopoly, which use two six sided aces when using two six sighted Dice's,
the
possibilities
fit a
normal distribution. Let's go ahead and take a look at the example of two six cited divisive.
And in this
case, you can see that each DY has a value between one and six. However, we can never get a total value of one, nor can we get a total value of thirteen. And there's only one chance to get a total value of two. However, there are six chances to get a total value of seven and in this case are two six sided devices that the normal distribution where the closer we are to the mean, which is seven,
the more
likely the occurrence
will happen in this
case to row a value of two. That would be one in thirty six. However, to row a seven, that would be six and thirty six or one in six.
So in a
game like Monopoly, expect your values to be between the values of five and nine and
plan for that.
So using normal distribution, randomness in our game will give us the feeling of randomness, but with the consistency that feels human in this case, our aims for the center. But not perfectly and not
always almost like a
human that is a beginner. And on top of that, like all game features, iteration will be needed to flesh out the feel of our
A.I. And this is
out of the scope for this
series. So here I
have an example of a primitive, normal distribution randomness.
And in this case,
we're just doing random integer range one through six
twice.
We add that and we return the value back and it is the job to convert that. And in this case, that would be a function point conversion
where we can convert the return
to value between a value of zero and the size on the Y axis for our petal. Now another primitive normal distribution randomness generator
is where
we get a random value between zero and one and return that back in a decimal
format. And to do that, we
just getting random value between zero and one six times divided by the number of random calls. And of course, be careful because the more you add, the closer to the center the values become. In this case, you can see that we are returning the addition of random values six times and then dividing that by six. And then, of course, again, it is the job to convert that and we can convert that between the value of
zero and the size on the one.
Is the algorithm you made the way to make a “proper” normal distribution?
No; it’s a quick and easy algorithm to implement on teh spot.
If you’d like a better way of implementing a normal distribution, you will need to look to math.
I recommend taking a look at the Box-Muller Transform
for a better way of creating a normal distribution.
It deals with values between 0.0-1.0, therefore you will need to translate that to a range.