📄 game.asm
字号:
;right------统计正确的次数
;total------统计下落字母的总数
;time-------有效游戏时间
;主程序开始时记录当前时刻的hour,minute,second,后来用于记录实际所用时间
date segment
table db 'qpalzmxnskwieudjcnvbfhrytqscgyjmkopzoxicvubhnymtgrfjrekqdfghyuiopmbeswzaqwqpbncxmalalpnqcxz'
hour db 0 ;要初始化
minute db 0
second db 0
right db 0
total db 0
date ends
stack segment stack
db 400 dup(0)
stack ends
code segment
assume ds:date,ss:stack,cs:code
start:
mov ax,data
mov ds,ax
call mpc
call spc
call enter
call down
;显示游戏开始界面的子程序
;入口参数---------------------空
;出口参数---------------------产生游戏开始界面
mpc proc far
mov ah,0
mov al,3
int 10h
mov ah,15
int 10h
mov dx,0000h
mov ah,2
int 10h
mov al,08h
mov bh,0
mov cx,80 ;显示上眉
mov ah,0ah
int 10h
mov cx,1
mov dx,0100h ;显示左披
left: mov ah,2
int 10h
mov al,08h
mov ah,0ah
int 10h
inc dh
cmp dh,24
jb left
mov dl,79 ;显示右披
right: mov ah,2
int 10h
mov al,08h
mov ah,0ah
int 10h
dec dh
ja right
mov dx,1701h
mov ah,2
int 10h
mov al,01h
mov cx,78
mov ah,0ah
int 10h
mov dx,1800h
mov ah,2
int 10h
mov al,08h
mov cx,80 ;显示下眉
mov ah,0ah
int 10h
ret
mpc endp
; 显示游戏界面上方字母的子程序
topword proc far
lea si,table
mov cx,1
mov dx,0101h ;预制光标位置
con: mov ah,2
int 10h
mov ah,0ah
mov al,table[si]
int 10h
inc si
inc dl
cmp dl,79
jb con ;显示的字母不足78个转
ret
topword endp
;游戏界面子程序和游戏子程序间的等待ENTER输入的子程序
enter proc far ptr
push ax
push cx
push dx
again: mov ah,8
int 21h
cmp al,0ah ;有输入时比较输入是否为enter键
jmp out2
cmp al,0dh
jne again
out2: mov ah,2ch ;为enter键则读取游戏开始时刻
int 21h
mov hour,ch
mov second,cl
mov minute,dh
pop dx
pop cx
pop ax
ret
enter endp
;建立一个随机数发生程序,用于控制字母下降的位置的随机变化
;出口参数------------bl,存放一个小于79大于0的随机数
random proc far
push ax
push cx
push dx
mov ah,2ch
int 21h
cmp dl,79
ja above
mov bl,dl
jmp ok
above: mov bl,dh
ok: pop dx
pop cx
pop ax
ret
random endp
; 游戏界面上方字母随机下落的子程序
;入口参数--------------主程序中的字母表table
;出口参数--------------键盘的输入值ax
down proc far
push cx
push dx
push ax
push si
INC TOTAL ;下降的字符个数的计数器增一
MOV CX,1
MOV DH,1
call far ptr random
MOV DL,BL ;bl为random产生的随机数
REPTDO:
MOV AH,2
INT 10H ; set cursor position
MOV SI,BL
MOV AL,TABLE[SI]
MOV AH,10
INT 10H ; display spade
CALL DELAY
MOV AL,0
MOV AH,10
INT 10H
MOV AH,1 ;判断键盘是否有输入
INT 16H
JZ COND ;无输入时转字符继续下落
CALL FAR PTR SPEKEY ;有输入时转特殊键处理
COND: INC DH
CMP DH,24
JNE REPTDO
MOV DH,1
MOV DL,BL
MOV AH,2
INT 10H ;recover the top character
MOV SI,BL
MOV AL,TABLE[SI]
MOV AH,10
INT 10H
pop si
pop ax
pop dx
pop cx
ret
DOWN ENDP
DELAY PROC FAR
PUSH CX
PUSH DX
MOV DX,32
DL1:
MOV CX,0FFFFH
DL2:
LOOP DL2
DEC DX
JNZ DL
POP DX
POP CX
RET
DELAY ENDP
;判断输入是否ESC、ENTER、TAB等特殊键,若是则进行处理否则转comkey子程序进行处理
;入口参数------------键盘输入的值ax
;出口参数------------对特殊键处理完毕,非特殊键给后面的comkey子程序处理
spekey proc far
cmp al,'Q'
jz exit ;为'Q'键则结束游戏
cmp ah,01h
jnz concmp
call far ptr time
JMP START ;为ESC键跳转到主程序头,调出主界面
concmp: cmp al,20h
jz istap
call far ptr comkey ;非特殊键转一般键处理
jmp gback
istap: call far ptr time ;为TAB键则暂停计时
call far ptr tab
gback: ret
exit: mov ah,4ch
int 21h
spekey endp
;统计游戏有效时间的子程序
;入口参数:主程序记录上一当前时刻的hour,minute,second
;出口参数:子程序统计实际所用时间的zhour,zminute,zsecond
;注意每次重新启动计时功能前需将hour,minute,second即时化
tdata segment
zhour db 0
zminte db 0
zsecond db 0
tdata ends
tstack segment stack
db 100 dup(0)
tstack ends
tcode segment
assume ds:tdata,ss:tstack,cs:tcode
time proc far
push ax
push bx
push cx
push dx
mov ah,2ch ;读取当前时刻
int 21h
mov ah,ch ;存储当前时刻
mov al,cl
mov bh,dh
cmp dh,second
jns setsec
dec cl
add dh,60
setsec: sub dh,second ;设置秒数
add zsecond,dh
cmp zsecond,60
jb dealmin
sub zsecond,60
inc zminute
dealmin:cmp cl,minute
jns setmin
del ch
add cl,60
setmiu: sub cl,minute ;设置分钟数
add zminute,cl
cmp zminute,60
jb dealhou
sub zminute,60
inc zhour
dealhou:cmp ch,hour
jnb sethou
add ch,24
sethou: sub ch,hour ;设置小时数
add zhour,ch
mov hour, ah
mov minute,al
mov second,dh
pop dx
pop cx
pop bx
pop ax
ret
time endp
tcode ends
;实现按下tab键游戏暂停,并统计前段所用时间,再按下tab键游戏继续的子程序
;入口参数:-------------输入的tab键
tap proc far ptr
push ax
push cx
push dx
wait3: mov ah,2
int 16h
jz wait3 ;键盘没有输入时等待
cmp al,20h ;有输入时比较输入是否为空格
jne wait3
mov ah,2ch ;为空格则读取当前时刻
int 21h
mov hour,ch ;重置当前时刻
mov second,cl
mov minute,dh
pop dx
pop cx
pop ax
ret
tab endp
;将键盘输入值与当前正在下落的字母比较,若击中转redown;否则无操作返回,让字母继续下降
;人口:-------------------当前下落的字母序号放在bl中
;入口:-------------------键盘输入的字母放在ax中
comkey proc far ptr
push si
push cx
mov si,bl
mov cl,table[si]
cmp al,cl ;有输入时比较输入是否和当前下落字母一致
jne back
inc right
call far ptr redown ;击中则调用另一字母下落子程序
back: ret
comkey endp
;击中后,修复顶部字母下落后的空缺,中止当前字母的下落,然后让另一字母开始下落
;人口:-------------------当前下落的字母序号放在bl中
;出口:-------------------另一字母开始下落
redown proc far ptr
MOV DH,1
MOV DL,BL
MOV AH,2
INT 10H ;recover the top character
MOV SI,BL
MOV AL,TABLE[SI]
MOV AH,10
INT 10H
call far ptr down
ret
redown endp
;函数功能:将某一数按十进制输出
;入口参数: ax---存贮一数字
;出口参数: 转换后的数字在显示器上输出
;所用寄存器:bx----地址逆计数器
data2 segment
numchar db 6 dup(0)
cout equ $-numchar
pot2 db ?
data2 ends
stack2 segment stack
db 100 dup(0)
stack2 ends
pro2 segment
assume cs:pro2,ds:data2,ss:stack2
num_char proc far
push si
push di
push ds
push cx
push dx
mov cx, data2 ;将numchar与数据段联系起来
mov ds,cx
mov bx,cout ;地址逆计数器
dec bx
lea si,numchar
mov ch,'$'
mov [bx+si],ch
mov pot2,0h ;预置pot2=0代表ax为正
mov cx,10
mov dx,0 ;ax扩展待用
cmp ax,0 ;判断待输出的数字正负性
jns pov ;ax为正转
mov pot2,'-'
neg ax ;将负数转换成对应相反数
pov: idiv cx
add dl,30h
dec bx
mov [bx+si],dl
cmp ax,0
jne not_end
jmp exit2
not_end:mov dx,0
jmp pov
exit2: dec bx
mov al,pot2
mov [bx+si],al
mov dx,bx
mov ah,9
int 21h
pop dx
pop cx
pop ds
pop di
pop si
ret
pro2 ends
num_char endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -