Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
251 lines (210 sloc) 10.8 KB
; LeanChess
; Copyright (c) 2019 Dmitry Shechtman
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
.model tiny
code segment
org 100h
assume cs: code
int 10h ;BIOS display mode 0
mov si, offset init_db ;Set row metadata address
mov di, offset board_db ;Set board address
push cx ;Save row counter
mov ax, 0808h ;Border
stosw ;Write two bytes
stosw ;Write two bytes
mov cl, 8 ;Set square counter
lodsb ;Read one byte
test al, 80h ;First rank?
jz init_cont ;No, proceed to write row
dec si ;Back one byte
rep movsb ;Copy row
rep stosb ;Write row
pop cx ;Restore row counter
loop init_loop ;Move to next row
mov cl, 106 ;(Ranks + 1) * width + margin width
mov si, offset board_db + 21 ;Grab two preceding tabs
mov di, offset buffer_db ;Set buffer address
mov dx, di ;Clone buffer address
lodsb ;Read square contents
test al, 38h ;Piece or border?
jz disp_cont ;No, proceed to write square
inc ax ;Zero-align king
cmp al, 09h ;Border?
jz disp_cont ;Yes, proceed to write square
and al, 27h ;Isolate piece type and black/lowercase
add al, 4Bh ;King, (none), (reserved), kNight, bishOp, Pawn, Queen, Rook
stosb ;Write square
loop disp_loop ;Move to next square
mov ax, 0924h ;String terminator/Write string
stosb ;Write string terminator
int 21h ;DOS I/O function
mov dx, 1828h ;Set player's and opponent's colors
mov cl, 3 ;Set search depth
push offset main_loop ;Repeat forever
mov ax, offset move_sub ;Perform two moves:
push ax ;Perform computer's move
push ax ;Perform human's move
push offset read_sub ;Read destination square
;Read square from input
; DI - Square address
mov bp, di ;Clone address
mov di, offset board_db + 123 - 160h ;Bottom right corner + margin - ASCII offset
mov ah, 01h ;Read character
int 21h ;DOS I/O function
add di, ax ;Add result to base address
int 21h ;DOS I/O function
and al, 0Fh ;Isolate number (expected 1-8)
mov ah, 12 ;
mul ah ;Multiply by 12
sub di, ax ;Subtract result from base address
;Perform move and find best next move
; DL - Player's color + border
; DH - Opponent's color + border
; CX - Search depth
; BP - Source square address
; DI - Destination square address
; AL - Player's max value
; AH - Opponent's max value
; DL - Opponent's color + border
; DH - Player's color + border
; SI - Opponent's best source square address
; DI - Opponent's best destination square address
xor ax, ax ;Clear contents + opponent's max value
xchg al, [bp] ;Read and write source square
xchg al, [di] ;Read and write destination square
xchg dl, dh ;Swap player's and opponent's colors
and al, 07h ;Isolate piece type
mov bx, offset eval_db ;Set base values' address
xlat ;Get player's gain
jcxz sub_ret ;If depth is zero, return
pusha ;Save all GP registers
mov bp, offset board_db + 28 ;Start from top left corner
mov cl, 78 ;Ranks * width - margin width
mov al, [bp] ;Read source square
test al, dl ;Opponent's piece or border?
jnz src_cont ;Yes, proceed to next source square
and ax, 07h ;Isolate piece type
jz src_cont ;No piece, proceed to next source square
mov bl, al ;Save piece type
mov si, offset moves_knight - 2 ;Set base metadata address
add si, ax ;Calculate absolute metadata address
lodsb ;Read relative vectors address
add si, ax ;Calculate absolute vectors address
lodsb ;Read vector
mov di, bp ;Clone source square address
cbw ;Extend vector's sign
add di, ax ;Calculate destination square address
mov ah, [di] ;Read destination square
mov bh, ah ;Clone destination square contents
test ah, dh ;Player's piece or border?
jnz vec_cont ;Yes, proceed to next vector
cmp bl, 04h ;Black or white pawn?
jne eval ;No, proceed to evaluate move
test al, 01h ;Any file change?
jnz pawn_cont ;Yes, proceed to check destination square
xor ah, 30h ;Invert destination's color
test ah, dl ;Opponent's piece (or border)?
jz vec_cont ;No, proceed to next vector
push ax ;Save vector
and al, 80h ;Isolate sign bit
shr al, 2 ;Align with black bit
xor al, dh ;Flip color and border bits
pop ax ;Restore vector
jnp vec_cont ;Odd, proceed to next vector
pusha ;Save all GP registers
push bp ;Save source square address
push di ;Save destination square address
mov si, sp ;Clone stack pointer
mov cx, [si + 32] ;Read current depth
dec cx ;Decrement depth
call move_sub ;Recursively call self
mov ah, [si + 35] ;Read player's max value
cmp al, ah ;Max value exceeds current value?
pop di ;Restore destination square address
pop bp ;Restore source square address
jl undo ;Yes, proceed to undo move
mov [si + 35], al ;Write max value
mov [si + 20], di ;Write destination square address
mov [si + 24], bp ;Write source square address
popa ;Restore all GP registers
xchg bh, [di] ;Read and write original destination square
mov [bp], bh ;Write original source square
test [di], dl ;Opponent's piece (or border)?
jnz vec_cont ;Yes, proceed to next vector
test bl, bl ;Check piece type
jp dest_loop ;Slider, move to next destination
neg al ;Invert vector
js sign_loop ;Negative, proceed to reset destination address
jnz vec_loop ;Non-zero, move to next vector
inc bp ;Increment source square address
loop src_loop ;Move to next source
popa ;Restore all GP registers
sub al, ah ;Calculate player's max value
moves_knight db vec_knight - moves_knight - 1
moves_bishop db vec_bishop - moves_bishop - 1
moves_pawn db vec_pawn - moves_pawn - 1
moves_queen db vec_king - moves_queen - 1
moves_rook db vec_rook - moves_rook - 1
moves_king db vec_king - moves_king - 1
vec_knight db 10, 14, 23, 25, 0
vec_pawn db 12
vec_bishop db 11, 13, 0
vec_king db 11, 13
vec_rook db 12, 1
eval_db: ;Fall through 1 byte
db 0, 0, 3, 3, 1, 9, 5, 46
db 08h, 08h, 0A6h, 0A2h, 0A3h, 0A5h, 0A7h, 0A3h, 0A2h, 0A6h
db 24h, 00h, 00h, 00h, 00h, 14h
db 96h, 92h, 93h, 95h, 97h, 93h, 92h, 96h
board_db: ;Fall through 3 bytes
db 156 dup(?)
code ends
end start
You can’t perform that action at this time.