递归运行真的很慢 - AsyncTask

时间:2014-08-10 16:55:29

标签: java android recursion android-asynctask ram

我试图制作TicTacToe游戏,计算机试图赢得而不是失败 - 它部分有效,但代码在Android上运行速度非常慢,但在计算机上运行良好。

计算机的决定是在AsynTask中完成的,而doInBackground则是一种UI方法。

我一直在:

D/dalvikvm(14142): GC_CONCURRENT freed 1924K, 15% free 26534K/30996K, paused 2ms+11ms, total 136ms

D/dalvikvm(14142): GC_FOR_ALLOC freed 1711K, 12% free 24208K/27304K, paused 106ms, total 106ms

以下代码或此处:https://www.dropbox.com/s/xf6dd2mlkqw2rmr/OnePlayer.java

    public class ComputerTurn extends AsyncTask<Void, Integer, Void> {
    ProgressDialog progressDialog;

    public Context activity;

    public ComputerTurn(Context a)
    {
        this.activity = a;
    }

    @Override
    protected void onPreExecute(){
        //progressDialog = ProgressDialog.show(OnePlayer.this, "Progress Dialog Title Text","Process Description Text", true);
    };      
    long interval =0;
    @Override
    protected Void doInBackground(Void... params){
        Date interestingDate = new Date();
        ((OnePlayer) activity).ComputerPromptInputandSet(current_player);
        interval = (new Date()).getTime() - interestingDate.getTime();
        System.out.println("Time: " +interval);
        return null;
    }       

    @Override
    protected void onPostExecute(Void result){
        super.onPostExecute(result);
        AlertDialog.Builder builder = new AlertDialog.Builder(OnePlayer.this);
        builder.setMessage("Time: " +interval)
            .setCancelable(false)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    //  do things

                }
            });
        AlertDialog alert = builder.create();
        alert.show();
        //progressDialog.dismiss();
    }
 }

ComputerPromptInputandSet:

void ComputerPromptInputandSet(int current_player) {
    //task.doProgress(1);
    depth = 0;
    System.out.println("Computer turn");
    bestMoves = new ArrayList<String>();
    drawMoves = new ArrayList<String>();

    for(int i=0; i <3; i++){
        for(int j =0; j <3; j++){
                if(board[i][j].equalsIgnoreCase("-") 
                  && !board[i][j].equalsIgnoreCase("O") 
                  && !board[i][j].equalsIgnoreCase("X")){
                    CompNode currentNode = null;
                    String [][] temp = board;
                    depth = 0;
                    System.out.println("Calling AI");
                    AI(i, j, currentNode, temp, 0);
                    board[i][j]="-";
                    //print(board);
                    //System.exit(0);
             }
        }
    }
    System.out.println("depth of win: " + bestwin_depth);
    System.out.println("depth of draw: " + bestdraw_depth);
    System.out.println("depth of lose: " + bestlose_depth);

    System.out.println("bestwin: " + bestwin);
    System.out.println("bestdraw: " + bestdraw);
    System.out.println("bestlose: " + bestlose);
    WINNER_FOUND = false;
    game_winner = false;
    is_draw = false;

}

AI:

