home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* VIER.PAS *)
- (* "Vier gewinnt" von Jens Vygen *)
- PROGRAM vier;
- TYPE
- t1 = ARRAY[1..4] OF BYTE;
- t2 = RECORD
- art, zahl : BYTE;
- feldnr : t1;
- END;
- t3 = RECORD
- art, reiheanz, hoehe : BYTE;
- reihenr : ARRAY[1..13] OF BYTE;
- END;
- tReihe = ARRAY[1..69] OF t2;
- tFeld = ARRAY[11..76] OF t3;
- VAR
- reihe : tReihe;
- feld : tFeld;
- spieler, i, j, sieg, zug, tiefe, maxtiefe : BYTE;
- wert : REAL;
- maxwert : ARRAY[0..6] OF REAL;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE U1; (* Initialisierung der Variablen *)
- VAR i1, j1, k1 : BYTE;
- BEGIN
- ClrScr;
- WriteLn('V I E R G E W I N N T');
- WriteLn('-----------------------------------');
- WriteLn;
- WriteLn('Stufe 1 - sehr schlecht');
- WriteLn('Stufe 2 - maessig');
- WriteLn('Stufe 3 - akzeptabel');
- WriteLn('Stufe 4 - sehr gut');
- WriteLn('Stufe 5 - hervorragend');
- WriteLn('Stufe 6 - einsame Spitze');
- WriteLn; Write('Schwierigkeitsgrad(1-6)? '); ReadLn(maxtiefe);
- FOR i1 := 1 TO 69 DO WITH reihe[i1] DO BEGIN art := 0; zahl := 0; END;
- FOR j1 := 1 TO 4 DO BEGIN
- FOR i1 := 1 TO 24 DO
- reihe[i1].feldnr[j1] := ((i1-1) DIV 4)+1+10*(((i1-1) MOD 4)+j1);
- FOR i1 := 25 TO 45 DO
- reihe[i1].feldnr[j1] := ((i1-1) MOD 3)+j1+10*((i1-25) DIV 3+1);
- FOR i1 := 46 TO 57 DO BEGIN
- reihe[i1].feldnr[j1] := ((i1-46) DIV 4)+11*j1+10*(((i1-2) MOD 4));
- reihe[i1+12].feldnr[j1] := ((i1-46) DIV 4)-9*j1+10*(8-((i1-2) MOD 4));
- END;
- END;
- maxwert[0] := -1E11; i := 0; sieg := 0;
- Write('Wer soll beginnen (1=Spieler, 2=Computer)? '); ReadLn(spieler);
- FOR i1 := 11 TO 76 DO BEGIN
- WITH feld[i1] DO BEGIN
- art := 0; hoehe := i1 MOD 10; reiheanz := 0;
- FOR j1 := 1 TO 69 DO
- FOR k1 := 1 TO 4 DO
- IF reihe[j1].feldnr[k1] = i1 THEN BEGIN
- reiheanz := Succ(reiheanz); reihenr[reiheanz] := j1;
- END;
- END;
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- (* Prozedur zur Aktualisierung der Variablen "reihe2","feld2" und "sieg2" *)
- (* nach einem tatsaechlichen oder angenommenen Zug "zug2" durch den Spie- *)
- (* ler "spieler2". *)
- PROCEDURE U2 (VAR reihe2 : tReihe; VAR feld2 : tFeld;
- VAR sieg2, zug2, spieler2 : BYTE);
- VAR i2, pos2 : BYTE;
- BEGIN
- pos2 := 10*zug2+7-feld2[10*zug2+6].hoehe; feld2[pos2].art := spieler2;
- FOR i2 := pos2 TO 10*zug2+6 DO feld2[i2].hoehe := Pred(feld2[i2].hoehe);
- FOR i2 := 1 TO feld2[pos2].reiheanz DO
- WITH reihe2[feld2[pos2].reihenr[i2]] DO BEGIN
- art := art OR spieler2; zahl := Succ(zahl);
- IF (zahl = 4) AND (art < 3) THEN sieg2 := art;
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- (* Funktion zur statischen Stellungsbewertung. Ohne weiter vorauszudenken, *)
- (* wird die an die Funktion uebergebene Stellung aus Sicht desjenigen Spie-*)
- (* lers,dessen Nummer uebergeben wurde,mit einer simplen Methode bewertet. *)
- FUNCTION U3 (VAR reihe3 : tReihe; VAR feld3 : tFeld;
- VAR spieler3 : BYTE): REAL;
- VAR i3 : BYTE; wert3 : REAL;
- BEGIN
- wert3 := 0;
- FOR i3 := 1 TO 69 DO
- WITH reihe3[i3] DO
- IF (art = 1) OR (art = 2) THEN
- wert3 := wert3+zahl*(0.5-abs(spieler3-art));
- U3 := wert3;
- END;
- (* ----------------------------------------------------------------------- *)
- (* Funktion zur dynamischen Stellungsbewertung. Diese rekursive Funktion *)
- (* geht alle moeglichen Zuege durch und ruft sich selbst wieder auf. Ist *)
- (* allerdings die maximale Suchtiefe "maxtiefe" erreicht, so wird die Funk-*)
- (* tion U3 (statische Stellungsbewertung) aufgerufen. Ausserdem speichert *)
- (* die Funktion U4 den nach dem Minimax-Prinzip ermittelten zur Zeit bes- *)
- (* ten Zug (Variable:zug) und ist somit Hauptbestandteil der Funktion U7 *)
- (* (Computerzug). *)
- (*$A-*)
- FUNCTION U4 (reihe4 : tReihe; feld4 : tFeld; spieler4 : BYTE) : REAL;
- VAR sieg4, gegenspieler4, i4 : BYTE;
- wert4 : REAL;
- reiheneu4 : tReihe;
- feldneu4 : tFeld;
- abbr : BOOLEAN;
- BEGIN
- gegenspieler4 := 3-spieler4; tiefe := Succ(tiefe);
- maxwert[tiefe] := -1E10; i4 := 4; abbr := FALSE;
- REPEAT
- IF feld4[10*i4+6].hoehe>0 THEN BEGIN
- reiheneu4 := reihe4; feldneu4 := feld4; sieg4 := 0;
- U2(reiheneu4,feldneu4,sieg4,i4,spieler4);
- IF sieg4 > 0 THEN wert4 := (0.5-abs(sieg4-spieler4))*1E10
- ELSE IF tiefe = maxtiefe THEN wert4 := U3(reiheneu4,feldneu4,spieler4)
- ELSE wert4 := -U4(reiheneu4,feldneu4,gegenspieler4);
- IF wert4 >= -maxwert[tiefe-1] THEN
- BEGIN abbr := TRUE; maxwert[tiefe] := wert4+1; END
- ELSE IF wert4 > maxwert[tiefe] THEN BEGIN
- maxwert[tiefe] := wert4;
- IF tiefe = 1 THEN zug := i4;
- END;
- END;
- IF i4 > 3 THEN i4 := 7-i4 ELSE i4 := 8-i4;
- UNTIL (i4 = 0) OR abbr;
- U4 := maxwert[tiefe]; tiefe := Pred(tiefe);
- END;
- (*$A+*)
- (* ----------------------------------------------------------------------- *)
- (* Funktion zur Eingabe des Spielerzuges. Dieser ist dann auch das Ergeb- *)
- (* nis der Funktion *)
- FUNCTION U5 : BYTE;
- VAR b5 : BOOLEAN; zug5 : BYTE;
- BEGIN
- b5 := FALSE;
- REPEAT
- WriteLn;
- Write('In welche Spalte (1-7) setzen Sie Ihren Stein? '); ReadLn(zug5);
- IF (zug5 > 0) AND (zug5 < 8) AND (feld[10*zug5+6].hoehe > 0) THEN
- b5 := TRUE;
- IF NOT b5 THEN BEGIN
- WriteLn;
- WriteLn(' Dieser Zug ist nicht erlaubt.');
- END;
- UNTIL b5;
- WriteLn; U5 := zug5;
- END;
- (* ----------------------------------------------------------------------- *)
- (* Prozedur zur Ausgabe der momentanen Stellung am Bildschirm *)
- PROCEDURE U6;
- VAR i6, j6, k6 : BYTE;
- BEGIN
- WriteLn;
- FOR i6 := 6 DOWNTO 1 DO BEGIN
- FOR k6 := 1 TO 2 DO BEGIN
- FOR j6 := 1 TO 7 DO BEGIN
- CASE feld[10*j6+i6].art OF
- 0: Write('----');
- 1: Write('OOOO');
- 2: Write('####');
- END;
- Write(' ');
- END;
- WriteLn;
- END;
- WriteLn;
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- (* Funktion zum Berechnen des besten Computerzuges. Dieser beste Zug (1-7) *)
- (* ist dann auch das Ergebnis der Funktion *)
- FUNCTION U7 : BYTE;
- VAR wert7 : REAL;
- BEGIN
- WriteLn; Write('Ich denke...'); tiefe := 0;
- CASE i OF
- 0..2 : zug := 4; (* Fest eingegebene *)
- 3 : IF feld[31].hoehe=0 THEN zug:=5 ELSE zug:=3; (* Anfangszuege *)
- 4..42 : wert7:=U4(reihe,feld,spieler); (* sonstige Zuege *)
- END;
- WriteLn(' Ich setze einen Stein in Spalte ',zug,'.'); WriteLn;
- U7 := zug;
- END;
- (* ----------------------------------------------------------------------- *)
- BEGIN
- U1; U6;
- WHILE (i < 42) AND (sieg = 0) DO BEGIN
- spieler := 3-spieler;
- IF spieler = 1 THEN zug := U7 ELSE zug := U5;
- U2(reihe,feld,sieg,zug,spieler); U6; i := Succ(i);
- END;
- CASE sieg OF
- 0 : WriteLn('Unentschieden.');
- 1 : WriteLn('Ich habe gewonnen.');
- 2 : WriteLn('Du hast gewonnen.');
- END;
- END.