Assembly 转弯错误会导致蛇死亡(组装)

Assembly 转弯错误会导致蛇死亡(组装),assembly,masm32,Assembly,Masm32,我的蛇游戏几乎可以顺利进行了。只有一只虫子,如果我转错弯,我的蛇就会死。例如,当我的蛇向右移动时,我向上按,然后向左按,它就死了。然而,当我按下右键时,它就活了。我检查零件打印位置的方法取决于上一页上读取的上一个字符。例如,如果在上一页上读取的上一个字符是“>”,则它将在下一页读取其左侧的字符,然后在另一页上打印读取的字符。这是我的密码: .model small .data mode db 03h startPosX db 39 start

我的蛇游戏几乎可以顺利进行了。只有一只虫子,如果我转错弯,我的蛇就会死。例如,当我的蛇向右移动时,我向上按,然后向左按,它就死了。然而,当我按下右键时,它就活了。我检查零件打印位置的方法取决于上一页上读取的上一个字符。例如,如果在上一页上读取的上一个字符是“>”,则它将在下一页读取其左侧的字符,然后在另一页上打印读取的字符。这是我的密码:

.model small
.data
mode db                 03h
startPosX db            39
startPosY db            12
myChar db               14
wdir db                 119, 48h, 87
sdir db                 115, 50h, 83
adir db                 97, 4bh, 65
ddir db                 100, 4dh, 68
curColor db             12h
cycle db                0
startPrompt db          'Press any key to start the game n___n', '$'
index dw              0
recycleTime EQU         100
maxX dw                 80
maxY dw                 25
food db                 01h
prevkey    db           ?
input db                ?
xpos db                 ?
ypos db                 ?
foodPosX db             ?
foodPosY db             ?
cloneXpos db            ?
cloneYpos db            ?
snakeLength db          5
partCount   db          1
curPage db              0
altPage db              1
cloneAltPage db         ?
boolCopied db           0
upChar db               '^'
downChar db             'v'
leftChar db             '<'
rightChar db            '>'
promptRetry db 'Want to play again?', '$'
choices db 'Yes       No', '$'
promptTY db 'Thank you for playing! n___n', '$'
arrowSelect db 16
mychoice db 'y'
.stack 100h
.code

loadPage macro page
    mov al, page
    mov ah, 05h
    int 10h
endm

setCursorPos macro x, y, page
    mov dh, y
    mov dl, x
    mov bh, page
    mov ah, 02h
    int 10h
endm

printChar macro char, color, page
    mov al, char
    mov bh, page
    mov bl, color
    xor cx, cx
    mov cx, 1
    mov ah, 09h
    int 10h
endm

loadPrompts proc
    call clearScreen
    call clearRegisters
    setCursorPos 30, 12, curPage
    lea dx, promptRetry
    mov ah, 09h
    int 21h

    setCursorPos 34, 13, curPage
    lea dx, choices
    mov ah, 09h
    int 21h
    ret
loadPrompts endp

printArrow proc
    setCursorPos xpos, ypos, curPage
    printChar arrowSelect, 0fh, curPage
    ret
printArrow endp

loadTYPrompt proc
    call clearscreen
    call clearRegisters
    mov xpos, 26

    setCursorPos xpos, 12, curPage
    lea dx, promptTY
    mov ah, 09h
    int 21h

    mov ah, 00h
    int 16h

    call clearScreen

    mov ax, 4c00h
    int 21h
    ret
loadTYPrompt endp

copy macro dest, source
    mov cl, source
    mov dest, cl
endm

gameover proc
    call clearScreen
    call loadPrompts
    setCursorPos 32, 13, curPage
    printChar arrowSelect, 0fh, curPage

    choose:
    mov ah, 00h
    int 16h
    mov input, al
    cmp al, 'a'
    je chooseYes
    cmp al, 'd'
    je chooseNo

    jmp done

    chooseYes:
    mov mychoice, 'y'
    mov xpos, 32
    mov ypos, 13
    jmp done

    chooseNo:
    mov mychoice, 'n'
    mov xpos, 42
    mov ypos, 13

    done:
    call clearScreen
    call loadPrompts
    call printArrow
    cmp input, 13
    jne choose

    cmp mychoice, 'y'
    je playagain

    call loadTYPrompt

    playagain:
    call clearRegisters
    mov snakeLength, 5
    mov partCount, 1
    loadPage altPage
    copy cloneAltPage, altPage
    copy altPage, curPage
    copy curPage, cloneAltPage
    mov boolCopied, 0
    mov input, 'd'
    mov prevkey, 'd'
    ret
