浏览代码

Added example: The console game of Pole Chudes

Arthur Yefimov 3 年之前
父节点
当前提交
1dced7dcc6
共有 4 个文件被更改,包括 195 次插入0 次删除
  1. 39 0
      Programs/Pole/Pole.Mod
  2. 65 0
      Programs/Pole/Visual.Mod
  3. 87 0
      Programs/Pole/Words.Mod
  4. 4 0
      Programs/Pole/words.dat

+ 39 - 0
Programs/Pole/Pole.Mod

@@ -0,0 +1,39 @@
+MODULE Pole;
+IMPORT Visual, Words;
+VAR word: Words.Word;
+  done: BOOLEAN;
+
+PROCEDURE GameTurn;
+VAR L: CHAR;
+  guess: BOOLEAN;
+BEGIN
+  Visual.ShowWord(word);
+  Visual.AskLetter(L);
+  Words.ApplyLetter(word, L, guess);
+  IF guess THEN Visual.Guessed(L) ELSE Visual.Failed END;
+  IF Words.IsOpen(word) THEN done := TRUE END
+END GameTurn;
+
+PROCEDURE GameRound;
+BEGIN
+  Words.RandomWord(word);
+  done := FALSE;
+  REPEAT GameTurn UNTIL done;
+  Visual.ShowWord(word);
+  Visual.GameOver
+END GameRound;
+
+PROCEDURE Run;
+VAR repeat: BOOLEAN;
+BEGIN
+  REPEAT
+    GameRound;
+    Visual.AskRepeat(repeat)
+  UNTIL ~repeat
+END Run;
+
+BEGIN
+  Visual.Intro;
+  IF ~Words.loaded THEN Visual.ShowWordsError END;
+  Run
+END Pole.

+ 65 - 0
Programs/Pole/Visual.Mod

@@ -0,0 +1,65 @@
+MODULE Visual;
+IMPORT Words, In, Out;
+
+PROCEDURE Intro*;
+BEGIN Out.Ln; Out.Ln;
+  Out.String('        Добро пожаловать в игру'); Out.Ln; Out.Ln;
+  Out.String('        " П О Л Е   Ч У Д Е С "'); Out.Ln; Out.Ln
+END Intro;
+
+PROCEDURE ShowWord*(VAR word: Words.Word);
+VAR i: INTEGER;
+BEGIN Out.Ln;
+  FOR i := 0 TO 40 DO Out.Char('-') END; Out.Ln; Out.Ln;
+  Out.String('        ');
+  FOR i := 0 TO word.len - 1 DO
+    Out.String(' [');
+    IF word.open[i] THEN Out.Char(word.L[i]) ELSE Out.Char('_') END;
+    Out.Char(']')
+  END;
+  Out.Ln; Out.Ln
+END ShowWord;
+
+PROCEDURE AskLetter*(VAR L: CHAR);
+VAR s: ARRAY 2 OF CHAR;
+BEGIN
+  Out.String('  Буква: '); In.Line(s); L := s[0];
+  WHILE ~(('А' <= L) & (L <= 'Я') OR
+          ('а' <= L) & (L <= 'я') OR
+          (L = 'Ё') OR (L = 'ё')) DO
+    Out.String('  Какая? '); In.Line(s); L := s[0]
+  END;
+  IF ('а' <= L) & (L <= 'я') THEN
+    L := CHR(ORD(L) - ORD('а') + ORD('А'))
+  ELSIF (L = 'Ё') OR (L = 'ё') THEN L := 'Е'
+  END
+END AskLetter;
+
+PROCEDURE AskRepeat*(VAR repeat: BOOLEAN);
+VAR s: ARRAY 2 OF CHAR;
+  c: CHAR;
+BEGIN
+  REPEAT Out.String('  Повторить игру? [д/н] '); In.Line(s); c := s[0]
+  UNTIL (c = 'Д') OR (c = 'д') OR (c = 'Н') OR (c = 'н') OR
+        (c = 'y') OR (c = 'n');
+  repeat := (c = 'Д') OR (c = 'д') OR (c = 'y')
+END AskRepeat;
+
+PROCEDURE Guessed*(L: CHAR);
+BEGIN Out.String('  Есть такая буква! Откройте букву "');
+  Out.Char(L); Out.String('".'); Out.Ln
+END Guessed;
+
+PROCEDURE Failed*;
+BEGIN Out.String('  Нет! Такой буквы здесь нет!'); Out.Ln
+END Failed;
+
+PROCEDURE GameOver*;
+BEGIN Out.String('  Игра окончена!'); Out.Ln
+END GameOver;
+
+PROCEDURE ShowWordsError*;
+BEGIN Out.String('Не найден файл со словами "words.dat".'); Out.Ln
+END ShowWordsError;
+
+END Visual.