void AI(int i, int j, CompNode cNode, String [][] fake, int depth){
    //task.doProgress(1);
    depth++;
    //System.out.println("In AI");
    //System.out.println("Depth: "+ depth);
    fake[i][j] =  getLetter(current_player); 
    //print(fake);
    boolean winner = CheckWinner(1, fake);
    if(winner){
        //System.out.println("Winner move found");
        //print(fake);
        //cNode.value= 1000;
        if(bestwin_depth >= depth){
            bestwin_depth = depth;
            bestwin = i+"/"+j;
        }
        bestMoves.add(i+"/"+j);
        WINNER_FOUND = false;
        game_winner = false;
        is_draw = false;
        return;
    }
    if(is_draw == true){
        //System.out.println("Draw found or no more space");
        drawMoves.add(i+"/"+j);
        WINNER_FOUND = false;
        game_winner = false;
        is_draw = false;
        return;
    }

    /*  check if game over on move
        if over 
            return
        if not over for comp

    */ 
    ArrayList<String> indexes = getLegalMoves(fake);
    //System.out.println("Legal Moves: "+ indexes.size());
    if(indexes.size() ==0){
        //System.out.println("Draw found or no more space");
        if(bestdraw_depth >= depth){
            bestdraw_depth = depth;
            bestdraw = i+"/"+j;
        }   
        drawMoves.add(i+"/"+j);
        return;
    }
    //permute (indexes, 0, i, j, cNode, fake);
    cNode = new CompNode(indexes.size(), i , j);

    Iterator sets = indexes.iterator();
    PlayerNode [] possibleMove = cNode.children;
    int k =0;


    while (sets.hasNext() ) {
        String index = (String) sets.next();

        String [] index_ =  index.split("/");
        int x = Integer.parseInt(index_[0]);
        int y = Integer.parseInt(index_[1]);

        //System.out.println("( "+x + ", " +y + " )");
        possibleMove[k] = new PlayerNode(indexes.size()-1, x, y);
        String [][]temp = fake;
        playerMove(x, y , possibleMove[k], temp, depth);
        //depth--;

        fake[x][y] = "-";
        k++;
    }
    //System.exit(0);
}

playerMove:

void playerMove(int i, int j, PlayerNode pNode, String [][]fake, int depth){
    //task.doProgress(1);
    depth++;
    //System.out.println("In playMove");
    //System.out.println("Player move: ");
    //System.out.println("Depth: "+ depth);
    fake[i][j] =  getOtherLetter(current_player); 
    //print(fake);

    boolean winner = CheckWinner(0, fake);
    pNode = new PlayerNode(0, 0, 0);
    if(winner){
        //System.out.println("Player winning move");
        if(bestlose_depth >= depth){
            bestlose_depth = depth;
            bestlose = i+"/"+j;
        } 
       // pNode.value= -1000;
        WINNER_FOUND = false;
        game_winner = false;
        is_draw = false;
        return;
    }
    if(is_draw == true){
        //System.out.println("Draw found or no more space");
        drawMoves.add(i+"/"+j);
        WINNER_FOUND = false;
        game_winner = false;
        is_draw = false;
        return;
    }

    ArrayList<String> indexes = getLegalMoves(fake);
    //System.out.println("Legal Moves: "+ indexes.size());
    if(indexes.size() ==0){
        //System.out.println("Draw found or no more space");
        if(bestdraw_depth >= depth){
            bestdraw_depth = depth;
            bestdraw = i+"/"+j;
        } 

        drawMoves.add(i+"/"+j);
        return;
    }
    //permutePlayer (indexes, 0, i, j, pNode, fake);
    pNode = new PlayerNode(indexes.size(), i , j);

    Iterator sets = indexes.iterator();
    CompNode [] possibleMove = pNode.children;
    int k =0;


    while (sets.hasNext() ) {
        String index = (String) sets.next();

        String [] index_ =  index.split("/");
        int x = Integer.parseInt(index_[0]);
        int y = Integer.parseInt(index_[1]);

        //System.out.println("( "+x + ", " +y + " )");
        possibleMove[k] = new CompNode(indexes.size()-1, x, y);
        String [][] temp = fake;
        AI(x, y , possibleMove[k], temp, depth);
        //depth--;
        fake[x][y] = "-";
        k++;
    }
    //System.exit(0);
}

PlayerNode Class

class PlayerNode {
    CompNode [] children;

    PlayerNode(int num, int i , int j){
    this.children = new CompNode[num];
    }
}

CompNode类:

class CompNode {
    PlayerNode [] children;

    CompNode(int num, int i, int j){
        this.children = new PlayerNode[num];
    }
}

ComputerPromptInputandSet需要52秒才能在我的手机上运行,​​2分钟在模拟器上运行,34秒在另一部手机上运行。

这是统计数据截图:

enter image description here

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

我是否更正确说您的电脑比手机快约500倍?这可能是正常的,可能是因为有限的移动内存会更频繁地调用垃圾收集器。

一般优化应解决问题。

代码非常复杂,我并没有真正理解它,但是如果getLegalMoves方法做了我认为你应该能够通过消除已经有玩家交叉的动作返回较少可能的动作来极大地优化它相同的x和y轴以及对角线。