我最近做了一个玩家tic tac toe游戏,我正在使用随机放置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);
}
}
非常感谢任何帮助。
答案 0 :(得分:2)
看起来你的winOrDraw检查没有按预期工作,它不会检测到绘制条件,你的应用程序卡在while循环中,随机选择一个空格并检查它是否为空。当游戏以绘制结束时,没有空(可点击)空格,因此while循环是一个无限循环并阻塞主线程,因此ANR。
我敢打赌你的错误是在没有获胜者的情况下检查是否计数== 10来宣布平局,应该是9,不应该是?