java - 井字游戏按钮按下创建 AND 键调度超时

标签 java android button onclick

我最近制作了一款单人井字游戏,我正在使用一个简单的 AI 来随机放置 Os.当我按下的最后一个按钮应该使游戏平局但游戏卡住并停止响应时,我收到 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 - 井字游戏按钮按下创建 AND 键调度超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17369606/

相关文章:

java - 如何在 spring mqtt 集成中停止重复订阅收到的保留消息

android - 在 Eclipse/Android 中转义 XML 中的尖括号

vba - 调用包含特定宏的每个按钮

ios - uitableview重置删除按钮

java - OpenGL:带有显示列表的 Material ?

java - 在 Groovy 中打开本地文件

android - 如何在 Android 中创建动态壁纸?

android - 按钮(有时)不绘制 StateList xml 背景

java - 如何在Spark框架中获取所有暴露的路由

java - 抽屉项目名称显示为 0