Nytro Posted February 3, 2015 Report Posted February 3, 2015 Toledo Atomchess GameBy January 28, 2015 came to my knowledge a new chess program written in 487 bytes of x86 assembly code. I don't ever ran it and moved to another things as I was kind of busy.Nevertheless my friends from JS1K and Twitter encouraged me to do something, and I've some notions of x86 machine code.So I started coding my own chess program in x86 assembler, I finished it in 24 hours and went for another 24 hours debugging it.After this I gave a look to the documentation of the other chess program and I was surprised it made illegal movements and doesn't even has a search tree, for me that is like not playing any chess.So here it is, my game is Toledo Atomchess and it is 481 bytes of x86 assembly code and it plays very reasonably under the limitations.Plays basic chess movements (no en passant, no castling and no promotion)Enter your movements as basic algebraic (D2D4)Your movements aren't checked for legalitySearch depth of 3-plyHow to run itTo run it you need a 1.44 MB floppy disk and put the 512 byte into the boot sector using an utility like Rawrite, also available as a COM file runable in MS-DOS or Wind*ws command-line.Download Toledo Atomchess package (5.8K)The source codeHere is the full source code[FONT=Verdana] ;[/FONT] ; Toledo Atomchess ; ; by Óscar Toledo Gutiérrez ; ; © Copyright 2015 Óscar Toledo Gutiérrez ; ; Creation: 28-ene-2015 21:00 local time. ; Revision: 29-ene-2015 18:17 local time. Finished. ; Revision: 30-ene-2015 13:34 local time. Debugging finished. ; Features: ; * Basic chess movements. ; * Enter moves as algebraic form (D2D4) (note your moves aren't validated) ; * Search depth of 3-ply ; * No promotion of pawns. ; * No castling ; * No en passant. ; * 481 bytes size (fits in a boot sector) ; Note: I'm lazy enough to write my own assembler instead of ; searching for one, so you will have to excuse my syntax code16 ; Change to org &0100 for COM file org &7c00 ; Housekeeping mov sp,stack cld push cs push cs push cs pop ds pop es pop ss ; Create board mov bx,boardsr1: mov al,bl and al,&88 ; 0x88 board jz sr2 mov al,&07 ; Frontiersr2: mov [bx],al inc bl jnz sr1 ; Setup board mov si,initialsr3: lodsb ; Load piece mov [bx],al ; Black pieces or al,8 mov [bx+&70],al ; White pieces mov al,&01 mov [bx+&10],al ; Black pawn mov al,&09 mov [bx+&60],al ; White pawn inc bx cmp bl,&08 jnz sr3 ; ; Main loop ;sr21: call display_board call key2 push di call key2 pop si movsb mov byte [si-1],0 call display_board mov ch,&08 ; Current turn (0=White, 8=Black) call play jmp short sr21 ; ; Computer plays ;play: mov bp,-32768 ; Current score push bp ; Origin square push bp ; Target square xor ch,8 ; Change side mov si,boardsr7: lodsb ; Read square xor al,ch ; XOR with current playing side dec ax cmp al,6 ; Ignore if frontier jnc sr6 or al,al ; Is it pawn? jnz sr8 or ch,ch ; Is it playing black? jnz sr25 ; No, jumpsr8: inc axsr25: dec si mov bx,offsets push ax xlat mov dh,al ; Movements offset pop ax mov bl,total&255 xlat mov dl,al ; Total movements of piecesr12: mov di,si ; Restart target square mov bl,displacement&255 mov al,dh xlat mov cl,alsr9: add di,cx and di,&ff or di,board mov al,[si] ; Content of: origin in al, target in ah mov ah,[di] or ah,ah ; Empty square? jz sr10 xor ah,ch sub ah,&09 ; Valid capture? cmp ah,&06 mov ah,[di] jnc sr18 ; No, avoid cmp dh,14 ; Pawn? jc sr19 test cl,1 ; Straight? je sr18 ; Yes, avoid jmp short sr19sr10: cmp dh,14 ; Pawn? jc sr19 test cl,1 ; Diagonal? jne sr18 ; Yes, avoidsr19: push ax ; Save for restoring in near future mov bl,scores&255 mov al,ah and al,7 cmp al,6 ; King eaten? jne sr20 cmp sp,stack-(3+8+3)*2 ; If in first response... mov bp,20000 ; ...maximum score (probably checkmate/slatemate) jne sr26 mov bp,7811 ; Maximum scoresr26: add sp,6 ; Ignore values jmp short sr24sr20: xlat cbw; cmp sp,stack-(3+8+3+8+3+8+3+8+3)*2 ; 4-ply depth cmp sp,stack-(3+8+3+8+3+8+3)*2 ; 3-ply depth; cmp sp,stack-(3+8+3+8+3)*2 ; 2-ply depth; cmp sp,stack-(3+8+3)*2 ; 1-ply depth jbe sr22 pusha movsb ; Do move mov byte [si-1],ah ; Clear origin square call play mov bx,sp sub [bx+14],bp ; Substract BP from AX popasr22: cmp bp,ax ; Better score? jg sr23 ; No, jump mov bp,ax ; New best score jne sr27 in al,(&40) cmp al,&55 ; Randomize it jb sr23sr27: pop ax add sp,4 push si ; Save movement push di push axsr23: pop ax ; Restore board mov [si],al mov [di],ahsr18: dec ax and al,&07 ; Was it pawn? jz sr11 ; Yes, check special cmp al,&04 ; Knight or king? jnc sr14 ; End sequence, choose next movement or ah,ah ; To empty square? jz sr9 ; Yes, follow line of squaressr16: jmp short sr14sr11: and cl,&1f ; Advanced it first square? cmp cl,&10 jnz sr14sr15: or ah,ah ; Pawn to empty square? jnz sr17 ; No, cancel double-square movement mov ax,si cmp al,&20 ; At first top row? jb sr14 ; Yes, jump cmp al,&60 ; At first bottom row? jb sr17 ; No, cancel double-square movementsr14: inc dh dec dl jnz sr12sr17: inc sisr6: cmp si,board+120 jne sr7 pop di pop si cmp sp,stack-2 jne sr24 cmp bp,-16384 ; Illegal move? (always in check) jl sr24 ; Yes, doesn't move movsb mov byte [si-1],0sr24: xor ch,8 retdisplay_board: ; Display board call display3 mov si,boardsr4: lodsb mov bx,chars xlat call display2sr5: cmp si,board+128 jnz sr4 retkey2: mov di,board+127 call key add di,ax call key shl al,4 sub di,ax retkey: push di mov ah,0 int &16 push ax call display pop ax and ax,&0f pop di retdisplay2: cmp al,&0d jnz displaydisplay3: add si,7 mov al,&0a call display mov al,&0ddisplay: push si mov ah,&0e mov bh,&00 int &10 pop si retinitial: db 2,5,3,4,6,3,5,2scores: db 0,10,50,30,90,30chars: db ".prbqnk",&0d,".PRBQNK"offsets: db 14,18,8,12,8,0,8total: db 4, 4,4, 4,8,8,8displacement: db -33,-31,-18,-14,14,18,31,33 db -16,16,-1,1 db 15,17,-15,-17 db -16,-32 db 15,17,16,32 ; 29 bytes to say something db "Toledo Atomchess" db "nanochess.org" ; ; This marker is required for BIOS to boot floppy disk ; ds &7dfe-* ; Change to &02fe for COM file db &55,&aaboard: ds 256 ds 256stack:[FONT=arial][FONT=Verdana] end[/FONT][/FONT]Sursa: Toledo Atomchess Game Quote