gameover endp

random macro maxCoor
    mov ah, 00h     
    int 1ah         

    mov  ax, dx
    xor  dx, dx
    mov  cx, maxCoor     
    div  cx         
endm

scanChar proc
    mov ah, 08h
    int 10h
    ret
scanChar endp

keystroke proc
    mov ah, 01h
    int 16h
    jz nopress

    mov ah, 00h
    int 16h

    cmp al, 00h
    jne wsadInput

    mov input, ah
    jmp nopress

    wsadInput:
    mov input, al
    nopress:
    ret
keystroke endp

spawnfood proc
    cmp cycle, 0
    jne setFood

    setFoodPos:
    random maxX
    mov foodPosX, dl
    random maxY
    mov foodPosY, dl

    setFood:
    setCursorPos foodPosX, foodPosY, curPage
    mov ah, 08h
    int 10h

    cmp ah, 12h
    je setFoodPos

    spawn:
    printChar food, 0fh, curPage
    ret
spawnfood endp

waitAmillisec proc
    mov cx, 1h
    mov dx, 0f4h
    mov ah, 86h
    int 15h
    inc cycle
    cmp cycle, recycleTime
    jle proceed

    mov cycle, 0

    proceed:
    ret
waitAmillisec endp

clearRegisters proc
    xor ax, ax
    xor bx, bx
    xor cx, cx
    xor dx, dx
    ret
clearRegisters endp

clearScreen proc
    mov ax, 0600h
    mov bh, 07h
    xor cx, cx
    mov dx, 184fh
    int 10h
    ret
clearScreen endp

initgraphics proc
    mov al,mode         
    mov ah,00                 
    int 10h              
    ret
initgraphics endp

closegraphics proc
    mov ax, 0003h      
    int 10h
    ret
closegraphics endp

main    proc

mov ax, @data
mov ds, ax

call initgraphics

mov cx, 3200h
mov ah, 01h
int 10h

setCursorPos 22, 12, curPage
lea dx, startPrompt
mov ah, 09h
int 21h

mov ah, 00h
int 16h

mov input, 'd'
mov prevkey, 'd'
call clearScreen

gameStart:
setCursorPos startPosX, startPosY, curPage
mov xpos, dl
mov ypos, dh

start:
printChar myChar, curColor, curPage
inc xpos
setCursorPos xpos, ypos, curPage
inc partCount
mov cl, partCount
cmp cl, snakeLength
jle start

dec xpos
mov partCount, 1

readchar:
call keystroke

mov index, 0
call clearRegisters

cmpDir:
mov bx, index
mov al, input
cmp al, [ddir+bx]
je moveright
cmp al, [wdir+bx]
je moveup
cmp al, [sdir+bx]
je movedown
cmp al, [adir+bx]
je moveleft
inc index
cmp index, 3
jl cmpDir

mov index, 0
copy input, prevkey
jmp cmpDir

moveup:
    cmp prevkey, 's'
    je movedown

    mov prevkey, 'w'
    copy mychar, upChar
    cmp ypos, 0
    jne up

    mov ypos, 24
    copy cloneYPos, snakeLength
    jmp keepmoving

    up:
    dec ypos
    jmp keepmoving

movedown:
    cmp prevkey, 'w'
    je moveup

    mov prevkey, 's'
    copy mychar, downChar
    cmp ypos, 24
    jne down

    mov ypos, 0
    copy cloneYPos, snakeLength
    jmp keepmoving

    down:
    inc ypos
    jmp keepmoving

moveleft:
    cmp prevkey, 'd'
    je moveright

    mov prevkey, 'a'
    copy mychar, leftChar
    cmp xpos, 0
    jne left

    mov xpos, 79
    mov cl, snakeLength
    copy cloneXPos, xpos
    sub cloneXPos, cl
    jmp keepmoving

    left:
    dec xpos
    jmp keepmoving

moveright:
    cmp prevkey, 'a'
    je moveleft

    mov prevkey, 'd'
    copy mychar, rightChar
    cmp xpos, 79
    jne right

    mov xpos, 0
    copy cloneXPos, snakeLength
    jmp keepmoving

    right:
    inc xpos

