2014-12-07 46 views
0

我在Prolog中做了很少的編程,並且發現目前爲止相當困難。編寫一個Prolog程序來模擬一個在網格中移動的大猩猩

我被給出了一個問題:大猩猩沿着8x8網格移動,只能向右或向上移動。它必須保持在網格內,必須在任意位置開始(8,8)。

編寫描述所有可能移動的移動謂詞。

我嘗試:

move(X,Y,X+1,Y). 
move(X,Y,X,Y+1). 

編寫使用移動謂詞來確定thte機器人shuld採取的路徑的路徑謂語。

我嘗試:

path('right'):- 
    move(X,Y,X+1,Y). 
path('up'):- 
    move(X,Y,X,Y+1). 

寫序言謂詞模型堵塞在(1,2),(4,2)和(4,1)。

到目前爲止,從我所發現的看來,我需要建立一個列表,以便給出所有可能的位置。

我寫的可能位置的列表,但不知道如何實現它:

[(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8), 
(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(2,8), 
(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),(3,7),(3,8), 
(4,1),(4,2),(4,3),(4,4),(4,5),(4,6),(4,7),(4,8), 
(5,1),(5,2),(5,3),(5,4),(5,5),(5,6),(5,7),(5,8), 
(6,1),(6,2),(6,3),(6,4),(6,5),(6,6),(6,7),(6,8), 
(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(7,7),(7,8), 
(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8)] 

這似乎是它會是一個簡單的程序,但我似乎無法把握的概念,或者至少放他們都在一起成爲一個可行的方案。

任何方向的幫助將不勝感激。

回答

1

有相當一些問題與您的代碼。讓我們一次一個地看看它。

1.可能的位置

雖然你可能位置的名單是確定的,就像我不會硬編碼。這是很容易做到的檢查,如果位置在格:

grid_position(X, Y) :- 
    X >= 1, 
    X =< 8, 
    Y >= 1, 
    Y =< 8. 

注意,這隻能用來驗證一個給定的位置。如果您希望能夠生成所有可能的頭寸,您可以使用從library(clpfd)

2.允許位置

如果如以上對被阻止的位置沒有簡單的邏輯,沒有其他的方式比自己一一列舉。

blocked(1, 2). 
blocked(4, 2). 
blocked(4, 1). 

利用這一點,我們就可以判斷哪些是我們大猩猩允許的立場:即對電網,但不阻止任何位置。

allowed_position(X, Y) :- 
    grid_position(X, Y), 
    \+blocked(X, Y). 

3.移動

這裏的主要問題是,在條款的頭寫X+1沒有做什麼,你認爲它。要評估算術表達式,您需要使用is謂詞。

此外,如果允許下一個位置,我只允許移動。由於大猩猩已經在當前位置,因此我不包括支票以查看這個位置是否實際允許。

move(X, Y, X2, Y) :- 
    X2 is X + 1, 
    allowed_position(X2, Y). 
move(X, Y, X, Y2) :- 
    Y2 is Y + 1, 
    allowed_position(X, Y2). 

4路

這是我如何解釋的要求:給定的起始位置,返回用於到達終點位置移動列表。

爲此,我們需要3個參數:X和Y位置以及輸出。這裏的輸出將是一個位置列表,而不是一系列移動,如果需要,我會留給您修改。

那麼什麼構成了我們的道路?那麼,首先你做出一個動作,然後你從下一個位置找到其餘的路徑。

path(X, Y, [(X,Y)|Ps]) :- 
    move(X, Y, X2, Y2), 
    path(X1, Y1, Ps). 

當然,我們必須確保這最終目標位置,因此對於基礎情況下,我們可以使用:

path(8, 8, (8, 8)). 

您可能還需要驗證初始位置是允許的位置,我已經遺漏了。


合併所有內容,您將得到如下所示的輸出。

?- path(5,6,L).   
L = [(5,6),(6,6),(7,6),(8,6),(8,7)|(8,8)] ? ; 
L = [(5,6),(6,6),(7,6),(7,7),(8,7)|(8,8)] ? ; 
L = [(5,6),(6,6),(7,6),(7,7),(7,8)|(8,8)] ? ; 
... 

這可能不是你正在尋找的東西,但我希望它能幫助你順利過關。

1

所以你可能想說出你在做什麼時你正在移動的地方。所以我會建議一個謂語move/3這樣的:

% move(From_Position, To_Position, Direction). 

move((X,Y),(X,Y1), up) :- 
    grid(G), 
    member((X,Y1),G), 
    Y1 is Y + 1. 
move((X,Y),(X1,Y), rigth):- 
    grid(G), 
    member((X1,Y),G), 
    X1 is X + 1. 

網格電話是有保證你會永遠留在網格。您還可以使用更智能的謂詞in_grid並避免調用member(這非常耗時)。

grid([(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8), 
(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(2,8), 
(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),(3,7),(3,8), 
(4,1),(4,2),(4,3),(4,4),(4,5),(4,6),(4,7),(4,8), 
(5,1),(5,2),(5,3),(5,4),(5,5),(5,6),(5,7),(5,8), 
(6,1),(6,2),(6,3),(6,4),(6,5),(6,6),(6,7),(6,8), 
(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(7,7),(7,8), 
(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8)]). 

的路徑可能應該是路線清單:

path((8,8), []). 
path(Position, [Direction| Before]):- 
    \+ Position = (8,8), 
    move(Position, NewPosition, Direction), 
    path(NewPosition,Before). 

積累,你可以使用bagofsetof

all_paths(Position,Paths):- 
    setof(Path,path(Position,Path),Paths). 
+3

是的,@Nonpareil將*完全*明白這一點。 – 2014-12-07 02:52:19

+0

@斯科特獵人對不起,我不小心點擊提交,我想編輯並重讀,如果我理解問題的權利(我沒有)。 – 2014-12-07 03:06:29

+0

非常感謝你,看到你寫的東西的原始版本,並開始把我的頭撞在桌子上更多... 這對我有用,對我有意義。 – Nonpareil 2014-12-07 03:12:09

相關問題