Go Back   CodingForums.com > :: Server side development > Java and JSP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 07-07-2012, 05:19 AM   PM User | #1
Scriptr
Regular Coder

 
Join Date: Oct 2011
Posts: 106
Thanks: 12
Thanked 0 Times in 0 Posts
Scriptr is an unknown quantity at this point
Game AI

I am developing a Pong game. The problem, though, is it cannot be won.

I made a very simple AI (not in the sense of actual AI, but of a bot operating without input from the user) that follows the ball. The problem is that it cannot be beaten. It can move as fast or as slow as the ball, so it will hit the ball dead center every time.

How can I make the AI miss occasionally?

Current AI code:
Code:
import static org.lwjgl.opengl.GL11.*;

public class AI {
	
	private int aix = 130;
	private int aiwidth = 60;
	private boolean uIP = false;
	
	public void updateAI(Ball b){
		if(uIP)
			return;
		uIP = true;
		if(b.getBX() < aix + 30){
			aix--;
		}
		if(b.getBX() > aix + 30){
			aix++;
		}
		glColor3f(1.0f,0.5f,0.5f);
		
		glBegin(GL_QUADS);
		    glVertex2f((float) (aix),550);
		    glVertex2f((float) (aix)+aiwidth,550);
		    glVertex2f((float) (aix)+aiwidth,550+10);
		    glVertex2f((float) (aix),550+10);
		glEnd();
		uIP = false;
	}
	public int getAIX(){
		return aix;
	}
}

Last edited by Scriptr; 07-08-2012 at 05:59 PM..
Scriptr is offline   Reply With Quote
Old 07-08-2012, 05:37 PM   PM User | #2
Scriptr
Regular Coder

 
Join Date: Oct 2011
Posts: 106
Thanks: 12
Thanked 0 Times in 0 Posts
Scriptr is an unknown quantity at this point
Solution, new problem

I finally determined that at 0.04f it stops moving quickly enough to track the ball exactly, and at 0.032f it will miss occasionally.

However, I have a new problem. In my pure Java version of this game, I did a few tricks with the random ball generator to ensure it would always hit 504 on the y axis:

Code:
	public void genBall(){
		Random ran = new Random();
		ballX = ran.nextInt(400-bSize);
		ballY = (ran.nextInt(33) * 6);
		if(ran.nextBoolean())
			deltaX = -deltaX;
		if(ran.nextBoolean())
			deltaY = -deltaY;
	}

With this, I attempted to do the same by dividing the Random constraint argument by 0.04 (the ball's y movement per frame) and then multiplying the result by the same number, thus ensuring divisibility by 0.04. However, it does not always touch y = 1500 * 0.04 = 60. I have been at this for the past few days, and have not been able to come up with a viable solution.
Scriptr is offline   Reply With Quote
Old 07-08-2012, 06:46 PM   PM User | #3
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,752
Thanks: 4
Thanked 2,468 Times in 2,437 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Nice, I was thinking of reducing the paddle speed as well, but wasn't sure how that would work out (I'm definitely not an animator in any language or tool O.o).

For the calculations, float can at times be pains, due to the "reasonably accurate" threshold. My suggestion would be to actually divide the 1500 by 100, and cast it to an integer. Then take this number, and multiple it by 4 instead of 0.04. The straight int calculations guarantee an integer result, while the float doesn't guarantee that its exactly 60.0. Alternatively, you can also try casting the result to an integer, so if you have a float of 60.00000000000008 it'll end up with just 60.
Give one or both of those a shot, and see what you end up with. I don't know what the "y" datatype is and I'm hoping out for it to be a float/double.
Fou-Lu is offline   Reply With Quote
Old 07-08-2012, 11:22 PM   PM User | #4
Scriptr
Regular Coder

 
Join Date: Oct 2011
Posts: 106
Thanks: 12
Thanked 0 Times in 0 Posts
Scriptr is an unknown quantity at this point
Quote:
Originally Posted by Fou-Lu View Post
Nice, I was thinking of reducing the paddle speed as well, but wasn't sure how that would work out (I'm definitely not an animator in any language or tool O.o).

For the calculations, float can at times be pains, due to the "reasonably accurate" threshold. My suggestion would be to actually divide the 1500 by 100, and cast it to an integer. Then take this number, and multiple it by 4 instead of 0.04. The straight int calculations guarantee an integer result, while the float doesn't guarantee that its exactly 60.0. Alternatively, you can also try casting the result to an integer, so if you have a float of 60.00000000000008 it'll end up with just 60.
Give one or both of those a shot, and see what you end up with. I don't know what the "y" datatype is and I'm hoping out for it to be a float/double.
The data type for the coordinates are both float in LWJGL's use of OpenGL.
One of two things I dislike about it (the other being the lack of a function for a circle, which I solved after a few google searches)

And actually, it is the paddle speed that I reduced. Increasing the ball speed made the game still in favor of the computer based on reaction time alone (but you've given me an idea for different difficulty levels once I make a launcher; thanks)

but thanks for the help; I'll tell you how it goes.

Last edited by Scriptr; 07-08-2012 at 11:34 PM..
Scriptr is offline   Reply With Quote
Old 07-21-2012, 03:42 AM   PM User | #5
Scriptr
Regular Coder

 
Join Date: Oct 2011
Posts: 106
Thanks: 12
Thanked 0 Times in 0 Posts
Scriptr is an unknown quantity at this point
I use a 3px tall "collision range" in lieu of a single "collision pixel", meaning my only bug occurs when (~1 in every 3 balls, but random) they are able to and do run into the ball with the side of the paddle, and it "rolls" along. Your solution didn't work, but it was because a bit was left out on my part.

That is my current ball generation code:
Code:
Random ran = new Random();
if(ran.nextBoolean())
	deltaX = -deltaX;
if(ran.nextBoolean())
	deltaY = -deltaY;
x = (float) (ran.nextInt(300) + 25);

//important part
y = (float) (ran.nextInt(200) + 200);
And I need to make it so that it will necessarily touch y = 60.
This would be done by making it so that both are multiples of 0.04f. 60 is already a multiple (0.04 *1500). Now I need to make it so that the ball is a multiple.

Therefore, theoretically anyway, it should work to use
Code:
y = (float) ((ran.nextInt(50) + 50) * 4);
using your answer as a base.

However it does not.

Any ideas, now that you have all the information?


(also, I apologize for the delay; I was working on the NetIO class for MP, not to mention family vacation)
Scriptr is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 11:05 PM.


Advertisement
Log in to turn off these ads.