# Pong AI

## Recommended Posts

nano511    103
Hello, before i start, i chose to put this here because i think its to simple to be called AI. But anyways..

I want to be able to find out where the ball.yPos is going to hit AI_X_POS. I dont really know how i would do this at all. Could someone please [b][i][u]explain[/u] [/i] [/b] how i would go about doing this. Dont just give me a whole big line of code with a whole bunch of math. Im just going into 9nth grade these year so please be as simple as possible.

E: WAIT DONT TELL ME! I just remembered something i learned last year that might be able to figure it out. I'll tell you if it diddnt work

E2: I think i got like half of it. Here's what i have... y = slope * AI_X_POS + b. Not really sure where to go from here o_O( slope = (ball.yPos - lastBallYPos) / (ball.xPos - lastBallXPos ); )

You can help me now[img]http://public.gamedev.net/public/style_emoticons/default/biggrin.gif[/img]

##### Share on other sites
SimonForsman    7642
[quote name='nano511' timestamp='1312727402' post='4845791']
Hello, before i start, i chose to put this here because i think its to simple to be called AI. But anyways..

I want to be able to find out where the ball.yPos is going to hit AI_X_POS. I dont really know how i would do this at all. Could someone please [b][i][u]explain[/u] [/i] [/b] how i would go about doing this. Dont just give me a whole big line of code with a whole bunch of math. Im just going into 9nth grade these year so please be as simple as possible.

E: WAIT DONT TELL ME! I just remembered something i learned last year that might be able to figure it out. I'll tell you if it diddnt work

E2: I think i got like half of it. Here's what i have... y = slope * AI_X_POS + b. Not really sure where to go from here o_O( slope = (ball.yPos - lastBallYPos) / (ball.xPos - lastBallXPos ); )

You can help me now[img]http://public.gamedev.net/public/style_emoticons/default/biggrin.gif[/img]
[/quote]

If we got a ball with position bx,by and velocity vx,vy we only need to figure out what by will be when bx is AI_X_POS

thus we get:
targetx = bx+t*vx;
targety = by+t*vy;

we allready know what targetx should be:

thus

AI_X_POS = bx+t*vx;

since we know bx and vx allready we can get t

t = (AI_X_POS-bx)/vx; (if t is negative the ball is moving away from the ai paddle)

now we can calculate targety using the formula above

if targety is higher or lower than the upper/lower edge of the field the ball will bounce and the AIs prediction will be wrong, for pong however this is probably a good idea to keep the AI beatable (the AI will switch direction when the ball bounces on the walls rather than move to the correct position immediatly)

given the variables you have we get something like :

[code]
float t = (AI_X_POS-ball.xPos) / (ball.xPos-ball.lastXPos);
float AI_TARGET_Y_POS = min(highestPossibleYPosition,max(lowestPossibleYPosition,ball.yPos + t*(ball.yPos-ball.lastXPos)));
//(highest and lowest PossibleYPosition should be set to the highest and lowest Y positions the paddle can have)
[/code]

(you have to make sure that ball.xPos-ball.lastXPos never is 0)

##### Share on other sites
Wooh    1088
So the ball is moving in a linear motion so we can describe the line by the an equation of the form y = k * x + m

We can easily calulate k an m:
k = ball.xVel / ball.yVel
m = ball.yPos - k * ball.xPos

now we can solve the equation when x=AI_X_POS
y = k * AI_X_POS + m

You might also want to take the wall bounce into the calculation but that should not be too hard when you know the basics.

##### Share on other sites
Hidden
You're pretty much there :-)

You've got y = mx + c. Just set c = ball.yPos - then you're basically adding the change in position (in y) to the current position (in y) which will give you the exact coordinates where it hits the AI's vertical line.

Incidentally, I'm not sure why you need to do currentPosition - lastPosition to find slope. Don't you store the ball's velocity (speed and direction - how the ball's position changes over time) as separate x and y coordinates somewhere? If so, you could just do something like ball.xVel / ball.yVel.

sooner123    269
[quote name='Wooh' timestamp='1312730847' post='4845797']
So the ball is moving in a linear motion so we can describe the line by the an equation of the form y = k * x + m

We can easily calulate k an m:
k = ball.xVel / ball.yVel
m = ball.yPos - k * ball.xPos

now we can solve the equation when x=AI_X_POS
y = k * AI_X_POS + m

You might also want to take the wall bounce into the calculation but that should not be too hard when you know the basics.
[/quote]

Lol. Obviously the OP was asking about wall bounces. He wanted to know how to make predictions about where the ball will end up once it reaches the opposing side.

Not how to calculate movement in a straight line.

The answer is that you must compute the linear trajectory and see if it hits before the opponent's side, if not, you have the intersection. if it does, you calculate one more iteration, if this hits the opponent's side, you're done. if not, you have the interval length, now you go "mod that length" and then you only have to compute from the last interval to the opponent's side.

it's very simple and can easily take place in the time it takes to render a single frame. if you want an unscoreable opponent, this is all you need to do.

having it angle the ball to maximize the difficulty of your return is a simple linear system on points scored against you vs. the terminal angle of the ball as it approaches your side, using the reverse of the above calculation to force it.

pong has always been a game of dumbing down the opponent enough that the game is fun to play.

