📄 block.asm
字号:
push cx
push dx
push di
;取最左上的地址,放入bx
mov ah,i
dec ah
mov al,12
mul ah
mov bx,ax
mov ah,0
mov al,j
dec al
add bx,ax
;取下面的地址放入di
mov di,bx
add di,55
cmp di,299
jc s35
mov di,299
s35:
cmp matrix[bx],byte ptr -1
jnz s36
mov matrix[bx],0
s36:
inc bx
cmp bx,di
jnz s35
pop di
pop dx
pop cx
pop bx
pop ax
ret
i_j_clear endp
i_j_paste proc near
;将临时矩阵中的内容粘贴到(i,j)上面去
push ax
push bx
push cx
push dx
push si
push di
;取最左上的地址,放入bx
;bx用做矩阵寻址
mov ah,i
dec ah
mov al,12
mul ah
mov bx,ax
mov ah,0
mov al,j
dec al
add bx,ax
;di用作temp4x4临时矩阵的寻址
mov di,0
;用ah,al,ch,cl来控制双重循环
;使用直到型循环
mov ah,i
mov al,j
mov ch,ah
mov cl,al
add ch,4
add cl,4
cmp ch,26
jc s37
mov ch,26
s37:
cmp cl,12
jc s38
mov cl,12
s38:
mov al,j
mov dx,0
s39:
;*******************
cmp matrix[bx],byte ptr -1
jnz s40
mov matrix[bx],0
s40:
cmp temp4x4[di],byte ptr 9
jnz s41
mov matrix[bx],-1
s41:
;*******************
inc dx
inc bx
inc di
inc al
cmp al,cl
jnz s39
add bx,12
sub bx,dx
add di,4;修补di可能在右边界出现的bug
sub di,dx
inc ah
cmp ah,ch
jnz s38
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
i_j_paste endp
getmode proc near
;将模型内的图形取到临时矩阵里面去
;要取的模型编号为pasteid
;pasteid的编号为:0,1,2,3...
push ax
push bx
push cx
push dx
push si
push di
;取模型号码
mov cl,pasteid
;计算模型第一个元素的偏移地址,用bx保存
mov al,16
mul cl
mov bx,ax
;用di在temp4x4中寻地址
mov di,0
;开始复制
mov cx,16
s42:
mov ah,mode[bx]
mov temp4x4[di],ah
inc bx
inc di
loop s42
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
getmode endp
i_jchkclash proc near
;将临时矩阵temp4x4与matrix i,j位置比较
;1为有冲突,0为没有冲突
;将比较结果写入变量chkclash
;s43-s48
;我操,被这个函数整死了
push ax
push bx
push cx
push dx
push si
push di
;先设置为不冲突
mov chkclash,0
;寻找matrix第一格元素的偏移地址, 放入bx
mov ah,i
dec ah
mov al,12
mul ah
mov bx,ax
mov al,j
dec al
mov ah,0
add bx,ax
;寻找辅助矩阵的第一格元素的偏移地址,放入si
mov si,0
;开始循环
mov ch,4
s44:mov cl,4
s43:
;*******
cmp temp4x4[si], byte ptr 9
jnz s46
cmp bx,311
jnc s45
cmp matrix[bx],byte ptr 1
jz s45
cmp matrix[bx],byte ptr 2
jz s45
jmp s46
s45:
;冲突
mov chkclash,1
jmp s47
s46:
;*******
inc si
inc bx
dec cl
jnz s43
add bx,8
dec ch
jnz s44
s47:
;结束
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
i_jchkclash endp
i_j_change proc near
;让正在下落的模型变形
push ax
push bx
push cx
push dx
;取得当前模型号码
mov al,mdnow
;取变形目标的模型号码
mov ah,0
mov bx,ax
mov al,mdchange[bx]
;取模型数据
mov pasteid,al
call getmode
;判断冲突
call i_jchkclash
;如果不冲突,[清掉当前的-1??],将新模型写入,重新设置now的编号
cmp chkclash,byte ptr 1
jz s49
call i_j_paste
mov mdnow,al
s49:
pop dx
pop cx
pop bx
pop ax
ret
i_j_change endp
new_block proc near
;产生新模型并且判断游戏是否结束
push ax
push bx
push cx
push dx
;取得生成位置
mov ch,borni
mov cl,bornj
mov i,ch
mov j,cl
;取得模型号码
mov al,mdnow
;取模型数据
mov pasteid,al
call getmode
;判断是否冲突
call i_jchkclash
cmp chkclash,byte ptr 1
jnz s50
;冲突设置游戏结束标记
mov gameover,1
s50:
call i_j_paste
pop dx
pop cx
pop bx
pop ax
ret
new_block endp
clear_floor proc near
;这个函数实现得太垃圾了
;显示区域[72, 299]
;处理一轮下落之后可能的消层zhi
push ax
push bx
push cx
push dx
push si
push di
;第一轮扫描,做标记,做统计
;用2标记
;用dl统计
mov dl, 0;统计待clear的层数
mov si, 299
mov bx, 299
s61:
;统计一行
mov dh,0;
mov cx,12
mov di,si
s62:
add dh,matrix[si]
dec si
loop s62
cmp dh,4
jz s64break
cmp dh,14
jnz s63
;********************
;累计消层数量
;在待消层做标记
inc dl
dec di
mov matrix[di],2
;********************
s63:
cmp si,71
jnz s61
s64break:
cmp dl,0
jz s72exit
;***********************************
;消层数量统计在dl里面
;如果想累计得分功能,可以在附近此添加
;***********************************
;第2轮扫描,处理消层
;用si寻找
;用bx更新
mov si,299
mov bx,299
s65:
;*********一行一行的扫描
;空行则跳过
cmp matrix[si-1], byte ptr 2
jnz s66
sub si,12
jmp s68
s66:
;非空行
;这里效率很差,改过让跳转,不过有错,算了不改了
;之前有比较si和bx,若相等跳到s68,不过会死循环,不知道原因
mov cx,12
s67:
mov dh,matrix[si]
mov matrix[bx],dh
dec si
dec bx
loop s67
s68:
;***********************
s69:
cmp si,71
jnz s65
;将BX扫描到底
s70:
cmp matrix[bx],2
jz s71
mov matrix[bx],0
s71:
dec bx
cmp bx,71
jnz s70
s72exit:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
clear_floor endp
set_next proc near
;该函数的功能,用mdnext替换mdnow,并且根据
;之前配置的概率信息得到一个新的mdnext
;采用线性同余法生成伪随机数
;线性同余,return :(101 * x + 37) mode 149,这几个参数已经经过了测试
;概率算法,见设计文档
push ax
push bx
push cx
push dx
push si
push di
;设置当前
mov ah,mdnext
mov mdnow,ah
;然后准备去产生下一个
;读取权值和,放到mdnext里面
mov si,0
mov bh,0
mov cx,0
mov cl,mdcount
s73:
add bh,mdchance[si]
inc si
loop s73
mov mdnext,bh
;初始化随机数据种子,dl做种子
MOV AH,2CH
INT 21H
;计算随机数字,线性同余
mov al,101
mul dl
add ax,37
mov dl,149
div dl
mov al,ah
mov ah,0
div mdnext
mov al,ah
mov ah,0
;al为0~权值和减1之间的随机数
;下面来根据随机al和权值情况选节点
;算法见设计文档
;使用ah来累计权值
mov ah,0
mov bx,-1
s74:
inc bx
add ah,mdchance[bx]
cmp mdchance[bx],0
jz s74
cmp al,ah
jc s75
jmp s74
s75:
;得到模型,写入mdnext
mov mdnext,bl
;然后将该模型贴入右上角区域
mov pasteid,bl
mov ch,i
mov cl,j
mov i,2
mov j,8
call getmode
call i_j_paste
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
set_next endp
judgedn proc near
;下落触发器
push ax
push bx
push cx
push dx
;取间隔放入bx里面
mov al,mulnum
mul basicwait
mov bx,ax
;读取现在的秒和百分秒
MOV AH,2CH
INT 21H
;秒的差距放
sub dh,sec
jns s77
add dh,60
s77:
mov al,100
mul dh
mov dh,0
add ax,dx
mov dl,persec
mov dh,0
sub ax,dx
;比较百分秒差距和间隔
cmp ax,bx
jc s78else
;触发下落的情况
mov trigger,1
MOV AH,2CH
INT 21H
mov sec,dh
mov persec,dl
jmp s79exit
s78else:
;非触发下落的情况
mov trigger,0
s79exit:
pop dx
pop cx
pop bx
pop ax
ret
judgedn endp
mainloop proc near
;主游戏循环
;由于跳转的长度有限制
;没办法把结束的代码放到前面来
;以后再改
push ax
push bx
push cx
push dx
s91:
call set_next
call new_block
mov turnover,0
call scan_board
cmp gameover, byte ptr 1
jnz s92
pop dx
pop cx
pop bx
pop ax
ret
s92:
;如果有合法按键,处理变形或移动
mov ah,1
int 16h
jz s93
mov ah,0
int 16h
mov ah,al
cmp al,dnkey
jnz s92_1
mov ah,'d'
mov movsign,ah
call block_move
call scan_board
jmp s93
s92_1:
cmp al,rtkey
jnz s92_2
mov ah,'r'
mov movsign,ah
call block_move
call scan_board
jmp s93
s92_2:
cmp al,ltkey
jnz s92_3
mov ah,'l'
mov movsign,ah
call block_move
call scan_board
jmp s93
s92_3:
cmp al,cgkey
jnz s92_4
call i_j_change
call scan_board
jmp s93
s92_4:
s93:
cmp turnover,1
jz s94
;添加处理触发下落的模块,添到什么地方呢
call judgedn
cmp trigger,1
jnz s94
;触发下落
mov ah,'d'
mov movsign,ah
call block_move
call scan_board
s94:
cmp turnover,1
jnz s92
call clear_floor
jmp s91
mainloop endp
code ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -