<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
% mastermind- peli
% esimerkki satunnaisuuden käytöstä logiikkaohjelmoinnissa
% mmeri 12.11.2004
% Interaktiivinen peli mmm -predikaatin kutsulla (ks. lähdekoodin loppu)
% Automaattinen peli mma -predikaatin kutsulla
% Tässä on ajatuksena että automaattinenkaan versio ei voi käydä yhdellä vuorolla testaamassa
% enempää kuin yhden kandidaatin, tämä valinta joka kierroksella voi johtaa siihen että päädytään
% haun haaraan josta ratkaisua ei löydy, jolloin joudutaan palaamaan
% taaksepäin ja tässä ratkaisussa kylmästi palataan alkuun.
% Jäljellä olevien ratkaisuvaihtoehtojen joukko on sellainen että siinä olevilla jäsenillä
% on sama määrä merkkejä samassa paikassa kuin mitä kullakin aikaisemmalla tarkistetulla 
% kandidaatilla oli oikeita merkkejä oikeassa paikassa verrattuna ratkaisuun pelin ilmoituksen 
% perusteella

init([A,B,C,D]) :-
    A is random(4),
    B is random(4),
    C is random(4),
    D is random(4).

ask([A,B,C,D]) :-
    prompt(Old,'Anna lista: \n' ),
    read([A,B,C,D]),
    prompt1(Old).

count_match([],[],[],[],0).
count_match([A | T1],[A | T2],T11,T21,CP1) :-
    count_match(T1,T2,T11,T21,CP),
    CP1 is CP + 1.
count_match([A | T1],[B | T2],[A | T11],[B| T21],CP) :-
    A \= B,
    count_match(T1,T2,T11,T21,CP).    

count_perm([],[],0).

count_perm(A,B,C1) :-
    select(A1,A,ARest),
    select(A1,B,BRest),
    !,
    count_perm(ARest,BRest,C),
    C1 is C + 1.

count_perm(_,_,0).

compare(Prob,Answ,CP,CS) :-
    count_match(Prob,Answ,PRest,ARest,CP),
    count_perm(PRest,ARest,CS).

round(Round,Prob,Answers) :-
    ask(Answ),
    compare(Prob,Answ,CP,CS),
    RoundN is Round + 1,
    CP &lt; 4, 
    !,
    format("Oikea paikka ~d oikea tyyppi ~d \n",[CP,CS]),
    round(RoundN,Prob,[Answ | Answers]).

round(_,_,_).

round_aut(Round,Prob,AnswersWithVal) :-
    gen(AnswersWithVal,Answ,Al),
    compare(Prob,Answ,CP,CS),
    CP =:= 4, 
    !,
    [A,B,C,D] = Answ,
    format(" Kierroksella ~d kandidaatti [~d ~d ~d ~d ] \n naapurustosta jonka koko ~d ,\n oikealla paikalla  ~d oikean tyyppisiä ~d \n\n",[Round,A,B,C,D,Al,CP,CS]).

round_aut(Round,Prob,AnswersWithVal) :-
    gen(AnswersWithVal,Answ,Al),
    compare(Prob,Answ,CP,CS),
    RoundN is Round + 1,
    CP &lt; 4, 
    Al &gt; 1,
    !,
    [A,B,C,D] = Answ,
    format("Naapuruston koko: "),write(Al),tab(1),
    format(" [~d ~d ~d ~d ],Oikea paikka ~d  oikea tyyppi ~d \n",[A,B,C,D,CP,CS]),
    round_aut(RoundN,Prob,[[Answ,[CP,CS]] | AnswersWithVal]).

% restart
round_aut(Round,Prob,_) :-
    format("Käynnistetään uudestaan\n"),
    RoundN is Round + 1,
    round_aut(RoundN,Prob,[]).

gen(AnswersWithVal,Answ,Al) :-
    findall(Answ1,gen0(AnswersWithVal,Answ1),As),
    length(As,Al),
    Ind is random(Al),
    nth0(Ind,As,Answ),
    !.

gen0(AnswersWithVal,Answ) :-
    member(A,[0,1,2,3]),
    member(B,[0,1,2,3]),
    member(C,[0,1,2,3]),
    member(D,[0,1,2,3]),
    Answ = [A,B,C,D],
    \+member([Answ,[_,_]],AnswersWithVal),
    forall(member([Old,[OP,OT]],AnswersWithVal),
        (compare(Old,Answ,CP,CT),
        CP =  OP,
        CT =  OT)).

mmm :-
    init(Prob),
    write(Prob),nl,
    format("Ratkaisun neljä alkiota ovat lukuja 0 - 3 väliltä"),nl,ttyflush,
    write([*,*,*,*]),format("."),nl,ttyflush,
    !,
    round(1,Prob,[]).

mma :-
    init(Prob),
    write(Prob),nl,
    format("Ratkaisun neljä alkiota ovat lukuja 0 - 3 väliltä"),nl,ttyflush,
    write([*,*,*,*]),format("."),nl,ttyflush,
    !,
    round_aut(1,Prob,[]).
    

% Usage:
% Interactive MasterMind
% mmm.
% Automatic MasterMind
% mma.

</pre></body></html>