Results 1 to 11 of 11
  1. #1
    Trevers89 is offline Member
    Join Date
    Jul 2011
    Posts
    5
    Rep Power
    0

    Default Java beginner- Noughts and Crosses help

    Hi, I'm quite new to Java but I'm trying to program a game of noughts and crosses for a test. I've included my code below, and if you copy/paste and compile it you can see what my problem is. My noughts and crosses board is built from an array of JButtons, each of which has an integer tag (BoxTag[]) connected with it. BoxTag[] is initialised as 0 which indicates the button has not been pressed. If the player presses the button BoxTag[] takes the value 1 and if the computer moves there it takes the value 2. My code then uses the value of BoxTag[] to replace the old JButton with a new one with an "X" or "O" in.

    If you run the code you can see what the problem is. The buttons pressed by the player don't change straight away but instead change after the next button is pressed. Also if the mouse is moved over a previously pressed button the text in it vanishes. I can't see any reason for this happening.

    Please bear in mind that my program is nowhere near complete so the game doesn't yet work perfectly. Thanks

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.*;
    
    public class Test {
    	public static void main(String[] args) {
    		JFrame frame = new JFrame("Tic Tac Toe");
    		frame.add(new TestFrame("Tic Tac Toe"));
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setSize(375,500);
    		frame.setVisible(true);
    	}
    }
    
    class TestFrame extends JComponent implements ActionListener {
    	String theMessage;
    	int messageX=125, messageY=95; // Coordinates of the message
    
    	JButton[] Box = new JButton[9];
    	int[] xpos = new int[9];
    	int[] ypos = new int[9];
    	int[] BoxTag = new int[9];
    
    	public TestFrame(String message) {
    		theMessage = message;
    		
    
    		ypos[0] = ypos[1] = ypos[2] = xpos[0] = xpos[3] = xpos[6] = 75;
    		ypos[3] = ypos[4] = ypos[5] = xpos[1] = xpos[4] = xpos[7] = 150;
    		ypos[6] = ypos[7] = ypos[8] = xpos[2] = xpos[5] = xpos[8] = 225;
    
    		for (int i=0; i<9; i++) {
    			Box[i] = new JButton();
    			add(Box[i]);
    			setLayout(null);			
    			Box[i].setBounds(xpos[i], ypos[i], 75, 75);
    			Box[i].addActionListener(this);
    			repaint();
    		}
    		
    		Start();
    	}
    
    	public void paintComponent(Graphics g) {
    		g.drawString(theMessage, messageX, messageY);
    	}
    
    	public void Start() {
    		for (int i=0; i<9; i++) {
    			BoxTag[i] = 0;
    		}
    		Random generator = new Random();										//Coin toss to determine who starts
    		int Coin = generator.nextInt(2);
    		if (Coin==0) {
    			System.out.println("Computer starts!");
    			JTextArea text = new JTextArea("Computer starts!");
    			text.setBounds(20,20,200,50);
    			add(text);
    			text.setText(null);
    			Computer();
    		}
    		else if (Coin==1) {
    			System.out.println("Player starts!");
    			JTextArea text = new JTextArea("Player starts!");
    			text.setBounds(20,20,200,50);
    			add(text);
    			//actionPerformed();
    		}
    	}
    
    	public void actionPerformed(ActionEvent e) {
    		for (int i=0; i<9; i++) {
    			if (e.getSource() == Box[i]) {
    				if (BoxTag[i] == 0) {
    					BoxTag[i] = 1;
    					Computer();
    				}
    				else {}
    			}
    			
    		}
    	}
    	
    	public void Computer() {
    		Random CompGenerator = new Random();
    		int CompRand = CompGenerator.nextInt(9);
    		if (BoxTag[CompRand] == 0) {
    			BoxTag[CompRand] = 2;
    			JTextArea text = new JTextArea("Your go!");
    			text.setBounds(20,20,200,50);
    			add(text);
    			Continue();
    		}
    		else {
    			Computer();
    		}
    	}
    
    	public void Continue() {
    		for (int i=0; i<9; i++) {
    			if (BoxTag[i] == 1) {
    				Box[i] = new JButton("X");
    				add(Box[i]);
    				Box[i].setBounds(xpos[i], ypos[i], 75, 75);
    			}
    			else if (BoxTag[i] == 2) {
    				Box[i] = new JButton("O");
    				add(Box[i]);
    				Box[i].setBounds(xpos[i], ypos[i], 75, 75);
    			}
    		}
    	}
    }

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    One main suggestion I have is not to replace JButtons or JTextFields which can get quite tricky if you're not familiar with the process, but rather to leave them in place and instead change the text displayed on them. This can be easily done for both JButtons and JTextFields by calling setText("...") on the button or text field. Next you may wish to learn about using the Swing/AWT layout managers to help make your layouts much easier to create and at the same time less prone to bugs.

    Oh and welcome to the forum! You've already passed the forum's first intelligence test by correctly using code layouts from the get-go. Good show!
    Last edited by Fubarable; 07-03-2011 at 04:14 PM.

  3. #3
    Trevers89 is offline Member
    Join Date
    Jul 2011
    Posts
    5
    Rep Power
    0

    Default

    THanks, that worked straight away!

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    You're quite welcome! Wishing you much success in your course work and future in programming!

  5. #5
    Trevers89 is offline Member
    Join Date
    Jul 2011
    Posts
    5
    Rep Power
    0

    Default

    I'm struggling with changing the text in the JTextArea in other methods than the one it was declared in. This is easy for the JButtons since they exist as an array. I've tried creating the JTextArea as a single valued array but it doesn't want to let me do that. Is there any way I can do this?

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    The reason for this difference is due to a problem of scope: where are the variables visible? You've declared your JButton array in the class and this allows it to be visible from within all non-static methods of the class. The JTextArea(s) on the other hand are declared within methods and are only visible from within the methods where they're declared and no where else. The solution is to do what you did for the JButtons: create one JTextArea variable, declare it in the class, initialize it once, probably at declaration time, and now you can call its methods from within any non-static method of the class. Check out Google for more on Java scope issues as it is a very important concept.

    Best of luck and keep up the good work!

  7. #7
    Trevers89 is offline Member
    Join Date
    Jul 2011
    Posts
    5
    Rep Power
    0

    Default

    I followed your advice and now I have a strange problem. If I directly take the code:

    Java Code:
    JTextArea text = new JTextArea("Computer starts!");
    			text.setBounds(20,20,200,50);
    			add(text);
    and move it from the Start() method where I had declared it, and instead paste it directly under my declaration for the JButton in the TestFrame class. Now it refuses to recognise the method add(Test) to add the JTextArea even though it worked perfectly fine previously, and does work perfectly fine in the same class for declaring and initialising the JButtons. Eclipse tries to create a new public void method called add() { } to deal with this. Why on earth would add() suddenly not work?

  8. #8
    DarrylBurke's Avatar
    DarrylBurke is online now Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,256
    Rep Power
    19

    Default

    A declaration (and optionally, initializer) is legal in class scope. Method calls and other statements, not -- they must reside in a method. constructor or initializer.

    And why are you using setBounds? Learn to use layout managers.
    Lesson: Laying Out Components Within a Container (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    db

  9. #9
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Trevers89 View Post
    I followed your advice and now I have a strange problem. If I directly take the code:

    Java Code:
    JTextArea text = new JTextArea("Computer starts!");
    			text.setBounds(20,20,200,50);
    			add(text);
    and move it from the Start() method where I had declared it, and instead paste it directly under my declaration for the JButton in the TestFrame class. Now it refuses to recognise the method add(Test) to add the JTextArea even though it worked perfectly fine previously, and does work perfectly fine in the same class for declaring and initialising the JButtons. Eclipse tries to create a new public void method called add() { } to deal with this. Why on earth would add() suddenly not work?
    As they say in real estate, the three things that matter most are location, location, location. You've now declared your JTextField in the class, not in a method, and this is good because now it is visible to all non-static methods, but the only thing you can do in this location is to declare your variables like so:

    Java Code:
    public class Fubarific {
       private MyClass myVariable;
    }

    or declare and initialize the variables, like so:


    Java Code:
    public class Fubarific {
       private MyClass myVariable = new MyClass();
    }

    You can't call methods in this location as it is simply not allowed, but instead will have to call them elsewhere, and I recommend that you do so in the constructor:


    Java Code:
    public class Fubarific {
       private MyClass myVariable = new MyClass();
       // myVariable.someMethod(); // this is not allowed!!
    
      public Fubarific() {
          myVariable.someMethod(); // but this is allowed
      }
    }

  10. #10
    DarrylBurke's Avatar
    DarrylBurke is online now Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,256
    Rep Power
    19

    Default

    I don't think noughts and crosses is ific enough to be named Fubarific

    db

  11. #11
    Trevers89 is offline Member
    Join Date
    Jul 2011
    Posts
    5
    Rep Power
    0

    Default

    Thanks so much for all the help so far, I've got everything working (almost) perfectly!

    I have a strange problem though. I've built in a
    Java Code:
    .removeActionListener(this);
    so that the buttons cease to function at the end of the game. I've also built in a New Game button to reset the board. The removeActionLister(); works fine on the first time; however if the player presses the New Game button to reset the board, after a winner is declared the other buttons can still be pressed. I've also built in a
    Java Code:
    System.out.println("Computer starts!");
    line to print to the console the result when the coin is tossed to determine who starts. After the board is reset is cycles through this coin toss multiples times, and it cycles through more times with each subsequent New Game. I wonder if the two problems are related somehow? I've had a look through and I have no idea what's causing this, and why it should cease to function properly on the second cycle

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.*;
    
    public class NoughtsAndCrosses {
    	public static void main(String[] args) {
    		JFrame frame = new JFrame("Noughts and Crosses");
    		frame.add(new NoughtsAndCrossesFrame("Noughts and Crosses"));
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setSize(375,600);
    		frame.getContentPane().setBackground(Color.WHITE);
    		frame.setVisible(true);
    	}
    }
    
    class NoughtsAndCrossesFrame extends JComponent implements ActionListener {
    	String theMessage;
    
    	JButton[] Box = new JButton[9];
    	int[] xpos = new int[9];
    	int[] ypos = new int[9];
    	int[] BoxTag = new int[9];
    	JTextArea text = new JTextArea("");
    	JTextArea Comp = new JTextArea("Computer: ");
    	JTextArea CompWins = new JTextArea("0");
    	JTextArea Play = new JTextArea("Player 1:");
    	JTextArea PlayWins = new JTextArea("0");
    	int[] Counter = new int[1];
    	int[] Wins = new int[2];
    	JButton NewGame = new JButton("New Game");
    	Font font = new Font("Verdana", Font.BOLD, 16);
    
    		
    	public NoughtsAndCrossesFrame(String message) {
    		ypos[0] = ypos[1] = ypos[2] = xpos[0] = xpos[3] = xpos[6] = 75;
    		ypos[3] = ypos[4] = ypos[5] = xpos[1] = xpos[4] = xpos[7] = 150;
    		ypos[6] = ypos[7] = ypos[8] = xpos[2] = xpos[5] = xpos[8] = 225;
    
    		for (int i=0; i<9; i++) {
    			Box[i] = new JButton();
    			add(Box[i]);
    			setLayout(null);			
    			Box[i].setBounds(xpos[i], ypos[i], 75, 75);
    			repaint();
    		}
    		
    		Start();
    	}
    	
    	public void Start() {
    		Counter[0] = 0;		
    		Comp.setBounds(75, 375, 58, 25);
    		add(Comp);
    		CompWins.setBounds(135, 375, 20, 25);
    		add(CompWins);
    		Play.setBounds(75, 400, 58, 25);		
    		add(Play);
    		PlayWins.setBounds(135, 400, 20, 25);
    		add(PlayWins);
    		NewGame.setBounds(125, 450, 100, 50);
    		NewGame.addActionListener(this);
    		
    		for (int i=0; i<9; i++) {
    			BoxTag[i] = 0;
    			Box[i].setText(null);
    			Box[i].addActionListener(this);
    		}
    		repaint();
    		
    		Random generator = new Random();							//Coin toss to determine who starts
    		int Coin = generator.nextInt(2);
    		if (Coin==0) {
    			System.out.println("Computer starts!");
    			text.setText("Computer starts!");
    			text.setBounds(113,20,149,25);
    			text.setFont(font);
    			text.setForeground(Color.BLACK);
    			add(text);
    			Computer();
    		}
    		else if (Coin==1) {
    			System.out.println("Player starts!");
    			text.setText("Player starts!");
    			text.setBounds(129,20,117,25);
    			text.setFont(font);
    			text.setForeground(Color.BLACK);
    			add(text);
    		}
    	}
    
    	public void actionPerformed(ActionEvent e) {
    		for (int i=0; i<9; i++) {
    			if (e.getSource() == Box[i]) {
    				if (BoxTag[i] == 0) {
    					BoxTag[i] = 1;
    					Counter[0]++;
    					System.out.println("Counter = " + Counter[0]);
    					Check();
    					Computer();
    				}
    				else {}
    			}
    			else if (e.getSource() == NewGame) {
    				Start();
    			}
    		}	
    	}
    	
    	public void Computer() {
    		
    		if (Counter[0] == 0){
    			BoxTag[4] = 2;
    			Counter[0]++;
    			Check();
    		}
    		
    		else {
    			Random CompGenerator = new Random();
    			int CompRand = CompGenerator.nextInt(9);
    			if (BoxTag[CompRand] == 0) {
    				BoxTag[CompRand] = 2;
    				Counter[0]++;
    				System.out.println("Counter = " + Counter[0]);
    				Check();
    			}
    			else if (Counter[0] < 9) {
    				Computer();
    			}
    		}
    	}
    
    	public void Check(){
    		for (int i=0; i<9; i++) {
    			if (BoxTag[i] == 1) {
    				Box[i].setText("X");
    				Box[i].setFont(font);
    			}
    			else if (BoxTag[i] == 2) {
    				Box[i].setText("O");
    				Box[i].setFont(font);
    			}
    		}
    		if (BoxTag[0] == 1 && BoxTag[3] == 1 && BoxTag[6] == 1
    		|| BoxTag[1] == 1 && BoxTag[4] == 1 && BoxTag[7] == 1
    		|| BoxTag[2] == 1 && BoxTag[5] == 1 && BoxTag[8] == 1
    		|| BoxTag[0] == 1 && BoxTag[1] == 1 && BoxTag[2] == 1
    		|| BoxTag[3] == 1 && BoxTag[4] == 1 && BoxTag[5] == 1
    		|| BoxTag[6] == 1 && BoxTag[7] == 1 && BoxTag[8] == 1
    		|| BoxTag[0] == 1 && BoxTag[4] == 1 && BoxTag[8] == 1
    		|| BoxTag[2] == 1 && BoxTag[4] == 1 && BoxTag[6] == 1) {
    			repaint();
    			text.setText("You win!");
    			text.setBounds(150,320,75,50);
    			text.setFont(font);
    			text.setForeground(Color.RED);
    			Wins[0]++;
    			GameEnd();
    		}
    		else if (BoxTag[0] == 2 && BoxTag[3] == 2 && BoxTag[6] == 2
    		|| BoxTag[1] == 2 && BoxTag[4] == 2 && BoxTag[7] == 2
    		|| BoxTag[2] == 2 && BoxTag[5] == 2 && BoxTag[8] == 2
    		|| BoxTag[0] == 2 && BoxTag[1] == 2 && BoxTag[2] == 2
    		|| BoxTag[3] == 2 && BoxTag[4] == 2 && BoxTag[5] == 2
    		|| BoxTag[6] == 2 && BoxTag[7] == 2 && BoxTag[8] == 2
    		|| BoxTag[0] == 2 && BoxTag[4] == 2 && BoxTag[8] == 2
    		|| BoxTag[2] == 2 && BoxTag[4] == 2 && BoxTag[6] == 2) {
    			repaint();
    			text.setText("Computer wins!");
    			text.setBounds(119,320,137,50);
    			text.setFont(font);
    			text.setForeground(Color.RED);
    			Wins[1]++;
    			GameEnd();
    		}
    		else if (Counter[0] == 9){
    			System.out.println("Draw!");
    			text.setText("Draw!");
    			text.setBounds(161,320,53,50);
    			text.setFont(font);
    			text.setForeground(Color.RED);
    			GameEnd();
    		}
    	}
    	
    	public void GameEnd() {
    		for (int i = 0; i < 9; i++) {
    			Box[i].removeActionListener(this);
    		}
    		add(NewGame);
    		repaint();
    		String playwins = Integer.toString(Wins[0]/2);
    		PlayWins.setText(playwins);
    		String compwins = Integer.toString(Wins[1]);
    		CompWins.setText(compwins);
    	}
    }

Similar Threads

  1. Beginner in Java - need some help
    By ea09530 in forum Advanced Java
    Replies: 4
    Last Post: 04-05-2010, 11:47 PM
  2. java beginner
    By devstarter in forum New To Java
    Replies: 4
    Last Post: 03-03-2010, 08:39 AM
  3. Java Beginner needs urgent help!
    By Polyy in forum New To Java
    Replies: 3
    Last Post: 11-24-2008, 03:11 AM
  4. Java Beginner needs help!!
    By Polyy in forum New To Java
    Replies: 4
    Last Post: 11-23-2008, 02:11 AM
  5. beginner to Java
    By notwist in forum New To Java
    Replies: 15
    Last Post: 04-18-2008, 09:41 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •