;legal moves table generation steps: ; - copy board to temp table ; - if it's white's turn, flipflop all pieces (checks for legal black moves) ; - find first black piece ; - find first move ; - determine if in check with this move, if so , don't record it ; - record it ; - do over agian till no more legal moves ; copy board to table agian (no flip flop) ; check for pawn movements (different for black and white) ; check for castling (can't when in check!) ; if total tally of legal moves is 0, then checkmate! (or stalemate) getlegalmoves3: ;no want to copyboard! hl = movetablepos push hl ld b, 0 jr z, skipcopyboardglm getlegalmoves: ld hl, freespace getlegalmoves2: push hl call copyboard2 skipcopyboardglm: ld h, b ; start at 0,0 ld l, b ld (curglmx), hl pop hl ld (movetablepos), hl ld b, 64 ;start major loop (64 squares on chess board) ld hl, tempboard gmoveloop2: push bc push hl call findking pop hl push hl ld a, (hl) or a jr z, noaddqueen cp 2 call z, addbishop cp 3 call z, addknight cp 4 call z, addrook cp 5 call z, addking cp 1 call z, addpawn cp 6 jr nz, noaddqueen call addrook call addbishop noaddqueen: ld a, (curglmx) inc a cp 8 call z, addy ld (curglmx), a pop hl inc hl pop bc djnz gmoveloop2 call add255 ret addpawn: ld a, (curglmx) ld (nxtglmx), a ld de, 8 ;load pointer increment ld c, 1 ;load (x, y) increment ld b, 1 ;load y-pos for two space jump ld a, (curturn) or a call z, whitepawncheck ld a, (curglmy) add a, c ld (nxtglmy), a blackpawncheck: ld a, (hl) add hl, de push hl ld a, (hl) or a jr nz, nogoup1 ;check for stuff in the way push de call addtomovesandcheck pop de add hl, de ld a, (hl) or a jr nz, nogoup1 ;check for go up 2 ld a, (curglmy) cp b jr nz, nogoup1 ld a, (nxtglmy) add a, c ld (nxtglmy), a call addtomovesandcheck ld a, (curglmy) add a, c ld (nxtglmy), a nogoup1: pop hl dec hl ld a, (hl) cp 7 jr c, nocaptureleft ld a, (curglmx) dec a ld (nxtglmx), a call addtomovesandcheck nocaptureleft: inc hl inc hl ld a, (hl) cp 7 jr c, nobp ld a, (curglmx) inc a ld (nxtglmx), a call addtomovesandcheck nobp: xor a ret whitepawncheck: ld de, -8 ld c, 255 ld b, 6 ret add255: ld a, 255 ld hl, (movetablepos) ld (hl), a ret addy: ld hl, curglmy inc (hl) xor a ret addking: ld hl, kingmoves jr samestuff2 addknight: ld hl, knightmoves samestuff2: ld b, 8 aknghtloop: call getnextcoords call checklegal or a jr z, notlegal call getnextboardpos ld a, (de) or a jr z, islegal cp 7 jr c, notlegal islegal: call addtomovesandcheck notlegal: djnz aknghtloop xor a ret addrook: ld hl, rookmoves ld b, 28 jr abshploop addbishop: ld hl, bishopmoves-2 ld b, 29 ;change this stuff to what it SHOULD be and weird abshploop: ;stuff happens... (rather confusing...) :( call getnextcoords call checklegal or a jr z, noaddmove call getnextboardpos ld a, (de) or a jr z, skipamove cp 7 jr c, noaddnextsplit call gotonextsplit skipamove call addtomovesandcheck noaddmove: djnz abshploop xor a ret noaddnextsplit call gotonextsplit jr noaddmove gotonextsplit ld a, b cp 29 ret z cp 22 ret z cp 15 ret z cp 8 ret z cp 1 ret z inc hl inc hl dec b jr gotonextsplit checklegal: cp 8 jr nc, legalman ld a, (nxtglmx) cp 8 jr nc, legalman inc a ret legalman xor a ret addtomovesandcheck: push bc push hl call getnextboardpos push de call getcurboardpos pop hl call executemove ld a, (hl) cp 5 call z, findking call checkforcheck2 push af call copyboard2 pop af pop hl pop bc or a ret z addtomoves2: ld a, (nxtglmx) call checklegal or a ret z addtomoves: push hl ld hl, (movetablepos) ld de, (curglmx) ld (hl), e inc hl ld (hl), d inc hl ld de, (nxtglmx) ld (hl), e inc hl ld (hl), d inc hl ld (movetablepos), hl pop hl ret copyboard2: call copyboard ld a, (curturn) or a jp z, flipboard ret copyboard: ld hl, board ld de, tempboard ld bc, 64 ldir ret curglmx: .db 0 curglmy: .db 0 nxtglmx: .db 0 nxtglmy: .db 0 movetablepos: .db 0 .db 100, 100 ;legal move table bishopmoves: ; bishop legal moves: (or queen) .db 255, 255, 254, 254, 253, 253, 252, 252, 251, 251, 250, 250, 249, 249 .db 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 .db 255, 1, 254, 2, 253, 3, 252, 4, 251, 5, 250, 6, 249, 7 .db 1, 255, 2, 254, 3, 253, 4, 252, 5, 251, 6, 250, 7, 249 .db 100, 100 rookmoves: ; rook legal moves: (or queen) .db 255, 0, 254, 0, 253, 0, 252, 0, 251, 0, 250, 0, 249, 0 .db 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0 .db 0, 255, 0, 254, 0, 253, 0, 252, 0, 251, 0, 250, 0, 249 .db 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7 .db 100, 100 knightmoves: ; knight legal moves: .db 1, 2 .db 2, 1 .db 255, 2 .db 254, 1 .db 1, 254 .db 2, 255 .db 255, 254 .db 254, 255 .db 100, 100 kingmoves: .db 255, 255, 255, 0, 255, 1 .db 1, 255, 1, 0, 1, 1 .db 0, 255, 0, 1 getcurboardpos: push hl ld a, (curglmy) rlca rlca rlca ld c, a ld a, (curglmx) jr memsave getnextboardpos: push hl ld a, (nxtglmy) rlca rlca rlca ld c, a ld a, (nxtglmx) memsave: add a, c ld e, a ld d, 0 ld hl, tempboard add hl, de ex de, hl pop hl ret isthismovelegal: ld b, 0 ld hl, freespace push hl pop ix ismovelegalloop: ld a, (tempposx) cp 255 jr z, nomoves ld c, (ix+0) cp c jr nz, notthismove ld a, (tempposy) ld c, (ix+1) cp c jr nz, notthismove ld a, (selposx) ld c, (ix+2) cp c jr nz, notthismove ld a, (selposy) ld c, (ix+3) cp c jr nz, notthismove ld a, 1 ret notthismove: inc ix inc ix inc ix inc ix djnz ismovelegalloop nomoves: push de call copyboard2 ld hl, (tempposx) ld (nxtglmx), hl call getnextboardpos ld a, (de) cp 5 jr nz, notakingcastle call getboardpos push de ld hl, (selposx) ld (nxtglmx), hl call getnextboardpos ld a, (de) pop de cp 4 jr nz, notakingcastle ld a, (selposy) ld b, a ld a, (tempposy) cp b jr nz, notakingcastle call tryqueencastle call trykingcastle notakingcastle: xor a pop de ret tryqueencastle: ld a, (selposx) or a ret nz push de pop ix inc de ld a, (de) or a ret nz inc de ld a, (de) or a ret nz inc de ld a, (de) or a ret nz ld b, 4 ld a, (curturn) or a jr nz, werenotwhiterook2 ld b, 10 werenotwhiterook2: ld a, b ld (de), a push ix pop de xor a ld (de), a pop hl pop de pop bc ;these stack ops were a little tricky! pop hl inc hl inc hl push hl push bc inc a ret trykingcastle ld a, (selposx) cp 7 ret nz push de pop ix dec de ld a, (de) or a ret nz dec de ld a, (de) or a ret nz ld b, 4 ld a, (curturn) or a jr nz, werenotwhiterook ld b, 10 werenotwhiterook: ld a, b ld (de), a push ix pop de xor a ld (de), a pop hl pop de pop bc ;these stack ops were a little tricky! pop hl dec hl push hl push bc inc a ret ;How to check for check: ; -Find the king on the board ; -get all possible rook moves and search them for an opposing queen or rook ; -get all possible bishop moves and search for bishop or queen ; -same with knight moves ; -same with king moves ; -do individual searching (white and black) for pawn attacks checkforcheck call findking jr checkforcheck2 findking: ld hl, 0 ld (kingposx), hl ld hl, tempboard coclp1: ld a, (hl) ;search for king cp 5 jr z, foundking ld a, (kingposx) inc a push hl cp 8 call z, addyking pop hl ld (kingposx), a inc hl jr coclp1 foundking: ld (kingpos), hl ret kingpos: .dw 0 kingposx: .db 0 kingposy: .db 0 addyking: ld hl, kingposx+1 inc (hl) xor a ret checkforcheck2: ld hl, (nxtglmx) push hl ;check for rook moves ld hl, rookmoves-2 ld b, 29 call getcheckmoves ld c, 12 ;check for queen call checkforloop ld c, 10 ;check for rook call checkforloop ld hl, bishopmoves-2 ld b, 29 call getcheckmoves ld c, 12 ;check for queen call checkforloop ld c, 8 ;check for bishop call checkforloop ld hl, knightmoves-2 ld b, 9 call getcheckmoves2 ld c, 9 ;check for knight call checkforloop ld hl, kingmoves-2 ld b, 9 call getcheckmoves2 ld c, 11 ;check for king call checkforloop ld c, 7 ld hl, (kingpos) ld de, 9 ld a, (curturn) or a ;with 'or a', could still have a carry. jr nz, ccwp ;check for pawns ld de, -7 ccwp: add hl, de ld a, (hl) cp 7 jr z, weezaincheck dec hl dec hl ld a, (hl) cp 7 jr z, weezaincheck ld a, 1 pop hl ld (nxtglmx), hl ret weezaincheck: xor a pop hl ld (nxtglmx), hl ret checkforloop: pop ix ld hl, freespace+600 cfl ld a, (hl) cp 255 jr z, nomoreloop ld e, (hl) inc hl ld d, (hl) inc hl ld a, (de) cp c jr z, weezaincheck jr cfl nomoreloop push ix ret getcheckmoves2: ld e, 0 jr skipassigne getcheckmoves: ld e, 1 skipassigne: ld ix, freespace+600 gcmloop: ld c, (hl) ld a, (kingposx) add a, c ld (nxtglmx), a inc hl ld c, (hl) ld a, (kingposy) add a, c ld (nxtglmy), a inc hl call checklegal or a jr z, noaddmove2 push de push hl call getnextboardpos ld a, (de) pop hl pop de or a jr z, noaddmove2 ;we don't need to check the empty tiles anytime (BIG time saver) cp 7 jr c, noaddnextsplit2 ld a, e or a jr z, skipamove2 call gotonextsplit skipamove2 push de ld a, (nxtglmx) ld c, a ld a, (nxtglmy) rlca rlca rlca add a, c push hl ld hl, tempboard ld e, a ld d, 0 add hl, de ex de, hl pop hl ld (ix+0), e ld (ix+1), d inc ix inc ix pop de noaddmove2 djnz gcmloop dec b ld (ix+0), b ;add 255 to all moves to indicate end ret noaddnextsplit2 ld a, e or a jr z, noaddmove2 call gotonextsplit jr noaddmove2 flipboard: ld hl, tempboard ld b, 64 gmoveloop1: ld a, (hl) or a ;if no piece, no modifications needed jr z, nextloop add a, 6 ;make all black pieces white cp 13 ; if less than 13, then we were right jr c, nextloop sub 12 ;if not, then subtract 6 to undo the damage ;and then 6 more to make white pieces black nextloop: ld (hl), a ;assign 'new' value to board and increase board pos. inc hl djnz gmoveloop1 ret getnextcoords: ld c, (hl) ld a, (curglmx) add a, c ld (nxtglmx), a inc hl ld c, (hl) ld a, (curglmy) add a, c ld (nxtglmy), a inc hl ret .end