替换数组中的值并递增

问题描述 投票:0回答:1

我正在制作贪吃蛇游戏,遇到了两个问题。

  1. 我不明白如何进行更换。 当你移动时,在DS中你有星星的坐标,每颗星星都会移动一个 点在右边。 (第一个数字是第一个星星的坐标)在DS中说有:
    dw 452, 743, 534
    当我运行替换过程时,它看起来像:
    "new number", 452, 743
    我尝试了以下方法(它不起作用。无论我向哪个方向移动,星星都不会删除自己):
proc replace_stars
    mov cx, [st_am]   ;the amount of stars, how many loops
    mov bx, [st_am]
    dec bx
    shl bx, 1
    
replace:
    mov di, [stars+bx-2]    ;the one before last stars
    mov bx, [stars+bx]      ;the last stars
    mov [bx], di            ;in the last one, now the one before it
    sub di, 2
    sub bx, 2
    loop replace     ;loop the amount of stars
  ret
endp replace_stars

2)我不知道该怎么做,当我向任何方向移动并吃掉一个苹果时,另一颗星星及其坐标将添加到数组中。 (第一个数字是第一个星星的坐标)当我移动时(假设是对的),假设我在DS中:

dw 2342, 4532, 4653
移动后,它看起来像:(向右移动,所以-2)
2340, 2342, 4532, 4653

我的整个代码是:

MODEL small
STACK 100h
DATASEG
; --------------------------
; Your variables here
; --------------------------
saveal db ' '  ;used in line 223-233
dir db 0

app dw 0       ;place of the apple
st_am dw 3
stars dw 0, 0, 0  ;places of the *

CODESEG
proc black
body:
    mov [es:si], ax
    add si, 2
    cmp si, 25*80*2
    jnz body
  ret
endp black

proc up
    mov di, 80*2
    cmp si, di
    jb not_move_up
    
    cmp si, [app]
    jnz move_up
    call apple
    
move_up:
    call delete
    call replace_stars
    ;mov di, [stars+2]    failed attempt
    ;mov [stars+4], di
    ;mov di, [stars]
    ;mov [stars+2], di
    ;sub di, 80*2
    ;mov ah, 156
    ;mov al, '*'
    mov [es:di], ax

    sub si, 80*2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
    
not_move_up:
  ret
endp up

proc down

    mov di, (24*80*2)-1
    cmp si, di
    jg not_move_down
    
    cmp si, [app]
    jnz move_down
    call apple
    
move_down:
    call delete
    call replace_stars
    ;mov di, [stars+2]     failed attempt
    ;mov [stars+4], di
    ;mov di, [stars]
    ;mov [stars+2], di
    ;add di, 80*2
    ;mov ah, 156
    ;mov al, '*'
    mov [es:di], ax
    
    add si, 80*2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
    
not_move_down:
  ret
endp down
proc left

    mov dx, 0
    mov bx, si
    mov ax, si
    mov si, 80*2
    div si
    mov si, bx
    cmp dx,0
    jz not_move_left
    
    cmp si, [app]
    jnz move_left
    call apple
    
move_left:
    call delete
    call replace_stars
    
    ;mov di, [stars+2]    failed attempt
    ;mov [stars+4], di
    ;mov di, [stars]
    ;mov [stars+2], di
    ;mov ah, 156
    ;mov al, '*'
    ;mov [es:di], ax
    mov [stars], si
    
    sub si, 2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
    
not_move_left:
  ret
endp left
proc right

    mov dx, 0
    mov bx, si
    mov ax, si
    mov si, 80*2
    div si
    mov si, bx
    cmp dx,158
    jz not_move_right
    
    cmp si, [app]
    jnz move_right
    call apple
    
move_right:
    call delete
    call replace_stars
    
    ;mov di, [stars+2]    failed attempt
    ;mov [stars+4], di
    ;mov di, [stars]
    ;mov [stars+2], di
    ;mov ah, 156
    ;mov al, '*'
    ;mov [es:di], ax
    mov [stars], si
    
    add si, 2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
    
not_move_right:
  ret
endp right

proc apple
    mov ax, 40h
    mov es, ax
    mov ax, [es:6ch]
    and ax, 0000001111111110b
    mov di,ax
    mov [app], di
    mov ax, 0b800h
    mov es, ax
    
    mov al, '@'
    mov ah, 154
    mov [es:di], ax
  ret 
endp apple
    
proc delete
    mov bx, offset stars
    mov di, [st_am]
    dec di
    shl di, 1
    mov di, [bx+di]
    mov ax, 0b800h
    mov es, ax
    
    mov al, ' '
    mov ah, 0
    
    mov [es:di], ax
    
    ;mov di, [stars+2]
    ;mov [stars+4], di
    ;mov di, [stars]
    ;mov [stars+2], di
    
    mov [stars], si
  ret
endp delete

proc replace_stars
    mov cx, [st_am]   ;the amount of stars, how many loops
    mov bx, [st_am]
    dec bx
    shl bx, 1
    
