2015-04-03 43 views
1

所以我得到了這樣的問題:我想從一個黑點移動到另一個像這樣:如何使某物在矩陣中以特定順序移動?

enter image description here

,但每當我試圖做到這一點,它的動作是這樣的:

enter image description here

您只能在一個方向移動:北,南,東,西一次。 我試圖做這樣的事情:

 int distance = game.Distance(myPirate.Loc,loc); 
     List<Direction> allDirections = new List<Direction>() { Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, Direction.NOTHING }; 
     Location destination; 
     foreach (Direction dir in allDirections) 
     { 
      destination = game.Destination(myPirate, dir); 
      int distance2 = game.Distance(destination, loc); 
      if (distance2 < distance) return dir; 
     } 
     return Direction.NOTHING; 

但每當我試試這個代碼,我得到這些結果:

enter image description here

誰能幫我弄清楚如何像第一畫面移動和不喜歡第二個?你得到矩陣中2個黑方塊的位置。 如果您還需要更多,請告訴我。

+1

像直線(歐幾里德)距離作爲啓發式函數的A *搜索可能會應用? – 2015-04-03 22:58:31

+1

@ap或者如果您看另一種方式[DDA線條繪圖](http://en.wikipedia.org/wiki/Digital_differential_analyzer_%28graphics_algorithm%29)或其他線條繪製算法。 – 2015-04-03 23:16:17

+0

我不明白如何使用它,線繪圖算法怎麼可以幫助我呢? :( – 2015-04-04 06:11:25

回答

0

嘗試用隨機的目錄「(在allDirections方向Dir)」,以使它可以檢查不同的方向順序每一次,去的曲折方式..

因爲它總是在同一方向順序檢查北>南>西>東>沒有任何東西在直線上。

+0

我不能那樣做,不能轉換方向int – 2015-04-04 05:53:06

1

由於@ap和@AlexeiLevenkov在他們的評論中已經提到,您可以使用任何線條繪製算法來解決您的任務。

將您的矩陣看作像素字段(屏幕)。你想以最短的方式從起點移動到終點,這當然是一條直線(我確信你可以從幾何學課程中記住這一點)。所以你必須在柵格像素字段上的兩點之間「繪製」一條直線。這正是這些繪圖算法的要點。

讓我們使用簡單的DDA。

首先,你要確定你的路徑線斜率:

double slope = (endPoint.Y - startPoint.Y)/(double)(endPoint.X - startPoint.X); 

那麼你應該看看斜率絕對值是否小於或大於1。這是根據算法。如果它小於或等於1,那麼我們將在每個步驟的水平方向上移動(所以我們「採樣」dX = 1)。在另一種情況下,我們將沿垂直方向移動(「採樣」爲dY = 1)。

我們必須準備我們的「行」:我們計算DXDY偏移根據坡度。對於案例dX == 1,我們將在每次移動中向左或向右移動,並且另外使用dY值計算下一個垂直「跳躍」。如果我們確定我們應該向上或向下移動,那麼我們通常會另外做到這一點。但是由於每次迭代只允許一次移動,我們將需要跳過水平移動並改爲垂直移動。

在下一個示例代碼中,我將省略dY == 1的情況。你一定可以自己寫。此外,這段代碼並不是那麼簡潔,但爲了簡單起見,我就這樣離開它。您可以優化並重構它。

private double dX, dY; 
private double currentX, currentY; 

void PrepareMoving(Point startPoint, Point endPoint) 
{ 
    double slope = (endPoint.Y - startPoint.Y)/(double)(endPoint.X - startPoint.X); 
    if (Math.Abs(slope) <= 1.0) 
    { 
     this.dX = Math.Sign(endPoint.X - startPoint.X); 
     this.dY = slope; 
    } 
    else 
    { 
     this.dY = Math.Sign(endPoint.Y - startPoint.Y); 
     this.dX = slope; 
    } 

    this.currentX = startPoint.X; 
    this.currentY = startPoint.Y; 
} 

Direction DoNextMove(Point target) 
{ 
    // If we already have reached the destination... 
    if (new Point((int)this.currentX, (int)this.currentY) == target) 
    { 
     return Direction.NOTHING; 
    } 

    // if the horizontal moving is "primary" 
    if (Math.Abs(this.dX) == 1.0) 
    {  
     double nextValue = this.currentY + this.dY; 
     try 
     { 
      // we have to move up or down if we've got a "jump" 
      if (Math.Round(nextValue) != Math.Round(this.currentY)) 
      { 
       return this.dY > 0 ? Direction.SOUTH : Direction.NORTH; 
      } 
      // otherwise, just perform the "normal" left or right move 
      else 
      { 
       this.currentX += this.dX; 
       return this.dX > 0 ? Direction.EAST : Direction.WEST; 
      } 
     } 
     finally 
     { 
      // ensure we set the current values for the next move 
      this.currentY = nextValue; 
     } 
    } 
    else 
    { 
     // You know what to do here: vertical moving is "primary" 
    }  
}