Nim
Selles vanas idamaade mängus võtavad mängijad vaheldumisi
laule asetatud tikke. Korraga võib võtta ühe või kaks tikku (kuid midagi peab võtma); võidab see, kes
võtab viimase tiku.
Seda mängu on lihtne õpetada ka Proloogile. Eesmärgiks on teha laud puhtaks, ja lubatud on võtta kas
üks või kaks tikku:
võiduseis(0).
lubatud(1).
lubatud(2).
Laual olevate tikkude arv (Seis) muutub mängu ajal. Käigul olles püüab Prolog alati võtta niimitu tikku, et
tagada endale võiduseis. Kui järgmise käiguga saab kogu laua tühjendada, on seis ilmselt võiduseis. Kui
see pole võimalik, tuleb lauale jätta seis, mis ei ole võiduseis, s.t. ükskõik kuimitu tikku vastane ka ei
võtaks, tekkiv seis pole võiduseis:
võidetav(Seis,Käik) :-
lubatud(Käik),
Seis1 is Seis - Käik,
võiduseis(Seis1),
!.
võidetav(Seis,Käik) :-
lubatud(Käik),
Seis1 is Seis - Käik,
pole_võidetav(Seis1).
pole_võidetav(Seis) :-
Seis > 2,
Seis1 is Seis - 1,
Seis2 is Seis - 2,
võidetav(Seis1,_),
võidetav(Seis2,_).
Käike kirjeldab kahekohaline predikaat käik; selle esimene argument ütleb, kelle käik (arvuti/inimene) see on.
Kui arvuti käigul olles märkab, et laud on puhas, jääb tal üle vaid vastast õnnitleda; kui aga laual on veel tikke, kuid
need on võimalik kõik ära võtta (1 või 2), teebki Prolog nii:
käik(arvuti,0) :-
nl,
write('Õnnitlen, võitsid!'),
nl.
käik(arvuti,Seis) :-
lubatud(Seis),!,
nl,
write('Võtan kõik ja olen võitnud!'),
nl.
Kui laual on rohkem kui kaks tikku, otsib Prolog leida sellist käikku, et selle järel seis oleks
võidetav; kui sellist käiku pole, valib ta juhusliku arrvu tikke:
käik(arvuti,Seis) :-
lubatud(Käik),
võidetav(Seis,Käik),
!,
Seis1 is Seis - Käik,
write('Võtan '),
write(Käik),
write(', jääb '),
write(Seis1),
write(', sinu käik!'),
nl,
käik(inimene,Seis1).
käik(arvuti,Seis) :-
Käik is random(2)+1,
Seis1 is Seis - Käik,
write('Võtan '),
write(Käik),
write(', jääb '),
write(Seis1),
write(', sinu käik!'),
nl,
käik(inimene,Seis1).
Inimese käigul olles küsib arvuti inimeselt tema poolt võetavate tikkude arvu ja kontrollib, kas
see on lubatud; kui on, on järgmisena tema käik, kuid kui pole, hoiatab inimest ja kordab küsimust:
käik(inimene,Seis) :-
write('Mitu võtad? '),
read(Käik),nl,
lubatud(Käik),
Seis1 is Seis - Käik,
käik(arvuti,Seis1).
käik(inimene,Seis) :-
write('See käik ei ole lubatud!'),
nl,
käik(inimene,Seis).
Algseisu ja alustaja valiku jätab arvuti viisakalt inimesele:
mäng :-
algseis(Seis),
alustaja(Alustaja),
käik(Alustaja,Seis).
alustaja(Alustaja) :-
write('Kumb algab (inimene/arvuti)? '),
read(Alustaja).
algseis(Seis) :-
write('Mitmega algame ? ,
read(Seis).
Mäng on huvitavam, kui mängija näeb ekraanil seisu, seega võiks inimese käigu
esimese lause kirjeldada veidi põhjalikumalt:
käik(inimene,Seis) :-
write('Seis on: '),
joonista(Seis),nl,
write('Mitu võtad? '),
read(Käik),nl,
lubatud(Käik),
Seis1 is Seis - Käik,
käik(arvuti,Seis1).
Tikkude joonistamiseks kirjuta Prolog ekraanile tähti "I":
joonista(0):-
nl,!.
joonista(Seis):-
write('I '),
Seis1 is Seis - 1,
joonista(Seis1).
Inimesed pole mängu ajal tavaliselt vait (kuigi peaks): kui neil õnnestub midagi, siis nad kiitlevad,
vastasmängijat püütakse teda halvustades segadusse ajada jne. Ka Prologile võib õpetada sellise "inimlikku"
mänguviisi, kus ta valib juhuslikult mingi hooplemise või märkuse (mõnikord on ka vait) :
käik(arvuti,Seis) :-
lubatud(Käik),
võidetav(Seis,Käik),
!,
Seis1 is Seis - Käik,
write('Võtan '),
write(Käik),
write(', jääb '),
write(Seis1),
write(', sinu käik!'),
nl,
hooplemine,
nl,
käik(inimene,Seis1).
käik(arvuti,Seis) :-
Käik is random(2)+1,
Seis1 is Seis - Käik,
write('Võtan '),
write(Käik),
write(', jääb '),
write(Seis1),
write(', sinu käik!'),
nl,
märkus,
käik(inimene,Seis1).
hooplemine:-
N is random(4),
hooplemine(N,Tekst),
write(Tekst),
nl.
hooplemine(0, 'Selle mängu ma võidan kindlasti!').
hooplemine(1, 'Ma mängin paremini!').
hooplemine(2, 'Ära püüagi mind võita!').
hooplemine(3, '').
märkus:-
N is random(4),
märkus(N,Tekst),
write(Tekst),
nl.
märkus(0, 'Mängid üsna hästi!').
märkus(1, 'Täna mul ei vea!').
märkus(2, 'Sa võid isegi võita!').
märkus(3, '').
Ülesandeid:
1.
Sellest mängust on olemas ka keerukamaid versioone:
- laual on mitte üks, vaid mitu rida tikke, võtma peab endiselt 1 või 2, kuid kahe tiku võtmisel mõlemad samast reast; võidab
taas see, kes võtab kogu laualt viimase tiku;
mängu algul valitakse juhuslik arv N (N > 1) ja võtta võib kuni N tikku (s.t. ülalkirjeldatud versioonis N=2).
Täiusta programmi selliste versioonide mängimiseks!
Küsimused, probleemid:
©2004
Jaak Henno