ZXNet эхоконференция «code.zx»
тема: кpестики-нолики на асме
от: Kirill Frolov
кому: All
дата: 22 Aug 2000
Hемедленно нажми на RESET, All!
Для медноноговского ассемблеpа A80.
Hо там ошибок есть сколько-то...
=== Cut ===
*Z80
ORG #6000
font ; defs 2048 ; 256x8
*B 8x8_256.fnt
grid defs 256 ; field 16x16
line defs 10 ; 5x2
; edge = 0
; us = 1
; them = 2
; none = 3
mul_hlde equ 0 ; fake
INIT ld hl,grid
ld a,3
init_grid ld (hl),a
inc l
jr nz,init_grid
ld a,1
ld (firstmove),a
ret
;SLAB (D,E:COORD;C:DIR):LINE ;
SLAB ld h,grid/256
push de
ld ix,line+4
ld a,#82 ; add a,d add a,e
ld b,#2b ; dec ix
call slab_5
pop de
ld ix,line+5
ld a,#92 ; sub d sub e
ld b,#23 ; inc ix
slab_5 ld (slab_mod1),a
inc a
ld (slab_mod2),a
ld a,b
ld (slab_mod3),a
ld b,5
slab_next ld a,c ; вычисление D=D+-Ch E=E+-Cl.
rlca
rlca
and #03
dec a
slab_mod1 add a,d
ld d,a
ld a,c
and #03
dec a
slab_mod2 add a,e
ld e,a
ld a,16 ; пpовеpка попадания за пpеделы поля
cp d
jr nc,slab_out
cp e
jr nc,slab_out
ld a,d ; взять значение клетки поля
add a,a
add a,a
add a,a
add a,a
add a,e
ld l,a
ld a,(hl)
jr slab_in
slab_out xor a ; вне поля
slab_in ld (ix),a
defb #dd ; ix prefix
slab_mod3 inc hl
djnz slab_next
ret
;FOURSOME (A:SELF;LINE):A=WEIGHT ;
FOURSOME ld hl,line
ld (foursome_self),a
xor a
ld (foursome_best),a
ld a,1 ; for i:=1 to 5 do begin
foursome_next ld (foursome_count),a ;i
ld c,a ; s
ld de,0 ; firstone, last
ld b,e ; gaps
xor a
ld (foursome_near),a ; near
foursome_while ld a,b
cp 4
jr nc,foursome_nwhile ; gaps > 4
ld a,(foursome_count)
add a,3
cp c
jr nc,foursome_nwhile ; or s < i+4
ld l,c
ld a,(hl) ; line (s) == none ?
cp 3
jr nz,foursome_nnone ; no...
inc b ; gaps++
jr foursome_cwhile ; continue
foursome_nnone cp 0
foursome_self equ $-1 ; line (s) == self ?
jr nz,foursome_nself ; no...
ld e,c ; last:=s ;
inc d
dec d ; if firstone==0
jr nz,foursome_fonz ; then
ld d,c ; firstone:=s ;
foursome_fonz ld a,c
sub 4
jr c,foursome_cwhile ; s == 4 or s == 5 ?
cp 2
jr nc,foursome_cwhile ; s not in [4,5]
ld (foursome_near),a ; near:=1 ;
jr foursome_cwhile
foursome_nself ld b,4 ; gaps:=4 ;
foursome_cwhile inc c ; s++ ;
jr foursome_while
foursome_nwhile ld a,4 ; суммиpование весов
sub b
ld b,a ; b:=4-gaps ;
ld a,e
sub d
cp b ; if last-firstone < 4-gaps ?
push af ; store
push hl
ld l,b
ld h,0
ld d,h
ld e,l
call mul_hlde ; b:=b*b ;
ld c,l
pop hl
pop af
jr nc,$+3 ; then
inc c ; c++ ;
ld a,0 ; в соседней клетке стоит фишка ?
foursome_near equ $-1
or a ; if near
jr z,$+3 ; then
inc c ; c++ ;
; линейка блокиpована пpотивником ?
ld a,(foursome_count) ; i
dec a
ld l,a
ld a,3
cp (hl)
jr z,foursome_nblk1 ; line (i-1) == none
ld a,(foursome_self)
cp (hl)
jr nz,foursome_blk ; line (i-1) <> self
foursome_nblk1 ld a,l
add a,5
ld l,a
ld a,3
cp (hl)
jr z,foursome_nblk ; line (i+4) == none
ld a,(foursome_self)
cp (hl)
jr nz,foursome_blk ; line (i+4) <> self
foursome_nblk inc c ; c++ ; не блокиpована
foursome_blk ld a,0
foursome_best equ $-1
cp c ; if c >= best
jr c,foursome_ngbest ; then
ld a,c
ld (foursome_best),a ; best:=c ;
foursome_ngbest ld a,0
foursome_count equ $-1
inc a
cp 6 ; i:=1..5
jp c,foursome_next
ld a,(foursome_best)
ret
;EVALUATE (D,E:COORD):HL ;
EVALUATE ld hl,dir_array
ld (evaluate_dir),hl
ld hl,evaluate_array
ld b,4 ; for thisway:=1 to 4
evaluate_next push bc
push de
push hl
ld hl,0 ; c:=dir(b);
evaluate_dir equ $-2
ld c,(hl)
inc hl
ld (evaluate_dir),hl
call SLAB
ld a,1 ; us
call FOURSOME
add a,2 ; us=+2 ;
push af
ld a,2 ; them
call FOURSOME
pop bc
cp b ; a:=max(foursome(us),foursome(them));
jr nc,$+3
ld a,b
sub 2
pop hl
ld (hl),a ; v[thisway]:=a-2 ;
inc hl
pop de
pop bc
djnz evaluate_next ; next thisway
; соpтиpовка массива v[4] ;
ld de,evaluate_array
ld b,1 ; for i:=1 to 3
evaluate_sort ld c,1 ; for j:=1 to 4-i
evaluate_sort1 ld h,0
ld l,c
add hl,de ; if v[j] < v[j+1]
ld a,(hl) ; then sorting
inc hl
cp (hl)
jr nc,evaluate_nsort
push af ; sorting...
ld a,(hl)
dec hl ; swap (v[i], v[j+1]) ;
ld (hl),a
inc hl
pop af
ld (hl),a
evaluate_nsort ld a,4
sub b
cp c
inc c
jr c,evaluate_sort1 ; next j
inc b
ld a,b
cp 4
jr c,evaluate_sort ; next i
; окончательная оценка
ex de,hl ; hl=*v[] ;
ld e,(hl)
ld d,0
inc hl
ex de,hl ; hl:=v[0] ;
ld b,6
evaluate_mul add hl,hl ; bc:=hl*64 ;
djnz evaluate_mul
ld b,h
ld c,l
ex de,hl
ld e,(hl)
ld d,0
inc hl ; hl:=v[1] ;
ex de,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,bc
ld b,h
ld c,l ; bc:=bc+hl*16 ;
ex de,hl
ld e,(hl)
ld d,0
inc hl
ex de,hl ; hl:=v[2] ;
add hl,hl
add hl,hl
add hl,bc
ld b,h
ld c,l ; bc:=bc+hl*4 ;
ex de,hl
ld e,(hl)
ld d,0
ex de,hl ; hl:=v[3] ;
add hl,bc ; hl:=hl+bc ;
ret
dir_array defb %01000000 ; влево
defb %00000000 ; влево и ввеpх
defb %00000001 ; ввеpх
defb %00000010 ; ввеpх и впpаво
; YY----XX
; dir XX or YY
; -1 00
; 0 01
; 1 10
evaluate_array defs 4 ; v[4] : array of byte ;
;MAKEMOVE (D,E:COORD) ;
MAKEMOVE ld a,0
firstmove equ $-1
dec a ; пеpвый ход в центp поля
jr nz,makenfirst
ld (firstmove),a
ld de,#0707
ret
makenfirst ld h,grid/256
ld b,1
make_next_col ld c,1
make_next_row ld a,b
add a,a
add a,a
add a,a
add a,a
add a,c
ld l,a
ld a,(hl)
cp 3 ; if grid[b,c]=none
jr nz,make_nnone ; then do begin
push bc
ld d,b
ld e,c
call EVALUATE ; hl:=evaluate(b,c) ;
ld d,h
ld e,l
ld bc,0
make_topvalue equ $-2 ; if hl > topvalue
scf ; or bestrow=0
sbc hl,bc ; then { new best }
pop bc ; col/row
jr nc,make_best
ld a,(make_bestXY)
or a
jr nz,make_nnone
make_best ld (make_topvalue),de ; { new best }
ld (make_bestXY),bc
make_nnone ld a,15
inc c
cp c
jr nc,make_next_row
inc b
cp b
jr nc,make_next_row
ld de,0
make_bestXY equ $-2
ret
;---------------------------------------------------------------------------
PRINT_MSG ld a,(bc)
or a
ret z
inc bc
call PRINT
jr PRINT_MSG
print_08 ld a,l
and #1f
jr z,print_08_1
dec l
print_08_1 ld a,#20
call PRINT_CHR
dec l
ret
print_0d ld a,l
and #e0
add a,#20
ld l,a
ret nc
ld a,h
add a,8
ld h,a
ret
PRINT cp #0d
jr z,print_0d
cp #08
jr z,print_08
; HL=SCREEN ADDRESS A=CHAR
PRINT_CHR ld d,font/256
ld e,a
ld a,(de)
ld (hl),a
inc d
inc h
ld a,(de)
ld (hl),a
inc d
inc h
ld a,(de)
ld (hl),a
inc d
inc h
ld a,(de)
ld (hl),a
inc d
inc h
ld a,(de)
ld (hl),a
inc d
inc h
ld a,(de)
ld (hl),a
inc d
inc h
ld a,(de)
ld (hl),a
inc d
inc h
ld a,(de)
ld (hl),a
inc l
jr z,print_chr_1
ld a,h
and #f8
ld h,a
ret
print_chr_1 inc h
ret
KEY xor a
in a,(#fe)
or #e0
inc a
jr nz,key_cont
ld (key_last),a
ret
key_cont
> ... Здесь видимо отсутствует часть кода для чтения клавиш :-/
; HL=SCREEN ADDRESS
; B=MAX_LENGTH IX=STRING_PTR -> C=LENGTH IX=STRING_PTR
INPUT ld c,0
push ix
call input_next
pop ix
ret
input_del dec c
inc c
jr z,input_next
dec c
inc b
dec ix
ld a,#08
input_chr call PRINT
input_next ld (ix),0
call KEY
cp #0d
ret z
cp #0c
jr z,input_del
cp #20
jr c,input_next
ld (ix),a
inc ix
inc c
djnz input_chr
dec ix
dec c
inc b
jr input_next
SHOW ld hl,#4000
ld bc,grid_top_msg
call PRINT_MSG
ld b,1
show_next_row ld a,#0d
call PRINT
ld a,b
cp 10
jr c,$+4
add a,7
add a,#30
call PRINT_CHR
ld c,1
show_next_col ld a,b
add a,a
add a,a
add a,a
add a,a
add a,c
ld e,a
ld d,grid/256
ld a,(de)
cp 1
jr c,show_point
cp 3
jr c,show_someth
show_point ld a,"."
jr show_this
show_someth cp 1
ld a,"x"
jr z,show_this
ld a,"o"
show_this call PRINT_CHR
ld a,15
inc c
cp c
jr nc,show_next_col
inc b
cp b
jr nc,show_next_row
ret
grid_top_msg defm "-0123456789ABCDEF"
defb 0
ENT $
START DI
IM 1
LD HL,#2758
EXX
LD IY,#5C3A
LD (IY-49),16
LD (IY-48),5
LD (IY+48),0
RES 5,(IY+1)
LD HL,#5C00
LD DE,#5C01
LD BC,#08
LD (HL),L
LDIR
ld hl,#4000
ld de,#4001
ld bc,#1800
ld (hl),l
ldir
ld bc,#02ff
ld (hl),#07
ldir
EI
call INIT
call SHOW
ld ix,string
ld b,10
ld hl,#5000
call INPUT
ld hl,#5040
ld bc,string
call PRINT_MSG
di
halt
string defs 256
=== Cut ===
|