我正在为Android编写游戏。游戏的一种风格是用户与机器对战。在每次游戏迭代中,用户或机器很多地在棋盘上放置满足游戏规则的牌。当轮到机器时,我会在放置瓷砖时使用简单的先拟合算法。我循环通过可用的瓷砖,我循环通过电路板的行和列,我循环通过每个瓷砖的一系列3个旋转,直到我找到一个点。这可能是一个漫长的操作,所以我使用线程来分拆这项工作。大约三分之二的时间,它完美无缺。但是,有时它会间歇性地停止搜索 在一两个瓦片之后没有错误消息。由于我在搜索之前将'found'标志设置为false,因此线程返回时没有找到任何内容,它只是顺其自然。然而,如果有瓷砖继续通过而没有被中断,则有可能放置瓷砖。
我的代码启动线程以及搜索循环如下。
- 有人在代码中看到任何可疑的东西吗? - 我能做些什么来追踪线程在完成之前和找到一个点之前停止循环的原因?我可以看到Log.d喷出col / row和旋转以及每个tile的顶点,它只是退出,有时只有一两列后,它有时会一直遍历数据。
private void playDeviceTile() {
if (mDbHelper.isPlayingDevice(game_id)) {
// make sure I'm seeing all played tiles
refreshPlayedTiles();
final Boolean found;
final ProgressDialog dialog = new ProgressDialog(mcontext);
dialog.setMessage("Android is thinking...");
dialog.show();
new AsyncTask<Void,Void, Boolean>(){
@Override
protected void onPostExecute(Boolean isFound) {
if (!isFound) {
passPlay(1); // never found a tile to play. We have to pass
}
else {
playTile(currentTile,1);
}
dialog.dismiss();
postInvalidate();
invalidate();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
return doSearchforSpot();
} catch (Exception e) {
Log.e("DRAW", "Exception find spot for device tile", e);
}
return null;
}
}.execute();
}
}
private Boolean doSearchforSpot(){
Boolean found = false;
tileClass tile;
int tileNum;
BoardClass spot;
int rot;
int maxrot;
int score = -1;
int i = 0;
// totally brain-less, brute-force, 1st fit. Loop through
// all open spots on the board, and check each tile in each rotation
// and return the first time a valid placement and score occurs.
while ((i < deviceHandNumber) && (!found)) {
tileNum = deviceHand[i];
tile = tiles.get(tileNum);
int row = TileExtents[TOP];
int col = TileExtents[LEFT];
while ((row <= TileExtents[BOTTOM]) && (!found)) {
while ((col <= TileExtents[RIGHT]) && (!found)) {
spot = board.get(ColRowGrid[col][row]);
if (!spot.occupied) {
if (spot.facedown) {
rot = 3;
maxrot = 6;
}
else {
rot = 0;
maxrot = 3;
}
while ((rot < maxrot) && (!found)) {
// set the rotation and check for a score
tile.setRotate(rot);
Log.d("WTF","CRT "+col+" "+row+" "+rot+" "+tile.getScore(0)+" "+tile.getScore(1)+" "+tile.getScore(2));
score = placeTileOnBoard(spot.index, tileNum);
if (score >= 0) {
// hey! we found a spot. Play it.
turnScore = score;
currentTile = tileNum;
found = true;
}
rot++;
}
}
col++;
}
row++;
col=TileExtents[LEFT];
}
i++;
}
return found;
}
答案 0 :(得分:1)
我刚刚修好了。尽管有人的意见,但与使用异步或线程没有任何关系。这只是我的多线程代码覆盖变量的一种情况。我的代码的另一部分检查边界 - 首先将它们归零。我的搜索代码使用了这些边界。我只是没有意识到他们在搜索过程中得到了更新,而且很难找到。
答案 1 :(得分:0)
直接尝试使用Thread而不是AsyncTask。 它应该工作。