||Tetris in Miranda
||Idee: Mark Caeles Weyer + Fabian Nilius
||Realisierung: Fabian Nilius

||Hauptmodul:
||Hier wird das Spiel gestartet und beendet.
||Hier findet auch das einzige nicht-funktionale statt,
||da hier die Zeit (fuer den Zufallsgenerator) eingelesen wird.
||Der Eingabestream wird als unendlicher Stream an das Programm uebergeben.


%include "zustand" || zustand.m
|| Startzustand
|| Uebergang von einem Zustand zum Naechsten


%include "eingabe" || eingabe.m
|| Routinen zur Ein/Ausgabe, unter anderem:
|| teinstream
|| tausstream
|| eingabe
|| rest


%include "zellen"  || zellen.m
%include "stein"   || stein.m
|| hier eingebunden, aber erst von zustand benutzt, und dort erklaert



|| Startaufruf - Holt Systemzeit und Eingabestream (  $-  )

tetris :: tausstream

tetris 
= spielschritt (startzustand zeit) $-




|| Hauptschleife des Programms:
|| Aktuellen Zustand ausgeben
|| Eingabe lesen
|| Neuen Zustand berechnen
|| Rekursion


spielschritt :: tzustand->teinstream->tausstream

spielschritt zustand stream

|| Falls nicht Ende und Darstellung noetig
= (ausgeben zustand) ++ (spielschritt zustandneu (rest stream)),
  if (ende zustand = False) & (geaendert zustand)

|| Falls nicht Ende, Darstellung aber unveraendert
= spielschritt zustandneu (rest stream),
  if (ende zustand = False)

|| Falls Ende
= spielende zustand stream,
  otherwise

  where 

  zustandneu
  = neuerzustand zustand (eingabe stream)



|| spielende: Der Zustand wird hierhin mituebergeben, damit die in Zustand
|| kodierte Zufallszahl nicht verloren geht (fuer ein neues Spiel)

  spielende zustand stream
  = "Wir hoffen, Ihnen hat das Spiel gefallen.\nSie haben eine einfaches funktionales Programm sehr gluecklich gemacht.\n\nVerspueren Sie den Wunsch, noch einmal zu spielen,\nso tippen Sie '4'. Sonst bitte '2'.\n" ++ abwarten zustand stream


  abwarten zustand stream
  = [],
    if (eingabe stream) = '2'
  = spielschritt (startzustand (zufallszahl zustand)) (rest stream),
    if (eingabe stream) = '4'
  = abwarten zustand (rest stream),
    otherwise




|| Tja ja, nicht wirklich funktional

zeit :: num

zeit 
= ausschnitt (system "date +%H%M%S")

  where

  ausschnitt (ausgabe,fehler,exit) 
  = numval (take 6 ausgabe)