While loop help

Hey everyone, I’m trying to make a simple rock, paper, scissors game using JButtons and a simple random AI. I believe I have everything in order but the order of execution in my main. I’m trying to display the games options, wait for the user to select an option, next have the computer randomly select an option, then have the game compare the two choices then see who has won and display a score on the top of the window.

I think I need to tackle this problem with a nested while loops. I think I need to create a Boolean for my first while loop so that the program runs normally and then have my second while look wait for input from the user to execute the rest of the code. I’ve been stumped for some days so I thought I ask for help. If someone could point me the right direction I would be very appreciative!

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.*;


public class GamePanel implements ActionListener{
	
	static int playersco = 0;
	static int compsco = 0;
	
	static int player = 0;
	static int comp;
	String playerroc, playersis, playerpap ;
	static String compprint, comproc, comppap, compsis;
	JButton roc, pap, sis;
	JPanel selectpanel, gamtex, compout;
	static JLabel playerscore;
	JLabel compscore;
	JLabel compchoice;
	
	public JPanel ContentPane(){
		
		JPanel masterPanel = new JPanel();
		masterPanel.setLayout(null);
		
		gamtex = new JPanel();
		gamtex.setLayout(null);
		gamtex.setLocation(100, 10);
		gamtex.setSize(155,20);
		gamtex.setBackground(Color.yellow);
		masterPanel.add(gamtex);
		
		playerscore = new JLabel(""+ playersco +" Player");
		playerscore.setLocation(0,0);
		playerscore.setSize(90,20);
		playerscore.setHorizontalAlignment(0);
		gamtex.add(playerscore);
		
		compscore = new JLabel(""+compsco+" Computer");
		compscore.setLocation(20,0);
		compscore.setSize(190,20);
		compscore.setHorizontalAlignment(0);
		gamtex.add(compscore);
		
		compout = new JPanel();
		compout.setLayout(null);
		compout.setLocation(130,35);
		compout.setSize(110,100);
		masterPanel.add(compout);
		//compout.setBackground(Color.DARK_GRAY);
		
		compchoice = new JLabel(compprint);
		compchoice.setLocation(0,0);
		compchoice.setSize(85,20);
		compout.add(compchoice);
		
		selectpanel = new JPanel();
		selectpanel.setLayout(null);
		selectpanel.setLocation(0,15);
		selectpanel.setSize(100,190);
		//selectpanel.setBackground(Color.green);
		masterPanel.add(selectpanel);
		
		roc = new JButton("Rock");
		roc.setLocation(10,5);
		roc.setSize(80,30);
		roc.addActionListener(this);
		selectpanel.add(roc);
		
		pap = new JButton("Paper");
		pap.setLocation(10,45);
		pap.setSize(80,30);
		pap.addActionListener(this);
		selectpanel.add(pap);
		
		sis = new JButton("Sissors");
		sis.setLocation(10,85);
		sis.setSize(80,30);
		sis.addActionListener(this);
		selectpanel.add(sis);
		
		masterPanel.setOpaque(true);
		return masterPanel;
	}
	
	public void actionPerformed(ActionEvent e){
		
		if(e.getSource() == roc ){
			
			player = 1;
			
		}else if(e.getSource() == pap){
		
			player = 2;
			
		}else if(e.getSource() == sis){
			
			player = 3;
			
		}
		
	
	}
	
	
	public static  void comprandom(){
		
		Random randomGenerator = new Random();
		 int randomInt = randomGenerator.nextInt(3);
		 if(randomInt == 1){
			 
			 comp = 4; 
			 compprint = "Sissors!";
			
		 }else if(randomInt == 2){
			
			 comp = 5 ;
			 compprint = "Rock!"; 
			
		 }else
		 {
			 comp = 6 ;
			 compprint = "Paper!";
			
		 }
	}
	

		
	public static  void gamebrain()
	{
		if(player == 1 && comp == 4 ){
			playersco = playersco +1;
			playerscore.setText(""+ playersco +" Player");
		}else if( player == 2 &&  comp == 5) {
			playersco = playersco +1;
			playerscore.setText(""+ playersco +" Player");
		}else if( player == 3 && comp == 6){
			playersco = playersco +1;
			playerscore.setText(""+ playersco +" Player");
		}else{compsco = compsco + 1;}
	}

	
	private static void showgame(){
		
		JFrame frame = new JFrame("Rock, Paper, Sissors");
		
		GamePanel show = new GamePanel();
		frame.setContentPane(show.ContentPane());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(280, 190);
		frame.setVisible(true);
		
	}
	
