FUNCTION Bewertung(AmZug:tstein):integer; CONST maxval = maxint; VAR Summe, spst, rest : integer; x : Spieler..Rechner; om,gm : ARRAY[Spieler..Rechner] OF integer; PROCEDURE offen_zu_Muehlen(k:tstein; VAR om,gm :integer); (* Anzahl der offenen und geschlossenen Muehlen ermitteln *) VAR i,j,Z,L,f,anz,n,korr,halb:integer; m:tstein; BEGIN om:=0; gm:=0; halb:=0; korr:=0; (* Korrektur der offenen Muehlen ueber Kreuz *) FOR i:=0 TO 15 DO BEGIN Z:=0; FOR j:=0 TO 2 DO BEGIN m:=Feld.Brett[Muehlen[i,j]]; IF m=k THEN Z:=succ(Z) ELSE IF m<>leer THEN Z:=4 ELSE f:=Muehlen[i,j]; END; CASE Z OF 2 : BEGIN IF Feld.Brett[Muehlen_Nachb[f,0]]=k THEN IF Feld.Brett[Muehlen_Nachb[f,1]]=k THEN IF Feld.Brett[Muehlen_Nachb[f,2]]=k THEN IF Feld.Brett[Muehlen_Nachb[f,3]]=k THEN korr:=succ(korr); (* Zahl der ueberkreuz-Muehlen *) CASE Feld.Status[k].Modus OF Setzen, Springen: om:=succ(om); Ziehen : BEGIN anz:=0; FOR j:=0 TO 3 DO BEGIN n:=Nachbar[f,j]; IF n<>30 THEN IF Feld.Brett[n]=k THEN BEGIN IF NOT(n IN Muehlen_menge[i]) THEN anz:=succ(anz) END ELSE IF Feld.Brett[n]<>leer THEN halb:=halb OR 1; (* Muehle verstellt? *) END; IF anz <> 0 THEN BEGIN om:=succ(om); IF odd(halb) THEN halb:=2; END ELSE halb:=halb AND 2; END; END; (* case Modus *) END; 3 : gm:=succ(gm); END; (* case Z of *) END; (* for i *) om := om - korr DIV 2; IF k<>AmZug THEN IF Feld.Status[geg[k]].Modus=Ziehen THEN BEGIN IF halb AND 2<>0 THEN om := pred(om) END ELSE IF om<>0 THEN om:=pred(om); END; FUNCTION SteinBewertung(k:tstein):integer; (* Bewertet werden die Bewegungsfreiheiten der steine und ob als naechster Zug eine Muehle geschlossen werden kann *) VAR i,j,N,Wert : integer; BEGIN Wert:=0; FOR i:=0 TO 23 DO IF Feld.Brett[i]=k THEN BEGIN FOR j:=0 TO 3 DO BEGIN N:=Nachbar[i,j]; IF N<>30 THEN IF Feld.Brett[N]=leer THEN Wert:=succ(Wert); END; END; SteinBewertung:=Wert END; BEGIN (* Bewertung *) offen_zu_Muehlen(Spieler,om[Spieler],gm[Spieler]); offen_zu_Muehlen(Rechner,om[Rechner],gm[Rechner]); spst:=SteinBewertung(Spieler); rest:=SteinBewertung(Rechner); IF om[AmZug]<>0 THEN BEGIN Summe:=5*(2*ord(AmZug)-3); IF om[geg[AmZug]]<>0 THEN om[geg[AmZug]]:=pred(om[geg[AmZug]]) END ELSE IF om[geg[AmZug]]<>0 THEN Summe:=-5*(2*ord(AmZug)-3) ELSE Summe:=0; Summe:=Summe-40*om[Spieler]-30*gm[Spieler]-spst +40*om[Rechner]+30*gm[Rechner]+rest; WITH Feld.Status[Rechner] DO Summe:=Summe+20*(steine+zaehler); WITH Feld.Status[Spieler] DO Summe:=Summe-20*(steine+zaehler); IF Feld.Status[AmZug].Modus <> Setzen THEN BEGIN FOR x:=Spieler TO Rechner DO WITH Feld.Status[x] DO IF (steine=3) AND (om[geg[x]]<>0) THEN Summe:=Summe+80*(3-2*ord(x)); IF (spst<=3) AND (Feld.Status[Spieler].Modus=Ziehen) THEN BEGIN Summe:=Summe+4*(4-spst); IF spst=0 THEN IF AmZug=Spieler THEN Summe:=maxval ELSE Summe:=Summe+80; END; IF (rest<=3) AND (Feld.Status[Rechner].Modus=Ziehen) THEN BEGIN Summe:=Summe-4*(4-rest); IF rest=0 THEN IF AmZug=Rechner THEN Summe:=maxval ELSE Summe:=Summe-80; END; IF Feld.Status[Rechner].steine<3 THEN Summe:=-maxval ELSE IF Feld.Status[Spieler].steine<3 THEN Summe:=maxval; END ELSE IF Feld.Status[AmZug].zaehler < 5 THEN BEGIN IF (spst<=4) THEN Summe:=Summe+7*(5-spst); IF (rest<=4) THEN Summe:=Summe-7*(5-rest); END; Bewertung:=Summe; END; PROCEDURE MachZugListe(VAR ZugListe : Liste; AmZug : tstein; vz : integer); VAR HilfsBrett : tbrett; tmp : ListenInhalt; BEGIN Feld.k:=-1; Feld.Schl_Nr:=-1; Feld.L:=-1; ZugListe:=NIL; REPEAT Zug_ermitteln(AmZug); IF Feld.Anzahl=1 THEN BEGIN HilfsBrett:=Feld; mache_Zug(AmZug,NOT zeigen); tmp.value:=vz*Bewertung(geg[AmZug]); tmp.Zug:=Feld.Zug; einfuegen(ZugListe,tmp); Feld:=HilfsBrett; END; UNTIL Feld.Anzahl=0; END; (*$A-*) PROCEDURE Schachtlung (AmZug : tstein; i : integer); LABEL exit; VAR HilfsBrett : tbrett; ZugListe,t : Liste; Wert : integer; BEGIN ZugListe:=NIL; IF odd(i) THEN minmax[i]:=i-maxint ELSE minmax[i]:=maxint-i; IF Spielstaerke=i THEN BEGIN Feld.k:=-1; Feld.Schl_Nr:=-1; Feld.L:=-1; REPEAT Zug_ermitteln(AmZug); IF Feld.Anzahl=1 THEN BEGIN HilfsBrett:=Feld; mache_Zug(AmZug,NOT zeigen); Wert:=Bewertung(geg[AmZug] (* am Zug *)); Feld:=HilfsBrett; IF odd(i) THEN BEGIN IF Wert=maxint THEN Wert:=maxint-succ(i); IF Wert>minmax[i] THEN minmax[i]:=Wert; IF minmax[i]>minmax[pred(i)] THEN GOTO exit; END ELSE BEGIN IF Wert=-maxint THEN Wert:=succ(i)-maxint; IF WertNIL DO BEGIN Feld.Zug:=ZugListe^.Eintrag.Zug; mache_Zug(AmZug,NOT zeigen); Schachtlung(geg[AmZug],succ(i)); Feld:=HilfsBrett; t:=ZugListe; ZugListe:=t^.naechster; dispose(t); IF odd(i) THEN BEGIN IF minmax[succ(i)]>minmax[i] THEN minmax[i]:=minmax[succ(i)]; IF minmax[i]>minmax[pred(i)] THEN GOTO exit; END ELSE BEGIN IF minmax[succ(i)]NIL DO BEGIN t:=ZugListe; ZugListe:=t^.naechster; dispose(t) END; END; (*A+*) PROCEDURE writemove; VAR Z:integer; BEGIN WITH Feld DO FOR Z:=ord(Status[Rechner].Modus=Setzen) TO 1+ord(Muehle) DO write(posit[Zug[Z]],' '); END; PROCEDURE Schachtlung_Rechner; LABEL exit; VAR HilfsBrett : tbrett; ZugListe,t : Liste; Wert : integer; BEGIN MachZugListe(ZugListe,Rechner,1); minmax[1]:=-maxint+1; IF ZugListe<>NIL THEN IF Spielstaerke=1 THEN BEGIN wert:=ZugListe^.Eintrag.Value; IF Wert=maxint THEN Wert:=maxint-2; minmax[1]:=wert; BestZug:=ZugListe^.Eintrag.Zug; END ELSE BEGIN HilfsBrett:=Feld; REPEAT Feld.Zug:=ZugListe^.Eintrag.Zug; gotoxy(57,16); writemove; ClrEol; gotoxy(19,22); mache_Zug(Rechner,NOT zeigen); Schachtlung(Spieler,2); IF (minmax[2]>minmax[1]) OR ((minmax[2]=minmax[1]) AND (random(2)=0)) THEN BEGIN BestZug:=ZugListe^.Eintrag.Zug; minmax[1]:=minmax[2]; Feld:=HilfsBrett; Feld.Zug:=BestZug; gotoxy(57,17); WriteMove; Write('= ',MinMax[1]); ClrEol; gotoxy(19,22); END; Feld:=HilfsBrett; IF KeyPressed THEN IF Antwort_Ja('Abbrechen') THEN GOTO exit; t:=ZugListe; ZugListe:=t^.naechster; dispose(t); UNTIL ZugListe=NIL; END; exit: WHILE ZugListe<>NIL DO BEGIN t:=ZugListe; ZugListe:=t^.Naechster; Dispose(t); END; END;