keepmoving:
    call spawnfood
    setCursorPos xpos, ypos, altPage

    call scanChar
    cmp ah, curColor
    jne notDeads

    call gameOver
    jmp gameStart

    notDeads:
    printChar myChar, curColor, altPage

    mov cl, xpos
    cmp cl, foodPosX
    jne copyHeadPos

    mov cl, ypos
    cmp cl, foodPosY
    jne copyHeadPos

    add snakeLength, 2
    mov cycle, 0

    copyHeadPos:
    cmp boolCopied, 0
    jne keeplooking

    copy cloneXPos, xpos
    copy cloneYPos, ypos
    mov boolCopied, 1

    keepLooking:
    mov cl, partCount
    printbody:
        cmp cl, snakeLength
        je move
        call scanChar
        cmp al, rightChar
        je checkForRightPart
        cmp al, upChar
        je checkForUpPart
        cmp al, downChar
        je checkForDownPart
        cmp al, leftChar
        je checkForLeftPart

        checkForUpPart:
            cmp ypos, 24
            jne goUp

            mov ypos, 0
            jmp checkPrevChar

            goUp:
            inc ypos
        jmp checkPrevChar

        checkForDownPart:
            cmp ypos, 0
            jne goDown

            mov ypos, 24
            jmp checkPrevChar

            goDown:
            dec ypos
        jmp checkPrevChar

        checkForLeftPart:
            cmp xpos, 79
            jne goLeft

            mov xpos, 0
            jmp checkPrevChar

            goLeft:
            inc xpos
        jmp checkPrevChar

        checkForRightPart:
            cmp xpos, 0
            jne goRight

            mov xpos, 79
            jmp checkPrevChar

            goRight:
            dec xpos

        checkPrevChar:
        setCursorPos xpos, ypos, curPage
        mov ah, 08h
        int 10h
        inc partCount
        mov cl, partCount
        cmp cl, snakeLength
        jg move 
        cmp al, rightChar
        je printRight
        cmp al, upChar
        je printUp
        cmp al, downChar
        je printDown
        cmp al, leftChar
        je printLeft

        jmp move

        printUp:
        inc ypos
        jmp moveup

        printDown:
        dec ypos
        jmp movedown

        printLeft:
        inc xpos
        jmp moveleft

        printRight:
        dec xpos
        jmp moveRight
move:
call clearScreen
call spawnfood
copy xpos, cloneXPos
copy ypos, cloneYPos
loadPage altPage
copy cloneAltPage, altPage
copy altPage, curPage
copy curPage, cloneAltPage
mov partCount, 1
mov boolCopied, 0
call waitamillisec
jmp readchar

mov ax, 4c00h
int 21h

