Search code examples
androidandroid-studiotic-tac-toe

how to make the app click button automatically after user's click in android?


I'm making a Tic Tac Toe game. I want to create the one player part.

The user always starts with X.

When the user clicks on the button to write X, I want the device to write O on any button automatically to play with the user.

Here is my code but it doesn't work, when X wins the game, it will crash, but if O wins, the game works:

Button a1,a2,a3,b1,b2,b3,c1,c2,c3,newGameBtn;
Button[] bArrary;
TextView thincrativTV;

// X = true ; O = false.
boolean turn = true;
int turn_count = 0;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_one_player);

    //set font path
    String fontpath = "fonts/ubuntub.ttf";
    //loading the font
    Typeface tf = Typeface.createFromAsset(getAssets(), fontpath);


    newGameBtn = (Button) findViewById(R.id.onePlayer_BNewGame);

    a1 = (Button) findViewById(R.id.onePlayer_A1);
    a2 = (Button) findViewById(R.id.onePlayer_A2);
    a3 = (Button) findViewById(R.id.onePlayer_A3);

    b1 = (Button) findViewById(R.id.onePlayer_B1);
    b2 = (Button) findViewById(R.id.onePlayer_B2);
    b3 = (Button) findViewById(R.id.onePlayer_B3);

    c1 = (Button) findViewById(R.id.onePlayer_C1);
    c2 = (Button) findViewById(R.id.onePlayer_C2);
    c3 = (Button) findViewById(R.id.onePlayer_C3);

    bArrary = new Button[]{a1,a2,a3,b1,b2,b3,c1,c2,c3};

    for (Button b : bArrary){
        b.setOnClickListener(this);
        //set custom font to all buttons
        b.setTypeface(tf);
    }

    newGameBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // we need to reset turn and turn_count and re enable all buttons
            turn = true;
            turn_count = 0;
            enableDisableAllButtons(true);
        }
    });

    // to make the copyrights work
    thincrativTV = (TextView) findViewById(R.id.onePlayer_TextView);
    if (thincrativTV !=null) {
        thincrativTV.setMovementMethod(LinkMovementMethod.getInstance());
    }

}



@Override
public void onClick(View v) {
    Button b = (Button) v;
    buttonClicked(b);

    Handler myHandler = new Handler();

    myHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            randomClick();
        }
    },500);
    //randomClick();

}



public void randomClick(){
    Random rand = new Random();
    if (turn_count<9) {
        Button nextB = bArrary[rand.nextInt(bArrary.length)];
        while (!nextB.isClickable()) {
            nextB = bArrary[rand.nextInt(bArrary.length)];
        }
        buttonClicked(nextB);
    }
}



public void buttonClicked(Button b){

    // i just wanna change the text on the button to X/O.
    if (turn){
        // X's turn
        b.setText("X");
    }else {
        // O's turn
        b.setText("O");
    }

    turn_count++;

    // and change the turn
    b.setBackgroundColor(Color.LTGRAY);
    b.setClickable(false);
    turn = !turn;

    checkForWinner();
}



private void checkForWinner(){

    boolean there_is_a_winner = false;

    // first we check the horizontals.
    if (a1.getText() == a2.getText() && a2.getText() == a3.getText() && !a1.isClickable()){
        there_is_a_winner = true;
    }else if (b1.getText() == b2.getText() && b2.getText() == b3.getText() && !b1.isClickable()){
        there_is_a_winner = true;
    }else if (c1.getText() == c2.getText() && c2.getText() == c3.getText() && !c1.isClickable()){
        there_is_a_winner = true;
    }

    // second we check the verticals.
    if (a1.getText() == b1.getText() && b1.getText() == c1.getText() && !a1.isClickable()){
        there_is_a_winner = true;
    }else if (a2.getText() == b2.getText() && b2.getText() == c2.getText() && !b2.isClickable()){
        there_is_a_winner = true;
    }else if (a3.getText() == b3.getText() && b3.getText() == c3.getText() && !c3.isClickable()){
        there_is_a_winner = true;
    }

    // finally we check the diagonal.
    if (a1.getText() == b2.getText() && b2.getText() == c3.getText() && !a1.isClickable()){
        there_is_a_winner = true;
    }else if (a3.getText() == b2.getText() && b2.getText() == c1.getText() && !b2.isClickable()){
        there_is_a_winner = true;
    }


    if (there_is_a_winner) {
        if (!turn){
            toast("X wins");
        }else {
            toast("O wins");
        }

        enableDisableAllButtons(false);
    } else if (turn_count == 9){
        // when all the buttons are clicked and disabled.
        toast("Oops!, Play Again");
    }
}



private void enableDisableAllButtons(boolean enable){

    // false to disable
    for (Button b : bArrary){
        b.setClickable(enable);

        //this is for color.
        if (enable){
            b.setBackgroundColor(Color.parseColor("#3c94d3"));
            //set the text back to original blank
            b.setText("");
        }else {
            b.setBackgroundColor(Color.LTGRAY);
        }
    }
}



private void toast(String message){
    Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();

}

*Note: X is user and O is the device.


Solution

  • I see method buttonClicked(Button b) is only called when user clicks on any button. it is the user's turn, not be the machine. so after you process user's turn, you can choose random button and call the buttonClicked() with it.

    @Override
    public void onClick(View v) {
        Button b = (Button) v;
        buttonClicked(b);
    
        // now you choose random button nextB 
        // -> call buttonClicked(nextB);
        Random rand = new Random();
        // machine only can set "O" when the map has any button  (when turn_count < 9)
        if (turn_count < 9) {
            Button nextB = bArrary[rand.nextInt(bArrary.length)];
            while (!nextB.isClickable()) {
                nextB = bArrary[rand.nextInt(bArrary.length)];
            }
            buttonClicked(nextB);
        }
    }
    

    on method randomClicks(Button b) we will call b.setText("0").

    public void randomClicks(Button b){
        b.setText("O");
    }
    

    I think it will work.