|| In zustand.m wird der Zustand des Tetris-Spiels geaendert.
|| Der Zustand umfasst die Daten des Spiels (wie liegen die Steine)
|| ebenso wie Verwaltungsdaten
%include "parameter" || parameter.m
||hoehe, breite : Spielfeldgroesse
||tempo : Spielgeschwindigkeit
||drehen,
||rechts, links : Tasten zum bewegen der Steine
%include "eingabe" || eingabe.m
||zeichen : erstes Zeichen des Eingabestreams
||rest : der Rest des Streams ab dem Return
%include "zellen" || zellen.m
||
%include "stein" || stein.m
||neuerstein : num->stein
||-----
|| Der Zustand ist ADT:
abstype tzustand with
startzustand :: num->tzustand
|| Leerer Schirm, zufaelliger 1ter Stein (gemaess num)
neuerzustand :: tzustand->teinzeichen->tzustand
|| Ein Zustand wird geaendert
geaendert :: tzustand->bool
|| Ist der Zustand geaendert?
ende :: tzustand->bool
|| Ist der Zust. Endzustand (Spielende)
ausgeben :: tzustand->[char]
|| Zustand wird in ASC gewandelt
zufallszahl :: tzustand->num
|| Aus dem Zustand wird der Wert der aktuellen Zufallszahl extrahiert
tzustand == (tverwaltungsdaten, tspieldaten, taenderung)
tverwaltungsdaten == (tspielende,tcountdown, tzufallszahl)
tspielende == bool
tcountdown == num
tzufallszahl == num
tspieldaten == (tbildschirm, tspielstein)
tbildschirm == tzellen
tspielstein == tstein
taenderung == bool
|| Steht nicht mit bei den Verwaltungsdaten, da diese Flag haeufig
|| gebraucht wird und so der Zugriff weniger umstaendlich ist.
|| Der Startzustand wird berechnet, die Folge der Zufallszahlen
|| wird mit zeit initiallisiert
startzustand zeit
= ((False,0,zufall zeit), (startbild,neuerstein (zufall zeit)),True)
where
startbild
= neuezellen (breite, hoehe, (maskestart breite hoehe))
|| neuezellen aus dem Modul zellen.m bekommt eine Maske und
|| erzeugt eine entsprechende Zellstruktur
maskestart breite hoehe
= rep breite '1',
if hoehe =1
= '1':(rep (breite-2) '0')++"1"++ maskestart breite (hoehe-1),
otherwise
|| Der Zustand wird geaendert:
|| Zuerst werden die Aktionen des Spielers abgearbeitet,
|| dann faellt der Stein, falls wieder eine bestimmte Zeit verstrichen ist
neuerzustand zustand eingabe
= absinken (steuern zustand eingabe)
where
steuern (verwaltungsdaten,(bildschirm,stein),aenderung) eingabe
|| wenn Drehung gewuenscht und kollisionsfrei:
|| Stein drehen
= (verwaltungsdaten,(bildschirm,(steindrehen stein)), True),
if (eingabe = d) & (kollisionsfrei bildschirm (gibkoordinaten (steindrehen stein)) (steinstruktur (steindrehen stein)))
|| wenn Bewegung nach rechts gewuenscht und kollisionsfrei:
|| Stein nach rechts
= (verwaltungsdaten,(bildschirm,(steinrechts stein)), True),
if (eingabe = r) & (kollisionsfrei bildschirm (gibkoordinaten (steinrechts stein)) (steinstruktur (steinlinks stein)))
|| wenn Bewegung nach links gewuenscht und kollisionsfrei : Stein nach links
= (verwaltungsdaten,(bildschirm,(steinlinks stein)), True),
if (eingabe = l) & (kollisionsfrei bildschirm (gibkoordinaten (steinlinks stein)) (steinstruktur (steinlinks stein)))
||
= (verwaltungsdaten, (bildschirm,stein),False),
if (eingabe = 'O') & (system "oberon")=("","",0)
|| sonst keine Steinbewegung
= (verwaltungsdaten,(bildschirm,stein),False),
otherwise
d = drehung
r = rechts
l = links
absinken ((ende,countdown,zufi),(bild,stein),aenderung)
= ((ende,countdown+1,zufi),(bild,stein),aenderung),
if countdown < tempo
|| Zeitpunkt zum absinken ist noch nicht gekommen
= ((ende,0,zufi),(bild,steinunten stein),True),
if (countdown = tempo) & (kollisionsfrei bild (gibkoordinaten (steinunten stein)) (steinstruktur (steinunten stein)))
|| abgesunken
= ((ende,0,zufall zufi),(vereinigung bild (gibkoordinaten stein) (steinstruktur stein),steinneu),True),
if (kollisionsfrei bild (gibkoordinaten steinneu) (steinstruktur steinneu))
|| unten angekommen: Neuer Stein
= ((True,0,zufall zufi),(vereinigung bild (gibkoordinaten stein) (steinstruktur stein),steinneu),False),
|| Neuer Stein passt nicht mehr: Ende.
otherwise
where
steinneu = neuerstein (zufall zufi)
|| Abfragen
ende ((end,countdown,zufi),(spieldaten),aenderung)
= end
geaendert (verwaltung,spiel,aenderung)
= aenderung
zufallszahl ((end,count,zufi),spiel,aend)
= zufi
zufall :: num ->num
zufall x = ((x*547334)+11939) mod 5424563
|| Ausgabe wird von zellen.m erzeugt
ausgeben (verw,(bild,stein),aenderung)
= ausgabe bild (gibkoordinaten stein) (steinstruktur stein)