Sign in to follow this  
nano511

Pong AI

Recommended Posts

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 this post


Link to post
Share on other sites
[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 this post


Link to post
Share on other sites
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 this post


Link to post
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.

Share this post


Link to post
[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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
Here nano. Readup.


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

This might give you a general idee.

Share this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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 this post


Link to post
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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
here is the line:

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

Share this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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 )
AI.yVel = PADDLE_SPEED;
else
AI.yVel = -PADDLE_SPEED;

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

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

Share this post


Link to post
Share on other sites
I have a few questions about this line[code]destination = min(static_cast<float>(TOP_BOUNDARY), max(static_cast<float>(BOTTOM_BOUNDARY),ball.yPos + t*(ball.yPos-lastBallXPos )));[/code]
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 this post


Link to post
Share on other sites
[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 this post


Link to post
Share on other sites
[quote name='Wooh' timestamp='1312968879' post='4847092']
I have a few questions about this line[code]destination = min(static_cast<float>(TOP_BOUNDARY), max(static_cast<float>(BOTTOM_BOUNDARY),ball.yPos + t*(ball.yPos-lastBallXPos )));[/code]
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.


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this