2016-01-13 101 views
1

我有一個動態列表存儲領域的協調和該領域的所有者如何使用動態列表在遞歸函數中的Prolog

這個名單的
:-dynamic 
    board/2. 

一個條目看起來像這樣:

board(e4,[w]). 

還有22個看起來相似的板子位置。

我想實現一個AI的遊戲董事會的目的。 我正在使用alpha測試版算法,因此必須創建新的「板子」來回避這種情況。

我原板的副本來工作,但現在有一個功能調節板當前的舉動是這樣的:

move(position,boardOld,boardNew) 

這是在第二個電話boardOld稱爲遞歸因此等於boardNew和boardNew是分析中下一步行動的老闆。

我的想法是舊抄板在每次迭代,但我不知道如何做到這一點,因爲這

copy_predicate_clauses(boardOld(A,B),boardNew(A,B)). 

將舊的董事會,因爲名單已經存在添加到newBoard。

我使用以下算法(無法複製它,因爲它是一個圖像):

http://www.cuceinetwork.net/archivos/prolog/The_Art_of_Prolog.pdf

PDF頁面445(書頁407)。

該算法在初始化時將位置定義爲'Board',我不知道如何使用我的列表執行此操作,此外,子句移動(Move,Position,Position1)返回當前移動的新Board。這被稱爲遞歸,我不知道如何爲position1創建電路板而不覆蓋之前的電路板。

編輯//

好的,我得到了問題。但是我在遊戲中已經使用了這個謂詞,並且不想全部改變。我這樣做:

findall((X,Y),board(X,Y),CurrentBoard). 

CurrentBoard給了我這樣的

[(e4,[w,w]),(g4,[s,w]),(b7,[r,w,s])] 

列表現在我不能用我的方法來確定可能的行動。

我有一個像

move(e4,d5). 
move(d5,e6). 

說明哪些舉動事實(從,到)是可能的,現在我想這

findall((X,Y),listMoves(CurrentBoard,X,Y),possibleMoves). 

像這樣的東西。在這一點上,我很困難。我如何生成可能的移動列表。我不知何故必須從currentBoard獲取X座標,檢查來自該座標的列表頭(該座標上的棋子)是否屬於我,並檢查Y座標(to)是否空閒。

listMoves([Coordinate|[Head|Tail]], X, Y) :- 
    move(X,Y), 
    ownField(X,Coordinate,Head), 
+0

鑑於缺乏細節,這很難回答(如果不是不可能的話)。 –

+0

我將編輯問題並分享更多詳細信息 – Sven182

+0

您的問題是您試圖將動態存儲作爲列表處理(您自己這麼說,但「board/2」是謂詞,而不是列表),它不是列表真的不適合這個目的。你最好爲你的棋盤狀態制定明確的列表並傳遞給你,因爲操縱實際列表比在動態存儲中操縱事實要容易得多。 –

回答

1

如果從(打印)401頁閱讀,作者勾勒出基本的遊戲算法:

play(Game) :- 
     initialize(Game, Position, Player), 
     display_game(Position, Player), 
     play(Position, Player, Result). 

節的其餘部分使用的術語「位置」讓我相信他們指的是遊戲的整個狀態。對於象棋這樣的遊戲,這將是棋盤本身的狀態:棋子在哪裏。

從那裏,作者繼續討論move/2move/3,這些正是如此定義:

可以很方便地通過move/3

移動的選擇由 choose_move/3從其分離執行

然後在403頁上,

謂詞如果Move是從當前位置可能的移動,則爲10。

總之,這一切都表明,我認爲他們期望Position是完整的國際象棋棋盤(我想你下棋,對嗎?),並Move是一個合法的舉動,爲的目的定義move/2,然後move/3只是move/2,返回結果板。換言之,初始棋盤可能是這個樣子:

starting_board([[b-r, b-b, b-n, b-q, b-k, b-n, b-b, b-r], 
       [b-p, b-p, b-p, b-p, b-p, b-p, b-p, b-p], 
       [nil, nil, nil, nil, nil, nil, nil, nil], 
       [nil, nil, nil, nil, nil, nil, nil, nil], 
       [nil, nil, nil, nil, nil, nil, nil, nil], 
       [nil, nil, nil, nil, nil, nil, nil, nil], 
       [w-p, w-p, w-p, w-p, w-p, w-p, w-p, w-p], 
       [w-r, w-b, w-n, w-q, w-k, w-n, w-b, w-r]]).  

這是怎麼了,我可能將它設置;無疑可能有更高效或更明智的做法,但問題是,你的價值觀應該總是像這樣包含整個董事會的狀態。事實上,它可能需要包括其他信息,比如誰的輪到它,或者如果你想記錄每一個移動的日誌,你也可以把它扔到那裏。

從這裏,你準備寫move/2move/3。我會傾向於(爲了教學目的)寫move/3並使用它來構建move/2,但爲了提高效率,您可能需要單獨執行它們。我在國際象棋上已經夠壞了,所以我要在這裏停下來(我不相信你會下棋)。但基本上,你想看到move(StartPosition, Move, NewPosition),作爲一個開始位置,將統一Move與某種簡短的描述移動和NewPosition與整個董事會的狀態後,這樣做,所以你得到一個前 - 快照後。

一旦你建立了這些部分,我認爲你可以主要使用書本原樣。

我想你基本上有幾個誤區:

  1. 該主板不能與多個解決方案的斷言。這是一個您創建的數據結構,代表了正在發生的事情的整個故事。
  2. 動態謂詞不會形成一個列表。確實,您可以擁有多個解決方案並且他們有訂單,但對於您需要執行的各種操作來說,這並不是一個方便的數據結構。
  3. 我真的不認爲你想把這兩個想法混合在一起,看看會發生什麼。