贪吃蛇汇编代码

来源:互联网 发布:单片机载入plc 编辑:程序博客网 时间:2024/04/30 00:39

    微机原理project,第一次用汇编写游戏,感觉还行,DOS窗口运行,小蛇有点难看……

    这个程序可以实现速度的选择,成绩的显示,以及游戏终止等操作。

    还有一些不足:判断小蛇是否触墙或是咬到自己的算法太占用内存,并且效率不高,可以有改进,如对屏幕字符的判读;延时程序和随机函数比较山寨;跳转指令比较乱(我再看一遍依已然不知所云了,真不知道当时怎么一句一句写出来的……)

 

 

 

DATAS SEGMENT
    SNAKE DB  "-============#$"                                         ;@
    BLOCK DB  "                                                          ",13,10
       DB  "                                                          ",13,10
       DB  "                +++++++++++   ++++++++++                  ",13,10
       DB  "                +++++++++++   ++++++++++                  ",13,10
       DB  "                ++                    ++                  ",13,10
       DB  "                ++        +++++       ++                  ",13,10
       DB  "                ++        +++++       ++                  ",13,10
       DB  "                ++                    ++                  ",13,10
       DB  "                ++  ++            ++  ++                  ",13,10
       DB  "                    ++     +++    ++                      ",13,10
       DB  "                    ++     +++    ++                      ",13,10
       DB  "                ++  ++            ++  ++                  ",13,10
       DB  "                ++                    ++                  ",13,10
       DB  "                ++                    ++                  ",13,10
       DB  "                ++        +++++       ++                  ",13,10
       DB  "                ++        +++++       ++                  ",13,10
       DB  "                ++                    ++                  ",13,10
       DB  "                ++++++++++++++++++++++++                  ",13,10
       DB  "                ++++++++++++++++++++++++                  ",13,10,"$"        
    COUNT EQU $-BLOCK
    BLOCKPOSI DW 1000 DUP(0)
    B_Length DW 0                         
    Posi DW 100 DUP(0)
    S_Length DW 14
    COLS DB 0,24
    ROWS DB 1,58
    COL DW 23
    ROW DW 55
    Tail DW 26
    HEAD DW ?
    FOOD DW ?
    NUMS DB 0
    ANTI_DIR DB 75
    CUR_DIR DB 77
    CUR_DIR_2 DB 77
    WAIT_TIME DW 0
    WAIT_NUM DW 9
    MSG3 DB "Choose Game Speed On Right Side$"
    MSG1 DB "PRESS ANY KEY TO EXIT GAME$"
    MSG2 DB "After Pressing ESC:$"
    OVER DB "GAME OVER!$"
    SPEED DB "Choose Game Speed:$"
    NO DB "NORMAL$"
    LO DB "LOW$"
    FA DB "FAST$"
    ENDPOSI DW 1040H
    SPEED2 DW 0740H
    SCORE DB "SCORE: $"
    INFO DB "Snake By Jiangxl$"
    RESTART DB "Restart$"
    CONTINUE DB "Resume$"
    STOP DB "Quit$"
    CHOOSE DW 0
    CHOICE DW 0
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

 ;设置光标
SETCUR MACRO
 MOV AH,2
 MOV BH,0
 INT 10H
 ENDM
 
 ;输出蛇
PUTCHAR MACRO CH
 MOV AH,9
 MOV AL,CH
 MOV BH,0
 MOV BL,1EH
 MOV CX,1
 INT 10H
 ENDM

SHOWSCORE MACRO
 MOV DX,0249H
 SETCUR
 MOV AH,0
 MOV AL,NUMS
 MOV DH,10
 DIV DH
 MOV BH,AH
 MOV DL,AL
 ADD DL,30H
 MOV AH,2
 INT 21H
 MOV DL,BH
 ADD DL,30H
 INT 21H
 ENDM
   
CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:DATAS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV ES,AX
    ;设定显示模式
    MOV AH,0
    MOV AL,3
    INT 10H
    ;显示得分
    MOV DX,0242H
    SETCUR
    LEA DX,SCORE
    MOV AH,9
    INT 21H   
    ;显示速度
    MOV DX,053DH
    SETCUR
    LEA DX,SPEED
    MOV AH,9
    INT 21H
    ;慢速
    MOV DX,0742H
    SETCUR
    LEA DX,LO
    MOV AH,9
    INT 21H
    ;正常
    MOV DX,0942H
    SETCUR
    LEA DX,NO
    MOV AH,9
    INT 21H
    ;快速
    MOV DX,0B42H
    SETCUR
    LEA DX,FA
    MOV AH,9
    INT 21H
    ;红色边框       
    MOV AH,06
    MOV AL,0
    MOV BH,207
    MOV CX,0
    MOV DX,183BH
    INT 10H
    ;我的信息
    MOV DX,0016H
    SETCUR
    LEA DX,INFO
    MOV AH,9
    INT 21H
    ;终止信息
    MOV DX,0E3DH
    SETCUR
    LEA DX,MSG2
    MOV AH,9
 INT 21H
 MOV DX,1042H
    SETCUR
    LEA DX,RESTART
    MOV AH,9
 INT 21H
    MOV DX,1242H
    SETCUR
    LEA DX,CONTINUE
    MOV AH,9
 INT 21H
 MOV DX,1442H
    SETCUR
    LEA DX,STOP
    MOV AH,9
 INT 21H
 ;记录障碍物位置
 MOV CX,COUNT
 MOV SI,0
 MOV DI,0
 MOV DX,0200H
T1: CMP BLOCK[DI],' '
 JZ T2
 MOV BLOCKPOSI[SI],DX
 ADD SI,2
 INC B_Length
T2: INC DL
 CMP DL,60
 JB T3
 MOV DL,0
 INC DH
T3: INC DI
 LOOP T1
 
RESTARTING:
 ;初始化
 MOV SPEED2,0740H
 MOV NUMS,0
 SHOWSCORE
 MOV S_Length,14
 MOV Tail,26 
 MOV ANTI_DIR,75
    MOV CUR_DIR,77
    MOV CUR_DIR_2,77
    ;蓝色清屏
    MOV AH,06
    MOV AL,0
    MOV BH,1EH
    MOV CX,0102H
    MOV DX,1739H
    INT 10H
    ;隐藏光标
    MOV CX,1000h
 MOV AH,1
 INT 10H
 ;选择速度
 MOV DX,030CH
    SETCUR
    LEA DX,MSG3
    MOV AH,9
 INT 21H
 CALL SET_SPEED
 ;显示障碍物
 MOV DX,0200H
 SETCUR
 LEA DX,BLOCK
 MOV AH,9
 INT 21H
    ;中央显示黄色小蛇
    MOV AH,06
    MOV AL,0
    MOV BH,1EH
    MOV CX,030CH
    MOV DX,0330H
    INT 10H
    MOV DX,030CH
    SETCUR
    LEA DX,SNAKE
 MOV AH,9
 INT 21H
 ;记录初始位置
 MOV DX,030CH
 ADD DX,S_Length
 DEC DX
 MOV CX,S_Length
 MOV SI,0
G1: MOV Posi[SI],DX
 DEC DX
 ADD SI,2
 LOOP G1
 ;初始食物
 CALL PUT_FOOD
 
GAMESTART:
 ;监视键盘
 MOV ENDPOSI,1040H
 MOV AH,11H
 INT 16H
 JZ DELAY
 MOV AH,10H
 INT 16H
 ;ESC
 CMP AL,1BH 
 JZ END2
 ;若方向相反则等待
 CMP ANTI_DIR,AH
 JZ GAMESTART
 MOV CUR_DIR,AH
 JMP SNAKE_MOVE
 
DELAY: 
 ;延时
 MOV AH,0
 INT 1AH
 CMP DX,WAIT_TIME
 JB  GAMESTART
 ADD DX, WAIT_NUM
 MOV WAIT_TIME, DX

 MOV DX,02BBH    ;循环次数