	public static void main(String[] args){
		
	while(){
    	showgame();
    	
    	while(!(player == 0)){
    			gamebrain();
            	comprandom();
    	}
              
	}
        
		
    	  
	
	}


}

Search game loops on this forum if you are more serious about making games.

If you are just using Swing/AWT, you can do all this with actionListeners and will not need a loop. Every time the user selects either roc, pap, or sis, do the AI stuff, compare the AIs choice with the player, and display who won. If you want more fancy animations or anything then you will need to look into the game loops.

Don’t use while inside your main() method. Just simply call showGame(). Since human select first, put your comprandom() and gamebrain() in order inside actionPerformed(). That will make comp to pick after human clicks a button and process the comparison.

After all your game shouldn’t run, am i right? ‘player’ is 0 since begin.

http://www.java-gaming.org/index.php?topic=24220.0

The “public static void main(String[] args)” method is only ever used to start an application. It is there because the java compiler always looks for it from where to begin execution of a program.

It only gets executed once, at the very start of the program.

What you should do is this:

public static void main(String[] args){
   new GamePanel();
}

in general, “public static void main()” should be the ONLY static method in your program.

E.g your comprandom, gamebrain and showgame methods should all be NON-static. and your GamePanel class should handle the while loop.

E.g: inside GamePanel you could have a method like this:


public void run() {
   while (isRunning) {
       gameBrain();
       comprandom();
       showGame();

       try {
            Thread.sleep(20);
       } catch (Excpetion e) {}
   }
}

And you could start this loop by calling it inside GamePanels constructor. A construcor is a method inside the class that has the same name as the class.

E.g:


public GamePanel() {
   isRunning = true;
   run();
}

Constructors are called automatically when an object of that class is created.

To create objects from a class, you use the “new” keyword (like we did in the main() method).

public static void main(String[] args){
    new GamePanel();
}

[EDIT]: Try and keep away from static as much as possible! Arguably static things are completely useless and unnecessary - use them when you know what you’re doing. For a thing like this, you should absolutely never EVER use static like this. Java is an object oriented language - use it as such :]

I think a little API called LWJGL would beg to differ.

All categorical statements are false! :persecutioncomplex:

Ehh static non-static if it works it works.

umDr0mPuyQc

Self inconsistent statement are awesome.

Static methods that do not produce side effects are fantastic!

Whoa, I never expected such detailed responses. Thank you guys for the clearly and well explained answers! But, what is this argument between non-static, static, and who cares stuff? I know Micheal Scott feels strongly against the whole it doesn’t matter approach.

