我會排序的序列,並會使用像findall/3和append/2內置的插件。然後驗證謂詞是比較容易寫:
% build a bridge deck
bridge_deck(Cs) :-
findall(card(S,V), (member(S,[♥,♦,♣,♠]),between(1,13,V)), Cs).
% shuffle
bridge_hands([S,W,N,E]) :-
bridge_deck(Cs),
%setrand(rand(1,2,3)), % get a known random set, to ease debugging
random_permutation(Cs, RCs),
maplist([H]>>length(H,13), [S,W,N,E]),
append([S,W,N,E], RCs).
% behaves like a bridge player :)
hands_sorted(Sorted) :-
bridge_hands(Hands),
maplist(sort, Hands, Sorted).
group_hand(Hand, Groups) :-
findall([A,B,C|D],
(append([_,[A,B,C|D],_],Hand), 'same suit and consecutive numbers'([B,C|D],A)), Groups).
'same suit and consecutive numbers'([card(S,Y)|R], card(S,X)) :-
succ(X,Y),
'same suit and consecutive numbers'(R, card(S,Y)).
'same suit and consecutive numbers'([], _).
?- hands_sorted(Ps), maplist(group_hand, Ps, Gs), maplist(writeln, Gs).
Ps = [[card('♠', 1), card('♠', 4), card('♠', 5), card('♠', 11), card('♣', 2), card('♣', 4), card('♣', 10), card(..., ...)|...], [card('♠', 2), card('♠', 6), card('♠', 9), card('♠', 12), ...
Gs = [[], [], [[card('♥', 10), card('♥', 11), card('♥', 12)], [card('♥', 10), card('♥', 11), card('♥', 12), card(..., ...)], [card('♥', 11), card('♥', 12), card(..., ...)]], []].
我用橋邏輯更合適的表示:卡(套裝,價值)
編輯
SWI-Prolog有一個很好的結構化輸出設施。這段代碼佈局以可讀的形狀的橋接表:
:- use_module(library(http/html_write)).
bridge_cards :-
hands_sorted(Hands),
layout_table(Hands).
layout_table([S,W,N,E]) :-
phrase(html([\css,
table([
tr([\empty, \layout_hand(N), \empty]),
tr([\layout_hand(W), \empty, \layout_hand(E)]),
tr([\empty, \layout_hand(S), \empty])
])]), Tokens),
with_output_to(atom(X), print_html(Tokens)),
win_html_write(X).
css --> html(style(type='text/css',
['.size{background-color:lightgrey;}'
,'.player{color:blue;}'
,'.value{text-align:right;background-color:lightgreen}'
])).
empty --> html(td([class=size],[])).
layout_hand(Cards) -->
{findall(S-Vs, (
member(S, [♣,♦,♥,♠]),
findall(V, member(card(S,V),Cards), Vs)
), SuitesValues)},
html(td([class=player], table(\layout_suits(SuitesValues)))).
layout_suits([]) --> [].
layout_suits([Suit-Values|SVs]) -->
html(tr([td(Suit), \layout_values(Values)])),
layout_suits(SVs).
layout_values([]) --> [].
layout_values([V|Vs]) --> html(td([class=value], \layout_value(V))), layout_values(Vs).
layout_value(V) --> {nth1(V,['A',2,3,4,5,6,7,8,9,'T','J','Q','K'],C)}, html(C).
我認爲,在HTML獲得輸出是特別方便,因爲它允許以最小的大驚小怪和後來的實驗 - 如果需要的話 - 代碼移植到SWI-Prolog的HTTP服務器,在野外運行。
來自實例swipl-win運行,用HTML渲染被Qt處理:
不是很清楚你希望你的謂語工作。它是否具有卡片的第一個參數,並且作爲組的第二個參數? – 2016-04-25 16:44:19
'S1 = S2,連續號碼(S1,S2)'很奇怪。如果S1和S2相等,則它們不能連續。你的意思是'連續數字(N1,N2)'? –
是的,這是正確的托馬斯,我的意思是說我打電話給卡號的謂詞來檢查它們。 – John