-1

I have created an x-o game with GUI and almost finished it, but I have difficulties declaring the winner, I managed to do it manually but it took alot of code lines and it looks messy, here's what I did:

if((buttons[0].getText()=="X" && buttons[1].getText()=="X" && buttons[2].getText()=="X") ||
                (buttons[0].getText()=="X" && buttons[3].getText()=="X" && buttons[6].getText()=="X") ||
                (buttons[4].getText()=="X" && buttons[8].getText()=="X" && buttons[2].getText()=="X") ||
                (buttons[0].getText()=="O" && buttons[1].getText()=="O" && buttons[2].getText()=="O") ||
                (buttons[0].getText()=="O" && buttons[3].getText()=="O" && buttons[6].getText()=="O") ||
                (buttons[4].getText()=="O" && buttons[8].getText()=="O" && buttons[2].getText()=="O") ||
                (buttons[2].getText()=="X" && buttons[5].getText()=="X" && buttons[8].getText()=="X") ||
                (buttons[1].getText()=="X" && buttons[4].getText()=="X" && buttons[7].getText()=="X") ||
                (buttons[6].getText()=="X" && buttons[7].getText()=="X" && buttons[8].getText()=="X") ||
                (buttons[2].getText()=="O" && buttons[5].getText()=="O" && buttons[8].getText()=="O") ||
                (buttons[1].getText()=="O" && buttons[4].getText()=="O" && buttons[7].getText()=="O") ||
                (buttons[6].getText()=="O" && buttons[7].getText()=="O" && buttons[8].getText()=="O") ||    
                (buttons[3].getText()=="X" && buttons[4].getText()=="X" && buttons[5].getText()=="X") ||
                (buttons[3].getText()=="O" && buttons[4].getText()=="O" && buttons[5].getText()=="O") ||    
                (buttons[0].getText()=="X" && buttons[4].getText()=="X" && buttons[8].getText()=="X") ||
                (buttons[0].getText()=="O" && buttons[4].getText()=="O" && buttons[8].getText()=="O")   )

So I wanted to shorten this and add it in a loop, but it didnt work.

        for(int i=0;i<9;i++)
    {
        if(i%3==0){
            y+=50; x=40;
        }
        buttons[i]=new JButton();
        buttons[i].setSize(50, 50);
        buttons[i].setLocation(x, y);   
        int temp=i;
        buttons[temp].addActionListener(new ActionListener() {              
            public void actionPerformed(ActionEvent e) {
            String currentPlayer = turnCount % 2 == 0 ? "X" : "O";
            buttons[temp].setText(currentPlayer);
            buttons[temp].setFont(new Font("Arial", Font.PLAIN, 30));
            buttons[temp].setMargin(new Insets(0, 0, 0, 0));
            buttons[temp].setEnabled(false);
            turnCount++;

            if(buttons[temp].getText()==buttons[temp+1].getText())
            {
                System.out.println("GAME OVER!");
                for(int i=0;i<9;i++)
                    buttons[i].setEnabled(false);
                turnCount = 0;
            }
        }
        });
        myForm.add(buttons[i]);
        x+=50;
    }

It should print the code inside the if statement whenever 2 following buttons have the same value, but it doesn't work.

This is exactly what needs to be changed somehow

if(buttons[temp].getText()==buttons[temp+1].getText())

Thank you.

Heshamy
  • 69
  • 8

2 Answers2

3

If temp=i and he just instanciated buttons[i],, then buttons[temp+1] is null at this moment. Also, when temp reaches 8, buttons[temp+1] will be out of bound (I suspect your Button array is of size 9 ?)

Plus this won't be a condition for victory, you just test if the next button is of the same value, which means:

XX-
O--
---

Will be a victory for X.

As you can see from you big if, your duplicating too much code, you can do:

/**Checks if player X or O won **/
    public boolean isWinner(Button[] buttons){
                return playerWins(buttons, 'X') || playerWins(buttons, 'O');
    }

/**Checks if a player has 3 buttons aligned **/
    private boolean playerWins(Button[] buttons, char player) {
        return lineWin(buttons,player,0,1,2) ||
                lineWin(buttons,player,0,3,6) ||
                lineWin(buttons,player,3,4,5); //TODO add the 5 others conditions       
    }

/** Checks if the buttons at i,j and k belongs the player **/
    private boolean buttonsBelongToPlayer(Button[] buttons, char player, int i, int j, int k) {
        return buttons[i].getText()==player && buttons[j].getText()==player && buttons[k].getText()==player;
    }
Asoub
  • 2,273
  • 1
  • 20
  • 33
  • As of temp going out of bound, and the condition of victory, you're totally right but I'm just testing the a single condition before I add the others. Those 3 methods look a little bit confusing to be honest, first of all, it says "The method getText() is undefined for the type Button", and I cant call it in the main, "if(isWinner) doesnt work. – Heshamy Sep 16 '16 at 14:47
  • If you keep the logic like that you need to instantiate all the buttons first , and then add all actionListeners. Well I wasn't sure for the Button class, so I took the first one that came. You should replace the class by the one you have. The third method test if the 3 buttons at the indexes i, j and k belongs to the player, the second one test all combinations of lines that makes a player wins (I didn't writes the eights combinations), and the first one test victory for both player. It's basically a cleaner version of you "big if" (even though my method names aren't that clear ... I'll edit) – Asoub Sep 16 '16 at 14:57
  • Well, I understand it now, and also understand why the code I wrote didn't work properly, but I'm still somehow unable to call the isWinner inside the main, the 3rd method is also giving me an error, "The method getText() is undefined for the type Button". – Heshamy Sep 16 '16 at 15:06
  • Well, change the Button class in my code by the class you used in your first code sample (the "big if"). I've used the java.awt.Button class but I wasn't sure which one you used. – Asoub Sep 16 '16 at 15:10
  • Alright, I did that to and the 3 methods aren't giving me any errors now, but how do I call the isWinner method inside the main? I tried if(isWinner(buttons)) but it didn't work. – Heshamy Sep 16 '16 at 21:43
  • I keep getting this error "Cannot make a static reference to the non-static method isWinner(JButton[]) from the type XO" – Heshamy Sep 16 '16 at 22:12
  • add the word "static" between public/private and boolean. – Asoub Sep 19 '16 at 06:34
0

Strings should be compared using equals(), not ==.

So:

if(buttons[temp].getText().equals(buttons[temp+1].getText()))
walen
  • 7,103
  • 2
  • 37
  • 58