簡體   English   中英

使用謂詞更新 prolog 中的列表

[英]Using predicates to update a list in prolog

我沉迷於函數式編程,介詞編程對我來說很陌生,我需要使用 prolog 實現一個游戲。我定義了一個卡片列表作為

deck([(ace, spade), (two,spade), (three, spade),(four, spade), (five, spade), (six, spade), (seven, spade),
    (eight, spade), (nine, spade), (ten, spade),(jack, spade),(queen, spade), (king, heart),
    (ace, club), (two,club), (three, club),(four, club), (five, club), (six, club), (seven, club),
    (eight, club), (nine, club), (ten, club),(jack, club),(queen, club), (king, club),
    (ace, heart), (two,heart), (three, heart),(four, heart), (five, heart), (six, heart), (seven, heart),
    (eight, heart), (nine, heart), (ten, heart),(jack, heart),(queen, heart), (king, heart),
    (ace, diamond), (two,diamond), (three, diamond),(four, diamond), (five, diamond), (six, diamond), (seven, diamond),
    (eight, diamond), (nine, diamond), (ten, diamond),(jack, diamond),(queen, diamond), (king, diamond)
    ]
).

第一個練習是為甲板創建一個初始經銷商規范是

% Deals the cards from the `Deck`. The initial deal consists of two cards given 
% to the player and two cards for the house. This predicate returns the new deck 
% without just dealt cards and the table i.e. list of lists containing cards of 
% both players.
%
% @param Table    List of cards held by both players (list of lists).
% @param NewDeck  Deck(s) of card with removed cards that were used for initial 
%                 deal.
% @param Deck     Deck(s) of cards used for initial deal.

我目前的試用是這樣的,但我真的懷疑它是否有效

initDeal([], [], []).
initDeal(Table, NewDeck, Deck) :-
    [X, Y, Rest] = Deck,
    FirstNewDeck = Rest,
    [M, N, Final] = NewDeck,
    NewDeck = Final,                                          
    Table = [[X,Y],[M,N]].

我真的很感激任何幫助

可能會注意到您不能“更新列表”,您可以創建一個新列表。

但是您可能會發現將事情分解一下會更容易一些。

定義您的套牌的一些事實

suite( clubs    ).
suite( diamonds ).
suite( hearts   ).
suite( spades   ).

一些更多的事實定義每張牌的點數(面值),但你必須弄清楚如何處理“高 A”與“低 A”二分法:

pips( two   ,  2 ).
pips( three ,  3 ).
pips( four  ,  4 ).
pips( five  ,  5 ).
pips( six   ,  6 ).
pips( seven ,  7 ).
pips( eight ,  8 ).
pips( nine  ,  9 ).
pips( ten   , 10 ).
pips( jack  , 11 ).
pips( queen , 12 ).
pips( king  , 13 ).
pips( ace   , 14 ).

然后,組裝一張卡片就很容易了(在回溯時,它會依次找到所有 52 張可能的卡片):

card( P-S ) :- pips(P,_), suite(S).

組裝甲板也很容易:

deck(Cards) :- findall( C, card(C), Cards ).

一旦你有了卡片列表,洗牌就幾乎一樣容易了。 通用算法:

  • 遍歷列表。 對於列表中的每個成員,使用-/2結構為其分配一個隨機值作為鍵: <key>-<value>
  • 使用內置的keysort/2謂詞,按鍵對列表進行排序。
  • 剝離密鑰以產生隨機打亂的列表:
shuffle( Deck, Shuffled ) :- 
    assign_random_keys(Deck,Ds),
    keysort(Ds,Ss),
    remove_keys(Ss,Shuffled).

assign_random_keys( []     , []       ) .
assign_random_keys( [X|Xs] , [K-X|Ys] ) :- random(K), assign_random_keys(Xs,Ys).

remove_keys( []       , []     ) .
remove_keys( [_-X|Xs] , [X|Ys] ) :- remove_keys(Xs,Ys).

創建一副牌並將其洗牌非常簡單:

Deck(Cards), shuffle(Deck, Shuffled).

https://swish.swi-prolog.org/p/iFytxOWh.pl查看實際效果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM