trivial/de

From Free Pascal wiki
Revision as of 08:39, 25 January 2015 by Olaf (talk | contribs) (Created page with "{{VierGewinnt}} <br> Zurück zur Konsolenseite.<br> <br> Dieses Spiel Trivial ist ein einfaches Spiel für die Konsole (Windows), das Terminal (Linux) oder auch...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Template:VierGewinnt
Zurück zur Konsolenseite.

Dieses Spiel Trivial ist ein einfaches Spiel für die Konsole (Windows), das Terminal (Linux) oder auch für die Kommandozeile (DOS).
Das Spiel soll die Möglichkeiten von Free Pascal demonstrieren.

Dieses Spiel hat keine Hilfe.
Das Programm wird durch das drücken einer der Tasten <ESC>, oder <E> beendet.

Das Hauptprogramm trivial ruft die einzelnen Unterprogramme auf:

program trivial;

{$mode objfpc}{$H+}
{$IMPLICITEXCEPTIONS OFF}

uses
  uDateiEinLesen,
  uSpielLogik,
  uAusgabe,
  Crt;

{$R *.res}


begin

  // Liest die Datei mit den Fragen ein
  subDateiEinlesen;
  repeat

    subFragenReihenfolge;
    subAusgabe;
    subEingabe;
    // Zwei Sekunden Pause
    Delay(2000);
  until 0 > 1;

end.



Die Unit subDateiEinlesen.pas liest die Textdatei mit den Fragen ein.
Die Datei mit den Fragen hat folgendes Format:

  • Die Datei mit den Fragen ist eine csv-Datei ohne Kopfzeile und ohne Größenbegrenzung.
  • Das Trennzeichen zwischen der Frage und den möglichen Antworten ist das Semikolon.
  • Die erste Antwort, die nach der Fage kommt ist die richtige Antwort.
unit uDateiEinLesen;

{$mode objfpc}{$H+}
{$IMPLICITEXCEPTIONS OFF}

interface

uses
  SysUtils, uSpielLogik;

var
  intSemikolonZaehler: integer = 0;

procedure subDateiEinlesen;

implementation

procedure subArrayZuWeisen(strDateiInhalt: string);
var
  intI: integer = 0;
  //intSemikolonZaehler: integer = 0;
  intarrLaenge: integer = 0;

begin

  // prüft, ob ein leerer String übergeben wurde
  if strDateiInhalt = '' then
    Exit;

  // setzt den Semikolonzähler wieder auf 0
  intSemikolonZaehler := 0;

  // Legt die neue Grösse des Arrays fest
  intarrLaenge := length(arrTrivial);
  SetLength(arrTrivial, intarrLaenge + 1);

  for intI := 0 to length(strDateiInhalt) do
  begin

    if strDateiInhalt[intI] = ';' then
      intSemikolonZaehler := intSemikolonZaehler + 1
    else
    begin

      case intSemikolonZaehler of
        0:
          arrTrivial[intarrLaenge].strFrage :=
            arrTrivial[intarrLaenge].strFrage + strDateiInhalt[intI];
        1:
          arrTrivial[intarrLaenge].strAntwort1 :=
            arrTrivial[intarrLaenge].strAntwort1 + strDateiInhalt[intI];
        2:
          arrTrivial[intarrLaenge].strAntwort2 :=
            arrTrivial[intarrLaenge].strAntwort2 + strDateiInhalt[intI];
        3:
          arrTrivial[intarrLaenge].strAntwort3 :=
            arrTrivial[intarrLaenge].strAntwort3 + strDateiInhalt[intI];
      end;

    end;

  end;

end;


procedure subDateiEinlesen;
var
  datDatei: TextFile;
  strDateiInhalt: string;

begin

  // öffnet die Datei
  AssignFile(datDatei, 'Trivial.txt');
  // setzt den Dateizeiger auf den Anfang der Datei
  Reset(datDatei);

  // liest die Datei bis zu ihrem Ende ein
  while not EOF(datDatei) do
  begin
    ReadLn(datDatei, strDateiInhalt);
    if strDateiInhalt <> '' then
      subArrayZuWeisen(strDateiInhalt);
  end;

  //Schliesst die Datei
  CloseFile(datDatei);

end;

end.



Die Unit uSpiellogik.pas enthält die Spielsteuerung.
Hier befindet sich auch die Anweisung für den Programmabbruch.
Die Tasten <ESC>, oder <E> beenden das Programm.

unit uSpielLogik;

{$mode objfpc}{$H+}
{$IMPLICITEXCEPTIONS OFF}

interface

uses
  SysUtils, crt;

type
  TTrivial = record
    strFrage: string;
    strAntwort1: string;
    strAntwort2: string;
    strAntwort3: string;
  end;


type
  TAntwort = record
    strAntwort1: string;
    strAntwort2: string;
    strAntwort3: string;
  end;


var
  arrTrivial: array of TTrivial;
  typeAntwort: TAntwort;

const
  // Die Konstanten sind typisierte Konstanten
  conintZufallszahlAntwort: integer = 0;
  conintZufallszahlArray: integer = 0;


procedure subFragenReihenfolge;
procedure subEingabe;

implementation

uses
  uAusgabe;

procedure subZufallszahlArray;
begin
  randomize;
  conintZufallszahlArray := random(length(arrTrivial));
end;


procedure subZufallszahlAntwort;
begin
  randomize;

  // Da die Verteilung der Zufallszahlen bei random(2) + 1 zu ungenau ist,
  // wurde dieser Lösungsansatz gewählt:
  conintZufallszahlAntwort := random(29) + 1;

  if (conintZufallszahlAntwort mod 3) = 0 then
    conintZufallszahlAntwort := 3
  else if (conintZufallszahlAntwort mod 2) = 0 then
    conintZufallszahlAntwort := 2
  else
    conintZufallszahlAntwort := 1;

  // Alternativ zu obigen Weg geht auch dieser Weg:
  {case conintZufallszahlAntwort of
    3, 6, 9, 12, 15, 18, 21, 24, 27, 30:
      conintZufallszahlAntwort := 3;
    2, 4, 8, 10, 14, 16, 20, 22, 26, 28:
      conintZufallszahlAntwort := 2;
    else
      conintZufallszahlAntwort := 1;
  end;}

end;


procedure subFragenReihenfolge;
begin
  // Wählt die Frage aus
  subZufallszahlArray;
  // Wählt aus, an welcher Stelle
  // die richtige Antwort erscheinen soll
  subZufallszahlAntwort;

  case conintZufallszahlAntwort of
    1:
    begin
      typeAntwort.strAntwort1 := arrTrivial[conintZufallszahlArray].strAntwort1;
      typeAntwort.strAntwort2 := arrTrivial[conintZufallszahlArray].strAntwort2;
      typeAntwort.strAntwort3 := arrTrivial[conintZufallszahlArray].strAntwort3;
    end;
    2:
    begin
      typeAntwort.strAntwort1 := arrTrivial[conintZufallszahlArray].strAntwort2;
      typeAntwort.strAntwort2 := arrTrivial[conintZufallszahlArray].strAntwort3;
      typeAntwort.strAntwort3 := arrTrivial[conintZufallszahlArray].strAntwort1;
    end;
    3:
    begin
      typeAntwort.strAntwort1 := arrTrivial[conintZufallszahlArray].strAntwort3;
      typeAntwort.strAntwort2 := arrTrivial[conintZufallszahlArray].strAntwort1;
      typeAntwort.strAntwort3 := arrTrivial[conintZufallszahlArray].strAntwort2;
    end;
    else
    begin
      typeAntwort.strAntwort1 := ' Fehler ' + IntToStr(conintZufallszahlAntwort);
      typeAntwort.strAntwort2 := ' Fehler ' + IntToStr(conintZufallszahlAntwort);
      typeAntwort.strAntwort3 := ' Fehler ' + IntToStr(conintZufallszahlAntwort);
    end;
  end;
end;


procedure subEingabe;
var
  chrEingabe: char = ' ';

begin

  // Wandelt Tastatureingabe in Kleinbuchstaben um
  chrEingabe := LowerCase(Readkey);

  // Überschreibt den Inhalt der Statuszeile und
  // setzt die Farbe für die Schrift wieder auf Hellgrau
  subStatuszeile('                                                          ',
    LightGray);

  case chrEingabe of
    #27, 'q', 'e':
    begin
      // Gibt an der Statuszeile das Programmende aus und
      // setzt die Farbe für die Schrift auf Hellgrau
      subStatuszeile('Das Programm Trivial wurde beendet.', LightGray);
      halt;
    end;

    'a':
    begin
      begin
        if typeAntwort.strAntwort1 =
          arrTrivial[conintZufallszahlArray].strAntwort1 then
          subStatuszeile('Richtig', LightGreen)
        else
          subStatuszeile('Falsch', LightRed);
      end;
    end;

    'b':
    begin
      begin
        if typeAntwort.strAntwort2 =
          arrTrivial[conintZufallszahlArray].strAntwort1 then
          subStatuszeile('Richtig', LightGreen)
        else
          subStatuszeile('Falsch', LightRed);
      end;
    end;

    'c':
    begin
      if typeAntwort.strAntwort3 =
        arrTrivial[conintZufallszahlArray].strAntwort1 then
        subStatuszeile('Richtig', LightGreen)
      else
        subStatuszeile('Falsch', LightRed);
    end;
  end;

end;

end.



Die Unit uAusgabe.pas ist für die Anzeige des Spiels an der Konsole zuständig.

unit uAusgabe;

{$mode objfpc}{$H+}
{$IMPLICITEXCEPTIONS OFF}

interface

uses
  SysUtils, crt, uSpielLogik;

const
  constrCopyright = '(c) 2015 by Olaf Schanz';
  constrVersion = 'Version: 0.4.0';
  conintStatuszeile = 14;

procedure subAusgabe;
procedure subStatuszeile(strUebergabe: string; intFarbe: integer);


implementation


function funTextZentrieren(strText: string): integer;
begin
  Result := Trunc((80 - length(strText)) / 2);
end;


procedure subTitel;
begin
  ClrScr;
  GOTOXY(funTextZentrieren('TRIVIAL'), 1);
  Write('TRIVIAL');
  GOTOXY(funTextZentrieren(constrVersion), 2);
  Write(constrVersion);
  GOTOXY(funTextZentrieren(constrCopyright), 3);
  Write(constrCopyright);
end;


procedure subKoerper;
begin
  GOTOXY(1, 6);
  Write(arrTrivial[conintZufallszahlArray].strFrage);
  GOTOXY(1, 8);
  Write('a) ' + typeAntwort.strAntwort1);
  GOTOXY(1, 9);
  Write('b) ' + typeAntwort.strAntwort2);
  GOTOXY(1, 10);
  Write('c) ' + typeAntwort.strAntwort3);
  GOTOXY(1, 12);
end;


procedure subStatuszeile(strUebergabe: string; intFarbe: integer);
begin
  TextColor(intFarbe);
  GOTOXY(1,conintStatuszeile);
  Write(strUebergabe);
  TextColor(LightGray);
  GOTOXY(1,conintStatuszeile + 2);
end;


procedure subInfo();
begin
  GOTOXY(1,conintStatuszeile + 1);
  WriteLn('Die Tasten <ESC>, <q> oder <e> beenden das Programm.');
end;

procedure subAusgabe;
begin
  subTitel;
  subKoerper;
  subInfo;
end;

end.



Beispiel für die Datei (Trivial.txt) die die Fragen und die Antworten enthält:

Was ist der Pumukl?;ein Kobold;ein Klabautermann;ein Schreinermeister
Was ist ein Gugelhupf?;ein Kuchen;eine Froschart;ein Schnaps
Was sind Tapas?;kleine Appetithappen;Tiere;Gebäude
Was sind Tapire?;Tiere;kleine Appetithappen;Wanddekorationen
Was sind Tapeten?;Wanddekorationen;ein Kuchen;kleine Tiere
Was ist ein Wolpertinger?;ein bayerisches Fabelwesen;eine seltene Tierart;ein Einwohner des Ortes Wolpert
Was ist ein Tatzelwurm?;ein alpenländisches Fabeltier ählich einem Drachen;ein seltene Wurmart;eine Katze
Was ist ein Lindwurm?;ein Fabeltier ähnlich einer Schlange;eine seltene Wurmart;eine Schlange
Was ist Frau Holle?;eine Märchen- oder Sagengestalt;ein Hausmädchen;eine Putzfrau
Was ist ein Wal?;ein Säugetier;ein Fisch;eine Amphibie
Was ist ein Pinguin?;ein Vogel;ein Fisch;ein Säugetier
Wer nascht mehr Süsses?;Frauen;Männer;beide naschen gleich viel
Was ist eine Schnecke?;ein Weichtier;ein Primat;eine Pilzart
Wann sind die Rauhnächte?;meist zwischen dem 24.12. und dem 06.01.;zu Ostern;zwischen dem 06.7. und dem 01.08.
Was ist Freibier?;ein Bier das man selbst nicht zahlen mus;obergärig;untergärig
Was ist ein Obazter?;ein angemachter Käse;ein Raufbold;ein Kuchen



--Olaf 08:39, 25 January 2015 (CET)