main    endp
end main
。型号小
.数据
模式db 03h
startPosX数据库39
startPosY db 12
myChar数据库14
wdir数据库119、48小时、87
sdir db 115、50小时、83小时
adir db 97,4bh,65
ddir db 100,4dh,68
curColor db 12h
周期分贝0
startPrompt db'按任意键开始游戏n_uuuun','$'
索引dw0
回收时间等于100
maxX dw 80
maxY dw 25
食品数据库01h
prevkey数据库?
输入分贝?
XPOSDB?
ypos数据库?
FoodPosxDB?
FoodPosyDB?
clonexposdb?
克隆人数据库?
蛇形长度db 5
零件计数数据库1
curPage数据库0
备用页数据库1
克隆网页数据库?
boolCopied数据库0
upChar数据库“^”
downChar数据库'v'
leftChar数据库“”
promptRetry db“想再次播放吗?”,“$”
选项数据库“是否”,“美元”
promptTY db'感谢您的参与!n_____n','$'
箭头选择db 16
mychoice数据库'y'
.烟囱100小时
.代码
加载页宏页
莫夫·艾尔,第页
mov啊,05h
int 10h
endm
setCursorPos宏x,y,第页
mov dh,y
mov-dl,x
莫夫·波黑,第页
mov啊,02h
int 10h
endm
printChar宏字符、颜色、页面
莫夫·阿尔,查尔
莫夫·波黑,第页
mov bl,颜色
异或
mov cx,1
mov啊,09h
int 10h
endm
加载提示程序
呼叫清除屏幕
调用清除寄存器
setCursorPos 30、12、curPage
lea dx,提示重试
mov啊,09h
int 21h
setCursorPos 34、13、curPage
lea dx,选择
mov啊,09h
int 21h
ret
加载提示endp
打印箭头程序
setCursorPos xpos、ypos、curPage
打印字符箭头选择,0fh,当前页面
ret
打印箭头endp
加载提示程序
呼叫清除屏幕
调用清除寄存器
mov xpos,26
setCursorPos xpos,12,curPage
利阿dx,Prompty
mov啊,09h
int 21h
mov啊,00h
int 16h
呼叫清除屏幕
mov-ax,4c00h
int 21h
ret
加载提示结束
复制宏dest,source
mov-cl,源
移动目的地,cl
endm
gameover程序
呼叫清除屏幕
调用加载提示
setCursorPos 32、13、curPage
打印字符箭头选择,0fh,当前页面
选择:
mov啊,00h
int 16h
mov输入,al
“a”
我的选择
cmp al'd'
我选择了
jmp完成
选择者:
mov mychoice,“y”
mov xpos,32
mov ypos,13岁
jmp完成
选择否:
mov我的选择'n'
mov xpos,42
mov ypos,13岁
完成:
呼叫清除屏幕
调用加载提示
调用printArrow
cmp输入,13
jne选择
我的选择是“y”
我又玩了
调用loadTYPrompt
再次播放:
调用清除寄存器
莫夫蛇形长度,5
mov零件计数,1
加载页altPage
复制cloneAltPage,altPage
复制altPage,curPage
复制curPage、cloneAltPage
mov boolCopied,0
mov输入'd'
mov prevkey'd'
ret
gameover endp
随机宏maxCoor
mov啊,00h
int 1ah
mov-ax,dx
异或dx,dx
莫夫cx,马克斯库尔
分区cx
endm
扫描字符程序
mov啊,08h
int 10h
ret
扫描字符endp
击键过程
mov-ah,01h
int 16h
jz nopress
mov啊,00h
int 16h
cmp-al,00h
jne wsadInput
mov输入啊,
jmp-nopress
wsadInput:
mov输入,al
否:
ret
击键结束
产卵食品加工
cmp循环,0
塞特食品
setFoodPos:
随机最大值
mov foodPosX,dl
随机最大值
mov foodPosY,dl
食物:
setCursorPos foodPosX、foodPosY、curPage
mov啊,08h
int 10h
啊,12小时
je setFoodPos
产卵:
printChar食品,0fh,curPage
ret
产卵食物端
waitAmillisec程序
mov-cx,1h
mov-dx,0f4h
mov啊,86h
int 15h
inc循环
cmp循环,循环时间
继续
mov循环,0
进行:
ret
韦塔米利塞克酒店
清除寄存器程序
xor ax,ax
异或bx,bx
异或
异或dx,dx
ret
清除寄存器endp
清屏程序
mov ax,0600h
莫夫波黑,07h
异或
莫夫dx,184fh
int 10h
ret
透明屏幕endp
初始化图形程序
莫夫·艾尔,模式
mov啊,00
int 10h
ret
初始化图形endp
闭合图形程序
mov ax,0003h
int 10h
ret
闭合图形endp
主进程
mov-ax,@data
mov-ds,ax
调用initgraphics
mov-cx,3200h
mov-ah,01h
int 10h
setCursorPos 22、12、curPage
lea dx,StartCompt
mov啊,09h
int 21h
mov啊,00h
int 16h
mov输入'd'
mov prevkey'd'
呼叫清除屏幕
游戏开始:
setCursorPos startPosX、startPosY、curPage
mov xpos,dl
莫夫伊普斯,dh
开始:
printChar myChar、curColor、curPage
xpos公司
setCursorPos xpos、ypos、curPage
公司零件数
mov cl,零件计数
蛇长
jle启动
dec xpos
mov零件计数,1
readchar:
呼叫击键
mov指数,0
调用清除寄存器
cmpDir:
指数
mov-al,输入
cmp铝[ddir+bx]
我要右转
cmp铝,[wdir+bx]
je向上移动
cmp铝,[sdir+bx]
je下移
cmp铝[adir+bx]
我向左移动
公司索引
cmp指数,3
jl-cmpDir
mov指数,0
复制输入,prevkey
jmp-cmpDir
上移:
cmp前置键“s”
je下移
mov prevkey“w”
复制mychar,upChar
cmp-ypos,0
振作起来
mov ypos,24岁
复制克隆体,蛇形长度
jmp保持
move(insert direction here):
    cmp prevkey, 'a' <-
    je moveleft <-
cmpDir:
mov bl, index
mov bh, 0
mov al, input
cmp al, [ddir+bx]
je moveright
index dw                0
...
cmpDir:
mov bx, index
mov al, input
cmp al, [ddir+bx]
je moveright
   ...
moveup:
   cmp prevkey, 's'
   je movedown
   mov prevkey, 'w'
moveup_draw:
   copy mychar, upChar
   ...
   ...
   jmp move
printUp:
   inc ypos
   jmp moveup_draw
   ...
...
cmp al, 'd'
je chooseNo
             ; Here is something missing!
jmp done