LB: XOR CX,CX
LA: 
 LOOP LA
 DEC DX
 JNZ LB
  
SNAKE_MOVE: 
 MOV DX,Posi[0]
UP:
 CMP CUR_DIR,72
 JNZ DOWN
 DEC DH
 MOV ANTI_DIR,80
 JMP MOVE
LEFT:
 CMP CUR_DIR,75
 JNZ RIGHT
 DEC DL
 MOV ANTI_DIR,77
 JMP MOVE
RIGHT:
 CMP CUR_DIR,77
 JNZ OTHER
 INC DL
 MOV ANTI_DIR,75
 JMP MOVE
DOWN:
 CMP CUR_DIR,80
 JNZ LEFT
 INC DH
 MOV ANTI_DIR,72
 JMP MOVE
 
OTHER:
 MOV AL,CUR_DIR_2
 MOV CUR_DIR,AL
 JMP GAMESTART
 
MOVE: 
 ;保留更新的蛇头坐标
 MOV HEAD,DX
 MOV AL,CUR_DIR
 MOV CUR_DIR_2,AL 
 ;更新位置坐标
 MOV SI,Tail
 MOV CX,S_Length
 UPDATE:
 MOV DX,Posi[SI]
 MOV Posi[SI+2],DX
 SUB SI,2
 LOOP UPDATE
 ;判断是否吃到食物
 MOV DX,HEAD  
 CMP DX,FOOD
 JNZ MOVE_HEAD
 INC NUMS
 SHOWSCORE
 ADD Tail,2
 INC S_Length
 MOV SI,Tail
 MOV DX,Posi[SI]
 MOV Posi[SI+2],DX
 CALL PUT_FOOD 
 
MOVE_HEAD:
 ;检查蛇头是否咬到自身,触墙
 MOV AX,HEAD
 LEA DI,Posi
 MOV CX,S_Length
 REPNZ SCASW
 JZ END1
 LEA DI,BLOCKPOSI
 MOV CX,B_Length
 REPNZ SCASW
 JZ END1
 MOV CX,2
 LEA DI,ROWS
 REPNZ SCASB
 JZ END1
 MOV CX,2
 MOV AL,AH
 LEA DI,COLS
 REPNZ SCASB
 JZ END1
 ;移动蛇头 
 MOV DX,Posi[0]
 SETCUR
 PUTCHAR '='
 MOV DX,HEAD
 MOV Posi[0],DX
 SETCUR
 PUTCHAR '#'
 ;移动蛇尾
 MOV SI,Tail
 MOV DX,Posi[SI]
 SETCUR
 PUTCHAR '-'
 MOV DX,Posi[SI+2]
 SETCUR
 PUTCHAR ' '
 JMP GAMESTART
 
END2:
 MOV DX,1040H
 SETCUR
 PUTCHAR 01H
 MOV DX,1240H
 SETCUR
 PUTCHAR ' '
 MOV DX,1440H
 SETCUR
 PUTCHAR ' '
 
E2: MOV AH,0 
 INT 16H
 CMP AL,0DH
 JZ GETEND
 MOV DX,ENDPOSI
 SETCUR
 PUTCHAR ' '
 ADD DH,2
 CMP DH,14H
 JBE E1
 MOV DH,10H
E1: MOV ENDPOSI,DX
 SETCUR
 PUTCHAR 01H
 JMP E2
GETEND:
 MOV AH,06
    MOV AL,0
    MOV BH,07H
    MOV CX,1040H
    MOV DX,1440H
    INT 10H
 MOV DX,ENDPOSI
 CMP DX,1040H
 JNZ C1
 JMP RESTARTING
C1: CMP DX,1240H
 JNZ C2
 JMP GAMESTART
C2: JMP END_FINAL

