I am basically trying to make a TicTacToe game in Netbeans GUI builder. I have nine(3x3) buttons to show a grid for the game and that's where you mark X and O's. I want to make it one player game.
I wanted to know how to make an array of buttons(JButton).?It is needed to conveniently flip over different buttons.
In the game, computer would need to play with another player and has to mark O and X randomly across nine buttons. So , can you pls also tell me how to randomly shuffle over elements in button array and choose a button that is not currently marked, which would be used by computer player to mark his turn.?
I have not started with the code yet, so i am giving any sample code. Your help would be greatly appreciated. Pls help

Recommended Answers

All 6 Replies

choose a button that is not currently marked

When you chose a button, test if it is marked (how are you marking the buttons) and if it is marked, chose another one.

how to randomly shuffle over elements in button array

Use the Random class to chose the row and again to chose the column.

how to make an array of buttons

Define a 2D array: button[][] theArray =

just my 2 cents but when i wanted to make a tictactoe game, i found that the buttons were not very elegant for that!

what i did, and keep in mind this is just a suggestion, or a challenge if you want, is simply add a JPanel to my JFrame, draw lines on that JPanel and then add a MouseListenner to it.

then whenever clicked i would get the x,y coordinates of the click and calculate which square was clicked. (modulo "%" is your friend) , then check if this square was free against a char array of size 9 (or a 3x3 2d char array cant remember, both work fine).

Using drawLine() and such to draw my Xs and Os.

I found that to be much cleaner than JButtons. but its just an opinion :)

Yes, the default appearance of buttons is not good for this application, but it's easy to change that. For example a quick button.setMargin(new Insets(0, 0, 0, 0)); will leave you with a simple plain rectangle. Then you can still use button.setText("X"), or setIcon for a snazzier look wthout any need for hand-coded graphics or mouse coordinate arithmetic.

hmmm here is some code to help you out i didnt include the checkForWin() method procedures as its very lengthy...

package tictactoetest;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 *
 * @author David
 */
class TicTacToe {

    private final JFrame frame = new JFrame("TicTacToe");
    private JPanel panel;
    private JButton[] buttons = new JButton[9];
    private boolean[] markedArray = new boolean[9];
    private String symbol;
    private String cpuPiece = "O";
    private String playerPiece = "X";

    public TicTacToe() {
        createAndShowGui();
    }

    private void createAndShowGui() {
        frame.setSize(500, 400);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        addComponentsToFrame();

        frame.setVisible(true);
    }

    private void addComponentsToFrame() {

        panel = new JPanel();
        panel.setLayout(new GridLayout(3, 3));

        for (int i = 0; i < buttons.length; i++) {

            //create a new button
            buttons[i] = new JButton();

            //set the buttons action command to its position in the array i.e 0-8
            buttons[i].setActionCommand(String.valueOf(i));
            //doesnt look as much like a button
           buttons[i].setContentAreaFilled(false);

            //set the boolean value at same position of button array to false it hasnt been marked yet
            markedArray[i] = false;
            //adds action listener to each button
            buttons[i].addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    setSymbol(playerPiece);//switch to player symbol

                    if (markedArray[Integer.parseInt(e.getActionCommand())] == true) {
                        return;
                    }

                    //when the button is clicked the boolean value with same position as button is changed to true
                    markedArray[Integer.parseInt(e.getActionCommand())] = true;
                    //set button with the current symbol
                    buttons[Integer.parseInt(e.getActionCommand())].setText(symbol);
                    callComputer();
                }
            });

            panel.add(buttons[i]);

        }

        frame.add(panel);

    }

    private void callComputer() {

        checkForWin();//will call method to check if anyone has won

        setSymbol(cpuPiece);//switch to cpu symbol

        if (isBoardFull()) {//check if the board is full
            JOptionPane.showMessageDialog(panel, "Game done");
            System.exit(0);
        } else {
            Random random = new Random();
            int i = -1;

            while (i == -1) {
                i = doButtonClick(random.nextInt(9));
            }
        }
        //after cpu moved recheck if win
        checkForWin();//will call method to check if anyone has won

    }

    void setSymbol(String s) {
        symbol = s;
    }

    boolean isBoardFull() {
        int count = 0;

        for (int i = 0; i < buttons.length; i++) {
            if (markedArray[i] == true) {
                count++;
            }
        }

        if (count == 9) {
            return true;
        } else {
            return false;
        }

    }

    int doButtonClick(int n) {

        if (markedArray[n] == true) {
            return -1;
        } else {//'simulate' click from cpu without actually calling actionlistener as only player will use that
            buttons[n].setText(symbol);
            markedArray[n] = true;
            return -2;
        }

    }

    private void checkForWin() {
    }
}

and the test driver:

/**
 *
 * @author David
 */
public class TicTacToeTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TicTacToe();
            }
        });

    }
}

Yes, the default appearance of buttons is not good for this application, but it's easy to change that. For example a quick button.setMargin(new Insets(0, 0, 0, 0)); will leave you with a simple plain rectangle. Then you can still use button.setText("X"), or setIcon for a snazzier look wthout any need for hand-coded graphics or mouse coordinate arithmetic

indeed, as i was writing my post i thought of that and realized i might have taken the long way home haha! Im still glad i did it, as it was during college, and a very good practice code wise! :)

Thank you so much David!I will also try to work the way Philippe told me!
Thank you!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.