+ 87 - 0
Programs/Pole/Words.Mod

@@ -0,0 +1,87 @@
+MODULE Words;
+IMPORT Files, Random;
+CONST maxLetters = 33;
+  maxWords = 1000;
+TYPE
+  Word* = RECORD
+    len*: INTEGER;
+    L*: ARRAY maxLetters OF CHAR;
+    open*: ARRAY maxLetters OF BOOLEAN
+  END;
+
+VAR loaded*: BOOLEAN;
+  error: BOOLEAN;
+  words: ARRAY maxWords, maxLetters OF CHAR;
+  lengths: ARRAY maxWords OF INTEGER;
+  nofwords: INTEGER;
+
+PROCEDURE RandomWord*(VAR word: Word);
+VAR i, n: INTEGER;
+BEGIN
+  n := Random.Int(nofwords);
+  word.len := lengths[n];
+  FOR i := 0 TO word.len - 1 DO
+    word.L[i] := words[n][i];
+    word.open[i] := FALSE
+  END
+END RandomWord;
+
+(** Returns TRUE if all letters in word are open. *)
+PROCEDURE IsOpen*(VAR word: Word): BOOLEAN;
+VAR i: INTEGER;
+BEGIN i := 0;
+  WHILE (i # word.len) & word.open[i] DO INC(i) END
+RETURN i = word.len END IsOpen;
+
+PROCEDURE ApplyLetter*(VAR word: Word; L: CHAR; VAR applied: BOOLEAN);
+VAR i: INTEGER;
+BEGIN applied := FALSE;
+  FOR i := 0 TO word.len - 1 DO
+    IF ~word.open[i] & (word.L[i] = L) THEN
+      word.open[i] := TRUE;
+      applied := TRUE
+    END
+  END
+END ApplyLetter;
+
+PROCEDURE FallbackWords;
+BEGIN
+  loaded := FALSE;
+  nofwords := 2;
+  words[0] := 'РЫБАЛКА'; lengths[0] := 7;
+  words[1] := 'ЯКУБОВИЧ'; lengths[1] := 8
+END FallbackWords;
+
+PROCEDURE LoadWord*(VAR r: Files.Rider);
+VAR c: CHAR;
+  i: INTEGER;
+BEGIN i := 0;
+  Files.ReadChar(r, c);
+  WHILE ~r.eof & (c > ' ') DO
+    IF (i # maxLetters) & ('А' <= c) & (c <= 'Я') THEN
+      words[nofwords][i] := c;
+      INC(i)
+    ELSE error := TRUE
+    END;
+    Files.ReadChar(r, c)
+  END;
+  lengths[nofwords] := i;
+  INC(nofwords)
+END LoadWord;
+
+PROCEDURE LoadWords;
+VAR F: Files.File;
+  r: Files.Rider;
+BEGIN
+  F := Files.Old('words.dat');
+  IF F = NIL THEN FallbackWords
+  ELSE Files.Set(r, F, 0);
+    nofwords := 0; error := FALSE;
+    WHILE ~r.eof & ~error & (nofwords # maxWords) DO LoadWord(r) END;
+    loaded := ~error
+  END
+END LoadWords;
+
+BEGIN
+  LoadWords
+END Words.

+ 4 - 0
Programs/Pole/words.dat

@@ -0,0 +1,4 @@
+ЕЛКА
+ЖАВОРОНОК
+СОТРУДНИК
+ЛОКОМОТИВ