I have a Tic Tac Toe GUI that lets a user play against a computer. I use an actionListener to receive the users mouse clicks on where they want to put their “X” on the board. The problem I have is, the way my code is set up, my GUI waits for a mouse click whenever it’s the computers turn before placing their piece. In other words, the user goes first and puts their “X” piece down wherever they want. After the user goes, the user must click on an empty piece on the board to simulate the computers turn, i.e. to simulate the computer putting down an “O” piece. My goal is to try and make the computer’s piece automatically appear on the board without having the user click an empty piece to simulate the computer’s movement. Here is my code for initializing the board which uses ActionListener:
private void initializeBoard() { Font f1 = new Font(Font.DIALOG, Font.BOLD, 100); for(int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { JButton button = new JButton(); gameBoard[i][j] = button; button.setFont(f1); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(((JButton)e.getSource()).getText().equals("") && isWinner == false) { if(isPlayersMove) //players turn to make a move { button.setText(currentPlayer); isPlayersMove = false; crossesCount += 1; } else //computers turn to make a move { computersMove(); circlesCount += 1; isPlayersMove = true; } hasWinner(); } } }); pane.add(button); } } }
Here’s the code for how the computer determines where to place a piece (randomized, for now):
// Choose a random number between 0-2 private int getMove() { Random rand = new Random(); int x = rand.nextInt(3); return x; } /* * Decision making for the computer. Currently, the computer * chooses a piece on the board that is empty based on a random * value (0-2) for the row and column */ public void computersMove() { int row = getMove(), col = getMove(); while(gameBoard[row][col].getText().equals("x") || //if space is occupied, choose new spot gameBoard[row][col].getText().equals("o")) { row = getMove(); col = getMove(); } gameBoard[row][col].setText(computerPlayer); }
Advertisement
Answer
Because the computer should make its move right after the user does his, I believe you can bind it to the same event. This way, whenever the user selects his position, he will trigger the computers move.
You can optionally add a short delay, between those two actions.
public void actionPerformed(ActionEvent e) { if(((JButton)e.getSource()).getText().equals("") && isWinner == false) { button.setText(currentPlayer); crossesCount += 1; hasWinner(); // optional short delay computersMove(); circlesCount += 1; hasWinner(); } }