2014-11-02 53 views
0

對不起,第一個問題,我是全新的......我對代碼進行了清理。問題是: 我有一個方形網格,包含路徑和障礙物。我想找到從一個點到另一個點的最短路徑。這是人工智能的一部分。當路徑太大時,我看不到bash上的所有點,但是在遊戲中,這個路徑上的角色不是最短路徑。所以,我的問題是,我如何改變這個代碼來解決最短路徑。非常感謝!使用序言的網格中的最短路徑

mov(X1,Y1,X2,Y2):- 
    pos(X1,Y1), X2 is X1 , Y2 is Y1+1 ,pos(X2,Y2). 
mov(X1,Y1,X2,Y2):- 
    pos(X1,Y1), X2 is X1 , Y2 is Y1-1 ,pos(X2,Y2). 
mov(X1,Y1,X2,Y2):- 
    pos(X1,Y1), X2 is X1+1 , Y2 is Y1 , pos(X2,Y2). 
mov(X1,Y1,X2,Y2):- 
    pos(X1,Y1), X2 is X1 -1 , Y2 is Y1 , pos(X2,Y2). 

path(X1,Y1,X2,Y2,Path) :- 
    travel(pos(X1,Y1),pos(X2,Y2),[pos(X1,Y1)],Q), 
    reverse(Q,Path). 

travel(pos(X1,Y1),pos(X2,Y2),P,[pos(X2,Y2)|P]) :- 
    mov(X1,Y1,X2,Y2). 
travel(pos(X1,Y1),pos(X2,Y2),Visited,Path) :- 
    mov(X1,Y1,X,Y), 
    pos(X,Y) \== pos(X2,Y2), 
    \+member(pos(X,Y),Visited), 
    travel(pos(X,Y),pos(X2,Y2),[pos(X,Y)|Visited],Path). 
+1

如果您認爲您不想調試那些混亂,請想象我們的感受。 – 2014-11-02 05:30:29

+0

你需要進一步解釋。你輸入了什麼?你期望什麼反應?出現什麼錯誤信息(如果有)? – lurker 2014-11-02 12:14:09

+0

在'mov/4'中,你可以刪除所有'pos/2'的目標,因爲在所有其他部分中,pos/2只是作爲函數而不是謂詞。 – false 2014-11-02 13:57:56

回答

1

首先是一些Prolog的建議。

  1. member/2是一個內置的,你不應該定義它。
  2. ISO否定爲\+,而不是not/1
  3. 對於表演,memberchk/2節拍member/2
  4. 我在你的代碼中看到了很多foo(X,Y) :- X == Y, ...。如果你只是說foo(X,X)並且爲自己省去做這樣的顯式測試的麻煩,除非你打算做一個條件表達式來避免選擇點或其他東西,這會更好。
  5. 此代碼中有大量的削減。削減和錯誤往往是很好的朋友,因爲削減可以通過阻止它被執行來破壞合理的代碼。

如果我必須解決這個問題,我想分開最短路徑的邏輯從網格遍歷邏輯。你永遠無法調試,即使你這樣做了,你將會得到的是那些無法修改的不可讀代碼塊之一。很顯然,由於您將遍歷邏輯嵌入到路徑查找邏輯中,因此存在大量術語。把它們分成兩個單獨的步驟,你可能會發現你可以進行更有意義的測試和調試。無論語言如何,這都是一種很好的編程方式:如果您需要更改網格結構或使尋路更智能或更復雜,您會做什麼?保持碎片總是有助於管理變化。

至於S.O.禮儀,這不是很好:你應該談論什麼不行,你試過什麼,你想提供一個minimum, complete, verifiable example。我懷疑製作這樣的東西你可能會自己解決問題。

+0

謝謝丹尼爾,我會嘗試提供更好的代碼。 – marciomolusco 2014-11-02 13:00:33