##### Share on other sites
nano511    103
Im talking about finding where the ball will be when its in line with the line that the AI moves on. The AI only moves up and down on one line, AI_x_POS. I need the AI to know what the ball's y value will be when the ball crosses AI_X_POS. the AI need to know this before the ball reaches there. I

have yet to read simons because i dont have time right now, but someone was talking about bouncing off walls. For that, i just reverse the y value. Ill be back in about an hour and a half and ill tell you what's going on.

##### Share on other sites
Idono87    101

[url="http://en.wikipedia.org/wiki/Line-line_intersection"]http://en.wikipedia....ne_intersection[/url]

This might give you a general idee.

##### Share on other sites
nano511    103
What do i have to include to use min() and max()?

##### Share on other sites
nano511    103
I included algorithm and im using namespace std but it says "no instance of overloaded function "min: matches the argument list" and the same for max.

##### Share on other sites
nano511    103
I still need help lol

##### Share on other sites
Wooh    1088
To use std::max and std::min you should only have to include the <algorithm> header.
[code]#include <algorithm>
#include <iostream>

int main()
{
std::cout << std::max(5, 3) << std::endl;
std::cout << std::min(5, 3) << std::endl;
}[/code]

##### Share on other sites
[quote name='nano511' timestamp='1312855881' post='4846490']
I included algorithm and im using namespace std but it says "no instance of overloaded function "min: matches the argument list" and the same for max.
[/quote]

can u paste the line where you call the min function?

##### Share on other sites
popsoftheyear    2194
This the appropriate usage.
[code]std::min(a, b)[/code]

Note that it takes 2 arguments, not 3+.

Also note, that a and b must be the same [i]type[/i] in order for the compiler to figure out how to use the correct min. (It deduces the template type by the arguments). So if 'a' is an int, and 'b' is a float, you should cast one to the other's type, at the very least.

##### Share on other sites
nano511    103
here is the line:

[code]destination = min(TOP_BOUNDARY, max(BOTTOM_BOUNDARY,ball.yPos + t*(ball.yPos-lastBallXPos )));[/code]

##### Share on other sites
popsoftheyear    2194
Ok... let's assume 't' is a float, and '[size="2"][font="CourierNew, monospace"]BOTTOM_BOUNDARY' [/font][font="Arial"]and [/font][font="CourierNew, monospace"]'TOP_[/font][/size][size="2"][font="CourierNew, monospace"]BOUNDARY' [/font][font="Arial"]are ints or something. Your second parameter in 'max' will be converted to a float through that expression, whereas the first is not a float. Therefore the compiler can't determine if 'max' should be comparing floats or ints... essentially.[/font][/size][font="Arial"]

[size="2"]One possible solution? Whatever type BOTTOM/TOP_BOUNDARY is, you need to cast the second expression in 'max' to that type.[/size]

[size="2"]Or, if you want to maintain floating point accuracy, make TOP_BOUNDARY and BOTTOM_BOUNDARY match the type of 't'.[/size]

[size="1"]Note that this response makes a lot of assumptions...[/size][/font]

##### Share on other sites
nano511    103
I got it working but the AI just goes straight up. Heres what makes him move.
[code]
destination = min(static_cast<float>(TOP_BOUNDARY), max(static_cast<float>(BOTTOM_BOUNDARY),ball.yPos + t*(ball.yPos-lastBallXPos )));

if( destination > AI.yPos )
else

if( AI.yPos + PADDLE_HEIGHT + AI.yVel >= BOTTOM_BOUNDARY )
if( AI.yPos + AI.yVel <= TOP_BOUNDARY )

AI.yPos += AI.yVel;
[/code]

##### Share on other sites
Wooh    1088
What is (ball.yPos-lastBallXPos)? You mix X and Y positions in there, is this really what you want?
From the other code it looks like Y grows downwards, in that case your use of max and min here is reversed. BOTTOM_BOUNDARY is likely to be the maximum and TOP_BOUNDARY is likely to be the minimum. That's why destination gets set to TOP_BOUNDARY all the time and the AI goes up.

[quote name='achild' timestamp='1312905562' post='4846747']
This the appropriate usage.
[code]std::min(a, b)[/code]
Note that it takes 2 arguments, not 3+.[/quote]
Actually, there is a version of max and min that takes a comparison function as the third argument. In C++0x there is a version that can take any number of arguments through the use of initializer_list. std::max({4, 6, 12, 65, 3});

##### Share on other sites
Wait a minute.. what shape is this ball?

##### Share on other sites
nano511    103
[quote name='__Homer__' timestamp='1312969763' post='4847098']
Wait a minute.. what shape is this ball?
[/quote]

Lol cant tell if your serious, but its 'suppose' to look round but its made up of pixels so ya know...But anyways its colision box is square.

##### Share on other sites
nano511    103
[quote name='Wooh' timestamp='1312968879' post='4847092']
What is (ball.yPos-lastBallXPos)? You mix X and Y positions in there, is this really what you want?
From the other code it looks like Y grows downwards, in that case your use of max and min here is reversed. BOTTOM_BOUNDARY is likely to be the maximum and TOP_BOUNDARY is likely to be the minimum. That's why destination gets set to TOP_BOUNDARY all the time and the AI goes up.

[/quote]

I just wrote what Simon said to write lol. TOP_BOUNDARY is near the top of the screen, and BOTTOM_BOUNDARY is near the bottom.