I reason why I choose to use statics everywhere was because Eclipse told me to do it :’(
I actually had no idea why it wanted me to do it, but after listening to Eclipse’s suggestions my program would run without any problems so I thought I was doing good. I guess I was super wrong.

The reason why I made player == 0, ReBirth, was so that the game would start the player off with nothing and then as soon as the player chose something it would change it’s value, then the game would compare that value against the computers randomized value. But, nope that isn’t true. Thanks for pointing that out, because I know it would of caused a headache later.

You can set player to 0 when the result of current match popped.

Eclipse didn’t tell you to make everything static. You tried calling non-static methods from a static context, and the compiler complained. So the “obvious” fix was just to make everything static, rather than create a non-static context, i.e. instantiate an object.

Every time I see yet another person say “Eclipse made me do X” or “I put this in and Eclipse wouldn’t take it”, I become more convinced that newbies simply shouldn’t ever be taught with IDEs. It’s not the IDE’s fault, but it certainly isn’t helping anyone learn.

I agree. Having built a significant amount of my game’s ancestral engine code with GCC and the command prompt, I can say that taught me a lot about spotting bugs and figuring out the right thing to do without an IDE’s guidance. Now I just abuse the crap out of using NetBeans :smiley:

Colton

I leaned how to code java with notepad first then I jumped up to notepad++ I was suck a boss. I actually had this guy in my data structures class that was wondering why all his stuff sometimes had to have static in everything and face palmed. He ended up getting a higher grade. >:(

I am not saying static does not matter as it does obviously. Its just that there are many places where use can use it without causing any issues. If I am coding something that will be used by others and needs re-usability, I will do everything properly. For me it seems that when you want really good clean documentation, code, and readability, then you start dropping all the short cuts and hackyness.

Indeed. I’d like to think there’s a time and a place to use static methods and when not to use them, even if you can get away with either more or less of the time. Currently, my engine has a few static methods, but 99% of the whole thing is non-static. A couple examples I have are a few pixel map to image functions, as well as functions between two of my procedural generators that allow them to work together without needing to instantiate both of them. Aside from that, we ain’t havin none of that static :smiley:

By the way, I do love Notepad++… that’s what I was coding in for a long while before I jumped on the NetBeans bandwagon.

As sproingie said, it’s because you tried to use non-static methods in a static contest.

WTF does this mean, you say? It simply means that you tried calling non-static methods inside a static method. (non-static methods live outside objects while normal methods live inside objects.)

HOW Did I end up doing that, you say? Because a java program is started from the “public static void main()” method, you thought you’d put your game logic and loops in there - this is a big nono. Only use the "public static void main()’ to start off something (I.e, create an object) - it should have NOTHING to do with the actual program itself!

You could also have a “start()” method in your GamePanel class to start it off instead of it starting itself when it is created (through the constructor). To call methods inside objects you simply append a . at the end of their name + the method you want to call.

E.g:

class GamePanel {
   boolean isRunning = false;

   public void start() {
      isRunning = true;
      run();
   }

   public void run() {
      while (isRunning) {
         // Do Game logic
      }
   }
}
public static void main(String[] args) {
   /* the public static void main() method doesn't need to be inside the GamePanel class. */
   
   // Create object
   GamePanel myObject = new GamePanel();
  
   // Set it off
   myObject.start(); 
}

One thing I like about Scala … no static contexts. Main is a singleton object that extends App.


object Hello extends App {
   println("Hello world")
}

Thanks everyone for the input. I was able to get my game running the way that I want it to and I took out all of the statics that shouldn’t of been, but I’m still having a problem with my loop. My loop right now is empty, as I implemented all of the actions of the game into my ActionPerformed method. What I would like to know is can I get my game running through a Loop? I ready the tutorials and played around and just got things going in infinite loops.

Also, I’m planning to add some very, very simple graphics to the game. If I can’t use my current loop for my game logic and updates can I use this loop for the graphics?

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.*;


public class GamePanel implements ActionListener{
	private boolean isRunning = false;
	int playersco = 0;
	int compsco = 0;
	
	int player;
	int comp;
	String playerroc, playersis, playerpap ;
	String compprint, comproc, comppap, compsis;
	JButton roc, pap, sis;
	JPanel selectpanel, gamtex, compout;
	JLabel playerscore;
	JLabel compscore;
	JLabel compchoice;
	
	public JPanel ContentPane(){
		
		JPanel masterPanel = new JPanel();
		masterPanel.setLayout(null);
		
		gamtex = new JPanel();
		gamtex.setLayout(null);
		gamtex.setLocation(100, 10);
		gamtex.setSize(155,20);
		gamtex.setBackground(Color.yellow);
		masterPanel.add(gamtex);
		
		playerscore = new JLabel(""+ playersco +" Player");
		playerscore.setLocation(0,0);
		playerscore.setSize(90,20);
		playerscore.setHorizontalAlignment(0);
		gamtex.add(playerscore);
		
		compscore = new JLabel(""+compsco+" Computer");
		compscore.setLocation(20,0);
		compscore.setSize(190,20);
		compscore.setHorizontalAlignment(0);
		gamtex.add(compscore);
		
		compout = new JPanel();
		compout.setLayout(null);
		compout.setLocation(130,35);
		compout.setSize(110,100);
		masterPanel.add(compout);
		//compout.setBackground(Color.DARK_GRAY);
		
		compchoice = new JLabel(compprint);
		compchoice.setLocation(0,0);
		compchoice.setSize(85,20);
		compout.add(compchoice);
		
		selectpanel = new JPanel();
		selectpanel.setLayout(null);
		selectpanel.setLocation(0,15);
		selectpanel.setSize(100,190);
		//selectpanel.setBackground(Color.green);
		masterPanel.add(selectpanel);
		
		roc = new JButton("Rock");
		roc.setLocation(10,5);
		roc.setSize(80,30);
		roc.addActionListener(this);
		selectpanel.add(roc);
		
		pap = new JButton("Paper");
		pap.setLocation(10,45);
		pap.setSize(80,30);
		pap.addActionListener(this);
		selectpanel.add(pap);
		
		sis = new JButton("Sissors");
		sis.setLocation(10,85);
		sis.setSize(80,30);
		sis.addActionListener(this);
		selectpanel.add(sis);
		
		masterPanel.setOpaque(true);
		return masterPanel;
	

	
	}
	

	
	public void actionPerformed(ActionEvent e){
		
		if(e.getSource() == roc ){
			
			player = 1;
			
		}else if(e.getSource() == pap){
		
			player = 2;
			
		}else if(e.getSource() == sis){
			
			player = 3;
			
		}
		
		comprandom();
		gamebrain();
		
	}
	
	
	public void comprandom(){
		
		Random randomGenerator = new Random();
		 int randomInt = randomGenerator.nextInt(3);
		 if(randomInt == 1){
			 
			 comp = 4; 
			 compchoice.setText("Sicssors!");
			
		 }else if(randomInt == 2){
			
			 comp = 5 ;
			 compchoice.setText("Rock!");
			
		 }else
		 {
			 comp = 6 ;
			compchoice.setText("Paper!");
		}
	}
	

		
	public void gamebrain()
	{
		if((player == 1 && comp == 4) ||( player == 3 && comp == 6)||( player == 2 &&  comp ==5 )){
			playersco = playersco +1;
			playerscore.setText(""+ playersco +" Player");
		
		}else if( (player == 1 && comp == 5) ||(player == 2 && comp == 6) ||(player == 3 && comp == 4) ){
		
			playerscore.setText(""+ playersco +" Player");
		}
		
		else{
			compscore.setText(""+ compsco +" Computer");
			compsco = compsco + 1;}
	}

	
	private void showgame(){
		
		JFrame frame = new JFrame("Rock, Paper, Scissors");
		frame.setContentPane(ContentPane());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(280, 190);
		frame.setVisible(true);
		
	}
	
	public void run() {
	
		
		showgame();
		while(isRunning){
	
			
			
			
			
		try{
			Thread.sleep(20);
				
			}catch(Exception e){}
	}
	}
	
	public GamePanel(){
		isRunning = true;
		run();
	}
	public static void main(String[] args){

		new GamePanel();
    	}
              
	}
        

Ok, time for me to get back to messin’ around!

If all of the game play visuals are in response to GUI events, then having the redraw of your screen come about due to calls to actionPerformed() could be fine. No game loop is needed, though one might be used.

If you want additional animation, then you will need some sort of game loop operating concurrently. The game loop will have to do its standard thing of updating the animation, then rendering it. If the animation is in response to a change in game state (in other words, changes that occur in your actionPerformed() method), then there is a technique commonly used to obtain the needed information.

  1. When an actionPerformed() executes, update variables that hold the game state.

  2. In the game loop, in the update part, consult these game state variables and then decide what to do.

It is common to mark variables that are consulted from concurrent threads (as you will have in the above scenario) with the keyword volatile. This helps ensure that all threads always see the most current values in these variables.