Martin
Martin

Reputation: 4836

Android thread intermittently stops?

I am writing a game for Android. One style of the game is for the user to play against the machine. In each iteration of play, the user or machine much place a tile on the board that satisfies the game rules. When it is the machine's turn, I use a simple first-fit algorithm when placing the tile. I loop through the available tiles, I loop through the rows and columns of the board and I loop through a series of 3 rotations of each tile until I find a spot. It can be a lengthy operation so I'm using threads to spin off that work. About two-thirds of the time, it works flawlessly. However, sometimes it intermittently stops searching after just a tile or two with no error messages. Since I set the 'found' flag to false before the search, the thread comes back as not having found anything and it just goes along. There were, however available spots to place a tile had it continued through without being interrrupted.

My code to initiate the thread as well as the search loop are below.

-Does anyone see anything suspicious in the code? -Anything I could do to track down why the thread stops looping before its finished and before finding a spot? I can watch the Log.d spew out the col/row and rotation along with the vertices of each tile and it just quits, sometimes after only one or two columns sometimes it goes all the way through the data.

start threads and wait for result

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();

    }
}

do the actual searching

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;

}

Upvotes: 2

Views: 273

Answers (2)

Martin
Martin

Reputation: 4836

I fixed this a while ago. Had nothing to do with using Async or threads, despite people's opinions. It was simply a case of my multi-threaded code overwriting a variable. Another part of my code check boundaries - zeroing them out first. My search code was using those boundaries. I just hadn't realized they are getting updated in the middle of the search and that was difficult to find.

Upvotes: 1

Rohit Sharma
Rohit Sharma

Reputation: 13815

Try Using Thread directly instead of AsyncTask. It should work then.

Upvotes: 0

Related Questions