END1:
 ;清屏
 MOV AH,06
    MOV AL,0
    MOV BH,4FH
    MOV CX,0A14H
    MOV DX,1024H
    INT 10H
    MOV DX,0B18H
    SETCUR
    LEA DX,OVER
    MOV AH,9
 INT 21H
 MOV DX,0D16H
 SETCUR
 PUTCHAR 01H
 MOV DX,0F16H
 SETCUR
 PUTCHAR ' '
 
 MOV DX,0D18H
    SETCUR
    LEA DX,RESTART
    MOV AH,9
 INT 21H
 MOV DX,0F18H
    SETCUR
    LEA DX,STOP
    MOV AH,9
 INT 21H
 MOV CHOOSE,0
 MOV CHOICE,0
WAIT_INPUT2:
 MOV AH,0 
 INT 16H
 CMP AL,0DH
 JZ SET_GO2
SELECT2: 
 INC CHOOSE
 CWD
 MOV AX,CHOOSE
 MOV CX,2
 DIV CX
 MOV CHOICE,DX
 CMP DX,0
 JNZ S2
 MOV DX,0D16H
 SETCUR
 PUTCHAR 01H
 MOV DX,0F16H
 SETCUR
 PUTCHAR ' '
 JMP WAIT_INPUT2
S2:
 MOV DX,0D16H
 SETCUR
 PUTCHAR ' '
 MOV DX,0F16H
 SETCUR
 PUTCHAR 01H
 JMP WAIT_INPUT2
SET_GO2:
 CMP CHOICE,0
 JZ RESTARTING 
 
END_FINAL:
 MOV BH,4FH
 MOV DX,0612H
    SETCUR
    LEA DX,MSG1
    MOV AH,9
 INT 21H
 
W: MOV AH,1
 INT 16H
 JZ W
   
 MOV AH,4CH
    INT 21H

SET_SPEED PROC
 MOV DX,0740H
 SETCUR
 PUTCHAR 01H
 MOV DX,0940H
 SETCUR
 PUTCHAR ' '
 MOV DX,0B40H
 SETCUR
 PUTCHAR ' '
P2: MOV AH,0 
 INT 16H
 CMP AL,0DH
 JZ GETSET
 MOV DX,SPEED2
 SETCUR
 PUTCHAR ' '
 ADD DH,2
 CMP DH,0BH
 JBE P1
 MOV DH,07H
P1: MOV SPEED2,DX
 SETCUR
 PUTCHAR 01H
 JMP P2
GETSET:
 MOV AH,06
    MOV AL,0
    MOV BH,07H
    MOV CX,0740H
    MOV DX,0B40H
    INT 10H
 MOV DX,SPEED2
 SETCUR
 PUTCHAR 01H
 CMP DX,0740H
 JNZ N
 MOV WAIT_NUM,8
 JMP RETURN
N: CMP DX,0940H
 JNZ F
 MOV WAIT_NUM,4
 JMP RETURN
F: MOV WAIT_NUM,0
RETURN: 
 RET 
SET_SPEED ENDP

;随机放置食物  
PUT_FOOD PROC
REPUT:
 ;取时钟滴答数
 MOV AH,0
 INT 1AH
 ;计算行号 
 MOV BX,DX
 MOV AX,DX
 XOR DX,DX
 DIV COL
 INC DX
 MOV CX,DX
 ;计算列号
 MOV AX,BX
 XOR DX,DX
 DIV ROW
 ADD DX,2
 MOV DH,CL
 MOV FOOD,DX
 ;检查食物位置是否被小蛇占据
 MOV AX,DX
 LEA DI,Posi
 MOV CX,S_Length
 REPNZ SCASW
 ;发现被占据,则重新生成 
 JZ REPUT
 LEA DI,BLOCKPOSI
 MOV CX,B_Length
 REPNZ SCASW
 JZ REPUT
 ;否则在该位置放置食物
 SETCUR
 PUTCHAR 01H
 RET
PUT_FOOD ENDP

CODES ENDS
    END START

 

原创粉丝点击