{****************************************************************************} {* NIM *} {****************************************************************************} PROGRAM nim; CONST nmax = 8; kmax = 15; TYPE Spieler = (Mensch, Computer); NimSchale = ARRAY[1..nmax] OF 0..kmax; VAR n : 2..nmax; Schale : NimSchale; Zug : RECORD Schale : 1..nmax; Anzahl : 1..kmax END; AnderReihe : Spieler; PUNKTE : integer; JaNein : char; PROCEDURE MachSpiel; VAR i : 1..nmax; BEGIN randomize; n:=random(nmax-1)+2; FOR i:=1 TO n DO Schale[i]:=random(kmax)+1 END; PROCEDURE ZeichneSchale(x:integer); VAR i,j : integer; BEGIN gotoxy((x-1)*10+1,14); write('\-----/'); FOR i:=0 TO (kmax-1) DIV 5 DO BEGIN gotoxy((x-1)*10+2,13-i); FOR j:=1 TO 5 DO IF Schale[x]>=i*5+j THEN write('o') ELSE write(' ') END; END; PROCEDURE SpielFeld; VAR i : 1..nmax; j : 1..kmax; BEGIN FOR i:=1 TO n DO BEGIN ZeichneSchale(i); gotoxy((i-1)*10+1,15); write('Schale ',i); END END; PROCEDURE MenschenZug; BEGIN REPEAT gotoxy(1,17); ClrEol; write('Ihr Zug : von Schale '); read(Zug.Schale); write(' nehmen Sie '); ClrEol; read(Zug.Anzahl); UNTIL (Zug.Schale<=n) AND (Zug.Schale>0) AND (Zug.Anzahl>0) AND (Schale[Zug.Schale]-Zug.Anzahl>=0); Schale[Zug.Schale]:=Schale[Zug.Schale]-Zug.Anzahl END; PROCEDURE ComputerZug; VAR ZugZahl : integer; PROCEDURE ZufallsZug; BEGIN REPEAT Zug.Schale:=random(n)+1 UNTIL Schale[Zug.Schale]>0; Zug.Anzahl:=random(Schale[Zug.Schale])+1 END; FUNCTION GewinnStellung:boolean; VAR HilfsSchale : NimSchale; NimZahl : integer; i : 1..nmax; BEGIN HilfsSchale:=Schale; HilfsSchale[Zug.Schale]:=HilfsSchale[Zug.Schale]-Zug.Anzahl; NimZahl:=HilfsSchale[1]; FOR i:=2 TO n DO NimZahl:=NimZahl XOR HilfsSchale[i]; GewinnStellung:=NimZahl=0 END; BEGIN ZugZahl:=0; Zug.Schale:=1; Zug.Anzahl:=0; IF GewinnStellung THEN ZufallsZug ELSE REPEAT ZufallsZug; ZugZahl:=ZugZahl+1; UNTIL GewinnStellung OR (ZugZahl>PUNKTE); Schale[Zug.Schale]:=Schale[Zug.Schale]-Zug.Anzahl; gotoxy(1,18); ClrEol; write('Ich nehme aus der ',Zug.Schale,'-ten Schale ',Zug.Anzahl,' weg.') END; PROCEDURE Abwechseln(VAR x : Spieler); BEGIN IF x=Mensch THEN x:=Computer ELSE x:=Mensch END; FUNCTION SpielEnde:boolean; VAR Summe, i : integer; BEGIN Summe:=0; FOR i:=1 TO n DO Summe:=Summe+Schale[i]; SpielEnde:=Summe=0 END; BEGIN {Hauptprogramm} PUNKTE:=0; AnderReihe:=Mensch; REPEAT ClrScr; writeln('*********':40); writeln('* NIM *':40); writeln('*********':40); MachSpiel; writeln('Ihre Punktzahl: ':60,PUNKTE); writeln('Vor uns befinden sich ',n,' Reisschalen.'); writeln('Bei jedem Zug koennen aus einer Schale beliebig viele Reiskoerner'); writeln('entnommen werden, mindestens jedoch eines.'); write ('Wer nicht mehr ziehen kann, weil alle Schalen leer sind,'); writeln(' hat verloren.'); SpielFeld; REPEAT IF AnderReihe=Mensch THEN MenschenZug ELSE ComputerZug; ZeichneSchale(Zug.Schale); Abwechseln(AnderReihe) UNTIL SpielEnde; gotoxy(1,20); IF AnderReihe=Computer THEN BEGIN writeln('Gratuliere, Sie haben gewonnen!'); PUNKTE:=PUNKTE+5 END ELSE BEGIN writeln('Sie haben leider verloren!'); PUNKTE:=PUNKTE-3 END; gotoxy(1,22); write('Noch ein Spiel ? '); REPEAT read(kbd,JaNein) UNTIL JaNein IN ['j','J','n','N'] UNTIL JaNein IN ['n','N'] END.