[FONT=courier new]VAR_INPUT
EB: BYTE; // Eingangsbyte für vertikale Auswahl (Reihe)
RESET: BOOL; // Spielfeld leeren
END_VAR
VAR_IN_OUT
SPIELER: BOOL; // Spielerauswahl -> 0 = Spieler 1 (ROT), 1 = Spieler 1 (GELB)
// wird intern nach Spielzug umgeschaltet,
// kann extern vorgegeben werden
END_VAR
VAR
SPIELFELD: ARRAY [1 .. 7, 1 .. 6] OF INT; // Spielfeld (7 Spalten, 6 Zeilen)
SPIELZUEGE: ARRAY [1 .. 42, 0 .. 2] OF INT; // Speicher Spielzüge (max. 7 x 6 = 42 Spielzüge,
// 0 enthält Spalte
// 1 enthält Zeile
// 2 enthält Spieler)
SPIELZUG_Nr: INT; // Zähler Spielzüge
EB_OLD: BYTE; // Bytemerker für Eingangsbyte
END_VAR
VAR_TEMP
Spielzug: BOOL; // Neuen Spielzug versuchen
Fehler: BOOL; // Spielzug korrekt absolviert
Gewinn: BOOL; // Spielzug mit Gewinn absolviert
Spalte: INT; // Index-Variable horizontal (7 Spalten nebeneinander)
Zeile: INT; // Index-Variable vertikal (6 Zeilen übereinander)
Folge: INT; // Folge gleicher Spielsteine für Gewinnauswertung
END_VAR
// Spielfeld rücksetzen
IF RESET THEN // nur bei Reset ausführen (man könnte
FOR Zeile:= 1 TO 6 BY 1 DO // die 6 Zeilen durchlaufen
FOR Spalte:= 1 TO 7 BY 1 DO // die 7 Spalten durchlaufen
SPIELFELD[Spalte, Zeile]:= 0; // Spieler aus Feld löschen
END_FOR;
END_FOR;
FOR SPIELZUG_Nr:= 42 TO 1 BY -1 DO // die maximal möglichen Spielzüge rückwärts durchlaufen
SPIELZUEGE[SPIELZUG_Nr, 0]:= 0; // Spalte auf 0 setzen
SPIELZUEGE[SPIELZUG_Nr, 1]:= 0; // Zeile auf 0 setzen
SPIELZUEGE[SPIELZUG_Nr, 2]:= 0; // Spieler auf 0 setzen
END_FOR; // SPIELZUG_Nr ist am Ende auf 1 zurückgesetzt
END_IF;
// Neuer Spielzug?
Spielzug:= EB <> EB_OLD; // Eingangsbyte ungleich dem letzten Zyklus
EB_OLD:= EB; // Eingangsbyte für nächsten Zyklus speichern
// nur bei neuem Spielzug ausführen
IF Spielzug THEN // Wenn das Eingansbyte verändert wurde
// Initialisierung
Fehler:= true; // Fehler initialisieren
Gewinn:= false; // Gewinn initialisieren
//Spaltenabfrage
CASE BYTE_TO_INT (EB) OF
0: Spalte:= 0; // keine Spalte gewählt
1: Spalte:= 1; // Spalte 1 definieren
2: Spalte:= 2; // Spalte 2 definieren
4: Spalte:= 3; // Spalte 3 definieren
8: Spalte:= 4; // Spalte 4 definieren
16: Spalte:= 5; // Spalte 5 definieren
32: Spalte:= 6; // Spalte 6 definieren
64: Spalte:= 7; // Spalte 7 definieren
ELSE: Spalte:= -1; // falsche (mehrfache) Auswahl
END_CASE;
// Leeres Feld suchen
IF Spalte > 0 THEN // nur wenn eine (korrekte) Spalte ausgewählt wurde
// Leere Zeile suchen
FOR Zeile:= 1 TO 6 BY 1 DO // die 6 Zeilen durchlaufen
IF SPIELFELD[Spalte, Zeile] = 0 THEN // wenn Spielfeld leer,
SPIELFELD[Spalte, Zeile]:= SEL (G:= SPIELER, IN0:= 1, IN1:= 2); // dann Spieler eintragen
SPIELZUEGE[SPIELZUG_Nr, 0]:= Spalte; // Spalte des Spielzuges merken
SPIELZUEGE[SPIELZUG_Nr, 1]:= Zeile; // Zeile des Spielzuges merken
SPIELZUEGE[SPIELZUG_Nr, 2]:= SPIELFELD[Spalte, Zeile]; // Spieler des Spielzuges merken
Fehler:= false; // Spielzug OK, Fehler rücksetzen
EXIT; // FOR-Schleife verlassen
END_IF;
END_FOR;
END_IF;
// Spielzug fehlerhaft?
IF Fehler THEN // Fehlerauswertung
;
ELSE // Gewinnauswertung
//Spalte prüfen
IF SPIELZUEGE[SPIELZUG_Nr, 1] > 3 THEN
Folge := 1; // Folge gleicher Spielsteine initieren
Spalte:= SPIELZUEGE[SPIELZUG_Nr, 0]; // Spalte des aktuellen Spielzuges auslesen
Zeile := SPIELZUEGE[SPIELZUG_Nr, 1]; // Zeile des aktuellen Spielzuges auslesen
REPEAT
Zeile:= Zeile - 1; // letzten Wert für Zeile um eins verringern
Folge:= SEL (G:= SPIELFELD[Spalte, Zeile] = // Im Spielfeld der
SEL (G:= SPIELER, IN0:= 1, IN1:= 2), // gleicher Spieler eingetragen?
IN0:= 0, // nein: Folge gleicher Spielsteine auf 1 rücksetzen
IN1:= Folge + 1); // ja: Folge Spielsteine um 1 erhöhen
UNTIL Folge = 0 OR Folge = 4 OR Zeile = 1 // Schleife eventuell wiederholen
END_REPEAT;
Gewinn:= Folge = 4; // Gewinn setzen, wenn Folge=4
END_IF;
END_IF; // Ende Fehler-/Gewinnprüfung
// automatischer Spielerwechsel
IF NOT (Fehler OR Gewinn) THEN // korrekter Spielzug ohne Gewinn
SPIELER:= NOT SPIELER; // Spieler wechseln
SPIELZUG_Nr:= SPIELZUG_Nr + 1; // nächster Spielzug
END_IF;
END_IF; // Ende Spielzug
[/FONT]