2013-06-28 67 views
0

我最近製作了一個單人遊戲tic tac toe遊戲,並且我使用了一個簡單的AI來隨機放置Os。當我按下最後一個按鈕時,我得到一個ANR應該使遊戲平局,但遊戲凍結並停止響應。Tic Tac Toe按鈕創建ANR keyDispatchedTimedOut

這些都是我的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

可能的重複:http://stackoverflow.com/questions/6978964/anr-keydispatchingtimedout –

+0

您應該使用調試器或日誌記錄來查找它掛起的位置。我的「主要嫌疑人」是'easyAnswer()'中的while(!ticTacToe [rowO] [colO] .isClickable())''' –

+0

@MichaelButscher代碼永遠不會到達該循環,因爲玩家X是導致ANR 。該按鈕在ticTacToe [row] [col] .setText(「X」);之前凍結了應用程序。發生。 – Gaurav

回答

2

看起來像你的winOrDraw檢查沒有按預期工作,它不會檢測到繪製條件,你的應用程序被卡在while循環中,隨機挑選一個空間並檢查它是否爲空。當遊戲以draw結束時沒有空的(可點擊的)空間,所以while循環是一個無限循環並阻塞主線程,因此ANR。

我敢打賭,你的錯誤是檢查如果計數== 10宣佈一個平局,當沒有贏家,它應該是9,不應該是?

+0

這是正確的!非常感謝你! – Gaurav

+0

不客氣,祝你的遊戲順利 –