📄 sysnake.asm
字号:
DATA SEGMENT
MESG1 DB "I am so sorry, you lose","$"
MESG2 DB "Thank you for playing!","$"
SNAKE DW 100 ;存储蛇身走过的位置坐标
DW ?
DW 100 DUP(?)
LEN DB 5
RANROW DB 08H ;食物随机产生的行位置
RANCOL DB 0FH ;食物随机产生的列位置
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV ES,AX
WR MACRO CHA,NUM ;连续写下NUM个字符CHA,行列位置存在DX中
PUSH AX
PUSH BX
PUSH CX
MOV AH,02H
MOV BH,0
INT 10H
MOV AL,CHA
MOV CX,NUM
MOV BL,1EH
MOV AH,09H
INT 10H
POP CX
POP BX
POP AX
ENDM
BLUE: ;刷蓝屏
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,6
MOV AL,0
MOV CL,0
MOV CH,0
MOV DH,18H
MOV DL,4FH
MOV BH,1EH
INT 10H
POP DX
POP CX
POP BX
POP AX
SK: ;初始小蛇的位置
PUSH DX
LEA DI,SNAKE
MOV DX,0E05H
MOV CL,LEN
LOP1:
MOV [DI],DX
ADD DI,2
INC DX
LOOP LOP1
POP DX
CALL DRAWFOOD ;先画一个食物
DRAWSNAKE: ;根据小蛇的初始位置,画出一条小蛇
PUSH DX
PUSH CX
LEA DI,SNAKE
MOV DX,[DI]
WR '-',1
MOV CL,LEN
SUB CL,2
LOP2:
ADD DI,2
MOV DX,[DI]
WR '=',1
LOOP LOP2
ADD DI,2
MOV DX,[DI]
WR '#',1
POP CX
POP DX
LEA DI,SNAKE
RIGHTWALK: ;小蛇向右行走的模块
CALL DELAY
LEA DI,SNAKE
MOV DX,[DI]
WR 0,1
MOV CL,LEN
DEC CL
LOP3:
MOV DX,[DI+2] ;小蛇向右走了一步后,新的位置坐标
MOV [DI],DX
ADD DI,2
LOOP LOP3
ADD [DI],0001H
CALL DEAD ;如果碰到了墙,就死掉了
MOV DX,[DI]
CMP DH,RANROW ;判断是否吃到了食物
JNE DRAWRIGHTSNAKE
CMP DL,RANCOL
JNE DRAWRIGHTSNAKE
INC LEN ;吃到了就伸长一个单位
ADD DX,0001H
MOV [DI+2],DX
CALL DRAWFOOD ;产生一个新的食物,替代被吃掉的食物
DRAWRIGHTSNAKE: ;把右移一格后的小蛇重新画出来
PUSH DX
PUSH CX
PUSH AX
PUSH BX
LEA DI,SNAKE
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,1
JE WRITE13
CMP AX,0FF00H
JE WRITE14
CMP AX,0100H
JE WRITE14
WRITE13:
LEA DI,SNAKE
MOV DX,[DI]
WR '-',1
JMP WRITE15
WRITE14:
LEA DI,SNAKE ;如果小蛇拐弯了,就要把尾巴竖起来
MOV DX,[DI]
WR 179,1
WRITE15:
MOV CL,LEN
SUB CL,2
LOP16:
ADD DI,2
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,1
JE WRITE111
CMP AX,0FF00H
JE WRITE12
CMP AX,0100H
JE WRITE12
WRITE111:
MOV DX,[DI]
WR '=',1
JMP NEXLOP11
WRITE12:
MOV DX,[DI]
WR 186,1 ;如果小蛇拐弯了,还要把身体也竖起来
NEXLOP11:
LOOP LOP16
ADD DI,2
MOV DX,[DI]
WR '#',1
POP BX
POP AX
POP CX
POP DX
MOV AH,1 ;在行走的过程当中,看是否有按键被按下
INT 16H
JNZ OUT1
JMP RIGHTWALK
OUT1:
MOV AH,0
INT 16H
CMP AL,27 ;按下ESC,就退出
JE EXIT2
CMP AH,72
JE UPWALK ;按下向上键,就拐向上方
CMP AH,80
JE DOWNWALK ;按下向下键,就拐向下方
JMP RIGHTWALK ;如果什么键都没按下,就接着向右行走
UPWALK: ;控制小蛇向上走的模块,整体设计思路和“向右走”的模块
;一致,需要考虑是否撞墙、吃到食物、是否拐弯了(尾巴、身体
;要竖起来、是否有新的按键被按下等等问题)
CALL DELAY
LEA DI,SNAKE
MOV DX,[DI]
WR 0,1
MOV CL,LEN
DEC CL
LOP5:
MOV DX,[DI+2]
MOV [DI],DX
ADD DI,2
LOOP LOP5
SUB [DI],0100H
CMP [DI],0
JL EXIT
MOV DX,[DI]
CMP DH,RANROW
JNE DRAWUPSNAKE
CMP DL,RANCOL
JNE DRAWUPSNAKE
INC LEN
SUB DX,0100H
MOV [DI+2],DX
CALL DRAWFOOD
DRAWUPSNAKE:
PUSH DX
PUSH CX
PUSH BX
LEA DI,SNAKE
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,1
JE WRITE3
CMP AX,0FF00H
JE WRITE4
CMP AX,0100H
JE WRITE4
WRITE3:
LEA DI,SNAKE
MOV DX,[DI]
WR '-',1
JMP WRITE5
WRITE4:
LEA DI,SNAKE
MOV DX,[DI]
WR 179,1
WRITE5:
MOV CL,LEN
SUB CL,2
LEA DI,SNAKE
LOP6:
ADD DI,2
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,1
JE WRITE1
CMP AX,0FF00H
JE WRITE2
CMP AX,0100H
JE WRITE2
WRITE1:
MOV DX,[DI]
WR '=',1
JMP NEXLOP
WRITE2:
MOV DX,[DI]
WR 186,1
NEXLOP:
LOOP LOP6
MOV DX,[DI+2]
WR '#',1
POP BX
POP CX
POP DX
NEXT3:
MOV AH,1
INT 16H
JNZ OUT2
JMP UPWALK
OUT2:
CMP AL,27
JE EXIT2
CMP AH,75
JE LEFTWALK
CMP AH,77
JE RIGHTWALK
JMP UPWALK
DOWNWALK: ;控制小蛇向下走的模块,整体设计思路和“向右走”的模块
;一致,需要考虑是否撞墙、吃到食物、是否拐弯了(尾巴、身体
;要竖起来、是否有新的按键被按下等等问题)
CALL DELAY
LEA DI,SNAKE
MOV DX,[DI]
WR 0,1
MOV CL,LEN
DEC CL
LOP8:
MOV DX,[DI+2]
MOV [DI],DX
ADD DI,2
LOOP LOP8
ADD [DI],0100H
MOV DX,[DI]
CMP DH,24
JG EXIT
MOV DX,[DI]
CMP DH,RANROW
JNE DRAWDOWNSNAKE
CMP DL,RANCOL
JNE DRAWDOWNSNAKE
INC LEN
ADD DX,0100H
MOV [DI+2],DX
CALL DRAWFOOD
DRAWDOWNSNAKE:
PUSH DX
PUSH CX
PUSH BX
LEA DI,SNAKE
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,1
JE WRITE7
CMP AX,0100H
JE WRITE8
CMP AX,0FF00H
JE WRITE8
WRITE7:
LEA DI,SNAKE
MOV DX,[DI]
WR '-',1
JMP WRITE9
WRITE8:
LEA DI,SNAKE
MOV DX,[DI]
WR 179,1
WRITE9:
MOV CL,LEN
SUB CL,2
LEA DI,SNAKE
LOP9:
ADD DI,2
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,1
JE WRITE10
CMP AX,0100H
JE WRITE11
CMP AX,0FF00H
JE WRITE11
WRITE10:
MOV DX,[DI]
WR '=',1
JMP NEXLOP2
WRITE11:
MOV DX,[DI]
WR 186,1
NEXLOP2:
LOOP LOP9
MOV DX,[DI+2]
WR '#',1
POP BX
POP CX
POP DX
NEXT9:
MOV AH,1
INT 16H
JNZ OUT3
JMP DOWNWALK
OUT3:
MOV AH,0
INT 16H
CMP AL,27
JE EXIT2
CMP AH,75
JE LEFTWALK
CMP AH,77
JE RIGHTWALK
JMP DOWNWALK
LEFTWALK: ;控制小蛇向左走的模块,整体设计思路和“向右走”的模块
;一致,需要考虑是否撞墙、吃到食物、是否拐弯了(尾巴、身体
;要竖起来、是否有新的按键被按下等等问题)
CALL DELAY
LEA DI,SNAKE
MOV DX,[DI]
WR 0,1
MOV CL,LEN
DEC CL
LOP33:
MOV DX,[DI+2]
MOV [DI],DX
ADD DI,2
LOOP LOP33
SUB [DI],0001H
MOV DX,[DI]
CMP DL,0
JL EXIT
MOV DX,[DI]
CMP DH,RANROW
JNE DRAWLEFTSNAKE
CMP DL,RANCOL
JNE DRAWLEFTSNAKE
INC LEN
SUB DX,0001H
MOV [DI+2],DX
CALL DRAWFOOD
DRAWLEFTSNAKE:
PUSH DX
PUSH CX
PUSH AX
PUSH BX
LEA DI,SNAKE
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,0FFFFH
JE WRITE23
CMP AX,0FF00H
JE WRITE24
CMP AX,0100H
JE WRITE24
WRITE23:
LEA DI,SNAKE
MOV DX,[DI]
WR '-',1
JMP WRITE25
WRITE24:
LEA DI,SNAKE
MOV DX,[DI]
WR 179,1
WRITE25:
MOV CL,LEN
SUB CL,2
LOP26:
ADD DI,2
MOV AX,[DI+2]
SUB AX,[DI]
CMP AX,0FFFFH
JE WRITE21
CMP AX,0FF00H
JE WRITE22
CMP AX,0100H
JE WRITE22
WRITE21:
MOV DX,[DI]
WR '=',1
JMP NEXLOP21
WRITE22:
MOV DX,[DI]
WR 186,1
NEXLOP21:
LOOP LOP26
ADD DI,2
MOV DX,[DI]
WR '#',1
POP BX
POP AX
POP CX
POP DX
MOV AH,1
INT 16H
JNZ OUT21
JMP LEFTWALK
OUT21:
MOV AH,0
INT 16H
CMP AL,27
JE EXIT2
CMP AH,72
JE UPWALK
CMP AH,80
JE DOWNWALK
JMP LEFTWALK
RAND1 PROC
PUSH CX
PUSH DX
PUSH AX
STI
MOV AH,0 ;读时钟计数器值
INT 1AH
MOV AX,DX ;清空高6位
AND AH,3
MOV DL,10 ;除以10,产生0到9的余数
DIV DL
MOV RANROW,AH
ADD RANROW,5 ;余数加上5后,存在RANROW中,作随机行数
POP AX
POP DX
POP CX
RET
RAND1 ENDP
RAND2 PROC
PUSH CX
PUSH DX
PUSH AX
STI
MOV AH,0 ;读时钟计数器值
INT 1AH
MOV AX,DX ;清空高6位
AND AH,3
MOV DL,40 ;除以40,产生0到39的余数
DIV DL
MOV RANCOL,AH
ADD RANCOL,5 ;余数加上5后,存在RANCOL中,作随机列数
POP AX
POP DX
POP CX
RET
RAND2 ENDP
DRAWFOOD PROC ;在RANROW,RANCOL确定的随机位置产生食物
CALL RAND1
CALL RAND2
MOV DH,RANROW
MOV DL,RANCOL
WR 2,1
RET
DRAWFOOD ENDP
EXIT: ;小蛇去世后输出信息
LEA DX,MESG1
MOV AH,09H
INT 21H
MOV AH, 4CH
INT 21H
EXIT2: ;用户选择离开后,输出信息
LEA DX,MESG2
MOV AH,09H
INT 21H
MOV AH, 4CH
INT 21H
DELAY PROC NEAR ;延时单元
PUSH CX
PUSH DX
MOV DX,1500
DL5:
MOV CX,0F000H
DL10:
LOOP DL10
DEC DX
JNE DL5
POP DX
POP CX
RET
DELAY ENDP
DEAD PROC NEAR ;判断小蛇是否走到了边界上
PUSH DX
LEA DI,SNAKE
MOV CL,LEN
DEC CL
LOLP:
ADD DI,2
LOOP LOLP
MOV DX,[DI]
CMP DH,1
JE EXIT
CMP DH,24
JE EXIT
CMP DL,1
JE EXIT
CMP DL,79
JE EXIT
POP DX
RET
DEAD ENDP
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -