Inhalt:

Vier Gewinnt

Überblick:
Im Rahmen einer Projektarbeit des Grundkurses Informatik 13/ I entstand eine Umsetzung des bekannten Spiels "Vier Gewinnt". Die Regeln sind dabei denkbar einfach: Ein Spieler gewinnt, wenn vier seiner Steine, die abwechselnd in ein Spielfeld geworfen werden, horizontal, vertikal oder auch diagonal eine Reihe bilden.

Programmodifikationen/ Zielsetzungen (Screenshot):
  • Laufzeitumgebung: MS Dos-Grafikmodus
  • Eingabe der Spielzüge von 2 menschlichen Spielern
  • Ausgabe der aktuellen Spielsituation
  • Mitteilung vom Computer, ob ein Sieger vorliegt
  • Quelltext [vierwin.pas, clever4.pas]
 

Variablen/ eigene Datentypen:
type
twert=(leer,pc,player); { Wertebereich des Spielfelds; Aussage ob ein Feld von Spieler 1,2 oder niemandem belegt ist }
tfeld=array[1..8,1..6] of twert; { Speicherbereich des Spielfelds}
tposition=record { Zur Auswertung der Züge der einzelnen Spieler }
   spalte,zeile:byte;
   end;
var
feld:tfeld ; { Eigentliches Spielfeld }
spieler,comp:tposition; {}
eingabe:char; { Auswertung der Eingabe }
ende:boolean; { Programmende/ Schleifenausstieg; kann mit Taste Escape (aufgeben) oder bei Sieg erreicht werden }

Prozeduren/ Funktionen: ruhen sie mit dem Mauszeiger auf einer Deklaration
function winner(p: tposition; f: tfeld): boolean;
function dreier(p: tposition; f: tfeld): boolean;
procedure init;
procedure steinchen(spalte:integer; color:word; am_zug:twert);
procedure abfrage;
procedure message(meldung:string);
procedure pfeil(spalte:integer; color:word);


Verwendete Algorithmen
1. Verwendete Befehle im Grafikmodus (siehe auch TP-Hilfe):
BefehlNutzen im Programm
SetColor(black);allg. Farbangabe
SetTextStyle(DefaultFont, HorizDir,2);Schrift im Grafikmodus
OutTextxy(50,400,meldung);Text im Grafikmodus
Line(x-5,y-10,x,y);Linien für Feldbegrenzung/ Pfeil
SetFillStyle(1,black);Füllfarbe für Steinchen
PieSlice(...);Zeichnet ausgefüllten Kreis

2.Feststellen der Falltiefe des Steines
Um zu bestimmen wie tief ein Stein fallen darf beginnt der Computer vom untersten Feld an solange aufwärts zu zählen, bis ein nicht belegtes Feld gefunden ist (siehe Grafik li). Im Quelltext ist dies so realisiert:
procedure steinchen(spalte:integer; color:word; am_zug:twert);
var zeile:integer;
   p:tposition;
begin
zeile:=6; { Beginn bei letzter Zeile}
while feld[spalte,zeile] <> leer do dec(zeile); {Durchlauf und Test}
...
end;

Gewinnsituation?

3. Überprüfung, ob Gewinner vorliegt
Die Überprüfung ob einer der Spieler gewonnen hat erfolgt direkt nach dem Zug. Die Auswertung des Spielzieles ist dabei nicht trivial. Es reicht hier nicht aus in allen 8 möglichen Richtungen nach 3 Steinen gleicher Farbe zu suchen, schließlich muss der gelegte Stein nicht nur den Anfang oder das Ende einer Vierekette bilden. So kann bei Belegung der Spalten 1,2 und 4 auch in Spalte 3 gelegt und gewonnen werden, obwohl weder nach rechts noch nach links von dieser Spalte aus 3 Steine angrenzen (2 li, 1 re). Daher wird behelfsmäßig die Existenz einer Viererkette angenommen und duch deren Verschiebung entlang der Suchachse ein Vergleich durchgeführt (siehe Grafik links). Für die Suche in der Diagonalen sieht dies so aus (andere Richtungen in clever4.pas):
for i:=0 to 3 do
    if (p.spalte+i-3 > 0) and (p.spalte+i < 9) then
if (f[p.spalte+i-3,p.zeile]=farbe) and
   (f[p.spalte+i-2,p.zeile]=farbe) and
   (f[p.spalte+i-1,p.zeile]=farbe) and
   (f[p.spalte+i,p.zeile]=farbe) then winner:=true;

  4. Hauptschleife des Spiels
repeat
eingabe:=readkey;{Einlesen des Tastenduckes}
case eingabe of
#27: ende:=true;{Escape}
#75: begin {Linke Richtungstaste}
pfeil(spieler.spalte,black);
{Neuen Pfeil setzen}
dec(spieler.spalte);
{Spalteposition nach links verschieben}
if spieler.spalte<1 then spieler.spalte:=8;
{Verlassen des Spielfeldes abfangen}
end;

#77: siehe #75 {rechte Richtungstaste}
#13: begin {Return-> Zug ausführen}
if spieler1 then begin{Spieler 1 am zug}
message(n1+' ,Sie sind am Zug');
steinchen(spieler.spalte,red,player);
end
else
{Spieler 2 am Zug}

begin
message(n2+' ,Sie sind am Zug');
steinchen(spieler.spalte,yellow,pc);
end;
spieler1:=not spieler1;
{anderer Spieler bekommt den Zug}
end;

end;
if
spieler1 then pfeil(spieler.spalte,red)
else pfeil(spieler.spalte,yellow);
{Neuen Pfeil setzen}

until ende;

Verbesserungsmöglichkeiten

©2000 Christoph Stöpel, Steffi Kuphal, Kerstin Keller