Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 17 of 17

Thread: Pinball bot

  1. #1
    Member
    Join Date
    Aug 2009
    Posts
    53
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Pinball bot

    I have been working a small "pinball" bot, which will play the win xp pinball game, 3d Pinball: Space Cadet.
    It uses the Robot class for pixel reading, and inputting keyboard keys. The source is on my desktop at home, but i can put it up later tonight, if anyone is interrested.

    It is in "somewhat" working state atm, but there is some problems:

    1: Obviously pixel reading is not the best way about a bot in a very dynamic game like pinball. It comes down to reading the right pixel at the right time. As it is now, very fast balls can pass through. The reading algorithm could probably be optimised to get a better result. Im using pixel reading since I wanted to do it in java (I only know java), so memory reading is sadly not an option.

    2: The bot is run using concurrency, but there is some problems with it. There is an on and a off button. Sometimes after a while, the off button doesnt stop the thread.

    I have i ideas I just havent gotten around to implement yet. Its a work in progress, and I school is keeping me very busy atm.

    It is meant to be a shared program, so anyone who wants to contribute, come with oppinions, do further development, or basicly whatever will be ofcourse be welcome to do so.


  2. #2
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Pinball bot

    Sounds interesting without reading memory you don't really have a choice but to pixel read, but thats not exactly easy and your algorithm must be pretty complex as it is.

    Chris

  3. #3
    Member
    Join Date
    Aug 2009
    Posts
    53
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Re: Pinball bot

    Quote Originally Posted by Freaky Chris View Post
    Sounds interesting without reading memory you don't really have a choice but to pixel read, but thats not exactly easy and your algorithm must be pretty complex as it is.

    Chris
    Actually its not as fancy as it sounds, The game claims to be 3d, but isnt. There is a static color of the ball to scan for. The problem is scanning the rigth place at the right time.

    Anyways here it is. Comments have just been thrown on there very fast, so bare with me.

    import java.awt.AWTException;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
     
    //Class responsible of initializing and setting up the gui.
    public class Driver {
     
    	public static void main(String[] args) throws AWTException, IOException {
     
    		JFrame frame = new JFrame("My Bot");
    		JButton button1 = new JButton("Start The Bot");
    		final int FIELD_WIDTH = 10;
    		final JTextField textfield = new JTextField(FIELD_WIDTH);
     
    		button1.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent event){
    				textfield.setText("Bot Active");
    				try {
    					ThreadHandler.getNewThread().start();
    				} catch (AWTException e) {
    				}
    			}
    		});
     
    		JButton button2 = new JButton("Stop The Bot");
     
    		button2.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent event){
    				ThreadHandler.getCurrentThread().interrupt();
    				textfield.setText("Bot Idle");
    			}
    		});
     
    		frame.setLayout(new FlowLayout());
    		frame.add(button1);
    		frame.add(button2) ;
    		frame.add(textfield);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.pack();
    		frame.setVisible(true);
     
    	}
    }

    import java.awt.AWTException;
    import java.awt.Color;
    import java.awt.Robot;
    import java.awt.event.KeyEvent;
     
    //Main Class of the bot
    public class PinballBotThread extends Thread {
     
    	private Robot bot;
    	//Color of a certain pixel ball, grayish
    	private Color color = new Color(140,140,140);
    	//The white that can be found on the ball. Only used for making the bot shoot
    	//shoot of start position.
    	private Color white = new Color(255,255,255);
    	private int x1;
    	private int x2;
    	private int x3;
    	private int x4;
    	private int y;
        private int startPosX;
        private int startPosY;
     
    	public PinballBotThread() throws AWTException{
    		bot = new Robot();
    		ScreenSetup ss = new ScreenSetup();
    		x1 = ss.getX1();
    		x2 = ss.getX2();
    		x3 = ss.getX3();
    		x4 = ss.getX4();
    		y = ss.getY();
    		startPosX = ss.getStartPosX();
    		startPosY = ss.getStartPosY();
    	}
     
    	public void run() {
     
    		//Main engine of the bot.
    		//It takes advantage of fact that the graphics of the ball is static, and there
    		//is a place of the ball where 6 adjecent pixels have the same color, Color(140,140,140);
    		//It checks for a given color across a belt of pixels near paddles.
    		//A lot of the programming could be more pretty, but for optimation purposes, as many
    		//calculations as possible have been taken out of the loop, at the expense of clarity.
    		try{
    			while (true) {
    				for (int x = x1; x < x2; x = x+6){
    					if (bot.getPixelColor(x, y).equals(color)){
    						bot.keyPress(KeyEvent.VK_Z);
    						//makes the bot wait before executing more instructions. The game cannot handle
    						//inhuman press/release times of keys, that the bot could deliver.
    						bot.delay(200);
     
    						bot.keyRelease(KeyEvent.VK_Z);
    						bot.delay(200);
    					}
    				}
       	   			for (int j = x3; j < x4; j = j+6){
       	   				if (bot.getPixelColor(j, y).equals(color)){
       	   					bot.keyPress(KeyEvent.VK_QUOTE);
       	   					bot.delay(200);
     
       	   					bot.keyRelease(KeyEvent.VK_QUOTE);
       	   					bot.delay(200);
       	   				}
       	   			}
     
       	   			if (bot.getPixelColor(startPosX, startPosY).equals(white)){
       	   				bot.keyPress(KeyEvent.VK_SPACE);
       	   				bot.delay(2000);
       	   				bot.keyRelease(KeyEvent.VK_SPACE);
       	   				bot.delay(200);
       	   			}
       	   			Thread.sleep(1);
       				} 
    			}catch (InterruptedException e){
       			}
    	}
    }

    import java.awt.*;
    //Class responsible for analyzing user screen resolution, and calculating which pixels need scanning.
    public class ScreenSetup {
        private Toolkit toolkit =  Toolkit.getDefaultToolkit ();
        private Dimension dim = toolkit.getScreenSize();
        private int x1;
        private int x2;
        private int x3;
        private int x4;
        private int y;
        private int startPosX;
        private int startPosY;
     
        public ScreenSetup(){
        	x1 = dim.width / 2 - 150;
        	x2 = dim.width / 2 - 120;
        	x3 = dim.width / 2 - 114;
        	x4 = dim.width / 2 - 84;
        	y = dim.height / 2 + 175;
        	startPosX = dim.width / 2 + 23;
        	startPosY = dim.height / 2 + 165;
        }
     
        public int getX1(){
        	return x1;
        }
     
        public int getX2(){
        	return x2;
        }
     
        public int getX3(){
        	return x3;
        }
     
        public int getX4(){
        	return x4;
        }
     
        public int getY(){
        	return y;
        }
     
        public int getStartPosX(){
        	return startPosX;
        }
     
        public int getStartPosY(){
        	return startPosY;
        }
    }

    import java.awt.AWTException;
     
    public class ThreadHandler {
    	private static Thread thread;
     
    	public static Thread getNewThread() throws AWTException{
    		thread = new PinballBotThread();
    		return thread;
    	}
     
    	public static Thread getCurrentThread(){
    		return thread;
    	}
    }

    To make it work:
    Start the pinball game. Dont move it from its start position in the middle of the screen, or the pixel reading will go haywire.
    Start a new game, let the ball be at the start position.
    Start the Bot.
    Give focus back to the pinball game.
    Watch the bot fail, and laugh.

    If you dont have the game, it should be out there for legal download, ill look for a link.
    Last edited by Johannes; August 12th, 2009 at 03:05 PM.

  4. #4
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Pinball bot

    I can see your approach now, scan the pixels next to the bat and if the ball is there then hit it. Not a bad idea, I cant think of a better lol!

  5. #5
    Member
    Join Date
    Aug 2009
    Posts
    53
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Re: Pinball bot

    Quote Originally Posted by Freaky Chris View Post
    I can see your approach now, scan the pixels next to the bat and if the ball is there then hit it. Not a bad idea, I cant think of a better lol!
    Yeah its not a clever bot. See it, whack it! I going through some possibilities to make it more intelligent, without slowing the while loop that scans.

    Its got a 6 million point high score on my labtop :-)

  6. #6
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Pinball bot

    Hehe I'm running Vista so I don't have the game you could try tracking the ball. So you always knew its location I think that is feasable

    Chris

  7. #7
    Member
    Join Date
    Aug 2009
    Posts
    53
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Re: Pinball bot

    Quote Originally Posted by Freaky Chris View Post
    Hehe I'm running Vista so I don't have the game you could try tracking the ball. So you always knew its location I think that is feasable

    Chris
    Yeah they stopped it at xp. The game itself is pretty boring, so i can understand why.

    The problem as I see it is, when the ball goes down towards the paddles, you have to scan exactly the pixel where the ball is at that exact time, or the paddles wont activate. If the while loop gets slower (by more checking more pixels), the chance of that happening decreases.
    Figuring out where the ball is at any given time will be impossible to implement with pixel reading, to the best of my knowledge atleast.

    Analysis of the while loop execution time (with no checks fullfilled)

    s = execution time Thread.sleep + the 1 millisecond it actually sleeps.
    n = execution time of Robot.getPixelColor() + calling equals method between colors (havent bothered checking out how its implemented).
    This is done 11 times each iteration, so
    11*n + s

    Before the loop was optimized, it checked 120 pixels. That would only activate on very slow balls.

    However if you have an idea about how to get location, please share.

  8. #8
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: Pinball bot

    I might give this a try later at home, sounds fun. I might have a solution to your start and stop bot issue.

    An idea would be to create and open source project somewhere and upload the code to a repository

    // Json

  9. #9
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Pinball bot

    You have a thing about uploading code to repositories lol!

    Another idea is, create an image of the section of the screen that surrounds each bat. using bot.createScreenCapture() then keep redoing that comparing it to the original, that way when the ball enters that area it will be a dif image

    Chris

  10. #10
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: Pinball bot

    hehe, indeed

    I'm not that familiar with the Robot class myself, but whats the performance like of it? I shall do some googling.

    // Json

  11. #11
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Pinball bot

    Poor lmao, but its the only thing we have to work with really but i think doing small images that are probably like 100 pixels big wouldnt take much time at all, lets hope!

    Chris

  12. #12
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: Pinball bot

    I guess it all comes down to the system/computer this is run on in the end

    // Json

  13. #13
    Member
    Join Date
    Aug 2009
    Posts
    53
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Re: Pinball bot

    The concurrency seems to work at it stands now, but it is not an optimal solution. Having to wait inside the princible loop, is just wrong. However i have not been able to find a substitution (havent looked too hard yet).

    Else checking 100 pixels can be done, especially with fast computers. Dont know if my 1.5 pentium m labtop will agree :-)

    Next implementation plan, is some sort of movement mechanism that will move the pinball window to the center of the screen, if it has been moved. Ill probable use the robot to manually drag it.

    Unrelated
    Just used a memoryscanner to find the address that holds the score, and now have a highscore of 999,999,999

    It should be relativly easy to find the adresses that are relavant for the ball position should anyone want to play around with it.

  14. #14
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Pinball bot

    Ye, but that requires being able to edit memory, which as far as im aware is not avaliable in Java thanks to its VM -evils-

    Chris

  15. #15
    Member
    Join Date
    Aug 2009
    Posts
    53
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Re: Pinball bot

    it is impossible in java. Just in case someone knew somthing that could.

  16. #16
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Pinball bot

    Could always play around with JNI and C oh the joys

  17. #17
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: Pinball bot

    hehe I was thinking that as well Chris

    // Json