home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* TITATOE.PAS *)
- (* Selbstlernendes TicTacToe-Spiel *)
- (* Turbo Pascal ab 5.0 *)
- (* (c) 1991 Simon Kröger & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$A+,B-,D-,E-,F-,I-,L-,N-,O-,R-,S-,V-}
- {$M 1024, 100000, 655360}
-
- USES Crt;
-
- TYPE FeldArray = ARRAY[1..9] OF BYTE;
- Zug_Rec = RECORD
- Feld : FeldArray;
- Zug : BYTE;
- END;
- Disk_Rec = RECORD
- Feld : LONGINT;
- Zug : BYTE;
- END;
- Zeiger =^Speicher_Rec;
- Speicher_Rec = RECORD
- Feld : LONGINT;
- Zug : BYTE;
- Naechster : Zeiger;
- END;
-
- VAR d : CHAR;
- Com_Gew,Spi_Gew,Unent,
- SpielZuege,Gewonnen,
- Gew_Alt,Zhl : INTEGER;
- Ende,Zufall : BOOLEAN;
- Zuege : ARRAY[1..10] OF Zug_Rec;
- ZErster,ZLetzter : Zeiger;
- Letzte_Zuege : ARRAY[1..9] OF BYTE;
- Halde :^INTEGER;
-
- FUNCTION FeldInt(F:FeldArray):LONGINT;
- VAR Int,Zehner : LONGINT;
- i : INTEGER;
- BEGIN
- Zehner:=1;
- Int:=0;
- FOR i:=9 DOWNTO 1 DO BEGIN
- Int:=Int+F[i]*Zehner;
- Zehner:=Zehner*10;
- END;
- FeldInt:=Int;
- END;
-
- PROCEDURE Kasten(x,y,x1,y1:INTEGER;Doppel:BOOLEAN);
- VAR i:INTEGER;
-
- PROCEDURE Print(c1,c2:BYTE);
- BEGIN
- IF Doppel THEN Write(Chr(c1))
- ELSE Write(Chr(c2));
- END;
-
- BEGIN
- GotoXY(x,y);
- Print(201,218);
- FOR i:=1 TO x1-x-1 DO Print(205,196);
- Print(187,191);
- FOR i:=1 TO y1-y-2 DO BEGIN
- GotoXY(x,i+y);
- Print(186,179);
- GotoXY(x1,i+y);
- Print(186,179);
- END;
- GotoXY(x,y1-1);
- Print(200,192);
- FOR i:=1 TO x1-x-1 DO Print (205,196);
- Print(188,217);
- END;
-
- PROCEDURE PrintAt(x,y:INTEGER;s:STRING);
- BEGIN
- GotoXY(x,y);
- Write(s);
- END;
-
- PROCEDURE Init;
- VAR i:INTEGER;
- BEGIN
- Com_Gew:=0;
- Spi_Gew:=0;
- Unent:=0;
- SpielZuege:=0;
- FOR i:=1 TO 9 DO Zuege[1].Feld[i]:=0;
- New(ZErster);
- ZLetzter:=ZErster;
- ZErster^.Naechster:=NIL;
- FOR i:=1 TO 9 DO Letzte_Zuege[i]:=1;
- Ende:=FALSE;
- Zufall:=FALSE;
- Gew_Alt:=0;
- Randomize;
- END;
-
- PROCEDURE Hilfe;
- BEGIN
- Window(28,15,47,22);
- ClrScr;
- Write(' Hilfe ');
- Write('--------------------');
- Write(' Benutzen Sie die ');
- Write(' Tasten "1" bis "9" ');
- Write(' um Ihren Stein ');
- Write(' zu setzen und ');
- Write('bestätigen Sie dann ');
- Write(' mit ENTER ');
- Window(1,1,80,25);
- END;
-
- PROCEDURE SpielFeld;
- BEGIN
- PrintAt(19,4 ,'╔════╤════╤════╗');
- PrintAt(19,5 ,'║ 1 │ 2 │ 3 ║');
- PrintAt(19,6 ,'╟────┼────┼────╢');
- PrintAt(19,7 ,'║ 4 │ 5 │ 6 ║');
- PrintAt(19,8 ,'╟────┼────┼────╢');
- PrintAt(19,9 ,'║ 7 │ 8 │ 9 ║');
- PrintAt(19,10,'╚════╧════╧════╝');
- END;
-
- PROCEDURE SpielStand;
- BEGIN
- GotoXY(74,14);Write(Com_Gew:3);
- GotoXY(74,15);Write(Spi_Gew:3);
- GotoXY(74,16);Write(Unent:3);
- PrintAt(74,19,' ');
- GotoXY(74,19);Write(SpielZuege:3);
- GotoXY(65,21);Write(MemAvail:6);
- END;
-
- PROCEDURE BildAufbau;
- BEGIN
- ClrScr;
- Kasten(1,1,80,25,TRUE);
- Kasten(50,2,78,24,FALSE);
- Kasten(52,3,76,10,FALSE);
- PrintAt(54,4,' Selbstlernendes');
- PrintAt(54,5,' Tick Tack Toe');
- PrintAt(54,7,' Ein Programm von');
- PrintAt(54,8,' Simon Kröger');
- PrintAt(52,12,'Spielstand :');
- PrintAt(52,13,'------------');
- SpielStand;
- Kasten(3,2,48,14,FALSE);
- Kasten(3,14,25,24,FALSE);
- Kasten(27,14,48,24,FALSE);
- SpielFeld;
- PrintAt(54,14,'Computer gewonnen : ');
- PrintAt(54,15,'Spieler gewonnen : ');
- PrintAt(54,16,'Unentschieden : ');
- PrintAt(54,19,'Bekannte Spielzüge: ');
- PrintAt(54,21,'Speicher : Bytes');
- PrintAt(4,15,' Menue :');
- PrintAt(4,16,'---------------------');
- PrintAt(4,17,' F1 : Laden');
- PrintAt(4,18,' F2 : Speichern');
- PrintAt(4,19,' F3 : Neues Spiel');
- PrintAt(4,20,' F4 : Zufall');
- PrintAt(4,22,'ESC : Ende');
- Hilfe;
- END;
-
- PROCEDURE ResetSpiel;
- VAR i : INTEGER;
- BEGIN
- Gewonnen:=0;
- Zhl:=1;
- SpielFeld;
- Zufall:=FALSE;
- FOR i:=1 TO 9 DO Letzte_Zuege[i]:=1;
- FOR i:=1 TO 9 DO Zuege[1].Feld[i]:=0;
- Hilfe;
- END;
-
- PROCEDURE Laden;
- VAR Datei:FILE OF Disk_Rec;
- Z :Disk_Rec;
- Z1 :Zeiger;
- BEGIN
- ResetSpiel;
- Window(28,15,47,22);
- ClrScr;
- Write(' Laden ');
- Write('--------------------');
- Write('Falls ein anderer ');
- Write('Wissensstand im ');
- Write('Speicher ist wird ');
- Write('er gelöscht. ');
- Write('Trotzdem laden ? ');
- Window(1,1,80,25);
- GotoXY(45,21);
- d:=ReadKey;
- Write(d);
- IF (UpCase(d)='J') THEN BEGIN
- Release(Halde);
- Assign(Datei,'T-T-T.DAT');
- Reset(Datei);
- New(ZErster);
- ZLetzter:=ZErster;
- SpielZuege:=0;
- REPEAT
- Inc(SpielZuege);
- Read(Datei,Z);
- New(Z1);
- ZLetzter^.Naechster:=Z1;
- ZLetzter:=Z1;
- Z1^.Feld:=Z.Feld;
- Z1^.Zug:=Z.Zug;
- UNTIL EoF(Datei);
- Z1^.Naechster:=NIL;
- Close(Datei);
- SpielStand;
- END;
- Hilfe;
- END;
-
- PROCEDURE Speichern;
- VAR Datei:FILE OF Disk_Rec;
- Z :Disk_Rec;
- Z1 :Zeiger;
- BEGIN
- ResetSpiel;
- Window(28,15,47,22);
- ClrScr;
- Write(' Speichern ');
- Write('--------------------');
- Write('Falls ein anderer ');
- Write('Wissensstand auf ');
- Write('Disk ist wird er ');
- Write('gelöscht. ');
- Write('Trotzdem Speichern ?');
- Window(1,1,80,25);
- GotoXY(28,22);
- d:=ReadKey;
- Write(d);
- IF (UpCase(d)='J') THEN BEGIN
- Assign(Datei,'T-T-T.DAT');
- ReWrite(Datei);
- Z1:=ZErster;
- REPEAT
- Z1:=Z1^.Naechster;
- Z.Feld:=Z1^.Feld;
- Z.Zug:=Z1^.Zug;
- Write(Datei,Z);
- UNTIL (Z1=NIL) OR (Z1=ZLetzter);
- Close(Datei);
- END;
- Hilfe;
- END;
-
- PROCEDURE Neu;
- BEGIN
- ResetSpiel;
- Window(28,15,47,22);
- ClrScr;
- Window(1,1,80,25);
- PrintAt(28,15,' Neues Spiel');
- PrintAt(28,16,'--------------------');
- PrintAt(28,17,'Soll der Spielstand ');
- PrintAt(28,18,'gelöscht werden ? ');
- d:=ReadKey;
- Write(d);
- IF (UpCase(d)='J') THEN BEGIN
- Com_Gew:=0;
- Spi_Gew:=0;
- Unent:=0;
- SpielStand;
- END;
- PrintAt(28,20,'Soll der Wissenstand');
- PrintAt(28,21,'gelöscht werden ? ');
- d:=ReadKey;
- Write(d);
- IF (UpCase(d)='J') THEN BEGIN
- Release(Halde);
- New(ZErster);
- ZLetzter:=ZErster;
- ZErster^.Naechster:=NIL;
- SpielZuege:=0;
- SpielStand;
- END;
- Hilfe;
- END;
-
- PROCEDURE Setze_Stein(Sp,Z:INTEGER);
- BEGIN
- GotoXY(21+((Z+5) MOD 3)*5,((Z-1) DIV 3)*2+5);
- CASE Sp OF
- 1 : Write(#17,#16);
- 2 : Write('[]');
- 3 : Write(' ');
- END;
- END;
- PROCEDURE Lernen;
- VAR Z1:Zeiger;
- BEGIN
- New(Z1);
- ZLetzter^.Naechster:=Z1;
- ZLetzter:=Z1;
- Z1^.Naechster:=NIL;
- Z1^.Feld:=FeldInt(Zuege[Zhl-2].Feld);
- Z1^.Zug:=Zuege[Zhl-2].Zug;
- Inc(SpielZuege);
- SpielStand;
- END;
-
- PROCEDURE Zufall_Spielt;
- BEGIN
- Zufall := NOT Zufall;
- IF Zufall THEN BEGIN
- Window(28,15,47,22);
- ClrScr;
- Write(' Zufall ');
- Write('--------------------');
- Write(' Jetzt spielt ein ');
- Write(' Zufallsgenerator ');
- Write(' gegen den Computer ');
- Write(' mit F4 können sie ');
- Write(' wieder selber ');
- Write(' spielen ! ');
- Window(1,1,80,25);
- END ELSE ResetSpiel;
- END;
-
- PROCEDURE Spiel_Ende;
- BEGIN
- Window(28,15,47,22);
- ClrScr;
- Write(' Ende ');
- Write('--------------------');
- Write('Das Wissen wird ');
- Write('nicht automatisch ');
- Write('gespeichert. Trotz- ');
- Write('dem beenden ? ');
- d:=ReadKey;
- Window(1,1,80,25);
- IF (UpCase(d)='J') THEN Ende:=TRUE ELSE Hilfe;
- END;
-
- PROCEDURE Spieler_Zieht;
- VAR Gesetzt : BOOLEAN;
- Z,er : INTEGER;
- BEGIN
- PrintAt(19,12,' Ihr Zug : ');
- Gesetzt:=FALSE;
- Z:=0;
- REPEAT
- IF (Zufall AND KeyPressed) OR (NOT Zufall) THEN BEGIN
- GotoXY(31,12);
- d:=ReadKey;
- CASE d OF
- #27 : Spiel_Ende;
- #13 : IF Z<>0 THEN Gesetzt:=TRUE;
- '1'..'9' : BEGIN
- Val(d,Z,er);
- Write(Z);
- END;
- END;
- IF d=#0 THEN BEGIN
- d:=ReadKey;
- CASE d OF
- ';' : Laden;
- '<' : Speichern;
- '=' : Neu;
- '>' : Zufall_Spielt;
- END;
- END;
- END;
- IF Zufall THEN BEGIN
- Z:=Letzte_Zuege[Zhl];
- IF (Gew_Alt<>1) OR (Zuege[Zhl].Feld[Z]<>0)
- THEN BEGIN
- REPEAT
- Z:=Random(9)+1;
- UNTIL Zuege[Zhl].Feld[Z]=0;
- Letzte_Zuege[Zhl]:=Z;
- END;
- Zuege[Zhl].Zug:=Z;
- Gesetzt:=TRUE;
- END;
- IF (NOT Zufall) AND (Z<>0) THEN BEGIN
- IF Gesetzt AND (Zuege[Zhl].Feld[Z]=0)
- THEN Zuege[Zhl].Zug:=Z
- ELSE Gesetzt:=FALSE;
- END;
- UNTIL Gesetzt OR Ende;
- IF Gesetzt THEN Setze_Stein(1,Z);
- END;
-
- FUNCTION Verboten(Fe:FeldArray;Zu:BYTE):BOOLEAN;
- VAR Z1 : Zeiger;
- v : BOOLEAN;
- Jetzt : LONGINT;
- BEGIN
- Z1:=ZErster;
- v:=FALSE;
- Jetzt:=FeldInt(Fe);
- WHILE (Z1<>ZLetzter) AND (NOT v) DO BEGIN
- Z1:=Z1^.Naechster;
- IF (Z1^.Feld=Jetzt) AND (Zu=Z1^.Zug) THEN v:=TRUE;
- END;
- Verboten:=v;
- END;
-
- PROCEDURE Computer_Zieht;
- VAR R : INTEGER;
- Gezogen : BOOLEAN;
- BEGIN
- R:=0;
- Gezogen:=FALSE;
- REPEAT
- Inc(R);
- IF (Zuege[Zhl].Feld[R]=0) AND
- (NOT Verboten(Zuege[Zhl].Feld,R)) THEN Gezogen:=TRUE;
- UNTIL Gezogen OR (R=9);
- IF NOT Gezogen THEN BEGIN
- Lernen;
- R:=0;
- REPEAT
- Inc(R);
- UNTIL Zuege[Zhl].Feld[R]=0;
- END;
- Zuege[Zhl].Zug:=R;
- Setze_Stein(2,R);
- END;
-
- PROCEDURE GewinnAbfrage;
- CONST M : ARRAY[1..8,1..3] OF BYTE =
- ((1,2,3),(4,5,6),(7,8,9),(1,4,7),
- (2,5,8),(3,6,9),(1,5,9),(3,5,7));
- VAR i,F,j : INTEGER;
- BEGIN
- Gewonnen:=0;
- Zuege[Zhl].Feld:=Zuege[Zhl-1].Feld;
- Zuege[Zhl].Feld[Zuege[Zhl-1].Zug]:=(Zhl MOD 2)+1;
- i:=0;
- REPEAT
- Inc(i);
- F:=Zuege[Zhl].Feld[M[i,1]];
- IF (F<>0) AND (Zuege[Zhl].Feld[M[i,2]]=F) AND
- (Zuege[Zhl].Feld[M[i,3]]=F) THEN Gewonnen:=F;
- UNTIL (i=8) OR (Gewonnen<>0);
- IF (Gewonnen<>0) AND (NOT Zufall) THEN BEGIN
- PrintAt(19,12,' << ENTER >>');
- REPEAT
- FOR j:=1 TO 3 DO Setze_Stein(3,M[i,j]);
- IF NOT KeyPressed THEN Delay(200);
- FOR j:=1 TO 3 DO Setze_Stein(Gewonnen,M[i,j]);
- IF NOT KeyPressed THEN Delay(200);
- UNTIL KeyPressed;
- d:=ReadKey;
- END;
- END;
-
- BEGIN
- Mark(Halde);
- Init;
- BildAufbau;
- REPEAT
- Gewonnen:=0;
- Zhl:=1;
- SpielFeld;
- SpielStand;
- REPEAT
- IF NOT Ende THEN BEGIN
- Spieler_Zieht;
- Inc(Zhl);
- GewinnAbfrage;
- END;
- IF (Zhl<10) AND (Gewonnen=0) AND (NOT Ende)
- THEN BEGIN
- Computer_Zieht;
- Inc(Zhl);
- GewinnAbfrage;
- END;
- UNTIL Ende OR (Gewonnen<>0) OR (Zhl>9);
- Gew_Alt:=Gewonnen;
- IF Gewonnen = 1 THEN BEGIN
- Inc(Spi_Gew);
- Lernen;
- END;
- IF Gewonnen=2 THEN Inc(Com_Gew);
- IF (Gewonnen=0) AND (NOT Ende) THEN BEGIN
- Inc(Unent);
- IF NOT Zufall THEN BEGIN
- PrintAt(19,12,' << ENTER >>');
- d:=ReadKey;
- END;
- END;
- UNTIL Ende;
- Release(Halde);
- END.
- (* ------------------------------------------------------ *)
- (* Ende von TITATOE.PAS *)
-