2015-11-21 88 views
4

所以我創建了一個迷宮應用程序(我從字符串數組讀取了迷宮,之後觸摸事件指導了一個球槽)。管理到目前爲止創建的一切,該應用程序工作正常。但我想包括一個選項來自動解決它。自動迷宮解決方案

我用在這裏發現了這個遞歸算法:https://en.wikipedia.org/wiki/Maze_solving_algorithm

基本上,我得到一個布爾多維數組(具有迷宮的大小)的路徑。

試圖實現類似設計的MWC,所以我有以下類:

LabyrinthView - 處理相關的一切繪製迷宮,並提請球 LabyrinthModel - 初始化迷宮,處理球的運動,也是我這裏檢查迷宮結束了,這裏 LabyrinthActivity實施recursiveSolve - 這是我帶來的一切融合在一起

就像我說的,到目前爲止解決迷宮手動就像一個魅力。 不知道如何動畫自動解決方案。 所以讓我給你一個迷宮例如:

<string-array name="labyrinthEasy"> 
    <item>0000000001</item> 
    <item>0111110110</item> 
    <item>0100000110</item> 
    <item>0101111000</item> 
    <item>0101000010</item> 
    <item>0101011010</item> 
    <item>0101011110</item> 
    <item>0101000010</item> 
    <item>0101111010</item> 
    <item>0100000010</item> 
    <item>0111111110</item> 
    <item>1000000000</item> 
</string-array> 

它會是這個樣子(E-項,F-顏色):

enter image description here

而且該解決方案:

enter image description here

這是我到目前爲止得到的結果:

private void selectControlMode() { 
    final CharSequence[] items = {"Human","Machine"}; 
    final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); 
    alertDialog.setItems(items, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      switch (which) { 
       case 0: 
        dialog.dismiss(); 
        break; 
       case 1: 
        dialog.dismiss(); 
        boolean temp; 
        temp = labyrinthModel.solveMaze(); 
        if(temp){ 
         new MazeSolver().execute(); 
        }else{ 
         AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext()); 
         builder.setMessage("The maze is unsolvable!"); 
         builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, int which) { 
           switch (which) { 
            case 0: 
             dialog.dismiss(); 
             Intent intent1 = new Intent(LabyrinthActivity.this, MainActivity.class); 
             intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
             startActivity(intent1); 
             break; 
           } 
          } 
         }); 
         AlertDialog alert = builder.create(); 
         alert.show(); 
        } 
        break; 
      } 
     } 
    }); 

} 

基本上我選擇人機對話的機器解決方案。如果選擇人類處理對話框和無(應用程序繼續並等待手動解決方案)。如果選擇了機器,我會得到路徑,如果可以解決的話,我想我應該在這裏啓動一個新的Thread,在這裏我可以爲自動解決方案設置動畫,否則如果無法解決,我會返回到應用程序的主菜單。現在這裏開始我的問題,因爲我不知道如何在我的AsyncTask類中實現這個。

我在doInBackgroung方法中執行邏輯,但無法弄清楚如何遵循正確的路徑。因爲如果我一行一行地遍歷數組,球就會從一行跳到另一行,並且不會遵循路徑的流動性。 另外我想我應該在每次迭代之後使用onProgressUpdate方法重繪我的進度。

這是我的手動邏輯是如何工作的(移動和繪圖):

labyrinthView.setOnTouchListener(new View.OnTouchListener() { 
     float x1 = 0, x2 = 0, y1 = 0, y2 = 0; 
     float dx, dy; 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      float MIN_DIST = 5; 
      switch (event.getAction()){ 
       case (MotionEvent.ACTION_DOWN): 
        x1 = event.getX(); 
        y1 = event.getY(); 
        break; 
       case (MotionEvent.ACTION_UP): 
        x2 = event.getX(); 
        y2 = event.getY(); 
        dx = x2-x1; 
        dy = y2-y1; 
        Log.v("log", dx + " " + dy); 
        if(Math.abs(dx) > MIN_DIST || Math.abs(dy) > MIN_DIST){ 
         if (Math.abs(dx) > Math.abs(dy)){ 
          if(dx > 0) { 
           labyrinthModel.right(); 
           finishMessage(); 
          } 
          else { 
           labyrinthModel.left(); 
           finishMessage(); 
          } 
         }else{ 
          if(dy > 0) { 
           labyrinthModel.down(); 
           finishMessage(); 
          } 
          else { 
           labyrinthModel.up(); 
           finishMessage(); 
          } 
         } 
        } 
        break; 
      } 
      labyrinthView.invalidate(); 
      return true; 
     } 


    }); 

而這正是我在assync任務迄今所做的:

private class MazeSolver extends AsyncTask<Void,Void,Void>{ 
    @Override 
    protected Void doInBackground(Void... params) { 
     for (int row = 0; row < labyrinthModel.correctPath.length; row ++) 
      for (int col = 0; col < labyrinthModel.correctPath[0].length; col++){ 
       if(labyrinthModel.correctPath[row][col + 1]){ 
        labyrinthModel.moveRight(); 
       } 
//here to do the implementaion of the path following logic??? 

      } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Void... values) { 
// here to redraw the progress ???? 
     super.onProgressUpdate(values); 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
    } 
} 

如果你能指點在正確的方向,我將非常感激。

回答

3

既然你被允許改寫了路徑信號二維數組,你只需要按照根從開始到結束:

travel(correctPath, 0, 0, 11, 8); 

void travel(bool a[][], int row, int col, int finalRow, int finalCol) { 
    // if we are already there stop 
    if(finalRow == row && col == finalCol) return; 

    // avoid comming back 
    a[row][col]=false; 

    // if the input is correct only on of this moves will be valid 
    // try each of them and see which move we can make 
    if(col - 1 >= 0 && a[row][col-1]) { left(); travel(a, row, col-1, finalRow, finalCol)}; 
    if(col + 1 < 8 && a[row][col+1]) { right(); travel(a, row,col+1, finalRow, finalCol)}; 
    if(row - 1 >= 0 && a[row-1][col]) { up(); travel(a, row-1, col, finalRow, finalCol)}; 
    if(row + 1 < 11 && a[row+1][col]) { down(); travel(a, row+1,col, finalRow, finalCol)}; 
}