replace:
    mov di, [stars+bx-2]    ;the one before last stars
    mov bx, [stars+bx]      ;the last stars
    mov [bx], di            ;in the last one, now the one before it
    sub di, 2
    sub bx, 2
    loop replace     ;loop the amount of stars
  ret
endp replace_stars

proc first_3_dots
    mov bx, offset stars
    mov si, ((12*80+40)*2)-2
    mov al, '*'
    mov ah, 156
    mov [es:si], ax
    mov [bx], si
    mov si, (12*80+40)*2
    mov al, '*'
    mov ah, 156
    mov [es:si], ax
    mov [bx+2], si
    mov si, ((12*80+40)*2)+2
    mov al, '*'
    mov ah, 156
    mov [es:si], ax
    mov [bx+4], si
  ret
endp first_3_dots

proc delay
    mov cx, 0FFFFh
delay1:
    mov ax, 300
delay2:
    dec ax
    jnz delay2
    loop delay1
  ret
endp delay


proc move_stars_right
    mov cx, [st_am]
    
    mov di, offset stars
    mov bx, di
    
move_loop:
    mov ax, [di]
    
    add ax, 2
    mov [bx], ax
    
    mov ah, 156
    mov al, '*'
    mov [es:di], ax
    
    add di, 2
    add bx, 2
    
    loop move_loop
    
  ret
endp move_stars_right
start:
    mov ax, @data
    mov ds, ax
; --------------------------
; Your code here
; --------------------------
    mov ax, 0b800h
    mov es, ax
    
    mov si,0
    mov al, ' '
    mov ah, 0
    call black
    
    call first_3_dots
    mov si, ((12*80+40)*2)-2    

    call apple
    
wasd:
    mov ah, 1h
    int 21h
    mov [byte ptr saveal], al
    
    cmp [byte ptr saveal], 'w'
    jz w
    cmp [byte ptr saveal], 'a'
    jz a
    cmp [byte ptr saveal], 's'
    jz s
    cmp [byte ptr saveal], 'd'
    jz d
    cmp [byte ptr saveal], 'q'
    jmp exit
    
w:
    call up
    jmp wasd
s:
    call down
    jmp wasd    
a:
    call left
    jmp wasd
d:
    call right
    jmp wasd
    
exit:
    mov ax, 4c00h
    int 21h
END start
assembly x86-16 tasm dosbox
1个回答
0
投票
dw 452, 743, 534
dw 2342, 4532, 4653

我发现看到这些你认为可能出现在 stars 数组中的示例令人担忧。存储在 stars 数组中的值表示 80x25 文本屏幕的视频内存中线性地址 000B8000h 处的偏移地址。那有什么问题吗?

  • 最高地址为3998
  • 所有地址都应该是偶数
  • 两个相邻数字之间的绝对差必须是 2 或 160

(第一个数字是第一个星星的坐标)

不是真的!数组中的第一个数字是第一个星星的屏幕上的偏移地址。坐标可以是列和行,或者 X 和 Y。

移动后,它看起来像:(向右移动,所以-2)2340, 2342, 4532, 4653

这又是一个没有真正理解移动蛇意味着什么的例子。当您在屏幕上向右移动时,地址(保留在 SI 中)会增加 +2,因此预期的数字将以 2344、2342、... 开头


replace_stars过程灾难性地将引用屏幕的地址与引用驻留在DATASEG中的

stars
数组的地址混合在一起 它执行的一次迭代太多了,因为在具有 3 个元素的数组中,您只能执行其中 2 个移动。
这是修改后的代码:

mov cx, [st_am] ; The amount of stars (3 or more) dec cx ; How many loops mov bx, cx shl bx, 1 ; Offset to the last star replace: mov ax, [stars+bx-2] mov [stars+bx], ax sub bx, 2 loop replace ret
此循环的更好版本不使用 

loop

 指令(因此不会破坏 CX 寄存器):

mov bx, [st_am] ; The amount of stars (3 or more) dec bx shl bx, 1 ; Offset to the last star replace: mov ax, [stars+bx-2] mov [stars+bx], ax sub bx, 2 jnz replace ret


我认为你的

move_stars_right过程是试图让蛇长大?算了,现在还太早了!您需要首先修复错误。您甚至没有应用我在之前的答案中谈到的更正......

与我所说的

replace_stars 过程类似,这个过程也灾难性地将引用屏幕的地址与引用驻留在 DATASEG 中的 stars

 数组的地址混合在一起!

你玩过贪吃蛇游戏吗?

https://www.google.be/url?esrc=s&q=&rct=j&sa=U&url=https://www.quora.com/Why-cant-snakes-crawl-backwards&ved=2ahUKEwjr8-6n_oWEAxXe2gIHHTuzAsgQFnoECAIQAw&usg=AOvVaw2fkOBLUqGbzjfOYcYSdgdt

当蛇当前向左移动时,您不能允许请求向右移动。

当蛇当前向右移动时,您不能允许请求向左移动。
当蛇当前移动到顶部时,您不能允许请求移动到底部。
当蛇当前移动到底部时,您不能允许请求移动到顶部。

我已经在我的

之前的回答中解决了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.