;Programm: chessfx ;Funktion: Schachprogramm ;Sprache: TASM ;Autor: Frank H”ppner ; (c) 1992 DMV Widuch GmbH & Co. KG ;Das Programm nicht ohne die ;beiden folgenden PCX-Bilder im ;aktuellen Verzeichnis starten: ;chess.pcx : Spielbrett & Figuren ;titel.pcx : beliebiges Titelbild .RADIX 10 .MODEL SMALL .STACK 200 .DATA ; ******************************** ; Schach-Konstanten / Variablen ; ******************************** Denkzeit EQU 10 Rand EQU 0 KoenigS EQU 1 DameS EQU 2 TurmS EQU 3 LaeuferS EQU 4 SpringerS EQU 5 BauerS EQU 6 leer EQU 7 BauerW EQU 8 SpringerW EQU 9 LaeuferW EQU 10 TurmW EQU 11 DameW EQU 12 KoenigW EQU 13 weiss EQU 0 schwarz EQU -1 false EQU 0 true EQU -1 betastart EQU -32000 alphastart EQU 32000 Schlagzug EQU 3 klRochade EQU 4 grRochade EQU 5 VideoSeg EQU 0B800h Zug STRUC von DB 0 nach DB 0 option DW 0 value DW 0 next DW 0 Zug ENDS ; Wortgr”áe vorausgesetzt Spielstand STRUC feld DB 120 DUP (0) list Zug 100 DUP (<0,0,0>) anzahl DW 0 start DW 0 EndSpielS DB 0 EndSpielW DB 0 MatWertS DW 0 MatWertW DW 0 MatDiff DW 0 StellungTyp DB 0 KoenPS DB 0 KoenPW DB 0 klRochWmgl DB 0 klRochSmgl DB 0 grRochWmgl DB 0 grRochSmgl DB 0 RochadeFaktor DB 0 RochadeErfolgt DB 0 dummy DB 0 AmZug DB 0 ZugNr DW 0 cutoff DB 0 alpha DW 0 beta DW 0 ruhewert DW 0 bedrohungwert DW 0 savelist Zug 100 DUP (<0,0,0>) saveanzahl DW 0 savestart DW 0 Spielstand ENDS GameStack Spielstand 8 DUP (?) aktStack DW 0 Depth0 EQU OffSet GameStack Depth1 EQU Depth0+SIZE Spielstand Depth7 EQU Depth0+7*SIZE Spielstand Brett DB 20 DUP (0) DB 0,3,5,4,2,1,4,5,3,0 DB 0,6,6,6,6,6,6,6,6,0 DB 0,7,7,7,7,7,7,7,7,0 DB 0,7,7,7,7,7,7,7,7,0 DB 0,7,7,7,7,7,7,7,7,0 DB 0,7,7,7,7,7,7,7,7,0 DB 0,8,8,8,8,8,8,8,8,0 DB 0,11,9,10,12,13,10,9,11,0 DB 20 DUP (0) Spalte DB 20 DUP (0) DB 6 DUP (0,1,2,3,4,5,6,7,8,0) Zeile DB 2 DUP (0,1,2,3,4,5,6,7,8,0) DB 10 DUP (1) DB 0,8 DUP (2),0 DB 0,8 DUP (3),0 DB 0,8 DUP (4),0 DB 0,8 DUP (5),0 DB 0,8 DUP (6),0 DB 0,8 DUP (7),0 DB 0,8 DUP (8),0 SprTW DW 20 DUP (0) ; Springerwert weiá DW 0,-420,-300,-180,-60 DW -60,-180,-300,-420,0 DW 0,-300,-180,-60,60 DW 60,-60,-180,-300,0 DW 0,-180,-60,60,180 DW 180,60,-60,-180,0 DW 0,-60,60,180,300 DW 300,180,60,-60,0 DW 0,-60,60,180,300 DW 300,180,60,-60,0 DW 0,-180,-60,60,180 DW 180,60,-60,-180,0 DW 0,-300,-180,-60,60 DW 60,-60,-180,-300,0 DW 0,-420,-300,-180,-60 DW -60,-180,-300,-420,0 ZAbst DW 20 DUP (0) ; Zentrumabstand DW 0,600,500,400,300 DW 300,400,500,600,0 DW 0,500,400,300,200 DW 200,300,400,500,0 DW 0,400,300,200,100 DW 100,200,300,400,0 DW 0,300,200,100,0 DW 0,100,200,300,0 DW 0,300,200,100,0 DW 0,100,200,300,0 DW 0,400,300,200,100 DW 100,200,300,400,0 DW 0,500,400,300,200 DW 200,300,400,500,0 DW 0,600,500,400,300 DW 300,400,500,600,0 ZWert DB 20 DUP (0) ; Bedrohungswert DB 0,20,20,20,20,20,20,20,20,0 DB 0,20,20,20,20,20,20,20,20,0 DB 0,20,20,60,60,60,60,20,20,0 DB 0,20,20,60,100,100,60,20,20,0 DB 0,20,20,60,100,100,60,20,20,0 DB 0,20,20,60,60,60,60,20,20,0 DB 0,20,20,20,20,20,20,20,20,0 DB 0,20,20,20,20,20,20,20,20,0 ; Vorrckwerte fr Bauern W/S VorBW DW 10 DUP (0) VorBS DW 10 DUP (0) ; Default Werte Vorrcken ; fr Mittel/Endspiel VorMS DW 0,0,0,390,540,700,230,0,0,0 VorES DW 0,200,200,200,200 DW 200,200,200,200,0 ; alle Daten zwischen POSBW und ; HORIZON werden bei neuer ; Stellung gel”scht ; Bauernposition, bei Null Anzahl PosBW DB 10 DUP (0) SpaBW DB 10 DUP (0) ZeiBW DB 10 DUP (0) PosBS DB 10 DUP (0) SpaBS DB 10 DUP (0) ZeiBS DB 10 DUP (0) ; Bauern-Z„hler pro Spalte W/S SZaBW DB 10 DUP (0) SZaBS DB 10 DUP (0) ; am wenigsten vorgerckte Bauern ; je Spalte W/S SlowBW DB 10 DUP (0) SlowBS DB 10 DUP (0) ; Bauernliste Position S/W ListBW DB 60 DUP (0) ListBS DB 60 DUP (0) ; Freibauern in Spalte S/W FreiBW DB 10 DUP (0) FreiBS DB 10 DUP (0) ; rckst„ndige Bauern S/W RuckBW DB 10 DUP (0) RuckBS DB 10 DUP (0) ; Position aller Figuren S/W ; bei Null Figurenz„hler PosFW DB 17 DUP (0) PosFS DB 17 DUP (0) SumFW DB 0 ; Summe Figuren weiá TurmSW DB 0 ; Turm-Spalte weiá DamePW DB 0 ; Dame-Position weiá GrlFW DB 0 ; Sum.Leichtfiguren Grundr. LaufW DB 0 ; L„ufer weiá vorhanden SumFS DB 0 ; dito schwarz TurmSS DB 0 DamePS DB 0 GrlFS DB 0 LaufS DB 0 schach DB 0 ; aktueller K”nig bedroht? DrohWrt DW 0 horizon DW 0 OutZone DW Depth7 zugwahl DW 0 schutzL DW 0 schutzR DW 0 gameovr DB 0 sieger DB 0 timeout DB 0 abort DB 0 Wert DW 0,0,-900,-500,-325,-325,-100 DW 0,100,325,325,500,900,0 msgCZ EQU 2 ; Computerzug msgSZ EQU 1 ; Spielerzug msgCG EQU 4 ; ComputerSieg msgSG EQU 5 ; SpielerSieg msgKG EQU 0 ; Remis msgEr EQU 3 ; ungltiger Zug txtCG DB 'Tja, die Partie ging an mich' DB '. Vielen Dank frs Spielen!$' txtSG DB 'Gratuliere, Sie haben gewonn' DB 'en. Wann gibts Revanche?$' txtKG DB 'Remis! Verschieben wir die E' DB 'ntscheidung auf die n„chste' DB ' Partie!$' txtAB DB 'Chess-fx abgebrochen!$' ; ******************************** ; VGA-Grafik Konstanten/Variablen ; ******************************** gCRTC EQU 3D4h gPixelX EQU 320d gPixelXHalf EQU gPixelX/2 gPixelY EQU 200d gPixelYHalf EQU gPixelY/2 gScreenSize EQU 200d*80d gScreenPage0 EQU 0000h gScreenPage1 EQU gScreenSize gScreenPage2 EQU 2*gScreenSize gScreenPage3 EQU 3*gScreenSize gScreenSegment EQU 0A000h gScreen DW gScreenPage1 gColor DB 02h FallDown DB 200,190,180,170,160 DB 150,140,130,120,110 DB 100,90,80,70,60,50,40 DB 30,20,10,0,5,10,15,20 DB 25,30,33,36,38,39,40 DB 40,40,39,38,36,33,30 DB 25,20,15,10,5,0,3,5 DB 7,9,11,11,9,7,5,3,0 DB 1,2,3,4,3,2,1,0 DB 1,2,3,2,1,0,1,2,1,0 DB 1,0,1,0,255 Aufbau DB 230,20,20,0,230,20,195,0 DB 254,20,20,154,254,20,195,154 DB 230,60,45,0,230,60,170,0 DB 254,60,45,154,254,60,170,154 DB 230,40,70,0,230,40,145,0 DB 254,40,70,154,254,40,145,154 DB 230,80,95,0,230,100,120,0 DB 254,80,95,154,254,100,120,154 FigurPos DW 0,0,230,300,230,280,230 DW 220,230,240,230,260,230,200 DW 0,0,254,200,254,260,254 DW 240,254,220,254,280,254,300 xcount DW 0 ycount DW 0 pack DB 0 bufpos DW 0 gPCXfileTitel DB 'TITEL.PCX',0 gPCXfileBrett DB 'CHESS.PCX',0 gPCXBuffer DB 1024 DUP (0) .CODE ; ******************************** ; CHESS-fx ; ******************************** call Intro mov ax,seg GameStack mov ds,ax mov es,ax mov ax,offset GameStack mov word ptr[ds:aktStack],ax mov si,aktStack call Spiel call gExit call Quit mov ah,4Ch int 21h ; ******************************** ; Zuggenerator-Zug eintragen ; ******************************** NeuerZug PROC ; Neuen Zug eintragen ; al=von, ah=nach ; dx=variante ; (Schlagzge werden autom. ; erkannt und markiert) push ax push bx push si mov si,AktStack xor bh,bh ; klRochade? cmp dl,klRochade je nz02 ; grRochade? cmp dl,grRochade je nz02 ; Zielfeld leer mov bl,ah cmp BYTE PTR [ds:si+bx],leer je nz02 cmp BYTE PTR [ds:si+bx],rand je nz01 ; wer schl„gt? mov bl,al cmp BYTE PTR [ds:si+bx],leer jl nz03 ; weiss schl„gt! mov bl,ah cmp BYTE PTR [ds:si+bx],leer ; sich selbst schlagen gilt nicht jg nz01 mov dx,Schlagzug jmp nz02 ; schwarz schl„gt! nz03: mov bl,ah cmp BYTE PTR [ds:si+bx],leer ; sich selbst schlagen gilt nicht jl nz01 mov dx,Schlagzug ; Zug eintragen nz02: push cx xor ch,ch mov cl,byte ptr[ds:ZWert+bx] add word ptr[ds:DrohWrt],cx pop cx ; noch volle Suche? cmp si,horizon jle nz02ok ; ja! ; nein, also Sonderzug? cmp dx,Schlagzug jne nz01 ; wurde Zug schon einmal bewertet? nz02ok: push ax push dx mov dx,ax ; Bewertung in ax holen ; (aus savelist) call Aussortieren ; Zug eintragen (von,nach,option) mov bx,word ptr[ds:si.anzahl] pop cx ; option mov word ptr[ds:si.list+bx.option],cx pop cx ; zug mov word ptr[ds:si.list+bx],cx ; nach letzter Bewertung(ax) ; einsortieren mov dx,word ptr[ds:si.anzahl] mov di,si add di,size feld mov bx,word ptr[ds:si.start] call Einsortieren mov word ptr[ds:si.start],bx add word ptr[ds:si.anzahl],size zug xor dx,dx nz01: pop si pop bx pop ax ret NeuerZug ENDP ; ******************************** ; Bauernzug -- weiss ; ******************************** BauernZugWeiss PROC push bx xor dx,dx mov al,bl ; Schlagzug links sub bl,11 mov ah,bl cmp BYTE PTR [ds:si+bx],leer jge bzgw03 CALL bzwEintragen ; Schlagzug rechts bzgw03: inc bl inc bl mov ah,bl cmp BYTE PTR [ds:si+bx],leer jge bzgw01 CALL bzwEintragen bzgw01: ; ein weiter leer? mov bl,al sub bl,10 mov ah,bl cmp BYTE PTR [ds:si+bx],leer jne bzgw02 CALL bzwEintragen ; zwei vorw„rts, wenn leer cmp al,80 jl bzgw02 sub bl,10 mov ah,bl cmp BYTE PTR [ds:si+bx],leer jne bzgw02 CALL NeuerZug bzgw02: pop bx ret BauernZugWeiss ENDP ; ******************************** ; Hilfroutine fr BauernZugWeiss ; ******************************** bzwEintragen PROC ; Bauernumwandlung? cmp ah,30 jg bzgw05 ; Bauer in Dame mov dx,DameW CALL NeuerZug ; Bauer in Springer mov dx,SpringerW CALL NeuerZug ret bzgw05: ; oder einfach vorw„rts CALL NeuerZug ret bzwEintragen ENDP ; ******************************** ; Bauernzug -- schwarz ; ******************************** BauernZugSchw PROC push bx xor dx,dx mov al,bl ; Schlagzug links add bl,9 mov ah,bl cmp BYTE PTR [ds:si+bx],leer jle bzgs03 CALL bzsEintragen ; Schlagzug rechts bzgs03: inc bl inc bl mov ah,bl cmp BYTE PTR [ds:si+bx],leer jle bzgs01 CALL bzsEintragen bzgs01: ; ein weiter leer? mov bl,al add bl,10 mov ah,bl cmp BYTE PTR [ds:si+bx],leer jne bzgs02 call bzsEintragen ; zwei vorw„rts, wenn leer cmp al,40 jg bzgs02 add bl,10 mov ah,bl cmp BYTE PTR [ds:si+bx],leer jne bzgs02 CALL NeuerZug bzgs02: pop bx ret BauernZugSchw ENDP ; ******************************** ; Hilfsroutine fr BauernZugSchw ; ******************************** bzsEintragen PROC ; dann Bauernumwandlung? cmp ah,90 jl bzgs05 ; Bauer in Dame mov dx,DameS CALL NeuerZug ; Bauer in Springer mov dx,SpringerS CALL NeuerZug ret bzgs05: ; oder einfach vorw„rts CALL NeuerZug ret bzsEintragen ENDP ; ******************************** ; Springerzug ; ******************************** SpringerZug PROC mov al,bl mov ah,al xor dx,dx add ah,21 ; 21 CALL NeuerZug sub ah,21+21 ; -21 CALL NeuerZug add ah,21+8 ; 8 CALL NeuerZug sub ah,8 +8 ; -8 CALL NeuerZug add ah,8 +12 ; 12 CALL NeuerZug sub ah,12+12 ; -12 CALL NeuerZug add ah,12+19 ; 19 CALL NeuerZug sub ah,19+19 ; -19 CALL NeuerZug ret SpringerZug ENDP ; ******************************** ; diagonale Zge ; ******************************** DiagonalZug PROC push bx mov al,bl mov ah,al xor dx,dx ; nach rechts oben (-9) dzro: sub ah,9 mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je dzro mov ah,al ; nach rechts unten (+9) dzru: add ah,9 mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je dzru mov ah,al ; nach links oben (-11) dzlo: sub ah,11 mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je dzlo mov ah,al ; nach links oben (+11) dzlu: add ah,11 mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je dzlu pop bx ret DiagonalZug ENDP ; ******************************** ; horizontale/vertikale Zge ; ******************************** HorizVertZug PROC push bx mov al,bl mov ah,al xor dx,dx ; nach links (-1) hvzl: dec ah mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je hvzl mov ah,al ; nach rechts (+1) hvzr: inc ah mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je hvzr mov ah,al ; nach oben (-10) hvzo: sub ah,10 mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je hvzo mov ah,al ; nach unten (+10) hvzu: add ah,10 mov bl,ah CALL NeuerZug cmp BYTE PTR [ds:si+bx],leer je hvzu pop bx ret HorizVertZug ENDP ; ******************************** ; K”nigszug ; ******************************** KoenigsZug PROC mov al,bl mov ah,al xor dx,dx inc ah ; 1 CALL NeuerZug sub ah,1+1 ; -1 CALL NeuerZug add ah,1+11 ; 11 CALL NeuerZug sub ah,11+11 ; -11 CALL NeuerZug add ah,11+10 ; 10 CALL NeuerZug sub ah,10+10 ; -10 CALL NeuerZug add ah,10+9 ; 9 CALL NeuerZug sub ah,9+9 ; -9 CALL NeuerZug ret KoenigsZug ENDP ; ******************************** ; Rochade nach Regeln m”glich? ; dx linkes Byte der zu unter- ; suchenden Doppelposition des ; Koenig (jetzt&test) ; (Update in KoenPs/w auáerhalb!) ; ******************************** RochadeMoeglich PROC push ax push bx push cx mov bx,dx mov ax,word ptr[ds:si+bx] xchg ah,al mov word ptr[ds:si+bx],ax push dx call KoenigImSchach pop bx mov ax,word ptr[ds:si+bx] xchg ah,al mov word ptr[ds:si+bx],ax pop cx pop bx pop ax ret RochadeMoeglich ENDP ; ******************************** ; Rochade nur erlaubt, wenn K”nig ; nicht im Schach steht ; ******************************** RochadeErlaubt PROC push ax push bx push cx call KoenigImSchach pop cx pop bx pop ax ret RochadeErlaubt ENDP ; ******************************** ; RochadenZug weiss ; ******************************** RochadenZugW PROC cmp al,95 jne rzwend mov al,bl ; kleine Rochade cmp BYTE PTR [ds:si+96],leer jne rzwg cmp BYTE PTR [ds:si+97],leer jne rzwg cmp BYTE PTR [ds:si.klRochWmgl],true jne rzwg call RochadeErlaubt jc rzwg mov byte ptr[ds:si.KoenPW],96 mov dx,95 call RochadeMoeglich mov byte ptr[ds:si.KoenPW],95 jc rzwg mov dx,klRochade mov ah,97 CALL NeuerZug ; groáe Rochade rzwg: cmp BYTE PTR [ds:si+92],leer jne rzwend cmp BYTE PTR [ds:si+93],leer jne rzwend cmp BYTE PTR [ds:si+94],leer jne rzwend cmp BYTE PTR [ds:si.grRochWmgl],true jne rzwend call RochadeErlaubt jc rzwend mov byte ptr[ds:si.KoenPW],94 mov dx,94 call RochadeMoeglich mov byte ptr[ds:si.KoenPW],95 jc rzwend mov dx,grRochade mov ah,93 CALL NeuerZug rzwend: ret RochadenZugW ENDP ; ******************************** ; RochadenZug schwarz ; ******************************** RochadenZugS PROC cmp bl,25 jne rzsend mov al,bl ; kleine Rochade cmp BYTE PTR [ds:si+26],leer jne rzsg cmp BYTE PTR [ds:si+27],leer jne rzsg cmp BYTE PTR [ds:si.klRochSmgl],true jne rzsg call RochadeErlaubt jc rzsg mov byte ptr[ds:si.KoenPW],26 mov dx,25 call RochadeMoeglich mov byte ptr[ds:si.KoenPW],25 jc rzsg mov dx,klRochade mov ah,27 CALL NeuerZug ; groáe Rochade rzsg: cmp BYTE PTR [ds:si+22],leer jne rzsend cmp BYTE PTR [ds:si+23],leer jne rzsend cmp BYTE PTR [ds:si+24],leer jne rzsend cmp BYTE PTR [ds:si.grRochSmgl],true jne rzsend call RochadeErlaubt jc rzsend mov byte ptr[ds:si.KoenPW],24 mov dx,24 call RochadeMoeglich mov byte ptr[ds:si.KoenPW],25 jc rzsend mov dx,grRochade mov ah,23 CALL NeuerZug rzsend: ret RochadenZugS ENDP ; ******************************** ; gesamte Zugliste l”schen ; ******************************** LoescheListe PROC cld mov di,aktStack mov word ptr[ds:di.Anzahl],0 mov word ptr[ds:di.Start],0 mov word ptr[ds:di.BedrohungWert],0 add di,SIZE feld xor ax,ax mov cx,SIZE List sar cx,1 rep stosw ret LoescheListe ENDP ; ******************************** ; sortierte Zugliste l”schen ; ******************************** LoescheSaveList PROC mov di,aktStack mov word ptr[ds:di.savestart],0 mov word ptr[ds:di.saveanzahl],0 add di,(size spielstand-size savelist-4) xor ax,ax mov cx,size savelist sar cx,1 rep stosw ret LoescheSaveList ENDP ; ******************************** ; m”gliche Zge fr weiss ; ******************************** ZugGenWeiss PROC push si CALL LoescheListe mov si,aktStack mov bx,20 mov cx,79 ; weisse Figur? zgw01: inc bx push cx mov cl,BYTE PTR [ds:si+bx] cmp cl,leer jle zgw02 mov word ptr[ds:DrohWrt],0 cmp cl,BauerW jnz zgw03 CALL BauernZugWeiss zgw03: cmp cl,SpringerW jnz zgw04 CALL SpringerZug jmp zgw02 zgw04: cmp cl,TurmW jnz zgw05 CALL HorizVertZug mov dx,word ptr[ds:DrohWrt] sal dx,1 add word ptr[ds:si.BedrohungWert],dx jmp zgw02 zgw05: cmp cl,LaeuferW jnz zgw06 CALL DiagonalZug mov dx,word ptr[ds:DrohWrt] sal dx,1 add word ptr[ds:si.BedrohungWert],dx jmp zgw02 zgw06: cmp cl,DameW jnz zgw07 CALL HorizVertZug CALL DiagonalZug mov dx,word ptr[ds:DrohWrt] add word ptr[ds:si.BedrohungWert],dx jmp zgw02 zgw07: cmp cl,KoenigW jnz zgw02 mov byte ptr[ds:si.KoenPW],bl CALL KoenigsZug CALL RochadenZugW zgw02: pop cx loop zgw01 call LoescheSaveList pop si ret ZugGenWeiss ENDP ; ******************************** ; m”gliche Zge fr schwarz ; ******************************** ZugGenSchwarz PROC push si CALL LoescheListe mov si,aktStack mov bx,20 mov cx,79 ; weisse Figur? zgs01: inc bx push cx mov cl,BYTE PTR [ds:si+bx] cmp cl,leer jge zgs02 mov word ptr[ds:DrohWrt],0 cmp cl,BauerS jnz zgs03 CALL BauernZugSchw zgs03: cmp cl,SpringerS jnz zgs04 CALL SpringerZug jmp zgs02 zgs04: cmp cl,TurmS jnz zgs05 CALL HorizVertZug mov dx,word ptr[ds:DrohWrt] sal dx,1 sub word ptr[ds:si.BedrohungWert],dx jmp zgs02 zgs05: cmp cl,LaeuferS jnz zgs06 CALL DiagonalZug mov dx,word ptr[ds:DrohWrt] sal dx,1 sub word ptr[ds:si.BedrohungWert],dx jmp zgs02 zgs06: cmp cl,DameS jnz zgs07 CALL HorizVertZug CALL DiagonalZug mov dx,word ptr[ds:DrohWrt] sub word ptr[ds:si.BedrohungWert],dx jmp zgs02 zgs07: cmp cl,KoenigS jnz zgs02 mov byte ptr[ds:si.KoenPS],bl CALL KoenigsZug CALL RochadenZugS zgs02: pop cx loop zgs01 call LoescheSaveList pop si ret ZugGenSchwarz ENDP ; ******************************** ; Fuehre Zug Nr BX aus ; ******************************** FuehreZugAus PROC push bx mov ax,word ptr [ds:si.list+bx] mov dx,word ptr [ds:si.list+bx.option] xor bx,bx mov bl,ah ; bx=nach mov ch,byte ptr [ds:si+bx] ; Rochadenrechte kl„ren ; (Turm/K”nig bewegt?) cmp al,25 ; Pos. schwarzer K”nig jne fza001 mov byte ptr[ds:si.klRochSmgl],false mov byte ptr[ds:si.grRochSmgl],false cmp dx,klRochade jge fza000 jmp fzaw fza000: sub byte ptr[ds:si.RochadeFaktor],100 mov byte ptr[ds:si.RochadeErfolgt],dl mov byte ptr[ds:si+bx],KoenigS mov byte ptr[ds:si+25],leer mov byte ptr[ds:si.KoenPS],bl add bl,25 shr bl,1 mov byte ptr[ds:si+bx],TurmS cmp dx,klRochade je fzaSKR mov byte ptr[ds:si+21],leer jmp fza99 fzaSKR: mov byte ptr[ds:si+28],leer jmp fza99 fza001: cmp al,21 ; Pos.links schw Turm jne fza002 mov byte ptr[ds:si.grRochSmgl],false jmp fzaw fza002: cmp al,28 ; Pos.rechts schw Turm jne fza003 mov byte ptr[ds:si.klRochSmgl],false jmp fzaw fza003: cmp al,95 ; Pos. weiáer K”nig jne fza004 mov byte ptr[ds:si.klRochWmgl],false mov byte ptr[ds:si.grRochWmgl],false cmp dx,klRochade jl fzaw add byte ptr[ds:si.RochadeFaktor],100 mov byte ptr[ds:si.RochadeErfolgt],dl mov byte ptr[ds:si+bx],KoenigW mov byte ptr[ds:si+95],leer mov byte ptr[ds:si.KoenPW],bl add bl,95 shr bl,1 mov byte ptr[ds:si+bx],TurmW cmp dx,klRochade je fzaWKR mov byte ptr[ds:si+91],leer jmp fza99 fzaWKR: mov byte ptr[ds:si+98],leer jmp fza99 fza004: cmp al,91 ;Pos.links weiáer Turm jne fza005 mov byte ptr[ds:si.grRochWmgl],false jmp fzaw fza005: cmp al,98 ;Pos.rechts weiáer Turm jne fzaw mov byte ptr[ds:si.klRochWmgl],false ; Schlagzug? fzaw: cmp ch,leer je fza09 jl fza01 ; weiá geschlagen push bx xor bh,bh mov bl,ch sal bx,1 mov dx,word ptr[ds:Wert+bx] pop bx sub word ptr[ds:si.MatWertW],dx sub word ptr[ds:si.MatDiff],dx jmp fza09 ; schwarz geschlagen fza01: push bx xor bh,bh mov bl,ch sal bx,1 mov dx,word ptr[ds:Wert+bx] pop bx sub word ptr[ds:si.MatWertS],dx sub word ptr[ds:si.MatDiff],dx fza09: mov bl,al ; bx=von mov cl,byte ptr [ds:si+bx] ; neue K”nigsposition cmp cl,KoenigW jne fza09a mov byte ptr[ds:si.KoenPW],ah jmp fza09b fza09a: cmp cl,KoenigS jne fza09b mov byte ptr[ds:si.KoenPS],ah ; Bauernumwandlung? fza09b: cmp cl,BauerW jne fza10 cmp bl,39 jg fza11 mov cl,dl push bx mov bx,dx sal bx,1 mov dx,word ptr[ds:Wert+bx] sub dx,word ptr[ds:Wert+2*BauerW] pop bx add word ptr[ds:si.MatWertW],dx add word ptr[ds:si.MatDiff],dx jmp fza11 fza10: cmp cl,BauerS jne fza11 cmp bl,80 jl fza11 mov cl,dl push bx mov bx,dx sal bx,1 mov dx,word ptr[ds:Wert+bx] sub dx,word ptr[ds:Wert+2*BauerS] pop bx add word ptr[ds:si.MatWertS],dx add word ptr[ds:si.MatDiff],dx fza11: mov bl,ah mov byte ptr [ds:si+bx],cl mov bl,al mov byte ptr [ds:si+bx],leer fza99: pop bx ret FuehreZugAus ENDP ; ******************************** ; Stellungsanalyse ; ******************************** Analyse PROC ; alte Daten l”schen xor ax,ax mov cx,offset Horizon sub cx,offset PosBW mov bx,offset PosBW sar cx,1 mov di,bx rep stosw ; Endspiel S/W cmp word ptr[ds:si.MatWertW],2000 jg an01 mov byte ptr[ds:si.EndspielW],true an01: cmp word ptr[ds:si.MatWertS],-2000 jl an02 mov byte ptr[ds:si.EndspielS],true ; Bauernstandorte an02: mov si,aktStack mov bx,20 mov cx,79 an03: inc bx cmp byte ptr[ds:si+bx],leer jl an03s je an03w cmp byte ptr[ds:si+bx],BauerW je an03w ; weiáe Figur eintragen xor dh,dh mov dl,byte ptr[ds:PosFW] inc dl mov di,dx mov byte ptr[ds:PosFW],dl mov byte ptr[ds:PosFW+di],bl mov dl,byte ptr[ds:si+bx] jmp an03w ; schwarze Figur eintragen an03s: cmp byte ptr[ds:si+bx],rand je an03w cmp byte ptr[ds:si+bx],BauerS je an04 xor dh,dh mov dl,byte ptr[ds:PosFS] inc dl mov di,dx mov byte ptr[ds:PosFS],dl mov byte ptr[ds:PosFS+di],bl mov dl,byte ptr[ds:si+bx] jmp an03w ; Konstr. wegen near jump an03a: loop an03 jmp an05 an03w: cmp byte ptr[ds:si+bx],BauerW jne an04 ; neuer Bauer inc byte ptr[ds:PosBW] ; di=wievielter weiáer Bauer xor dh,dh mov dl,byte ptr[ds:PosBW] mov di,dx ; Bauerspalte/zeile ermitteln ; ah=Zeile, al=Spalte mov ah,byte ptr[ds:bx+Zeile] mov al,byte ptr[ds:bx+Spalte] ; Bauernposition mov byte ptr[ds:di+PosBW],bl mov byte ptr[ds:di+SpaBW],al mov byte ptr[ds:di+ZeiBW],ah ; Bauern-Spaltenz„hler ; Position/Slowest xor ah,ah mov di,ax ; di=spalte mov dh,byte ptr[ds:di+SZaBW] inc byte ptr[ds:di+SZaBW] ; jeweils neuer Bauer ist auch ; langsamster weiáer Bauer mov byte ptr[ds:di+SlowBW],bl shl dh,1 mov dl,dh shl dh,1 shl dh,1 add dl,dh xor dh,dh add dx,di mov di,dx mov byte ptr[ds:di+ListBW],bl jmp an03a an04: cmp byte ptr[ds:si+bx],BauerS jne an03a ; neuer Bauer inc byte ptr[ds:PosBS] ; di=wievielter schwarzer Bauer xor dh,dh mov dl,byte ptr[ds:PosBS] mov di,dx ; Bauerspalte/zeile ermitteln ; ah=Zeile, al=Spalte mov ah,byte ptr[ds:bx+Zeile] mov al,byte ptr[ds:bx+Spalte] ; Bauernposition mov byte ptr[ds:di+PosBS],bl mov byte ptr[ds:di+SpaBS],al mov byte ptr[ds:di+ZeiBS],ah ; Bauern-Spaltenz„hler/Position xor ah,ah mov di,ax ; di=spalte mov dh,byte ptr[ds:di+SZaBS] inc byte ptr[ds:di+SZaBS] cmp dh,0 jnz an03b ; erster Bauer in Spalte ; (bei schwarz gleichzeitig der ; langsamste Bauer in Spalte) mov byte ptr[ds:di+SlowBS],bl an03b: shl dh,1 mov dl,dh shl dh,1 shl dh,1 add dl,dh xor dh,dh add dx,di mov di,dx mov byte ptr[ds:di+ListBS],bl jmp an03a ; Stellungstyp ermitteln an05: cmp byte ptr[ds:si.EndSpielW],true je an06 cmp byte ptr[ds:si.EndSpielS],true je an06 ; normal an08: mov byte ptr[ds:si.StellungTyp],4 jmp an07 ; noch weisse Bauern? an06: cmp byte ptr[ds:di+PosBW],0 jg an08 ; noch schwarze Bauern? cmp byte ptr[ds:di+PosBS],0 jg an08 ; Mattfhrung gg Schwarz? cmp word ptr[ds:si.MatDiff],500 jl an09 cmp word ptr[ds:si.MatWertS],-650 jl an08 mov byte ptr[ds:si.StellungTyp],3 jmp an07 ; Mattfhrung gg Weiss an09: cmp word ptr[ds:si.MatDiff],-500 jg an10 cmp word ptr[ds:si.MatWertW],650 jg an08 mov byte ptr[ds:si.StellungTyp],1 jmp an07 ; Remis-Stellungstyp an10: cmp word ptr[ds:si.MatWertW],325 jg an08 cmp word ptr[ds:si.MatWertS],-325 jl an08 mov byte ptr[ds:si.StellungTyp],2 an07: ret Analyse ENDP ; ******************************** ; Bauernbewertung weiss ; ******************************** BauernWertWeiss PROC mov si,aktStack ; berhaupt Bauern da? cmp byte ptr[ds:PosBW],0 jnz bww ret bww: xor ax,ax cmp byte ptr[ds:si.EndSpielW],false je bww01 push si mov si,offset VorES mov di,offset VorBW mov cx,8 rep movsw pop si ; Blockierung Zentrumsbauern bww01: cmp byte ptr[ds:si+84],BauerW jne bww02 cmp byte ptr[ds:si+74],leer je bww02 sub ax,1000 bww02: cmp byte ptr[ds:si+85],BauerW jne bww03 cmp byte ptr[ds:si+75],leer je bww03 sub ax,1000 ; cx=Anzahl weiáe Bauern ; ax=Bewertung der Bauern bww03: mov cl,byte ptr[ds:PosBW] xor ch,ch ; cx Nummer des weissen Bauern ; (wir z„hlen rckw„rts) ; di=cx,dh=Pos,bx=Spalte,dl=Zeile bwwl: mov di,cx xor bh,bh mov si,aktStack mov bl,byte ptr[ds:PosBW+di] add si,bx mov dh,bl mov bl,byte ptr[ds:SpaBW+di] mov dl,byte ptr[ds:ZeiBW+di] ; isolierte Bauern ; (isolierte Bauern haben links ; und rechts keine eigenen Bauern) cmp byte ptr[ds:SZaBW+bx-1],0 jne bww04 cmp byte ptr[ds:SZaBW+bx+1],0 jne bww04 sub ax,1500 ; Mehrfachbauern ; (in einer Spalte mehrere eigene ; Bauern) bww04: cmp byte ptr[ds:SZaBW+bx],2 jl bww05 sub ax,300 cmp byte ptr[ds:SZaBW+bx],2 je bww05 sub ax,1800 ; Freibauern (k”nnen durch ; gegn. Bauern nicht mehr ; geschlagen werden) ; links bww05: cmp byte ptr[ds:SZaBS+bx-1],0 jz bww05a cmp byte ptr[ds:SlowBS+bx-1],dh jge bww05a jmp bww06 ; geradeaus bww05a: cmp byte ptr[ds:SZaBS+bx],0 jz bww05b cmp byte ptr[ds:SlowBS+bx],dh jge bww05b jmp bww06 ; rechts bww05b: cmp byte ptr[ds:SZaBS+bx+1],0 jz bww05c cmp byte ptr[ds:SlowBS+bx+1],dh jge bww05c jmp bww06 ; ok, ist also Freibauer bww05c: mov byte ptr[ds:FreiBW+bx],true ; bewertung=+ESFaktor ; *UmwFaktor*Zeile*Zeile push bx push ax mov bx,115 cmp byte ptr[ds:si-10],leer ; gegner davor? jge bww05x mov bl,80 ; links oder rechts hinten ; eigener Bauer? bww05x: cmp byte ptr[ds:si+11],BauerW jnz bww05d add bl,35 jmp bww05e bww05d: cmp byte ptr[ds:si+9],BauerW jnz bww05e add bl,35 bww05e: cmp byte ptr[ds:si.endspielS],false jz bww05f shl bl,1 jmp bww05g bww05f: cmp byte ptr[ds:si.endspielW],false jz bww05g shl bl,1 ; Produkt errechnen bww05g: mov al,bl xor ah,ah ; mal Quadrat der Zeile mov bl,8 sub bl,dl mul bl mul bl mov bx,ax pop ax add ax,bx pop bx ; Vorrcken der Bauern ; ax:=ax+(8-zeile)*Vorrckwert bww06: push dx push ax shl bx,1 mov ax,7 sub al,dl mul word ptr[ds:VorBW+bx] mov dx,ax sar bx,1 pop ax add ax,dx pop dx ; rckst„ndige bauern ; (Bauern, die nicht durch eigene ; Bauern gedeckt sind (neben oder ; schr„g-hinter) aber am Vor- ; rcken durch gegn. Bauern ; gehindert werden) cmp byte ptr[ds:si-1],BauerW jz bww07 cmp byte ptr[ds:si+1],BauerW jz bww07 cmp byte ptr[ds:si+9],BauerW jz bww07 cmp byte ptr[ds:si+11],BauerW jz bww07 cmp byte ptr[ds:si-19],BauerS jnz bww07 sub ax,200 sub byte ptr[ds:RuckBS+di],200 cmp byte ptr[ds:si-21],BauerS jnz bww07 sub ax,200 sub byte ptr[ds:RuckBS+di],200 bww07: dec cx jz bww08 jmp bwwl bww08: ret BauernWertWeiss ENDP ; ******************************** ; Bauernbewertung schwarz ; ******************************** BauernWertSchw PROC mov si,aktStack ; berhaupt Bauern vorhanden? cmp byte ptr[ds:PosBS],0 jnz bws ret bws: xor ax,ax cmp byte ptr[ds:si.EndSpielS],false je bws01 push si mov si,offset VorES mov di,offset VorBS mov cx,8 rep movsw pop si ; Blockierung Zentrumsbauern bws01: cmp byte ptr[ds:si+34],BauerS jne bws02 cmp byte ptr[ds:si+44],leer je bws02 add ax,1000 bws02: cmp byte ptr[ds:si+35],BauerS jne bws03 cmp byte ptr[ds:si+45],leer je bws03 add ax,1000 ; cx=Anzahl schwarzen Bauern ; ax=Bewertung der Bauern bws03: mov cl,byte ptr[ds:PosBS] xor ch,ch ; cx Nummer des schwarzen Bauern ; (wir z„hlen rckw„rts) ; di=cx,dh=Pos,bx=Spalte,dl=Zeile bwsl: mov di,cx xor bh,bh mov si,aktStack mov bl,byte ptr[ds:PosBS+di] add si,bx mov dh,bl mov bl,byte ptr[ds:SpaBS+di] mov dl,byte ptr[ds:ZeiBS+di] ; isolierte Bauern ; (isolierte Bauern haben links ; und rechts keine eigenen Bauern) cmp byte ptr[ds:SZaBS+bx-1],0 jne bws04 cmp byte ptr[ds:SZaBS+bx+1],0 jne bws04 add ax,1500 ; Mehrfachbauern ; (in einer Spalte mehrere eigene ; Bauern) bws04: cmp byte ptr[ds:SZaBS+bx],2 jl bws05 add ax,300 cmp byte ptr[ds:SZaBS+bx],2 je bws05 add ax,1800 ; Freibauern (k”nnen durch ; gegn. Bauern nicht mehr ; geschlagen werden) ; links bws05: cmp byte ptr[ds:SZaBW+bx-1],0 jz bws05a cmp byte ptr[ds:SlowBW+bx-1],dh jle bws05a jmp bws06 ; geradeaus bws05a: cmp byte ptr[ds:SZaBW+bx],0 jz bws05b cmp byte ptr[ds:SlowBW+bx],dh jle bws05b jmp bws06 ; rechts bws05b: cmp byte ptr[ds:SZaBW+bx+1],0 jz bws05c cmp byte ptr[ds:SlowBW+bx+1],dh jle bws05c jmp bws06 ; ok, ist also Freibauer bws05c: mov byte ptr[ds:FreiBS+bx],-1 ; bewertung=+ESFaktor* ; UmwFaktor*Zeile*Zeile push bx push ax mov bl,115 cmp byte ptr[ds:si+10],leer ; gegner davor? jle bws05x mov bl,80 ; links oder rechts ; hinten eigener Bauer bws05x: cmp byte ptr[ds:si-11],BauerS jnz bws05d add bl,35 jmp bws05e bws05d: cmp byte ptr[ds:si-9],BauerS jnz bws05e add bl,35 bws05e: cmp byte ptr[ds:si.endspielS],false jz bws05f shl bl,1 jmp bws05g bws05f: cmp byte ptr[ds:si.endspielW],false jz bws05g shl bl,1 ; Produkt errechnen bws05g: mov al,bl xor ah,ah ; mal Quadrat der Zeile mov bl,dl mul bl mul bl mov bx,ax pop ax sub ax,bx pop bx ; Vorrcken der Bauern ; ax:=ax-(spalte)*Vorrckwert bws06: push dx push ax shl bx,1 xor ah,ah mov al,dl dec al dec al mul word ptr[ds:VorBS+bx] mov dx,ax sar bx,1 pop ax sub ax,dx pop dx ; rckst„ndige bauern cmp byte ptr[ds:si-1],BauerS jz bws07 cmp byte ptr[ds:si+1],BauerS jz bws07 cmp byte ptr[ds:si-9],BauerS jz bws07 cmp byte ptr[ds:si-11],BauerS jz bws07 cmp byte ptr[ds:si+19],BauerW jnz bws07 add ax,200 add byte ptr[ds:RuckBW+di],200 cmp byte ptr[ds:si+21],BauerW jnz bws07 add ax,200 add byte ptr[ds:RuckBW+di],200 bws07: dec cx jz bws08 jmp bwsl bws08: ret BauernWertSchw ENDP ; ******************************** ; Figurenwert weiá ; ******************************** FigurWertWeiss PROC mov si,aktStack xor ax,ax ; cx Anzahl Figuren weiá ; di Spalte aktuelle Figur ; bx Position aktuelle Figur xor ch,ch mov cl,byte ptr[ds:PosFW] fwwl: mov di,cx mov bl,byte ptr[ds:PosFW+di] xor bh,bh mov dl,byte ptr[ds:Spalte+bx] xor dh,dh mov di,dx cmp byte ptr[ds:si+bx],SpringerW jnz fww01 ; weiáer Springer shl bx,1 add ax,word ptr[ds:SprTW+bx] sar bx,1 inc byte ptr[ds:SumFW] cmp bl,90 jl fww00 inc byte ptr[ds:GrLFW] sub ax,470 fww00: jmp fww09 fww01: cmp byte ptr[ds:si+bx],LaeuferW jnz fww02 ; weiáer L„ufer cmp byte ptr[ds:LauFW],0 jz fww01a ; noch zwei L„ufer-Bonus add ax,400 fww01a: mov byte ptr[ds:LauFW],1 inc byte ptr[ds:SumFW] cmp bl,90 jl fww01b inc byte ptr[ds:GrlFW] sub ax,550 fww01b: jmp fww09 fww02: cmp byte ptr[ds:si+bx],TurmW jnz fww03 ; weiáer Turm vor gegn.Grundreihe? inc byte ptr[ds:SumFW] cmp bl,40 jl fww02a cmp bl,39 jg fww02a add ax,500 cmp byte ptr[ds:PosFS],30 jg fww02a add ax,600 ; Turm-Bauer Lage fww02a: cmp byte ptr[ds:SZaBW+di],0 jz fww02b add ax, 150 cmp byte ptr[ds:SZaBS+di],0 jnz fww02b add ax,250 ; zweiter Turm gleiche Spalte? fww02b: mov dx,di cmp byte ptr[ds:TurmSW],dl jne fww02c add ax,800 fww02c: mov byte ptr[ds:TurmSW],dl ; Freibauern auf dieser Spalte? cmp byte ptr[ds:FreiBS+di],0 jz fww02d add ax,1000 jmp fww03 fww02d: cmp byte ptr[ds:FreiBW+di],false jz fww03 add ax,1000 jmp fww09 ; Dame fww03: cmp byte ptr[ds:si+bx],DameW jnz fww04 add byte ptr[ds:SumFW],3 mov byte ptr[ds:DamePW],bl cmp bl,90 jl fww09 add byte ptr[ds:GrlFW],3 jmp fww09 ; K”nig (nur Position feststellen) fww04: cmp byte ptr[ds:si+bx],KoenigW jne fww09 mov byte ptr[ds:si.KoenPW],bl fww09: dec cx jz fww10 jmp fwwl fww10: ret FigurWertWeiss ENDP ; ******************************** ; Figurenwert schwarz ; ******************************** FigurWertSchw PROC mov si,aktStack xor ax,ax ; cx Anzahl Figuren schwarz ; di Spalte aktuelle Figur ; bx Position aktuelle Figur xor ch,ch mov cl,byte ptr[ds:PosFS] fwsl: mov di,cx mov bl,byte ptr[ds:PosFS+di] xor bh,bh mov dl,byte ptr[ds:Spalte+bx] xor dh,dh mov di,dx cmp byte ptr[ds:si+bx],SpringerS jnz fws01 ; schwarzer Springer shl bx,1 sub ax,word ptr[ds:SprTW+bx] sar bx,1 inc byte ptr[ds:SumFS] cmp bl,30 jg fws00 inc byte ptr[ds:GrLFS] add ax,470 fws00: jmp fws09 fws01: cmp byte ptr[ds:si+bx],LaeuferS jnz fws02 ; schwarzer L„ufer cmp byte ptr[ds:LauFS],0 jz fws01a ; noch zwei L„ufer => Bonus sub ax,400 fws01a: mov byte ptr[ds:LauFS],1 inc byte ptr[ds:SumFS] cmp bl,30 jg fws01b inc byte ptr[ds:GrlFS] add ax,550 fws01b: jmp fws09 fws02: cmp byte ptr[ds:si+bx],TurmS jnz fws03 ; schw. Turm vor gegn.Grundreihe? inc byte ptr[ds:SumFS] cmp bl,80 jl fws02a cmp bl,89 jg fws02a sub ax,500 cmp byte ptr[ds:PosFW],89 jl fws02a sub ax,600 ; Turm-Bauer Lage fws02a: cmp byte ptr[ds:SZaBS+di],0 jz fws02b sub ax, 150 cmp byte ptr[ds:SZaBW+di],0 jnz fws02b sub ax,250 ; zweiter Turm gleiche Spalte? fws02b: mov dx,di cmp byte ptr[ds:TurmSS],dl jne fws02c sub ax,800 fws02c: mov byte ptr[ds:TurmSS],dl ; Freibauern auf dieser Spalte? cmp byte ptr[ds:FreiBW+di],false jz fws02d sub ax,1000 jmp fws03 fws02d: cmp byte ptr[ds:FreiBS+di],0 jz fws03 sub ax,1000 jmp fws09 ; Dame fws03: cmp byte ptr[ds:si+bx],DameS jnz fws04 add byte ptr[ds:SumFS],3 mov byte ptr[ds:DamePS],bl cmp bl,30 jg fws09 add byte ptr[ds:GrlFS],3 jmp fws09 ; K”nig (nur Position feststellen) fws04: cmp byte ptr[ds:si+bx],KoenigS jne fws09 mov byte ptr[ds:si.KoenPS],bl fws09: dec cx jz fws10 jmp fwsl fws10: ret FigurWertSchw ENDP ; ******************************** ; K”nigswert weiá ; ******************************** ; gibt in ax den Abstand von cl,ch Abstand PROC xor ax,ax xor bh,bh mov bl,cl mov dl,byte ptr[ds:spalte+bx] mov al,byte ptr[ds:zeile+bx] mov bl,ch mov dh,byte ptr[ds:spalte+bx] mov ah,byte ptr[ds:zeile+bx] ; Zeilenabstand cmp al,ah jg abst01 xchg ah,al abst01: sub al,ah ; Spaltenabstand abst02: cmp dl,dh jg abst03 xchg dh,dl abst03: sub dl,dh ; summieren add al,dl xor ah,ah ret Abstand ENDP ; ******************************** ; bewertet Abst„nde Bauern-K”nig ; in cl den Standort des ; betreffenden K”nigs bergeben, ; addiert Bewertung zu ax ; ******************************** BauerKoenigAbst PROC push ax xor ax,ax xor dx,dx ; gewichteter Bauernabstand (weiá) xor bh,bh mov bl,byte ptr[ds:PosBW] or bl,bl jz bkas bka01: mov ch,byte ptr[ds:PosBW+bx] push cx push ax push dx push bx call Abstand pop dx mov bx,dx mov bl,byte ptr[ds:SpaBW+bx] cmp byte ptr[ds:FreiBW+bx],true mov bx,dx jne bka02 mov dx,600 mul dx pop dx add dx,6 jmp bka03 bka02: mov dx,200 mul dx pop dx add dx,2 bka03: mov cx,ax pop ax add ax,cx pop cx dec bx jnz bka01 bkas: xor bh,bh mov bl,byte ptr[ds:PosBS] or bl,bl jz bkadd bka04: mov ch,byte ptr[ds:PosBS+bx] push cx push ax push dx push bx call Abstand pop dx mov bx,dx mov bl,byte ptr[ds:SpaBS+bx] cmp byte ptr[ds:FreiBS+bx],true mov bx,dx jne bka05 mov dx,600 mul dx pop dx add dx,6 jmp bka06 bka05: mov dx,200 mul dx pop dx add dx,2 bka06: mov cx,ax pop ax add ax,cx pop cx dec bx jnz bka04 ; mitteln, dann wert=-6*(Mittel-6) mov cx,dx xor dx,dx div cx sub ax,600 mov bx,-600 imul bx bkadd: pop bx add ax,bx ret BauerKoenigAbst ENDP ; ******************************** ; K”nig Bewertung fr weiáen K”nig ; ******************************** KoenigWertWeiss PROC ; Endspiel oder Normalbewertung cmp byte ptr[ds:si.EndSpielW],true jne kww00 jmp kww11 ; Normalbewertung kww00: mov al,byte ptr[ds:si.rochadefaktor] cbw ; Abzug fr exponierte Stellung cmp byte ptr[ds:si.KoenPW],80 jg kww01 add ax,2000 xor bx,bx jmp kww10 ; Ermitteln der Gef„hrdungswerte ; der Flgel kww01: mov word ptr[ds:schutzL],0 mov word ptr[ds:schutzR],0 ; linker Flgel mov bx,1 kww02: cmp byte ptr[ds:si+bx+80],BauerW je kww03 add word ptr[ds:schutzL],50 cmp byte ptr[ds:SZaBW+bx],0 jne kww03 add word ptr[ds:schutzL],50 kww03: inc bx cmp bx,4 jl kww02 ; Rochade auf linkem Flgel mgl? cmp byte ptr[ds:si.RochadeErfolgt],0 jne kww04 add word ptr[ds:schutzL],50 cmp byte ptr[ds:si.grRochWmgl],true je kww04 add word ptr[ds:schutzL],150 ; rechter Flgel kww04: mov bx,7 kww05: cmp byte ptr[ds:si+bx+80],BauerW je kww06 add word ptr[ds:schutzR],50 cmp byte ptr[ds:SZaBW+bx],0 jne kww06 add word ptr[ds:schutzR],50 kww06: inc bx cmp bx,9 jl kww05 ; Rochade auf rechtem Flgel mgl? cmp byte ptr[ds:si.RochadeErfolgt],0 jne kww07 add word ptr[ds:schutzR],50 cmp byte ptr[ds:si.klRochWmgl],true je kww07 add word ptr[ds:schutzR],150 ; je nachdem, ob rochiert wurde ; den Flgel mit dem besseren ; Gef„hrdungswert aussuchen kww07: cmp byte ptr[ds:si.RochadeErfolgt],0 jne kww08 mov bx,word ptr[ds:schutzr] cmp bx,word ptr[ds:schutzl] jl kww10 mov bx,word ptr[ds:schutzl] jmp kww10 kww08: cmp [ds:si.RochadeErfolgt],klRochade jne kww09 mov bx,word ptr[ds:schutzR] jmp kww10 kww09: mov bx,word ptr[ds:schutzL] ; gefundene Summe mit gegnerischem ; Figurenwert mult. kww10: add ax,bx dec byte ptr[ds:SumFS] mul byte ptr[ds:SumFS] neg ax ret ; Endspielbewertung ; Zentralisierung kww11: xor bh,bh mov bl,byte ptr[ds:si.KoenPW] shl bx,1 mov ax,word ptr[ds:ZAbst+bx] shl ax,1 shl ax,1 neg ax mov cl,byte ptr[ds:si.KoenPW] call BauerKoenigAbst ret KoenigWertWeiss ENDP ; ******************************** ; K”nig Bewertung fr schw. K”nig ; ******************************** KoenigWertSchw PROC ; Endspiel oder Normalbewertung cmp byte ptr[ds:si.EndSpielS],true jne kws00 jmp kws11 ; Normalbewertung kws00: mov al,byte ptr[ds:si.rochadefaktor] cbw ; Abzug fr exponierte Stellung cmp byte ptr[ds:si.KoenPS],40 jl kws01 add ax,2000 xor bx,bx jmp kws10 ; Ermitteln der Gef„hrdungswerte ; der Flgel kws01: mov word ptr[ds:schutzL],0 mov word ptr[ds:schutzR],0 ; linker Flgel mov bx,1 kws02: cmp byte ptr[ds:si+bx+30],BauerS je kws03 add word ptr[ds:schutzL],50 cmp byte ptr[ds:SZaBS+bx],0 jne kws03 add word ptr[ds:schutzL],50 kws03: inc bx cmp bx,4 jl kws02 ; Rochade auf linkem Flgel mgl? cmp byte ptr[ds:si.RochadeErfolgt],0 jne kws04 add word ptr[ds:schutzL],50 cmp byte ptr[ds:si.grRochSmgl],true je kws04 add word ptr[ds:schutzL],150 ; rechter Flgel kws04: mov bx,7 kws05: cmp byte ptr[ds:si+bx+30],BauerS je kws06 add word ptr[ds:schutzR],50 cmp byte ptr[ds:SZaBS+bx],0 jne kws06 add word ptr[ds:schutzR],50 kws06: inc bx cmp bx,9 jl kws05 ; Rochade auf rechtem Flgel mgl? cmp byte ptr[ds:si.RochadeErfolgt],0 jne kws07 add word ptr[ds:schutzR],50 cmp byte ptr[ds:si.klRochSmgl],true je kws07 add word ptr[ds:schutzR],150 ; je nachdem, ob rochiert wurde, ; den Flgel mit dem besseren ; Gef„hrdungswert aussuchen kws07: cmp byte ptr[ds:si.RochadeErfolgt],0 jne kws08 mov bx,word ptr[ds:schutzr] cmp bx,word ptr[ds:schutzl] jl kws10 mov bx,word ptr[ds:schutzl] jmp kws10 kws08: cmp [ds:si.RochadeErfolgt],klRochade jne kws09 mov bx,word ptr[ds:schutzR] jmp kws10 kws09: mov bx,word ptr[ds:schutzL] ; gefundene Summe mit gegnerischem ; Figurenwert mult. kws10: add ax,bx dec byte ptr[ds:SumFW] mul byte ptr[ds:SumFW] ret ; Endspielbewertung ; Zentralisierung kws11: xor bh,bh mov bl,byte ptr[ds:si.KoenPS] shl bx,1 mov ax,word ptr[ds:ZAbst+bx] shl ax,1 shl ax,1 mov cl,byte ptr[ds:si.KoenPS] call BauerKoenigAbst ret KoenigWertSchw ENDP ; ******************************** ; Routine zur Mattbewertung, ; ax:=ax+16*(14-Abstand cl-ch) ; ******************************** AbstandWert PROC push ax call Abstand neg ax add ax,14 sal ax,1 sal ax,1 sal ax,1 sal ax,1 pop cx add ax,cx ret AbstandWert ENDP ; ******************************** ; Wert fr:weiá setzt schwarz matt ; ******************************** MattWertWeiss PROC ; Zentralisierung des schw. K”nigs xor bh,bh mov bl,byte ptr[ds:si.KoenPS] shl bx,1 mov ax,word ptr[ds:ZAbst+bx] shl ax,1 shl ax,1 shl ax,1 ; Abstand der K”nige mov cl,byte ptr[ds:si.KoenPS] mov ch,byte ptr[ds:si.KoenPW] call AbstandWert ; Abstand zu Springern xor bh,bh mov bl,byte ptr[ds:PosFW] mww00: cmp byte ptr[ds:PosFW+bx],SpringerW jne mww01 mov cl,byte ptr[ds:si.KoenPS] mov ch,byte ptr[ds:PosFW+bx] call AbstandWert mww01: dec bx jnz mww00 mov cl,7 sar ax,cl add ax,word ptr[ds:si.MatDiff] ret MattWertWeiss ENDP ; ******************************** ; Wert fr:schwarz setzt weiá matt ; ******************************** MattWertSchw PROC ;Zentralisierung des weiáen K”nigs xor bh,bh mov bl,byte ptr[ds:si.KoenPW] shl bx,1 mov ax,word ptr[ds:ZAbst+bx] shl ax,1 shl ax,1 shl ax,1 ; Abstand der K”nige mov cl,byte ptr[ds:si.KoenPS] mov ch,byte ptr[ds:si.KoenPW] call AbstandWert ; Abstand zu Springern xor bh,bh mov bl,byte ptr[ds:PosFS] mws00: cmp byte ptr[ds:PosFS+bx],SpringerS jne mws01 mov cl,byte ptr[ds:si.KoenPW] mov ch,byte ptr[ds:PosFS+bx] call AbstandWert mws01: dec bx jnz mws00 mov cl,7 sar ax,cl neg ax add ax,word ptr[ds:si.MatDiff] ret MattWertSchw ENDP ; ******************************** ; kann gegner. K”nig geschlagen ; werden? šberprfung anhand der ; Zuglisten (kein Check ob Listen ; leer...) Resultat in AX (0 wenn ; nicht im Schach, sonst Bewertung ; des Zuges) ; ******************************** KoenigSchlagbar PROC cmp byte ptr[ds:si.AmZug],weiss jne ks01 mov dl,byte ptr[ds:si.KoenPS] mov ax,30000+size spielstand sub ax,si jmp ks02 ks01: mov dl,byte ptr[ds:si.KoenPW] mov ax,-30000-size spielstand add ax,si ks02: xor bx,bx ks03: cmp byte ptr[ds:si.list+bx.nach],dl je ks04 add bx,size zug cmp bx,word ptr[ds:si.anzahl] jl ks03 ; Entwarnung clc ret ks04: stc ret KoenigSchlagbar ENDP ; ******************************** ; ist eigener K”nig im Schach? ; ******************************** KoenigImSchach PROC xor bh,bh mov byte ptr[ds:schach],false cmp byte ptr[ds:si.AmZug],weiss jne kis02 ; Routine fr weiss ; kann ein Bauer schlagen? mov ax,-30000-size spielstand add ax,si push ax mov bl,byte ptr[ds:si.KoenPW] mov dl,bl cmp byte ptr[ds:si.feld+bx-11],BauerS je kis_schach2 cmp byte ptr[ds:si.feld+bx-9],BauerS je kis_schach2 ; Figuren festlegen mov ah,DameS mov al,LaeuferS push ax mov al,TurmS mov cl,SpringerS jmp kis03 ; Routine fr schwarz kis02: mov ax,30000+size spielstand sub ax,si push ax mov bl,byte ptr[ds:si.KoenPS] mov dl,bl cmp byte ptr[ds:si.feld+bx+11],BauerW je kis_schach2 cmp byte ptr[ds:si.feld+bx+9],BauerW je kis_schach2 ; Figuren festlegen mov ah,DameW mov al,LaeuferW push ax mov al,TurmW mov cl,SpringerW jmp kis03 kis_schach1: pop dx kis_schach2: mov byte ptr[ds:schach],true pop ax stc ret ; Springer-Bedrohung kis03: cmp byte ptr[ds:si.feld+bx+21],cl je kis_schach1 cmp byte ptr[ds:si.feld+bx-21],cl je kis_schach1 cmp byte ptr[ds:si.feld+bx-19],cl je kis_schach1 cmp byte ptr[ds:si.feld+bx+19],cl je kis_schach1 cmp byte ptr[ds:si.feld+bx-12],cl je kis_schach1 cmp byte ptr[ds:si.feld+bx+12],cl je kis_schach1 cmp byte ptr[ds:si.feld+bx-8],cl je kis_schach1 cmp byte ptr[ds:si.feld+bx+8],cl je kis_schach1 ; Damen/L„ufer/Turm-Bedrohung mov dh,10 call suche jc kis_schach1 mov dh,-10 call suche jc kis_schach1 mov dh,1 call suche jc kis_schach1 mov dh,-1 call suche jc kis_schach1 pop ax mov dh,9 call suche jc kis_schach2 mov dh,-9 call suche jc kis_schach2 mov dh,11 call suche jc kis_schach2 mov dh,-11 call suche jc kis_schach2 pop ax clc ret KoenigImSchach ENDP ; ******************************** ; Hilfsroutine fr KoenigImSchach ; - sucht von dl in richtung dh ; nach Figur ah oder al ; ******************************** suche PROC mov bl,dl suche1: add bl,dh cmp byte ptr[ds:si.feld+bx],leer je suche1 cmp byte ptr[ds:si.feld+bx],ah je suche2 cmp byte ptr[ds:si.feld+bx],al je suche2 clc ; nicht bedroht ret suche2: stc ; bedroht ret suche ENDP ; ******************************** ; Bewertungsfunktion ; ******************************** BrettWert PROC cmp byte ptr[ds:si.StellungTyp],4 jl bw80 ; normale Bewertung ; CutOff-Vorhersage bei zu hoher ; Differenz Materialwert ; zu alpha/beta mov ax,word ptr[ds:si.MatDiff] sub ax,120 cmp ax,word ptr[ds:si.alpha] jl bw01 ret bw01: add ax,240 cmp ax,word ptr[ds:si.beta] jg bw02 ret ; nur Absch„tzung bei ; Schlagzugsuche bw02: mov ax,word ptr[ds:si.MatDiff] add ax,word ptr[ds:si.ruhewert] cmp si,horizon jle bw03 ret ; positionelle und ; materielle Bewertung bw03: call PosWert mov word ptr[ds:si.ruhewert],ax add ax,word ptr[ds:si.MatDiff] ret ; Endspielbewertung bw80: cmp byte ptr[ds:si.StellungTyp],1 jne bw81 call MattWertWeiss ret bw81: cmp byte ptr[ds:si.StellungTyp],3 jne bw82 call MattWertSchw ret bw82: xor ax,ax ; patt ret BrettWert ENDP ; ******************************** ; ermittelt positionelle ; Bewertung in ax ; ******************************** PosWert PROC push si call Analyse call BauernWertWeiss push ax call BauernWertSchw push ax call FigurWertWeiss push ax call FigurWertSchw push ax call KoenigWertWeiss push ax call KoenigWertSchw ; summieren pop bx add ax,bx pop bx add ax,bx pop bx add ax,bx pop bx add ax,bx pop bx add ax,bx add ax,word ptr[ds:si.BedrohungWert] sar ax,1 ; ax/2 sar ax,1 ; ax/4 sar ax,1 ; ax/8 ; Strafpunkte fr leichte Fig. ; auf der Grundlinie xor bh,bh mov bl,byte ptr[ds:grlfw] sub ax,bx mov bl,byte ptr[ds:grlfs] add ax,bx sar ax,1 ; ax/16 sar ax,1 ; ax/32 sar ax,1 ; ax/64 sar ax,1 ; ax/128 pop si ret PosWert ENDP ; ******************************** ; Zug/Save-Listen Verwaltung ; ******************************** ; **************************************** ; l”st einen Zug aus einer Liste heraus ; l”st den Zug DX (von/nach) aus SAVELIST ; heraus, falls Zug vorhanden war enth„lt ; AX dessen letzte Bewertung, ; sonst AX alpha/betastart ; **************************************** Aussortieren PROC ; ist Liste schon leer? cmp word ptr[ds:si.saveanzahl],0 ; ja, also ex. Zug nicht in Liste! je aus03 cmp word ptr[ds:si.savestart],0ffffh je aus03 ; ja, schon "leergesucht" ; ist Zug der Anfang der Liste? mov bx,word ptr[ds:si.savestart] cmp dx,word ptr[ds:si.savelist+bx] je aus02 ; nein, dann Vorg„nger finden aus00: mov cx,bx mov bx,word ptr[ds:si.savelist+bx.next] cmp bx,0ffffh ; Zugliste zuende, nicht gefunden je aus03 cmp dx,word ptr[ds:si.savelist+bx] je aus01 ; Zug gefunden bei BX jmp aus00 ; in Liste gefunden aus01: push dx mov ax,word ptr[ds:si.savelist+bx.value] ; in dx Nachfolger des ; auszusortierenden Zuges mov dx,word ptr[ds:si.savelist+bx.next] mov bx,cx ; in Vorg„nger diesen ; Nachfolger eintragen mov word ptr[ds:si.savelist+bx.next],dx pop dx jmp aus04 ; Zug ist Erster ; Nachfolger wird Anfang aus02: mov ax,word ptr[ds:si.savelist+bx.value] mov cx,word ptr[ds:si.savelist+bx.next] mov word ptr[ds:si.savestart],cx jmp aus04 ; Zug nicht gefunden, ; also Startwert zurckgeben aus03: cmp byte ptr[ds:si.AmZug],weiss je aus03w ; schwarz minimiert alpha mov ax,alphastart jmp aus04 ; weiá maximiert beta aus03w: mov ax,betastart aus04: ret Aussortieren ENDP ; **************************************** ; Einsortieren eines Zuges in eine Liste ; DX : Position des Zuges ; AX : Wert des Zuges, Sortierkriterium ; DI : zeigt auf die Liste (sort/save) ; BX : enth„lt den Listenanfang ; je nachdem, ob schwarz oder weiá am Zug ; ist erfolgt unterschiedliche Sortierung ; Es wird in BX der Listenanfang (eve. ; jetzt neu!) zurckgegeben. ; WICHTIG: bei gleicher Bewertung ; zweier Zge, hintendran anfgen ; **************************************** Einsortieren PROC ; Liste noch ganz leer? or dx,dx je ein01 push bx ; Listenanfang sichern ;ist es schwarze oder weiáe Liste? cmp byte ptr[ds:si.AmZug],schwarz je ein01s ;in "weiáer" Liste Position suchen cmp ax,word ptr[ds:di+bx.value] ; Position vor Listenanfang jg ein04 ein01wl: mov cx,bx mov bx,word ptr[ds:di+bx.next] ; Position am Listenende cmp bx,0ffffh je ein03 cmp ax,word ptr[ds:di+bx.value] jg ein02 ; Position gefunden jmp ein01wl ;in "schw." Liste Position suchen ein01s: cmp ax,word ptr[ds:di+bx.value] ; Position am Listenanfang jl ein04 ein01sl: mov cx,bx mov bx,word ptr[ds:di+bx.next] cmp bx,0ffffh je ein03 cmp ax,word ptr[ds:di+bx.value] jl ein02 ; Position gefunden jmp ein01sl ; allererster Eintrag der Liste ein01: xor bx,bx ; Listenanfang ganz vorn mov word ptr[ds:di+bx.next],0ffffh mov word ptr[ds:di+bx.value],ax ret ; mitten in Liste einsortieren ein02: mov bx,cx mov cx,word ptr[ds:di+bx.next] mov word ptr[ds:di+bx.next],dx mov bx,dx mov word ptr[ds:di+bx.next],cx mov word ptr[ds:di+bx.value],ax pop bx ; Listenanfang unver„ndert ret ; am Listenende einsortieren ein03: mov bx,cx mov word ptr[ds:di+bx.next],dx mov bx,dx mov word ptr[ds:di+bx.next],0ffffh mov word ptr[ds:di+bx.value],ax pop bx ; Listenanfang unver„ndert ret ; vor Listenanfang einsortieren ein04: xchg bx,dx mov word ptr[ds:di+bx.next],dx mov word ptr[ds:di+bx.value],ax pop dx ; neuer Listenanfang ret Einsortieren ENDP ; ******************************** ; erh”ht die Stacktiefe ; ******************************** IncDepth PROC mov cx,ds mov es,cx mov si,aktStack mov di,aktStack add di,SIZE Spielstand mov cx,SIZE Spielstand ; die Savelist & SaveStart ; nicht l”schen! sub cx,(SIZE savelist + 4) sar cx,1 rep movsw add aktstack,SIZE Spielstand mov si,aktstack not byte ptr[ds:si.AmZug] ret IncDepth ENDP ; ******************************** ; mindert die Stacktiefe ; ******************************** DecDepth PROC sub aktStack,SIZE Spielstand mov si,aktStack ret DecDepth ENDP ; ******************************** ; Weiss an der Reihe (maximiert) ; ******************************** WeissZug PROC cmp ax,word ptr[ds:si.alpha] jle wz01 mov byte ptr[ds:si.cutoff],true wz01: cmp ax,word ptr[ds:si.beta] jle wz02 mov word ptr[ds:si.beta],ax cmp si,Depth1 jne wz02 cmp byte ptr[ds:timeout],0 jnz wz02 mov cx,word ptr[ds:si.zugNr] mov word ptr[ds:ZugWahl],cx wz02: ret WeissZug ENDP ; ******************************** ; Schwarz an der Reihe (minimiert) ; ******************************** SchwarzZug PROC cmp ax,word ptr[ds:si.beta] jge sz01 mov byte ptr[ds:si.cutoff],true sz01: cmp ax,word ptr[ds:si.alpha] jge sz99 mov word ptr[ds:si.alpha],ax cmp si,Depth1 jne sz99 cmp byte ptr[ds:timeout],0 jnz sz99 mov cx,word ptr[ds:si.zugnr] mov word ptr[ds:ZugWahl],cx sz99: ret SchwarzZug ENDP ; ******************************** ; restauriert Brett ; ******************************** Restore PROC push di push si push cx mov si,aktStack sub si,SIZE Spielstand mov di,aktStack ; Brett restaurieren mov cx,50 ; Brett in Bytes 10*10/2 rep movsw ; Statistik restaurieren mov si,aktStack add si,offset EndSpielS-SIZE Spielstand mov di,aktStack add di,offset EndSpielS mov cx,9 rep movsw pop cx pop si pop di ret Restore ENDP ; ******************************** ; Suche,ermittelt den "besten" Zug ; ******************************** ZugAuswahl PROC ; weitere Vertiefung m”glich? cmp si,word ptr[ds:OutZone] jl za01 za00: call BrettWert ret za01: call IncDepth mov byte ptr[ds:si.cutoff],false cmp byte ptr[ds:si.AmZug],schwarz jne za02 call ZugGenSchwarz mov word ptr[ds:si.alpha],alphastart jmp za03 za02: call ZugGenWeiss mov word ptr[ds:si.beta],betastart ; berhaupt Zge vorhanden? za03: cmp word ptr[ds:si.anzahl],0 jne za03w call Brettwert call DecDepth ret ; illegale Stellung? za03w: call KoenigSchlagbar ; legt auch Bewertung fest! jnc za03x call DecDepth ret za03x: ; noch volle Suche? cmp si,horizon jle za03c ; nein, nur noch Schlagzge werden ; untersucht. Als Basis RUHEWERT ; ermitteln call brettwert cmp byte ptr[ds:si.AmZug],schwarz jne za03a call SchwarzZug jmp za03b za03a: call WeissZug za03b: cmp word ptr[ds:si.cutoff],true jne za03c call DecDepth ret za03c: mov bx,word ptr[ds:si.start] ; Zugschleife za04: mov word ptr[ds:si.ZugNr],bx call Restore call FuehreZugAus push bx cmp si,horizon jl za06 ; noch volle Suche cmp word ptr[ds:si.list+bx.option],0 jne za06 call KoenigImSchach jc za07 call BrettWert jmp za07 za06: call ZugAuswahl za07: pop bx mov cx,bx cmp byte ptr[ds:si.AmZug],schwarz jne za08 call SchwarzZug jmp za09 za08: call WeissZug ; bewerteten Zug in savelist ; einsortieren za09: mov cx,word ptr[ds:si.list+bx] push bx mov bx,word ptr[ds:si.saveanzahl] mov word ptr[ds:si.savelist+bx],cx mov dx,bx mov di,si add di,(size spielstand-size savelist-4) mov bx,word ptr[ds:si.savestart] call Einsortieren mov word ptr[ds:si.savestart],bx pop bx add word ptr[ds:si.saveanzahl],8 ; Ende der Suche durch CUTOFF? cmp byte ptr[ds:si.cutoff],true je za10 ; Ende der Liste? mov bx,word ptr[ds:si.list+bx.next] cmp bx,0ffffh je za10 ; Zeit zu Ende? cmp byte ptr[ds:timeout],0 jne za10 za09l: jmp za04 za10: cmp byte ptr[ds:si.AmZug],schwarz je za11 ; weiss am Zug: Bewertung=beta mov ax,word ptr[ds:si.beta] jmp za99 ; schwarz am Zug: Bewertung=alpha za11: mov ax,word ptr[ds:si.alpha] za99: call DecDepth ret ZugAuswahl ENDP ; ******************************** ; Computerzug ; ******************************** ComputerZug PROC mov bx,seg GameStack mov ds,bx mov es,bx ; GameStack-Reset xor ax,ax mov di,Depth1 mov cx,Size Spielstand*7/2 rep stosw ; Timer rcksetzen mov ah,1 xor cx,cx xor dx,dx int 15h ; Timer-Intervall setzen mov ah,83h xor al,al mov bx,offset timeout mov cx,15*Denkzeit xor dx,dx int 15h ; Flags l”schen mov byte ptr[ds:timeout],0 mov cx,5 mov bx,Depth0 ; Zug ermitteln cz00: add bx,size Spielstand mov horizon,bx push bx push cx call ZugAuswahl pop cx pop bx cmp byte ptr[ds:timeout],0 jne cz01 loop cz00 cz01: ; Stellung analysieren test ax,1000000000000000b jnz cz02 cmp ax,30000-2*size spielstand jl cz03 mov byte ptr[ds:gameovr],true mov byte ptr[ds:sieger],weiss jmp cz04 cz02: cmp ax,-30000+2*size spielstand jg cz03 mov byte ptr[ds:gameovr],true mov byte ptr[ds:sieger],schwarz jmp cz04 cz03: call Analyse cmp byte ptr[ds:si.StellungTyp],2 jne cz04 mov byte ptr[ds:gameovr],true mov byte ptr[ds:sieger],3 ; Fertigmeldung cz04: mov ah,0Eh mov al,07 int 10h ; Zug bergeben add si,size spielstand mov bx,word ptr[ds:ZugWahl] mov ax,word ptr[ds:si.list+bx] mov dx,word ptr[ds:si.list+bx.option] mov si,offset gamestack mov word ptr[ds:si.list],ax mov word ptr[ds:si.list+2],dx xor bx,bx ret ComputerZug ENDP ; ******************************** ; Spielverlauf-Schleife ; liest Koordinate von Tastatur ; liefert in bx Brettposition ; ******************************** KoordEingabe PROC ke01: mov ah,8 int 21h ; Umwandlung klein->groá cmp al,27 je ke99 cmp al,'a' jl ke01a sub al,32 ke01a: cmp al,'A' jl ke01 cmp al,'H' jg ke01 mov dl,al sub dl,64 ke02: mov ah,8 int 21h cmp al,27 je ke99 cmp al,'1' jl ke02 cmp al,'8' jg ke02 mov dh,':' sub dh,al ; 10 Mal Zeile shl dh,1 mov bl,dh shl dh,1 shl dh,1 add bl,dh ; plus Spalte add bl,dl xor bh,bh ret ; ESC-Abort Programm ke99: mov word ptr[ds:abort],true ret KoordEingabe ENDP ; ******************************** ; liest Spielerzug von Tastatur ; ******************************** ZugEingabe PROC ze_neu: call KoordEingabe cmp byte ptr[ds:abort],true je ze_abort cmp byte ptr[ds:si+bx],leer jle ze_neu mov al,bl push ax call KoordEingabe cmp byte ptr[ds:abort],true je ze_abort pop ax mov ah,bl mov bx,word ptr[ds:si.Anzahl] ze_suche: cmp ax,word ptr[ds:si.list+bx] je ze_found sub bx,SIZE Zug jns ze_suche mov ax,msgEr call Message jmp ze_neu ; eve. Bauernumwandlung gew„hlt? ze_found: push bx xor bh,bh mov bl,al cmp byte ptr[ds:si.feld+bx],BauerW jne ze_quit cmp bl,39 jg ze_quit ze_bauer: mov ah,8 int 21h cmp al,'a' jl ze_b01 sub al,32 ze_b01: cmp al,'D' jne ze_b02 mov dx,DameW jmp ze_b99 ze_b02: cmp al,'S' jne ze_bauer mov dx,SpringerW ze_b99: pop bx mov word ptr[ds:si.list+bx.option],dx ret ze_quit: pop bx ze_abort: ret ZugEingabe ENDP ; ******************************** ; abwechselnd Computer/Spieler Zug ; ******************************** Spiel PROC sp00: cmp byte ptr[ds:si.AmZug],weiss jne sp01 mov ax,msgSZ call Message call ZugGenWeiss sp01a: call ZugEingabe cmp byte ptr[ds:abort],true je sp_abort ; Zug korrekt (K”nig nicht ; ins Schach gestellt?) push bx call IncDepth call FuehreZugAus call ZugGenSchwarz call KoenigSchlagbar pop bx jnc sp01b call DecDepth mov ax,MsgEr call Message jmp sp01a sp01b: call DecDepth call Anzeige call FuehreZugAus not byte ptr[ds:si.AmZug] mov ax,msgCZ call Message jmp sp02 sp01: not byte ptr[ds:si.AmZug] call ComputerZug call Anzeige call FuehreZugAus sp02: cmp byte ptr[ds:gameovr],true jne sp00 cmp byte ptr[ds:sieger],weiss jne sp03 mov ax,msgSG jmp sp99 sp03: cmp byte ptr[ds:sieger],schwarz jne sp04 mov ax,msgCG jmp sp99 sp04: mov ax,msgKG sp99: call Message mov ah,86h mov cx,120 xor dx,dx int 15h sp_abort: ret Spiel ENDP ; ******************************** ; Mitteilung No AX anzeigen ; ******************************** Message PROC push es push bx mov dx,gScreen push dx cmp dx,gScreenPage0 je msg00 mov gScreen,gScreenPage0 jmp msg01 msg00: mov gScreen,gScreenPage2 msg01: mov bx,20 mul bx mov cx,278 add ax,200 call sGrab mov cx,244 mov ax,158 call sDrop pop dx mov gScreen,dx pop bx pop es ret Message ENDP ; ******************************** ; Anzeige des Zuges BX ; Aktualisierung des Brettes ; Eingabe : Spielfeldpos BX ; Ausgabe : x/y in cx/ax ; ******************************** Schirmkoord PROC mov dl,byte ptr[ds:spalte+bx] mov dh,byte ptr[ds:zeile+bx] dec dl dec dh ; x-Position in cx ermitteln xor ah,ah mov al,dl mov bx,25 push dx mul bx pop dx mov cx,ax add cx,20 ; y-Position in ax ermitteln xor ah,ah mov al,dh mov bx,22 mul bx ret Schirmkoord ENDP ; ******************************** ; Rochadezug ; als zwei Spielzge anzeigen ; ******************************** RochadeAnzeige PROC mov ax,word ptr[ds:si.list+bx] push ax mov dx,word ptr[ds:si.list+bx.option] push dx cmp dx,klRochade je ra01 ; groáe Rochade inc ah sub al,4 mov word ptr[ds:si.list+bx],ax mov word ptr[ds:si.list+bx.option],0 call Anzeige jmp ra02 ; kleine Rochade ra01: dec ah add al,3 mov word ptr[ds:si.list+bx],ax mov word ptr[ds:si.list+bx.option],0 call Anzeige ; ok, Zug restaurieren ra02: pop dx pop ax mov word ptr[ds:si.list+bx],ax mov word ptr[ds:si.list+bx.option],dx ret RochadeAnzeige ENDP ; ******************************** ; Animation eines Spielzuges ; ******************************** Anzeige PROC ; kleine oder groáe Rochade? cmp word ptr[ds:si.list+bx.option],4 jl anzNormal push bx mov bx,word ptr[ds:si.list+bx] xor bh,bh mov dl,byte ptr[ds:si+bx] pop bx cmp dl,BauerW je anzNormal cmp dl,BauerS je anzNormal call RochadeAnzeige anzNormal: push si push es call gCopy ; zuerst Startfeld l”schen ; (mit Feld-Backup) push bx mov bx,word ptr[ds:si.list+bx] xor bh,bh call SchirmKoord push ax push cx add ax,200 call sGrab pop cx pop ax call sDrop ; dann Spielfigur grabben pop bx push bx mov bx,word ptr[ds:si.list+bx] xor bh,bh mov bl,byte ptr[ds:si+bx] xor bh,bh shl bx,1 shl bx,1 mov cx,word ptr[ds:FigurPos+bx] mov ax,word ptr[ds:FigurPos+bx+2] call sGrab ; Toggle-Schleife verschiebt Figur pop bx push bx mov ax,word ptr[ds:si.list+bx] push ax mov bl,ah xor bh,bh call SchirmKoord mov word ptr[ds:xcount],cx mov word ptr[ds:ycount],ax pop ax mov bl,al xor bh,bh call SchirmKoord ; Animation anz00: push ax push cx call sToggle ; setzen call gSwitchEm call gWaitDisplay pop cx pop ax push ax push cx call sToggle ; l”schen pop cx pop ax cmp ax,word ptr[ds:ycount] jl anz01 jg anz02 jmp anz03 anz01: inc ax jmp anz03 anz02: dec ax anz03: cmp cx,word ptr[ds:xcount] jl anz04 jg anz05 jmp anz06 anz04: inc cx jmp anz06 anz05: dec cx anz06: cmp cx,word ptr[ds:xcount] jne anz00 cmp ax,word ptr[ds:ycount] jne anz00 ; Zielfeld l”schen pop bx push bx mov ax,word ptr[ds:si.list+bx] xor bh,bh mov bl,ah call SchirmKoord add ax,200 push ax push cx call sGrab pop cx pop ax sub ax,200 call sDrop ; Zugfigur setzen pop bx push bx mov di,word ptr[ds:si.list+bx.option] mov bx,word ptr[ds:si.list+bx] xor bh,bh mov dl,byte ptr[ds:si+bx] xor dh,dh ; Bauernumwandlung?? cmp dl,BauerW jne anz07 cmp bl,39 jg anz08 mov dx,di jmp anz08 anz07: cmp dl,BauerS jne anz08 cmp bl,80 jl anz08 mov dx,di ; dx nun Figur (bei Bauernumw. ; die Ersatzfigur) anz08: mov bx,dx shl bx,1 shl bx,1 mov cx,word ptr[ds:FigurPos+bx] mov ax,word ptr[ds:FigurPos+bx+2] call sGrab pop bx push bx mov ax,word ptr[ds:si.list+bx] xor bh,bh mov bl,ah call SchirmKoord call sToggle call gSwitchEm pop bx pop es pop si ret Anzeige ENDP ; ******************************** ; Quit (Verabschiedung) ; ******************************** Quit PROC mov ah,09h cmp byte ptr[ds:abort],true je q04 cmp byte ptr[ds:sieger],weiss je q00 cmp byte ptr[ds:sieger],schwarz je q01 cmp byte ptr[ds:sieger],3 je q02 q04: mov dx,offset txtAB int 21h ret q00: mov dx,offset txtSG int 21h ret q01: mov dx,offset txtCG int 21h ret q02: mov dx,offset txtKG int 21h ret Quit ENDP ; ******************************** ; Intro & Init ; ******************************** Intro PROC ; VGA-Grafikkarte vorbereiten call gInit call gHide mov dx,seg gPCXFileTitel mov ds,dx mov dx,offset gPCXFileTitel call gLoadPCX call gShow ; Titel CHESSfx anzeigen mov si,0 titelloop1: xor ah,ah mov al,byte ptr[ds:Falldown+si] mov bx,80d mul bx add ax,16000 mov bx,ax call gStartAddr mov ah,86h xor cx,cx mov dx,22000 int 15h inc si cmp byte ptr[ds:Falldown+si],255 jne titelloop1 ; Schachbrett vorbereiten mov dx,offset gPCXFileBrett mov gScreen,gScreenPage0 call gLoadPCX ; Bauern setzen mov cx,20 SetBauern: push cx mov ax,0 mov cx,230 call sGrab mov ax,22 pop cx push cx call sToggle mov ax,0 mov cx,254 call sGrab mov ax,132 pop cx push cx call sToggle pop cx add cx,25 cmp cx,220 jl SetBauern ; Figuren setzen mov si,offset Aufbau SetFiguren: xor ch,ch xor ah,ah mov cl,byte ptr[ds:si] inc si mov al,byte ptr[ds:si] inc si call sGrab xor ch,ch xor ah,ah mov cl,byte ptr[ds:si] inc si mov al,byte ptr[ds:si] inc si call SToggle cmp si,offset Aufbau+64 jl SetFiguren ; Figuren rechts l”schen mov si,offset gPCXBuffer mov word ptr[ds:ycount],0 mov word ptr[ds:xcount],230 tclear1: call gSetPix inc word ptr[ds:xcount] cmp word ptr[ds:xcount],230+73 jl tclear1 mov word ptr[ds:xcount],230 inc word ptr[ds:ycount] cmp word ptr[ds:ycount],120 jl tclear1 ; Spielfeld anzeigen mov bx,16000 titelloop2: sub bx,80 call gStartAddr mov ah,86h xor cx,cx mov dx,8000 int 15h or bx,bx jnz titelloop2 call gWaitDisplay ; Brett-Backup laden mov dx,offset gPCXFileBrett mov gScreen,gScreenPage1 call gLoadPCX mov gScreen,gScreenPage2 ; interne Schachwerte setzen ; Brett aufbauen mov ax,seg Brett mov es,ax mov ds,ax mov si,offset Brett mov di,offset GameStack mov aktStack,di mov cx,60 rep movsw ; Vorrck-Werte definieren mov si,offset VorMS mov di,offset VorBW mov cx,8 rep movsw mov si,offset VorMS mov di,offset VorBS mov cx,8 rep movsw mov si,aktStack mov word ptr[ds:si.alpha],alphastart mov word ptr[ds:si.beta],betastart mov word ptr[ds:si.matdiff],0 mov word ptr[ds:si.matwertw],4050 mov word ptr[ds:si.matwerts],-4050 mov byte ptr[ds:si.stellungtyp],4 mov byte ptr[ds:si.klRochWmgl],true mov byte ptr[ds:si.klRochSmgl],true mov byte ptr[ds:si.grRochWmgl],true mov byte ptr[ds:si.grRochSmgl],true mov byte ptr[ds:si.koenps],25 mov byte ptr[ds:si.koenpw],95 mov byte ptr[ds:abort],false ret Intro ENDP ; ******************************** ; Initialisiert Grafik ; ******************************** gInit PROC push ax push dx mov ax,13h int 10h mov dx,03C4h mov al,04h out dx,al inc dx in al,dx and al,(not 8h) out dx,al mov dx,03D4h mov al,14h out dx,al inc dx in al,dx and al,(not 40h) out dx,al dec dx mov al,17h out dx,al inc dx in al,dx or al,40h out dx,al mov ax,gScreenSegment mov es,ax xor ax,ax xor di,di mov cx,07FFFh rep stosw pop dx pop ax ret gInit ENDP ; ******************************** ; versteckt Bildaufbau ; ******************************** gHide PROC mov ah,12h mov al,01h mov bl,36h int 10h ret gHide ENDP ; ******************************** ; zeigt Bildschirm wieder ; ******************************** gShow PROC mov ah,12h mov al,00h mov bl,36h int 10h ret gShow ENDP ; ******************************** ; setzt wieder Textmodus ; ******************************** gExit PROC push ax xor ah,ah mov al,3h int 10h pop ax ret gExit ENDP ; ******************************** ; setzt einen Graphikpunkt ; ******************************** gSetPix PROC push bx push es push dx push cx mov cl,byte ptr[ds:si] mov ax,word ptr[ds:xcount] mov bx,word ptr[ds:ycount] push cx push ax push ax shl bx,1 shl bx,1 shl bx,1 shl bx,1 mov ax,bx shl bx,1 shl bx,1 add ax,bx pop bx shr bx,1 shr bx,1 add ax,bx mov di,gScreen add di,ax mov ax,gScreenSegment mov es,ax pop cx and cl,3h mov bx,1h shl bx,cl pop cx ; Color mov ah,bl mov al,2h mov dx,03C4h out dx,ax mov byte ptr es:[di],cl pop cx pop dx pop es pop bx ret gSetPix ENDP ; ******************************** ; setzt die Bildschirm-Start- ; auf 0A000:BX ; ******************************** gStartAddr PROC call gWaitDisplay push ds mov dx,gCRTC mov ah,bh mov al,0Ch out dx,ax mov ah,bl inc al out dx,ax xor cx,cx mov ds,cx mov WORD PTR ds:[044Eh],bx pop ds ret gStartAddr ENDP ; ******************************** ; Hilfsroutine fr LoadPCX ; ******************************** gNextPixel PROC inc word ptr[ds:xcount] cmp word ptr[ds:xcount],320 je gnp_next ret gnp_next: inc word ptr[ds:ycount] mov word ptr[ds:xcount],0 ret gNextPixel ENDP ; ******************************** ; L„dt ein 320x200x256 PCX Bild ; Dateiname bei ds:dx ; ******************************** gLoadPCX PROC ; Dateiname bei ds:dx ; Datei ”ffnen mov ah,3Dh mov al,10010000b int 21h ; 128 Bytes lesen mov bx,ax mov ah,3Fh mov cx,128 mov dx,seg gPCXBuffer mov ds,dx mov dx,offset gPCXBuffer int 21h ; gltige 320x200x256 PCX-Datei? mov si,offset gPCXBuffer cmp byte ptr[ds:si],10 jne glPCX_No cmp byte ptr[ds:si+3],8 jne glPCX_No jmp glPCX_Ok glPCX_No: mov ah,3Eh int 21h ret glPCX_Ok: mov word ptr[ds:xcount],0 mov word ptr[ds:ycount],0 mov byte ptr[ds:pack],0 glPCX_load: ; nachladen mov ah,3Fh mov cx,1024 mov dx,offset gPCXBuffer int 21h mov si,offset gPCXBuffer mov word ptr[ds:bufpos],0 glPCX_loop: cmp word ptr[ds:bufpos],cx jge glPCX_load cmp byte ptr[ds:pack],0 jz glPCX_nopack push cx xor ch,ch mov cl,byte ptr[ds:pack] glPCX_unpack: call gSetPix call gNextPixel loop glPCX_unpack pop cx mov byte ptr[ds:pack],0 jmp glPCX_next glPCX_nopack: mov al,byte ptr[ds:si] and al,0C0h cmp al,0c0h jnz glPCX_pixel mov al,byte ptr[ds:si] and al,3Fh mov byte ptr[ds:pack],al jmp glPCX_next glPCX_pixel: call gSetPix call gNextPixel glPCX_next: inc si inc word ptr[ds:bufpos] cmp word ptr[ds:ycount],200 je glPCX_end jmp glPCX_loop glPCX_end: push bx ; palette finden mov ah,42h mov al,2 mov cx,0FFFFh mov dx,-(3*256) int 21h ; palette laden mov ah,3Fh mov cx,3*256 mov dx,offset gPCXBuffer int 21h ; palette anpassen mov cx,2*256 mov si,offset gPCXBuffer glPCX_pal: shr byte ptr[ds:si],1 shr byte ptr[ds:si],1 inc si loop glPCX_pal ; palette setzen mov ax,seg gPCXBuffer mov es,ax mov dx,offset gPCXBuffer mov al,12h mov ah,10h xor bx,bx mov cx,256 int 10h pop bx ; File schlieáen mov ah,3Eh int 21h ret gLoadPCX ENDP ; ******************************** ; Spritegrabber ; bei cx,ax in gPCXBuffer ; ******************************** sGrab PROC cld push ds push si mov bl,20 mov bh,24 mov dx,(320-24)/4 push dx push bx mov bx,seg gPCXBuffer mov es,bx mov di,offset gPCXBuffer mov bx,320 shr bx,1 shr bx,1 mul bx mov bx,cx shr bx,1 shr bx,1 add ax,bx mov si,ax ; si Screenpos pop bx pop dx mov ax,gScreenSegment mov ds,ax ; ds:si Screenpos sg_yloop: push cx push dx push bx mov dx,03CEh mov al,4h sg_xloop: mov ah,cl and ah,3h out dx,ax movsb ; Transfer cmp ah,3h jz sg_noinc dec si ; div 4 sg_noinc: inc cx dec bh jnz sg_xloop pop bx pop dx add si,dx dec bl pop cx jnz sg_yloop pop si pop ds ret sGrab ENDP ; ******************************** ; Spielfigur gPCXBuffer ; bei cx,ax setzen ; ******************************** sDrop PROC cld push ds push si mov bl,20 mov bh,24 mov dx,(320-24)/4 push dx push bx mov bx,seg gPCXBuffer mov ds,bx mov si,offset gPCXBuffer mov bx,320/4 mul bx mov bx,cx shr bx,1 shr bx,1 add ax,bx mov di,ax ; si Screenpos add di,gScreen pop bx pop dx mov ax,gScreenSegment mov es,ax ; ds:si Screenpos sd_yloop: push cx push dx push bx mov dx,03C4h mov al,2h sd_xloop: push cx and cl,3h mov ah,1 shl ah,cl pop cx out dx,ax movsb ; Transfer cmp ah,8h jz sd_noinc dec di ; div 4 sd_noinc: inc cx dec bh jnz sd_xloop pop bx pop dx add di,dx dec bl pop cx jnz sd_yloop pop si pop ds ret sDrop ENDP ; ******************************** ; Spielfigur bei cx,ax togglen ; ******************************** sToggle PROC cld push ds push di push si mov bl,20 mov bh,24 mov dx,320/4 push dx push bx mov bx,seg gPCXBuffer mov es,bx mov di,offset gPCXBuffer mov bx,320/4 mul bx mov bx,cx shr bx,1 shr bx,1 add ax,bx mov si,ax ; si Screenpos add si,gScreen pop bx pop dx mov ax,gScreenSegment mov ds,ax ; ds:si Screenpos st_yloop: push cx push dx push bx push si st_xloop: mov al,byte ptr es:di cmp al,00h jz st_skipbyte mov ah,cl and ah,3h push ax mov dx,03CEh mov al,4h out dx,ax movsb dec si dec di pop ax push cx xchg ah,al mov cx,ax mov ah,1 shl ah,cl mov dx,03C4h mov al,2h out dx,ax mov byte ptr ds:si,ch pop cx st_skipbyte: push cx and cl,3h cmp cl,3h jnz st_noinc inc si st_noinc: pop cx inc di inc cx dec bh jnz st_xloop pop si pop bx pop dx add si,dx pop cx dec bl jnz st_yloop pop si pop di pop ds ret sToggle ENDP ; ******************************** ; gSwitchEm tauscht Anzeige- ; und Bearbeitungs- Grafikseite ; ******************************** gSwitchEm PROC push bx mov ax,SEG gScreen mov ds,ax cmp WORD PTR gScreen,gScreenPage0 je gSwitchEm_Disp0 gSwitchEm_Disp2: mov bx,gScreenPage2 CALL gStartAddr mov WORD PTR gScreen,gScreenPage0 call gCopy pop bx ret gSwitchEm_Disp0: mov bx,gScreenPage0 CALL gStartAddr mov WORD PTR gScreen,gScreenPage2 call gCopy pop bx ret gSwitchEm ENDP ; ******************************** ; Bildschirm-Kopie herstellen ; (fr flssige Animation) ; ******************************** gCopy PROC push bx push ax push cx push ds push si mov dx,3C4h mov al,2 out dx,al mov dx,3C5h mov al,0Fh out dx,al mov ah,0 mov al,1 call gSetMode mov di,word ptr gScreen cmp di,gScreenPage0 je gc1 mov si,gScreenPage0 jmp gc2 gc1: mov si,gScreenPage2 gc2: mov cx,16000 mov ax,gScreenSegment mov es,ax mov ds,ax rep movsb mov ah,0 mov al,0 call gSetMode pop si pop ds pop cx pop ax pop bx ret gCopy ENDP ; ******************************** ; setzt VGA-Schreibmodus r=ah,w=al ; ******************************** gSetMode PROC and ah,1h shl ah,1 shl ah,1 shl ah,1 and al,3h add ah,al or ah,40h mov dx,03CEh mov al,5h out dx,ax ret gSetMode ENDP ; ******************************** ; wartet auf Strahlrcklauf ; ******************************** gWaitDisplay PROC push ax mov dx,gCRTC+6 wd_r: in al,dx test al,8d jz wd_r wd_d: in al,dx test al,8d jnz wd_d pop ax ret gWaitDisplay ENDP END