0

Below is a peice of code where on click the player will make their move by placing the X counter and then the computer will make their move by placing a O counter. The only issue with this code currently is that when the player places their X counter, the O counter is placed as well at the same time. So it looks like both the player and the computer has made their moves at the same time and that happens everytime the player makes their move.

What I want to ask, is it possible to include like a 2 second time delay so that the player will place their X and then after 2 seconds the computer will place their O?

Thanks in advance

   @Override
    public void onClick(View v) {

        if (!((Button) v).getText().toString().equals("")) {
            return;
        }

        if (playerOneMove) {
            ((Button) v).setText("X");
            ((Button) v).setTextColor(playerX);
            computerMove();
        }
}

private void computerMove() {
    String[][] field = new String[3][3];
    Random random = new Random(); //you may want to declare this as a class field
    List<Button> emptyButtons = new ArrayList<>();

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            field[i][j] = buttons[i][j].getText().toString();
            if (field[i][j].equals("")) {
                emptyButtons.add(buttons[i][j]);
            }
        }
    }

    Button selectButton;

    for (int i = 0; i < 3; i++) {
        if (field[i][0].equals(field[i][1])
                && field[i][2].equals("")){
            //prevent win/win on rows by selecting the correct button here
        }
        else if (field[i][0].equals(field[i][2])
                && field[i][1].equals("")){
             //prevent win/win on rows by selecting the correct button here
        }
        else if (field[i][1].equals(field[i][2])
                && field[i][0].equals("")){
            //prevent win/win on rows by selecting the correct button here
        }
        else {
            selectButton = emptyButtons.get(random.nextInt(emptyButtons.size()));
        }

    selectButton.setText("O");
    selectButton.setTextColor(playerO);
}
maheryhaja
  • 1,617
  • 11
  • 18
Big Hendo
  • 185
  • 2
  • 14
  • Maybe this issue on pausing a thread will help you [how-to-pause-sleep-thread-or-process-in-android](https://stackoverflow.com/questions/1520887/how-to-pause-sleep-thread-or-process-in-android) – Andre Albert Jun 12 '18 at 08:25
  • Isn't it better to create handler/task then to block whole UI? – Jure Jun 12 '18 at 08:30

3 Answers3

2

You could put computer logic inside handler or timer task: How to call a method after a delay in Android

but you also need some flag, that will block user placing X while you are waiting for computer to make it move.

Jure
  • 799
  • 6
  • 25
  • ok that seems to make sense. The flag, I am just wondering how to set the true or false. I'm guessing let's call the variable playerCanMove = true. When it's computerMove which is in handler, set playerCanMove = false and then after the the code where ...setText('O'), change the playerCanMove = true. Is that the correct ball park? If not can you place a little example please on the flagging – Big Hendo Jun 12 '18 at 08:37
  • but then saying that I have 'isPlayerMove' already as a lfag so I wonder if I can just use that instead but just wondering how to block the player making a move – Big Hendo Jun 12 '18 at 08:38
  • You already have if(playerOneMove) if you check there if player is allowed to move, then you don't need no additional checks. – Jure Jun 12 '18 at 08:51
  • Yeah thought so, sorry I was over thinking it. Thanks – Big Hendo Jun 12 '18 at 08:57
2

i edited your onclick with the delay and i think you gonna need some sort of the flag wich blocks user until computer makes the move !

 @Override
public void onClick(View v) {

    if (!((Button) v).getText().toString().equals("")) {
        return;
    }

    if (playerOneMove) {
        ((Button) v).setText("X");
        ((Button) v).setTextColor(playerX);

          //2000 is your delay in mills format
        v.postDelayed(new Runnable() {
            @Override
            public void run() {
                computerMove();
            }
        },2000)

    }
}

and i think it would be good idea to use some random number between 1sec to 3sec for delay and not the constant delay it creates better experience for user

Amir Hossein Mirzaei
  • 2,325
  • 1
  • 9
  • 17
  • Thanks Amir, I want to know if you can place an example of the flagging so I can work out what I need to do in terms of implementing the flagging? – Big Hendo Jun 12 '18 at 08:43
  • @BigHendo you can have a Boolean variable and when there is computer turn you set that variable to true and when computer makes the move you set that variable to false and in user OnClick you should check this variable and if it was false than user can make a move – Amir Hossein Mirzaei Jun 12 '18 at 09:17
1

You can check out the Handler and Runnable class in android. You can delayed the time of a method as required.

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);