我最近制作了一个单人打井字游戏,并且使用的是随机放置OS的简易AI。当我按下的最后一个按钮应使游戏平局,但游戏冻结并停止响应时,我会收到ANR。

这些是我的ANR错误:

06-28 16:01:25.894: E/ActivityManager(63): ANR in g.icstictactoe (g.icstictactoe/.OnePlayer)
06-28 16:01:25.894: E/ActivityManager(63): Reason: keyDispatchingTimedOut
06-28 16:01:25.894: E/ActivityManager(63): Load: 0.81 / 0.33 / 0.25
06-28 16:01:25.894: E/ActivityManager(63): CPU usage from 19103ms to 0ms ago:
06-28 16:01:25.894: E/ActivityManager(63):   98% 677/g.icstictactoe: 98% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63):   0.1% 63/system_server: 0% user + 0.1% kernel / faults: 5 minor
06-28 16:01:25.894: E/ActivityManager(63):   0% 41/adbd: 0% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63): 100% TOTAL: 99% user + 0.1% kernel
06-28 16:01:25.894: E/ActivityManager(63): CPU usage from 1156ms to 1716ms later:
06-28 16:01:25.894: E/ActivityManager(63):   91% 677/g.icstictactoe: 91% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63):     89% 677/g.icstictactoe: 89% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63):   8.9% 63/system_server: 7.1% user + 1.7% kernel
06-28 16:01:25.894: E/ActivityManager(63):     7.1% 93/InputDispatcher: 5.3% user + 1.7% kernel
06-28 16:01:25.894: E/ActivityManager(63): 100% TOTAL: 98% user + 1.7% kernel
06-28 16:01:25.914: I/InputDispatcher(63): Dropping event because the pointer is not down.
06-28 16:01:48.365: W/ActivityManager(63):   Force finishing activity g.icstictactoe/.OnePlayer
06-28 16:01:48.395: I/ActivityManager(63): Killing g.icstictactoe (pid=677): user's request
06-28 16:01:48.395: I/Process(63): Sending signal. PID: 677 SIG: 9
06-28 16:01:48.465: I/ActivityManager(63): Process g.icstictactoe (pid 677) has died.


这是我的代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tictactoe);
    count = 0;
    gameOver = false;
    ticTacToe = new Button[3][3];
    ticTacToe[0][0] = (Button) findViewById(R.id.top_left);
    ticTacToe[0][1] = (Button) findViewById(R.id.top);
    ticTacToe[0][2] = (Button) findViewById(R.id.top_right);
    ticTacToe[1][0] = (Button) findViewById(R.id.left);
    ticTacToe[1][1] = (Button) findViewById(R.id.center);
    ticTacToe[1][2] = (Button) findViewById(R.id.right);
    ticTacToe[2][0] = (Button) findViewById(R.id.bottom_left);
    ticTacToe[2][1] = (Button) findViewById(R.id.bottom);
    ticTacToe[2][2] = (Button) findViewById(R.id.bottom_right);
    result = (TextView) findViewById(R.id.result);
    playagain = (Button) findViewById(R.id.playagain);
    for (int i = 0; i < ticTacToe.length; i++)
        for (int j = 0; j < ticTacToe[0].length; j++)
            ticTacToe[i][j].setOnClickListener(this);
    playagain.setOnClickListener(this);
    result.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.top_left: findAnswer(0, 0);
        break;
    case R.id.top: findAnswer(0, 1);
        break;
    case R.id.top_right: findAnswer(0, 2);
        break;
    case R.id.left: findAnswer(1, 0);
        break;
    case R.id.center: findAnswer(1, 1);
        break;
    case R.id.right: findAnswer(1, 2);
        break;
    case R.id.bottom_left: findAnswer(2, 0);
        break;
    case R.id.bottom: findAnswer(2, 1);
        break;
    case R.id.bottom_right: findAnswer(2, 2);
        break;
    case R.id.playagain: playagain();
        break;
    }
}

public void findAnswer(int row, int col) {
    String level = "EASY";
    if(level.equals(EASY))
        easyAnswer(row, col);
}

