home *** CD-ROM | disk | FTP | other *** search
- (* ====================================================== *)
- (* W O R D M A S T E R *)
- (* 'Künstlich intelligentes' Wortrate-Spielprogramm *)
- (* (C) 1989 Matthias Uphoff & TOOLBOX *)
- (* ====================================================== *)
- (* Hardware: IBM-kompatibler PC/AT Monochrom/Farbe *)
- (* Compiler: TopSpeed Modula-2 Version 1.14 *)
- (* ====================================================== *)
-
- MODULE WMaster;
-
- IMPORT SYSTEM, IO, FIO, Lib, Str, Window;
-
- TYPE
- WortTyp = ARRAY[0..6] OF CHAR;
- FileNameTyp = ARRAY[0..11] OF CHAR;
- CharSet = SET OF CHAR;
-
- CONST
- TxtDelTime = 25; (* Verzögerung bei Textausgabe *)
- AnzDelTime = 100; (* Verzögerung bei Anzeige Wortsuche *)
- MaxAnzahl = 2000; (* Max. Anzahl Wörter in der Liste *)
- MaxVersNr = 15; (* Max. Anzahl Versuche bis Ende *)
- BS = 10C; (* Backspace *)
- GrossBst = 'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ';
- MaxBst = 29; (* Anzahl Buchstaben in GrossBst *)
- Buchstaben = CharSet{'A'..'Z','Ä','Ö','Ü'};
-
- (* Fensterdefinitionen für Farbbildschirm *)
- FObenDefC = Window.WinDef
- (0, 0, 79, 2,
- Window.White, Window.Blue,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Blue);
- FLinksDefC = Window.WinDef
- (0, 3, 20, 21,
- Window.LightGreen, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.Green, Window.Black);
- FMitteDefC = Window.WinDef
- (21, 3, 58, 21,
- Window.Yellow, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Black);
- FRechtsDefC = Window.WinDef
- (59, 3, 79, 21,
- Window.LightRed, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.Red, Window.Black);
- FUntenDefC = Window.WinDef
- (0, 22, 79, 24,
- Window.White, Window.Blue,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Blue);
- FListeDefC = Window.WinDef
- (36,7,45,17,
- Window.LightGray,Window.Blue,
- FALSE, FALSE, FALSE, TRUE,
- Window.DoubleFrame,
- Window.LightGray, Window.Blue);
-
- (* Fensterdefinitionen für Schwarzweiß-Bildschirm *)
- FObenDefSW = Window.WinDef
- (0, 0, 79, 2,
- Window.White, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Black);
- FLinksDefSW = Window.WinDef
- (0, 3, 20, 21,
- Window.White, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Black);
- FMitteDefSW = Window.WinDef
- (21, 3, 58, 21,
- Window.White, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Black);
- FRechtsDefSW = Window.WinDef
- (59, 3, 79, 21,
- Window.White, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Black);
- FUntenDefSW = Window.WinDef
- (0, 22, 79, 24,
- Window.White, Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.SingleFrame,
- Window.LightGray, Window.Black);
- FListeDefSW = Window.WinDef
- (36,7,45,17,
- Window.LightGray,Window.Black,
- FALSE, FALSE, FALSE, TRUE,
- Window.DoubleFrame,
- Window.LightGray, Window.Black);
-
- VAR
- FensterOben, (* Fenster-Referenzen *)
- FensterUnten,
- FensterMitte,
- FensterLinks,
- FensterRechts: Window.WinType;
- WortListe: ARRAY[1..MaxAnzahl] OF WortTyp;
- VersComp: ARRAY[1..MaxVersNr] OF WortTyp;
- RBComp,
- RPComp: ARRAY[1..MaxVersNr] OF CARDINAL;
- ListPos, (* Position in Wortliste *)
- WortLaenge, (* Länge der Wörter in der Liste *)
- WortAnzahl, (* Anzahl der Wörter in der Liste *)
- VersSp, (* Anzahl Versuche Spieler *)
- VersC, (* Anzahl Versuche Computer *)
- ScoreSp, (* Punktestand Spieler *)
- ScoreC, (* Punktestand Computer *)
- Runde: (* Nummer der akt. Spielrunde *)
- CARDINAL;
- gelernt, (* Neues Wort in Liste aufgenommen? *)
- ExtKey, (* Flag für erweiterten Tastencode *)
- SW: (* Schwarz-Weiß-Bildschirm? *)
- BOOLEAN;
-
-
- (* ====================================================== *)
- (* ====================================================== *)
- (* Allgemeine Prozeduren *)
- (* ====================================================== *)
-
- (* =============================== verzögerte Textausgabe *)
-
- PROCEDURE WriteStr(s: ARRAY OF CHAR);
- VAR i: CARDINAL;
- BEGIN
- FOR i := 0 TO Str.Length(s)-1 DO
- IO.WrChar(s[i]);
- Lib.Delay(TxtDelTime);
- END;
- END WriteStr;
-
- (* ================ Textzeile ausgeben mit Zeilenvorschub *)
-
- PROCEDURE WriteLn(s: ARRAY OF CHAR);
- BEGIN
- WriteStr(s);
- IO.WrLn;
- END WriteLn;
-
- (* ============== Zahl mit führendem Leerzeichen ausgeben *)
-
- PROCEDURE WriteNum(n: CARDINAL);
- VAR St: ARRAY[0..9] OF CHAR;
- f: BOOLEAN;
- BEGIN
- Str.CardToStr(LONGCARD(n),St,10,f);
- Str.Insert(St,' ',0);
- WriteStr(St);
- END WriteNum;
-
- (* ========== Auf Taste warten, in Großbuchstaben wandeln *)
-
- PROCEDURE LeseZeichen(): CHAR;
- VAR c: CHAR;
- BEGIN
- ExtKey := FALSE;
- Window.CursorOn;
- c := CAP(IO.RdKey());
- Window.CursorOff;
- CASE c OF
- | 0C: c := IO.RdKey();
- ExtKey := TRUE;
- | 'ä': c := 'Ä';
- | 'ö': c := 'Ö';
- | 'ü': c := 'Ü';
- END;
- RETURN c;
- END LeseZeichen;
-
- (* =========== Test auf Farbe/Schwarzweiß, Fenster öffnen *)
-
- PROCEDURE InitScreen;
- VAR R: SYSTEM.Registers;
- BEGIN
- R.AH := 15;
- Lib.Intr(R,10H);
- SW := (R.AL = 0) OR (R.AL = 2) OR
- (R.AL = 5) OR (R.AL = 6) OR (R.AL = 7);
- IF SW THEN
- FensterOben := Window.Open(FObenDefSW);
- FensterLinks := Window.Open(FLinksDefSW);
- FensterMitte := Window.Open(FMitteDefSW);
- FensterRechts := Window.Open(FRechtsDefSW);
- FensterUnten := Window.Open(FUntenDefSW);
- ELSE
- FensterOben := Window.Open(FObenDefC);
- FensterLinks := Window.Open(FLinksDefC);
- FensterMitte := Window.Open(FMitteDefC);
- FensterRechts := Window.Open(FRechtsDefC);
- FensterUnten := Window.Open(FUntenDefC);
- END;
- END InitScreen;
-
- (* ====================================== Wortliste laden *)
-
- PROCEDURE LoadListe;
- VAR InFile: FIO.File;
- FName: FileNameTyp;
- BEGIN
- WortAnzahl := 0;
- FIO.IOcheck := FALSE;
- FName := 'LISTEX.DAT';
- FName[5] := CHR(WortLaenge+48);
- InFile := FIO.Open(FName);
- IF FIO.IOresult() = 0 THEN
- REPEAT
- INC(WortAnzahl);
- FIO.RdStr(InFile,WortListe[WortAnzahl]);
- UNTIL FIO.EOF OR (WortAnzahl = MaxAnzahl);
- DEC(WortAnzahl);
- END;
- FIO.Close(InFile);
- END LoadListe;
-
- (* ================================== Wortliste speichern *)
-
- PROCEDURE SaveListe;
- VAR i: CARDINAL;
- OutFile: FIO.File;
- FName: FileNameTyp;
- BEGIN
- FIO.IOcheck := FALSE;
- FName := 'LISTEX.DAT';
- FName[5] := CHR(WortLaenge+48);
- OutFile := FIO.Create(FName);
- IF FIO.IOresult() = 0 THEN
- FOR i := 1 TO WortAnzahl DO
- FIO.WrStr(OutFile,WortListe[i]);
- FIO.WrLn(OutFile);
- END;
- END;
- FIO.Close(OutFile);
- END SaveListe;
-
- (* ===================== Liest Antwort nach Ja/Nein-Frage *)
-
- PROCEDURE Ja(): BOOLEAN;
- VAR c: CHAR;
- BEGIN
- REPEAT
- c := LeseZeichen();
- UNTIL (c = 'J') OR (c = 'N');
- WriteLn(c);
- RETURN c = 'J';
- END Ja;
-
- (* ==== Gibt den Index eines vorhandenen bzw. die lexiko- *)
- (* ==== graphische Position eines neuen Wortes in der *)
- (* ==== Wortliste zurück. *)
-
- PROCEDURE WortPos(Wort: ARRAY OF CHAR): CARDINAL;
- VAR p: CARDINAL;
- i: INTEGER;
- BEGIN
- p := 0;
- REPEAT
- INC(p);
- i := Str.Compare(Wort,WortListe[p]);
- UNTIL (p = WortAnzahl) OR (i <= 0);
- IF i > 0 THEN INC(p) END;
- RETURN p;
- END WortPos;
-
- (* ============= Worteingabe mit eventueller Einblendung *)
- (* ============= der Wortliste organisieren *)
-
- PROCEDURE LeseWort(VAR Wort: WortTyp);
- VAR anz,x: CARDINAL;
- c: CHAR;
-
- (* =============================== Wortliste einblenden *)
-
- PROCEDURE ZeigeWortListe;
- VAR Fenster,
- FensterUnten,
- AktFenster: Window.WinType;
- fore, back: Window.Color;
- c: CHAR;
- Ende: BOOLEAN;
-
- (* =============== Akt. Ausschnitt der Liste ausgeben *)
-
- PROCEDURE SchreibeListe;
- VAR i,blanks: CARDINAL;
- BEGIN
- blanks := (8-WortLaenge) DIV 2 + 1;
- Window.TextColor(fore); Window.TextBackground(back);
- FOR i := 1 TO 4 DO
- IF (ListPos+i <= 5) THEN
- Window.GotoXY(1,i); Window.ClrEol
- ELSE
- Window.GotoXY(blanks,i);
- IO.WrStr(WortListe[ListPos+i-5])
- END;
- END;
- FOR i := 6 TO 9 DO
- IF (ListPos+i > WortAnzahl+5) THEN
- Window.GotoXY(1,i); Window.ClrEol
- ELSE
- Window.GotoXY(blanks,i);
- IO.WrStr(WortListe[ListPos+i-5])
- END;
- END;
- Window.TextColor(back); Window.TextBackground(fore);
- Window.GotoXY(1,5); Window.ClrEol;
- Window.GotoXY(blanks,5);
- IO.WrStr(WortListe[ListPos]);
- END SchreibeListe;
-
- (* -------------------------------------------------- *)
-
- BEGIN (* von ZeigeWortListe *)
- AktFenster := Window.Top();
- IF SW THEN
- Fenster := Window.Open(FListeDefSW);
- fore := FListeDefSW.Foreground;
- back := FListeDefSW.Background;
- FensterUnten := Window.Open(FUntenDefSW)
- ELSE
- Fenster := Window.Open(FListeDefC);
- fore := FListeDefC.Foreground;
- back := FListeDefC.Background;
- FensterUnten := Window.Open(FUntenDefC)
- END;
- Window.GotoXY(2,1);
- IO.WrStr('['+31C+']' + '['+30C+'] vor/zurück');
- Window.GotoXY(21,1);
- IO.WrStr('[A]..[Z] Anfangsbuchstabe');
- Window.GotoXY(48,1);
- IO.WrStr('[<┘] übernehmen');
- Window.GotoXY(65,1);
- IO.WrStr('[ESC] Abbruch');
- Window.PutOnTop(Fenster);
- Ende := FALSE;
- REPEAT
- SchreibeListe; (* 9 Wörter ausgeben *)
- c := LeseZeichen();
- IF ExtKey THEN (* Erweiterter Code *)
- IF (c = CHR(72)) AND (ListPos > 1) THEN
- DEC(ListPos); (* Cursor oben *)
- ELSIF (c = CHR(80)) AND (ListPos < WortAnzahl) THEN
- INC(ListPos); (* Cursor unten *)
- END
- ELSIF c IN Buchstaben THEN (* Anfangsbuchstabe *)
- ListPos := WortPos(c);
- IF ListPos > WortAnzahl THEN
- ListPos := WortAnzahl
- END;
- ELSIF c = CHR(13) THEN (* RETURN, übernehmen *)
- Wort := WortListe[ListPos];
- anz := WortLaenge;
- Ende := TRUE;
- ELSIF c = CHR(27) THEN (* ESC, Abbruch *)
- Ende := TRUE;
- END;
- UNTIL Ende;
- Window.Close(Fenster);
- Window.Close(FensterUnten);
- Window.PutOnTop(AktFenster);
- END ZeigeWortListe;
-
- (* ---------------------------------------------------- *)
-
- BEGIN (* von LeseWort *)
- anz := 0; x := Window.WhereX();
- REPEAT
- c := LeseZeichen();
- IF ExtKey THEN (* Erweiterter Code *)
- IF c = CHR(59) THEN (* F1 gedrückt *)
- ZeigeWortListe;
- IF anz = WortLaenge THEN
- Window.GotoXY(x,Window.WhereY());
- IO.WrStr(Wort);
- END
- END
- ELSIF c IN Buchstaben THEN (* Buchstabe *)
- Wort[anz] := c;
- INC(anz);
- IO.WrChar(c)
- ELSIF (c = BS) AND (anz > 0) THEN (* Backspace *)
- DEC(anz);
- IO.WrChar(c)
- ELSIF c = '?' THEN (* Fragezeichen *)
- Wort := '?';
- anz := WortLaenge;
- IO.WrChar('?')
- END;
- UNTIL anz = WortLaenge;
- Wort[anz] := 0C; (* Ende markieren *)
- IO.WrLn;
- END LeseWort;
-
- (* ============= Zählt die Treffer, die der Versuch VWort *)
- (* ============= gegenüber GWort erzielt. Gibt in rb die *)
- (* ============= Anzahl der richtigen Buchstaben und in *)
- (* ============= rp die richtigen Positionen zurück *)
-
- PROCEDURE ZaehleTreffer(VWort,GWort: WortTyp;
- VAR rb,rp: CARDINAL);
- VAR TWort: WortTyp;
- i,p: CARDINAL;
- BEGIN
- TWort := GWort;
- rb := 0; rp := 0;
- FOR i := 0 TO WortLaenge-1 DO
- p := Str.Pos(TWort,VWort[i]);
- IF p < MAX(CARDINAL) THEN
- INC(rb);
- TWort[p] := ' ';
- END;
- IF VWort[i] = GWort[i] THEN
- INC(rp);
- END;
- END;
- END ZaehleTreffer;
-
- (* ======= Gibt TRUE zurück, wenn ein Wort noch nicht in *)
- (* ======= der Liste vorhanden ist. Fragt nach, ob es neu *)
- (* ======= aufgenommen werden soll *)
-
- PROCEDURE NeuesWort(Wort: WortTyp;
- VAR aufgenommen: BOOLEAN): BOOLEAN;
- VAR p,i: CARDINAL;
- BEGIN
- p := WortPos(Wort);
- IF (p > WortAnzahl) OR
- (Str.Compare(Wort,WortListe[p]) <> 0) THEN
- WriteLn(' Das Wort kenne ich noch nicht.');
- WriteLn(' Soll ich es in meinen Wortschatz');
- WriteStr(' aufnehmen? (J/N): ');
- IF Ja() THEN
- IF WortAnzahl < MaxAnzahl THEN
- FOR i := WortAnzahl TO p BY -1 DO
- WortListe[i+1] := WortListe[i];
- END;
- WortListe[p] := Wort;
- INC(WortAnzahl);
- gelernt := TRUE;
- END;
- aufgenommen := TRUE;
- ELSE
- aufgenommen := FALSE;
- END;
- RETURN TRUE
- ELSE
- RETURN FALSE;
- END;
- END NeuesWort;
-
- (* ======== Versuch anzeigen und Treffer mit #+ markieren *)
-
- PROCEDURE ZeigeTreffer(Nr,rb,rp: CARDINAL;
- Versuch: WortTyp;
- Fenster: Window.WinType);
- BEGIN
- Window.PutOnTop(Fenster);
- Window.GotoXY(2,Nr+1);
- IO.WrCard(Nr,2); WriteStr('. '); WriteStr(Versuch);
- Window.GotoXY(13,Nr+1);
- IO.WrCharRep('#',rp); IO.WrCharRep('+',rb-rp);
- Window.PutOnTop(FensterMitte);
- END ZeigeTreffer;
-
-
- (* ====================================================== *)
- (* ====================================================== *)
- (* Der Spieler ist an der Reihe *)
- (* ====================================================== *)
-
- PROCEDURE FrageWort;
- VAR GeheimWort,
- Versuch: WortTyp;
- VersNr: CARDINAL;
- gefunden: BOOLEAN;
-
- (* ============ Eingabe und Überprüfung eines Versuches *)
-
- PROCEDURE NaechsterVersuch;
- VAR i: CARDINAL;
- gueltig,
- aufgenommen: BOOLEAN;
- BEGIN
- INC(VersNr);
- REPEAT
- gueltig := TRUE;
- WriteStr(' Ihr');
- WriteNum(VersNr); WriteStr('. Versuch: ');
- LeseWort(Versuch);
- IF Versuch[0] = '?' THEN
- FOR i := VersNr TO MaxVersNr DO
- ZeigeTreffer(i,0,0,'?',FensterLinks);
- END;
- VersNr := MaxVersNr
- ELSIF NeuesWort(Versuch,aufgenommen) THEN
- IF aufgenommen THEN
- IO.WrLn;
- WriteLn(' Wieder etwas Neues gelernt...');
- IO.WrLn;
- WriteStr(' Ihr'); WriteNum(VersNr);
- WriteStr('. Versuch: '); WriteLn(Versuch);
- ELSE
- IO.WrLn;
- WriteLn(' Dann ist der Versuch ungültig!');
- WriteLn(' Probieren Sie ein anderes Wort.');
- IO.WrLn;
- gueltig := FALSE;
- END
- END
- UNTIL gueltig;
- END NaechsterVersuch;
-
- (* ================= Auswertung und Anzeige der Treffer *)
-
- PROCEDURE TrefferAnzeige;
- VAR i,rb,rp: CARDINAL;
- BEGIN
- IF VersNr = MaxVersNr THEN
- WriteStr(' Das geheime Wort lautet ');
- WriteLn(GeheimWort);
- WriteStr(' Ihnen werden');
- WriteNum(VersNr); WriteLn(' Versuche');
- WriteLn(' angerechnet.');
- WriteLn(' Etwas mehr Ehrgeiz bitte!');
- IO.WrLn;
- gefunden := TRUE
- ELSE
- ZaehleTreffer(Versuch,GeheimWort,rb,rp);
- WriteStr(' Richtige Buchstaben:'); WriteNum(rb);
- IO.WrLn;
- WriteStr(' Richtige Positionen:'); WriteNum(rp);
- IO.WrLn; IO.WrLn;
- ZeigeTreffer(VersNr,rb,rp,Versuch,FensterLinks);
- IF rp = WortLaenge THEN
- WriteLn(' Das war richtig!');
- WriteStr(' Sie haben');
- WriteNum(VersNr); WriteLn(' Versuche gebraucht.');
- IO.WrLn;
- gefunden := TRUE;
- END;
- END;
- END TrefferAnzeige;
-
- (* ---------------------------------------------------- *)
-
- BEGIN (* FrageWort *)
- Window.PutOnTop(FensterUnten);
- Window.GotoXY(12,1); IO.WrStr('[?] Lösung verraten');
- Window.GotoXY(42,1); IO.WrStr('[F1] Wortliste zeigen');
- Window.PutOnTop(FensterMitte);
- IO.WrLn;
- VersNr := 0;
- gefunden := FALSE;
- GeheimWort := WortListe[Lib.RANDOM(WortAnzahl) + 1];
- REPEAT
- NaechsterVersuch;
- TrefferAnzeige;
- UNTIL gefunden;
- VersSp := VersNr;
- Window.PutOnTop(FensterUnten); Window.Clear;
- Window.PutOnTop(FensterMitte);
- END FrageWort;
-
-
- (* ====================================================== *)
- (* ====================================================== *)
- (* Der Computer ist an der Reihe *)
- (* ====================================================== *)
-
- PROCEDURE RateWort;
- VAR Versuch: WortTyp;
- WortBeg: CHAR;
- VersNr,
- p: CARDINAL;
- Ende,
- RundeOK: BOOLEAN;
- AnfBst: ARRAY[0..MaxBst-1] OF CHAR;
-
- (* ====== Falls das Wort nicht ermittelt werden konnte, *)
- (* ====== wird überprüft, ob es sich um ein unbekanntes *)
- (* ====== Wort handelt oder ein Eingabefehler vorliegt *)
-
- PROCEDURE NichtGefunden;
- VAR Wort: WortTyp;
- p,i,rb,rp: CARDINAL;
- aufgenommen: BOOLEAN;
- BEGIN
- Window.PutOnTop(FensterMitte);
- WriteLn(' Ich kann das Wort nicht finden.');
- WriteLn(' Bitte geben Sie das Wort ein: ');
- WriteStr(' ');
- LeseWort(Wort);
- IO.WrLn;
- IF NeuesWort(Wort,aufgenommen) THEN
- IF aufgenommen THEN
- FOR i := VersNr TO MaxVersNr DO
- ZeigeTreffer(i,0,0,'?',FensterRechts);
- END;
- VersNr := MaxVersNr
- ELSE
- IO.WrLn;
- WriteLn(' Dann war es ein ungültiges Wort.');
- RundeOK := FALSE;
- END
- ELSE
- p := 1;
- FOR i := 1 TO VersNr-1 DO
- ZaehleTreffer(VersComp[i],Wort,rb,rp);
- IF (rb <> RBComp[i]) OR (rp <> RPComp[i]) THEN
- p := i; RBComp[i] := rb; RPComp[i] := rp;
- END;
- END;
- WriteLn(' Mogeln hat keinen Zweck:');
- WriteStr(' Die Angaben für den');
- WriteNum(p); WriteLn('. Versuch');
- WriteLn(' waren falsch.');
- WriteLn(' Die korrekte Trefferquote ist:');
- WriteStr(' Richtige Buchstaben:');
- WriteNum(RBComp[p]); IO.WrLn;
- WriteStr(' Richtige Positionen:');
- WriteNum(RPComp[p]); IO.WrLn;
- RundeOK := FALSE;
- END;
- IO.WrLn;
- Ende := TRUE;
- END NichtGefunden;
-
- (* ============== Löscht einen Buchstaben aus der Liste *)
- (* ============== der noch möglichen Anfangsbuchstaben *)
-
- PROCEDURE LoescheAnfBst(c: CHAR);
- BEGIN
- Str.Delete(AnfBst,Str.Pos(AnfBst,c),1);
- END LoescheAnfBst;
-
- (* ======== Ermittelt neuen Versuch durch Vergleich der *)
- (* ======== Wörter aus der Liste mit allen bisherigen *)
- (* ======== Versuchen und deren Treffern *)
-
- PROCEDURE NaechsterVersuch;
- VAR VersOK: BOOLEAN;
- rb,rp,i: CARDINAL;
- BEGIN
- INC(VersNr);
- Window.PutOnTop(FensterRechts);
- Window.GotoXY(2,VersNr+1);
- IO.WrCard(VersNr,2); IO.WrChar('.');
- REPEAT
- INC(p); (* nächstes Wort der Liste *)
- WHILE WortBeg <> WortListe[p,0] DO
- (* Kein Wort mehr mit dem akt. Anfangsbuchstaben *)
- LoescheAnfBst(WortBeg);
- IF Str.Length(AnfBst) = 0 THEN
- (* Kein Anfangsbuchstabe mehr da *)
- Window.GotoXY(6,VersNr+1); WriteStr('? ');
- NichtGefunden;
- RETURN;
- END;
- (* Neuen Anfangsbuchstaben auswürfeln *)
- WortBeg := AnfBst[Lib.RANDOM(Str.Length(AnfBst))];
- (* Position des 1. Wortes bestimmen *)
- p := WortPos(WortBeg);
- IF p > WortAnzahl THEN p := 1 END; (* Wrap *)
- END;
- (* Nächsten Kandidaten als Versuch eintragen *)
- VersComp[VersNr] := WortListe[p];
- Window.GotoXY(6,VersNr+1);
- IO.WrStr(VersComp[VersNr]);
- Lib.Delay(AnzDelTime);
- (* Wort gegen alle vorherigen Versuche testen *)
- VersOK := TRUE;
- FOR i := 1 TO VersNr-1 DO
- ZaehleTreffer(VersComp[VersNr],VersComp[i],rb,rp);
- IF (rb <> RBComp[i]) OR (rp <> RPComp[i]) THEN
- VersOK := FALSE
- END;
- END;
- UNTIL VersOK; (* bis alle Treffer übereinstimmen *)
- Window.PutOnTop(FensterMitte);
- END NaechsterVersuch;
-
- (* == Eingabe der Treffer für den Versuch des Rechners. *)
- (* == Mit Backspace kann zur Eingabe für den vorherigen *)
- (* == Versuch zurückgeblättert werden. In diesem Fall *)
- (* == wird FALSE zurückgegeben. Bei gültiger Eingabe *)
- (* == wird in rb die Anzahl der richtigen Buchstaben, *)
- (* == in rp die richtigen Positionen und als Funktions- *)
- (* == ergebnis TRUE zurückgegeben *)
-
- PROCEDURE LeseTreffer(VAR rb,rp: CARDINAL): BOOLEAN;
- VAR c: CHAR;
- BEGIN
- WriteStr(' Richtige Buchstaben: ');
- REPEAT
- REPEAT
- c := LeseZeichen();
- IF (c = BackSpace) AND (VersNr > 1) THEN
- Window.PutOnTop(FensterRechts);
- Window.GotoXY(1,VersNr+1); Window.ClrEol;
- Window.GotoXY(13,VersNr); Window.ClrEol;
- Window.PutOnTop(FensterMitte);
- DEC(VersNr);
- AnfBst := GrossBst;
- p := WortPos(VersComp[VersNr]);
- WortBeg := VersComp[VersNr,0];
- IO.WrLn; IO.WrLn;
- RETURN FALSE (* Zurück zum vorherigen Versuch *)
- END;
- rb := ORD(c)-48;
- UNTIL rb <= WortLaenge;
- WriteLn(c);
- WriteStr(' Richtige Positionen: ');
- REPEAT
- c := LeseZeichen();
- rp := ORD(c)-48;
- UNTIL (rp <= rb) OR (c = BackSpace);
- IF c = BackSpace THEN (* Zurück zu richtige Buchst *)
- Window.GotoXY(Window.WhereX()+1,Window.WhereY()-1);
- IO.WrChar(c)
- END;
- UNTIL c <> BackSpace;
- WriteLn(c); IO.WrLn;
- RETURN TRUE; (* Gültige Treffereingabe *)
- END LeseTreffer;
-
- (* ======== Eingabe, Anzeige und Auswertung der Treffer *)
-
- PROCEDURE TrefferAnzeige;
- VAR i: CARDINAL;
- BEGIN
- IF NOT RundeOK THEN
- (* Eingabefehler oder ungültiges Wort *)
- WriteLn(' Ich beginne von vorne.');
- ELSIF VersNr = MaxVersNr THEN
- (* unbekanntes Wort nicht gefunden *)
- WriteLn(' Das kostet Lehrgeld: ');
- WriteStr(' Mir werden'); WriteNum(MaxVersNr);
- WriteLn(' Versuche angerechnet.');
- ELSE
- (* Treffereingabe *)
- Window.PutOnTop(FensterUnten);
- Window.GotoXY(24,1);
- IO.WrStr('[ <══ ] Letzte Eingabe löschen');
- Window.PutOnTop(FensterMitte);
- REPEAT
- WriteStr(' Mein');
- WriteNum(VersNr); WriteStr('. Versuch: ');
- WriteLn(VersComp[VersNr]);
- UNTIL LeseTreffer(RBComp[VersNr], RPComp[VersNr]);
- (* Trefferanzeige *)
- Window.PutOnTop(FensterUnten); Window.Clear;
- Window.PutOnTop(FensterMitte);
- ZeigeTreffer(VersNr,RBComp[VersNr],RPComp[VersNr],
- VersComp[VersNr],FensterRechts);
- (* Auswertung: Richtige Positionen =0, der 1. Buch- *)
- (* stabe des Wortes kommt nicht mehr als Anfangs- *)
- (* buchstabe in Frage *)
- IF RPComp[VersNr] = 0 THEN
- LoescheAnfBst(VersComp[VersNr,0]);
- WortBeg := ' ';
- END;
- (* Auswertung: Richtige Buchstaben =0, kein Buch- *)
- (* stabe des Wortes kann mehr Anfangsbuchstabe sein *)
- IF RBComp[VersNr] = 0 THEN
- FOR i := 1 TO WortLaenge-1 DO
- LoescheAnfBst(VersComp[VersNr,i]);
- END
- END;
- IF RPComp[VersNr] = WortLaenge THEN (* Heureka! *)
- WriteLn(" Das war's dann wohl...");
- IO.WrLn;
- Ende := TRUE;
- END;
- END;
- END TrefferAnzeige;
-
- (* ---------------------------------------------------- *)
-
- BEGIN (* von RateWort *)
- REPEAT
- IO.WrLn;
- RundeOK := TRUE;
- WriteLn(' Bitte denken Sie sich ein Wort mit');
- WriteNum(WortLaenge);
- WriteLn(' Buchstaben aus und drücken Sie');
- WriteStr(' dann eine Taste. ');
- WortBeg := LeseZeichen();
- IO.WrLn; IO.WrLn;
- VersNr := 0; p := 0;
- Ende := FALSE;
- AnfBst := GrossBst; WortBeg := ' ';
- Window.PutOnTop(FensterRechts); Window.Clear;
- REPEAT
- NaechsterVersuch;
- TrefferAnzeige;
- UNTIL Ende;
- UNTIL RundeOK;
- VersC := VersNr; (* Benötigte Versuche registrieren *)
- END RateWort;
-
-
- (* ====================================================== *)
- (* ====================================================== *)
- (* Der organisatorische Rahmen *)
- (* ====================================================== *)
-
- PROCEDURE Anleitung;
- VAR c: CHAR;
- BEGIN
- Window.PutOnTop(FensterMitte);
- IO.WrStr(' Raten Sie ein Wort, das sich WORD-'); IO.WrLn;
- IO.WrStr(' MASTER ausgedacht hat - oder las-'); IO.WrLn;
- IO.WrStr(' sen Sie das Programm Ihr Wort ra-'); IO.WrLn;
- IO.WrStr(' ten! Gewonnen hat, wer weniger'); IO.WrLn;
- IO.WrStr(' Versuche braucht.'); IO.WrLn;
- IO.WrStr(' Für jeden Versuch gibt es Treffer:'); IO.WrLn;
- IO.WrStr(' - Die Anzahl der richtigen Buch-'); IO.WrLn;
- IO.WrStr(' staben'); IO.WrLn;
- IO.WrStr(' - Die Anzahl der richtigen Posi-'); IO.WrLn;
- IO.WrStr(' tionen (Buchstaben an der rich-'); IO.WrLn;
- IO.WrStr(' tigen Stelle).'); IO.WrLn;
- IO.WrStr(' Doppelte Buchstaben erzielen nur'); IO.WrLn;
- IO.WrStr(' dann zwei Treffer, wenn sie auch'); IO.WrLn;
- IO.WrStr(" im 'Geheimwort' doppelt vorhanden"); IO.WrLn;
- IO.WrStr(' sind.'); IO.WrLn; IO.WrLn;
- IO.WrStr(' Bitte eine Taste drücken....');
- c := IO.RdKey(); Window.Clear;
- END Anleitung;
-
-
- PROCEDURE Spielstart;
- VAR c: CHAR;
- BEGIN
- REPEAT
- WriteLn(' Geben Sie bitte die gewünschte');
- WriteStr(' Wortlänge ein (3..6): ');
- REPEAT
- c := LeseZeichen();
- UNTIL (c >= '3') AND (c <= '6');
- WriteLn(c);
- WortLaenge := ORD(c) - 48;
- LoadListe;
- IF WortAnzahl = 0 THEN
- WriteLn(' Sorry... Es ist keine Datei mit');
- WriteLn(' dieser Wortlänge vorhanden!');
- IO.WrLn;
- END;
- UNTIL WortAnzahl > 0;
- gelernt := FALSE;
- Runde := 0; ScoreC := 0; ScoreSp := 0;
- ListPos := 1;
- Lib.RANDOMIZE;
- END Spielstart;
-
-
- PROCEDURE Spielstand;
- BEGIN
- WriteLn(' Das Ergebnis dieser Runde: ');
- IF VersC < VersSp THEN
- WriteStr(' Ich habe');
- WriteNum(VersSp-VersC); WriteStr(' Versuch');
- IF VersSp-VersC > 1 THEN WriteStr('e') END;
- WriteLn(' weniger');
- WriteLn(' gebraucht und damit gewonnen.');
- ScoreC := ScoreC + VersSp - VersC;
- ELSIF VersSp < VersC THEN
- WriteStr(' Ich habe');
- WriteNum(VersC-VersSp); WriteStr(' Versuch');
- IF VersC-VersSp > 1 THEN WriteStr('e') END;
- WriteLn(' mehr gebraucht');
- WriteLn(' und damit verloren.');
- ScoreSp := ScoreSp + VersC - VersSp;
- ELSE
- WriteStr(' Wir haben beide');
- WriteNum(VersC); WriteStr(' Versuch');
- IF VersC > 1 THEN WriteStr('e') END;
- IO.WrLn;
- WriteLn(' gebraucht.');
- END;
- IO.WrLn;
- WriteStr(' Der Stand nach der');
- WriteNum(Runde); WriteLn('. Runde:');
- WriteNum(ScoreC); WriteStr(' zu'); WriteNum(ScoreSp);
- IF ScoreC > ScoreSp THEN
- WriteLn(' für mich.')
- ELSIF ScoreC < ScoreSp THEN
- WriteLn(' für Sie.')
- ELSE
- WriteLn(' unentschieden.')
- END;
- IO.WrLn;
- END Spielstand;
-
-
- BEGIN (* Main *)
- InitScreen;
- Window.PutOnTop(FensterOben);
- Window.GotoXY(10,1);
- WriteStr('W O R D M A S T E R');
- Window.GotoXY(34,1);
- WriteStr('(C) 1989 Matthias Uphoff & TOOLBOX');
- Anleitung;
- Spielstart;
- REPEAT
- INC(Runde);
- Window.PutOnTop(FensterLinks); Window.Clear;
- Window.PutOnTop(FensterRechts); Window.Clear;
- Window.PutOnTop(FensterMitte); Window.Clear;
- WriteStr(' Okay... auf zur');
- WriteNum(Runde); WriteLn('. Runde.');
- WriteStr(' Möchten Sie anfangen? (J/N): ');
- IF Ja() THEN
- FrageWort;
- WriteLn(' Jetzt bin ich an der Reihe!');
- RateWort
- ELSE
- RateWort;
- WriteLn(' Jetzt sind Sie an der Reihe!');
- FrageWort
- END;
- Spielstand;
- WriteStr(' Noch eine Runde? (J/N): ');
- UNTIL NOT Ja();
- IF gelernt THEN SaveListe END;
- Window.FullScreen := Window.Open(Window.FullScreenDef);
- Window.Clear;
- END WMaster.