public void easyAnswer(int row, int col)
{
    ticTacToe[row][col].setText("X");
    ticTacToe[row][col].setClickable(false);
    if (!winOrDraw()) { // If X did not win
        int rowO = (int) (Math.random() * 3);
        int colO = (int) (Math.random() * 3);
        while (!ticTacToe[rowO][colO].isClickable())
        {
            rowO = (int) (Math.random() * 3);
            colO = (int) (Math.random() * 3);
        }
        ticTacToe[rowO][colO].setText("O");
        ticTacToe[rowO][colO].setClickable(false);
    }
    if(!gameOver)
        winOrDraw();
}

public boolean winOrDraw()
{
    if (checkGame("X")) {
        gameOver = true;
        result.setText("Game Over! X Wins!");
        disableGame();
    } else {
        if (checkGame("O")) {
            gameOver = true;
            result.setText("Game Over! O Wins!");
            disableGame();
        }
    }
    count++;
    if (count == 10 && !gameOver)
    {
        result.setText("This game is a draw!");
        gameOver = true;
    }
    return gameOver;
}

public boolean checkGame(String player) {
    // Horizontal
    if (ticTacToe[0][0].getText().equals(ticTacToe[0][1].getText())
            && ticTacToe[0][0].getText().equals(ticTacToe[0][2].getText())
            && ticTacToe[0][0].getText().equals(player))
        return true;
    else if (ticTacToe[1][0].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[1][0].getText().equals(ticTacToe[1][2].getText())
            && ticTacToe[1][0].getText().equals(player))
        return true;
    else if (ticTacToe[2][0].getText().equals(ticTacToe[2][1].getText())
            && ticTacToe[2][0].getText().equals(ticTacToe[2][2].getText())
            && ticTacToe[2][0].getText().equals(player))
        return true;
    // Vertical
    else if (ticTacToe[0][0].getText().equals(ticTacToe[1][0].getText())
            && ticTacToe[0][0].getText().equals(ticTacToe[2][0].getText())
            && ticTacToe[0][0].getText().equals(player))
        return true;
    else if (ticTacToe[0][1].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[0][1].getText().equals(ticTacToe[2][1].getText())
            && ticTacToe[0][1].getText().equals(player))
        return true;
    else if (ticTacToe[0][2].getText().equals(ticTacToe[1][2].getText())
            && ticTacToe[0][2].getText().equals(ticTacToe[2][2].getText())
            && ticTacToe[0][2].getText().equals(player))
        return true;
    // Diagonal
    else if (ticTacToe[0][0].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[0][0].getText().equals(ticTacToe[2][2].getText())
            && ticTacToe[0][0].getText().equals(player))
        return true;
    else if (ticTacToe[0][2].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[0][2].getText().equals(ticTacToe[2][0].getText())
            && ticTacToe[0][2].getText().equals(player))
        return true;
    else {
        result.setText("The game continues...");
        return false;
    }
}
public void playagain() {
    for (int i = 0; i < ticTacToe.length; i++)
        for (int j = 0; j < ticTacToe[0].length; j++) {
            ticTacToe[i][j].setClickable(true);
            ticTacToe[i][j].setText("");
        }
    result.setText("Click a button to start game");
    count = 0;
    gameOver = false;
}
public void disableGame() {
    for (int i = 0; i < ticTacToe.length; i++)
        for (int j = 0; j < ticTacToe[0].length; j++)
            ticTacToe[i][j].setClickable(false);
}
}


任何帮助将不胜感激。

最佳答案

看起来您的winOrDraw检查不能按预期方式工作,它不会检测到绘制条件,并且您的应用程序陷入了while循环中,该循环随机选择一个空格并检查是否为空。当游戏以平局结束时,没有空白(可单击)空间,因此while循环是一个无限循环并阻塞了主线程,因此阻塞了ANR。

我敢打赌,您的错误是在没有获胜者的情况下检查是否count == 10来宣布平局,应该为9,不是吗?

关于java - Tic Tac Toe按钮按下创建AND键分派(dispatch)超时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17369606/

10-10 03:24