资源描述
老虎机模拟程序
摘要
此次课程设计要求设计一个能够模拟实现老虎机游戏程序,程序不停产生3个1到7随机数,使用三个键分别控制老虎机开启、暂停和结束,依据暂停后得到数字确定获奖信息。本程序采取汇编语言,基于8086平台实现。老虎机开启、暂停和结束分别能够使用键盘上三个不一样键R,S,ESC来控制,经过读写端口实现键值输入和显示数字输出;老虎机滚筒上随机数,经过读取端口和取得BIOS系统累加时数来实现;老虎机图形界面,兼有欢迎信息和提醒信息,经过输出字符串来显示。最终实现了能够产生随机数,而且经过键盘控制开启、暂停和退出,有友善图形界面老虎机模拟程序。
关键字:老虎机;8086;汇编语言;随机数;图形界面
1. 设计任务分析和方案选择
1.1任务分析
此次课程设计需要模拟老虎机进行摇奖,有以下多个需求:
(1)随机数。老虎机三个滚筒上出现范围为1到7随机数。随机数能够经过读取端口或获取BIOS系统累加时数获取[1]。
(2)使用三个不一样键来控制老虎机开启、暂停和结束。由R键控制老虎机开启,S键控制老虎机暂停,ESC控制老虎机退出。而且在按到其它无关键时,不影响程序运行。
(3)和获奖数字比较。老虎机一共三位数,直接依次判定比较。
(4)较为完整运行界面。经过输出,在屏幕上显示欢迎信息、使用老虎机方法、中奖号码、老虎机现在状态、随机数出现方框。
1.2方案选择
1.2.1系统硬件设计选择
老虎机三位随机数要求数据各位同时传送,符合8255可编程并行接口特点,所以选择8255芯片。8255A工作于方法0,而且使用74LS138译码器实现8255A片选电路,经过键盘输入控制信号,显示器显示老虎机界面。
1.2.2软件设计选择
老虎机需要获取三位随机数,此次使用了两种方法取得随机数,一个是经过读取端口取得随机数,另一个是利用INT 1AH, AH = 0获取BIOS系统累加时数。要经过键盘上三个不一样按键控制老虎机开启、暂停和结束,调用21号中止08h功效能够实现无回显键盘输入。确定号码是否中奖直接经过逐位比较进行判定。图形界面调用10h中止进行设置[2]。软件设计编写和调试在emu8086上完成,最终运行和改善在Masm for Windows集成试验环境共享版上完成。
2. 具体设计
2.1理论分析和计算
此次设计最关键内容就是产生随机数,利用读取端口或获取BIOS系统累加时数全部能够得到随机数,不过得到随机数范围并不是在1到7之间,所以需要将得到随机数模7后加上1,即可得到1到7之间随机数。
得到随机数以后,还需要判定它是否为一个中奖号码。经过观察能够得悉,中奖号码有两种类型,一个是三个数字完全相同,另一个是三个数字呈依次加一递增,能够使用LOOP来判定,不过因为数字极少,只有三位,所以能够直接将该随机数每一位和获奖数字每一位进行比较。
2.2算法设计
图1 关键步骤
此次设计关键部分步骤图1所表示。用户在点击R或r键以后,老虎机滚筒就开始转动,状态显示为RUNNING,而且产生3个范围在1到7之间随机数,分别依次存放在num第零、第一、第二个位置。按下S或s键,随机数停止改变,暂停,进入判定是否中奖步骤。
随机数获取,能够利用INT 1AH, AH = 0获取BIOS系统累加时数来实现,然而假如只使用这一个方法,得到三位随机数将是完全相同,所以经过查阅相关资料,最终本程序采取了两种不一样方法获取随机数,一个就是利用INT 1AH, AH = 0获取BIOS系统累加时数,另一个则是经过读取端口取得随机数。本程序中,rand1和rand2是读取端口取得随机数,因为读取端口不一样,取得随机数也不一样;rand3是获取BIOS系统累加时数获取随机数。
;读取端口取得随机数
rand1 proc near
push cx
push dx
push ax
mov ax, 0h ;间隔定时器
out 43h, al ;经过端口43h
in al, 40h ;读取端口取得随机数
in al, 40h ;随机数在al中
mov bl, 7
div bl
mov bl, ah
add bl, 1
add bl, 30h
pop ax
pop dx
pop cx
ret
rand1 endp
;获取bios系统累加时数
rand3 proc near
push cx
push dx
push ax
mov ah, 0 ; 读计数器值
int 1ah
mov ax, dx
and ah, 3 ; 更随机
mov dl, 7
div dl
mov bl, ah
add bl, 1
add bl, 30h
pop ax
pop dx
pop cx
ret
rand3 endp
两种获取随机数代码图2a和图2b所表示:
图2a 经过读取端口获取随机数 图2b 获取bios系统累加时数
图3 判定是否中奖
获取随机数程序暂停以后,需要判定得到随机数是否为中奖号码。中奖号码分为两种,一个是三个数字完全相同,另一个是三个数字依次递增1。因为中奖号码只有三位数字,所以直接使用CMP判定,不用LOOP循环。
判定中奖过程图3所表示,首先判定第一个数是否和第二个数相等,假如相等继续判定第二个数和第三个是否相等,假如不等,那么没有中奖,不然中奖。假如第一个数和第二个数不等,判定第一个数是否比第二个数小1,假如不是,则没有中奖,不然继续判定第二个数是否比第三个数小1,假如是,则中奖,若不是,则没有中奖。
在判定完成后,假如没有中奖,程序将会在屏幕上显示信息,告诉玩家没有中奖;假如中奖,依据界面上已经有中奖号码展示,屏幕上将会提醒玩家取得几等奖,在玩家选择重新开始后,屏幕上中奖信息将被会清空。
2.3软件设计
整体步骤图图4所表示:
图4 整体步骤
整个程序能够分为四个板块:
(1)界面显示。经过改变背景和字体颜色,将整个界面分为了多个部分,分别有:欢迎界面、状态显示界面、中奖号码显示、中奖情况、随机号码显示。在欢迎界面中,打印了欢迎信息和提醒信息;状态显示界面显示程序现在状态是运行中还是暂停;中奖号码显示界面告诉玩家,哪些号码是有奖号码,分别对应几等奖;中奖情况在一次摇奖结束程序暂停时出现,用来显示玩家是否中奖;随机号码界面就是老虎机滚筒,上面显示三位1到7随机数。
(2)获取随机数。因为有老虎机有三位数,范围为1到7,假如只用一个rand函数,出现随机数是完全相同,所以此次设计里三个随机数函数rand1、rand2和rand3。分别用读取端口取得随机数和获取BIOS系统累加时数取得随机数,再经过除以7得到0到6之间余数加一,取得1到7之间随机数。
(3)判定是否中奖。随机得到数字保留在num中,只有三个数字,能够不用LOOP而直接依次判定是否满足三位数相同或三位数依次加一条件,假如满足,就根据游戏设定输出中奖信息,没有中奖就输出未中奖信息。
(4)延时板块[3]。能够在程序中加入delay函数来改变滚筒中随机数出现速度,该函数是经过循环来程序运行速度减慢,调整delayax和cx大小即可调整老虎机旋转速度快慢,也能够不使用该板块。
setpos macro row, col
push ax
push bx
push dx
mov ah, 02h ;调用10中止2号子程序
mov bh, 0
mov dh, row ;设置光标所在行
mov dl, col ;设置光标所在列
int 10h
pop dx
pop bx
pop ax
endm
在程序中,数次出现需要在某个特定位置输出字符,所以需要设置光标位置,为了能够方便地设置光标位置,查阅资料后,在程序中使用了一个宏,调用第10h号中止2号子程序用来置光标位置,图5所表示。
图5 设置光标位置
这段代码中,将AX、BX、DX压入栈,在程序结尾弹出栈,是因为在宏中这三个寄存器值会发生改变,所以将它们压入栈后确保了在这段代码运行结束后,AX、BX、DX值不会被改变,不影响主程序运行。
8086CPU
74LS138
译码器
8255A芯片
显示器
键盘
2.4硬件电路设计
图6 硬件电路框图
硬件电路框图图6所表示,关键使用了五种元器件,分别是:
(1)8086处理器,工作在最小模式,控制实施每条指令。
(2)74LS138译码器,片选电路,用于取得片选信号。
(3)8255A芯片,工作在方法0,也就是基础输入输出方法,PC口连接到键盘接口,经过键盘读入控制信号;PA口和PB口连接到显示器,在显示器上进行输出显示。
(4)显示器,显示目前老虎机界面状态。
(5)键盘,键入控制信号,控制老虎机状态。
3. 系统调试和效果分析
图7 开始界面
(1)玩家刚进入程序时界面图7所表示,屏幕上显示欢迎信息,欢迎玩家并介绍该游戏名称;操作说明,帮助玩家愈加快地了解怎样操作,方便玩家使用;状态栏,显示游戏目前状态;中奖号码板块,公布有奖号码;摇号区,显示玩家目前数字,最初进入游戏时为空。
图8 运行中
(2)按下R或r键以后,老虎机开始运行,界面图8所表示,状态栏显示目前状态RUNNING,同时玩家摇奖区中三位范围为1到7随机数不停改变。
图9 未能获奖
(3)RUNNING状态下按下S或s键暂停后,老虎机进入暂停状态,状态栏显示目前状态为STOP,摇奖区三个数字暂停滚动,依据摇奖区目前静止时得到数字和上方获奖数字比较后,判定出目前数字并未获奖,屏幕上显示信息告诉玩家未获奖,图9所表示。
图10 三个数相同获奖
(4)RUNNING状态下按下S或s键暂停后,老虎机进入暂停状态,状态栏显示目前状态为STOP,摇奖区三个数字暂停滚动,依据目前静止时得到数字判定是否中奖,若三个数字相同,则根据中奖号码栏目显示次序,确定取得几等奖,并显示获奖情况,图10所表示。
图11 三个数依次加一递增获奖
(5)RUNNING状态下按下S或s键暂停后,老虎机进入暂停状态,状态栏显示目前状态为STOP,摇奖区三个数字暂停滚动,依据目前静止时得到数字判定是否中奖,若三个依次递增1,则根据中奖号码栏目显示次序,确定取得几等奖,并显示获奖情况,图11所表示。
图12 结束退出界面
(6)按下ESC后,程序图12所表示,界面上显示退出提醒语句语句,提醒玩家再按下任意键以后即可退出程序。
4. 问题处理
(1)界面设置:最开始只能使用在字符串前面补充空格方法来使字符出现在指定位置,很不便于操作,以后经过查阅资料,使用了一个宏定义,来设置光标位置,相当于C语言中能够传输参数函数,每次传输行和列两个参数,即可将字符串输出在指定位置。而且为了使界面愈加美观,需要将一些地方设置成有颜色矩形框;在输出界面时候,最开始只能一行一行输出,代码十分冗长,在查资料后了解到在一段字符串后加上0dh,0ah,就能够将字符串换行。
(2)读入字符:21号中止01H功效,是带回显键盘输入,然而在此次设计当中,输入了字符以后不需要显示出来,这么显得愈加美观,所以使用了21号中止08H功效,这是无回显键盘输入。在程序运行中,假如按下了并非’S’键其它键,程序就会一直运行,再按下’S’键也不能暂停,为了处理这个问题,调用了INT 21H0CH功效,清除输入缓冲区。
(3)在使用jz跳转时候,出现错误:jz是短跳转指令,jmp为长跳转指令,所以先jz跳转到一个较近标签处,再从这个标签jmp到需要地方。
(4)随机数:假如只经过获取BIOS相同累加时数来获取随机数,得到三位数相同,所以查阅资料了解到了另一个获取随机数方法,经过读取端口取得随机数,读取两个不一样端口取得随机数也不一样,所以三位随机数就能成功得到。
参考文件
[1] 杨永生,王立红.汇编语言程序设计[M].北京:清华大学出版社,
[2] 鲍远慧.8088/8086汇编语言中宏编制和使用[J].智能计算机和应用,(3):20-21
[3] 王义.汇编语言程序设计关键点和技巧[J].中国西部科技,(29):32-33
stack segment
dw 64 dup(0)
stack ends
data segment
title1 db ' ************************************************************', 0dh, 0ah
db ' * *', 0dh, 0ah
db ' * Simulation Of Slot Machine *', 0dh, 0ah
db ' * *', 0dh, 0ah
db ' * WELCOME TO THE GAME, AND GOOD LUCK *', 0dh, 0ah
db ' * *', 0dh, 0ah
db ' * Press "R" to start, "S" to stop, "ESC" to exit *', 0dh, 0ah
db ' * *', 0dh, 0ah
db ' ************************************************************', '$'
title2 db ' YOUR NUMBERS ', '$'
win1 db ' 777 > 666 > 555 > 444 > 333 > 222 > 111 > ', '$'
win2 db ' 567 > 456 > 345 > 234 > 123 ', '$'
endstr1 db ' Thank you ! Welcome to the next time ! ', '$'
endstr2 db ' Press any key to exit. ', '$'
sta db ' Press R to start ', '$'
running db ' R U N N I N G ', '$'
stopping db ' S T O P ', '$'
num db ' ', '$'
blank db ' ', '$'
lose db ' What a pity ! You did not get anything ! ', '$'
p777 db ' Congratulations ! You won the 1st prize ! ', '$'
p666 db ' Congratulations ! You won the 2nd prize ! ', '$'
p555 db ' Congratulations ! You won the 3rd prize ! ', '$'
p444 db ' Congratulations ! You won the 4th prize ! ', '$'
p333 db ' Congratulations ! You won the 5th prize ! ', '$'
p222 db ' Congratulations ! You won the 6th prize ! ', '$'
p111 db ' Congratulations ! You won the 7th prize ! ', '$'
p567 db ' Congratulations ! You won the 8th prize ! ', '$'
p456 db ' Congratulations ! You won the 9th prize ! ', '$'
p345 db ' Congratulations ! You won the 10th prize ! ', '$'
p234 db ' Congratulations ! You won the 11th prize ! ', '$'
p123 db ' Congratulations ! You won the 12th prize ! ', '$'
data ends
code segment
assume ds: data, cs: code, ss: stack
setpos macro row, col
push ax
push bx
push dx
mov ah, 02h
mov bh, 0
mov dh, row
mov dl, col
int 10h
pop dx
pop bx
pop ax
endm
start:
mov ax, data
mov ds, ax
mov ah, 01h
mov cx, 3000h
int 10h
;***********设置背景****************
mov ax, 0700h
mov bh, 070h
xor cx, cx
mov dx, 2090h
int 10h
mov ax, 0700h
mov bh, 000h
mov cx, 0900h
mov dx, 1890h
int 10h
;*******欢迎界面*******
lea dx, title1
mov ah, 09h
int 21h
;*********状态框************
; 状态框(running/stop)
mov ax, 0600h ; 06h功效
mov bh, 004eh ; 设置颜色
mov cx, 0a1eh ; 设置上边界和左边界
mov dx, 0c30h ; 设置下边界和右边界
int 10h
setpos 11, 30
lea dx, sta
mov ah, 09h
int 21h
;***************************
; 中奖号码显示
mov ax, 0600h
mov bh, 0006h
mov cx, 0d10h
mov dx, 113ch
int 10h
mov ax, 0600h
mov bh, 000eh
mov cx, 1210h
mov dx, 133ch
int 10h
setpos 14, 8
lea dx, win1
mov ah, 09h
int 21h
setpos 16, 8
lea dx, win2
mov ah, 09h
int 21h
;********滚筒框***********
mov ax, 0600h
mov bh, 0070h
mov cx, 1512h
mov dx, 1721h
int 10h
mov ax, 0600h
mov bh, 0070h
mov cx, 1526h
mov dx, 172ah
int 10h
mov ax, 0600h
mov bh, 0070h
mov cx, 152eh
mov dx, 1732h
int 10h
mov ax, 0600h
mov bh, 0070h
mov cx, 1536h
mov dx, 173ah
int 10h
setpos 22, 19
lea dx, title2
mov ah, 09h
int 21h
;**********开始游戏*****************
begin:
mov ah, 0ch ; 清空键盘缓冲区
int 21h
mov ah, 08h
int 21h
cmp al, 'R'
jz run
cmp al, 'r'
jz run
cmp al, 1bh
jz exit1
jmp begin
;********************************************
exit1:
jmp exit
run:
setpos 18, 8
lea dx, blank
mov ah, 09h
int 21h
setpos 11, 30
lea dx, running
mov ah, 09h
int 21h
call rand1
;call RAND
;
mov si, offset num
mov [si], bl
setpos 22, 40
mov dl, bl
mov ah, 2
int 21h
call rand2
;CALL RAND
;add bl, 1
mov si, offset num
mov [si + 1], bl
setpos 22, 48
mov dl, bl
mov ah, 2
int 21h
call rand3
;CALL RAND
;add bl, 2
mov si, offset num
mov [si + 2], bl
setpos 22, 56
mov dl, bl
mov ah, 2
int 21h
; call delay
; 控制转动速度
mov ah, 01h
int 16h
cmp al, 'S'
jz stp
cmp al, 's'
jz stp
cmp al, 1bh
jz exit1
mov ah, 0ch
int 21h
and al, 00h
jz tmp
;************************
stp:
setpos 11, 30
lea dx, stopping
mov ah, 09h
int 21h
mov si, offset num
jmp cmp1
stp2:
mov ah, 08h
int 21h
; mov ah, 01h
; int 16h
cmp al, 'R'
jz tmp
cmp al, 1bh
jz exit
jmp begin
;******
tmp:
jmp run
;************cmp*************
cmp1:
; 判定第一个数和第二个是否相等,不等转到判定是否递增
; 若相等 继续判定
mov ah, [si]
mov al, [si + 1]
cmp ah, al
jnz cmp2
mov ah, [si + 2]
cmp ah, al
jz deal1
jnz deal3
cmp2:
add ah, 1
; 第一个数+1 和 第二个数比较 不等则不中奖
cmp ah, al
jnz deal3
; 假如相等 继续判定
mov al, [si + 2]
add ah, 1
cmp ah, al
jz deal2
jnz deal3
deal1:
; 三个数相等
mov si, offset num
mov al, [si]
cmp al, '7'
jz p7
cmp al, '6'
jz p6
cmp al, '5'
jz p5
cmp al, '4'
jz p4
cmp al, '3'
jz p3
cmp al, '2'
jz p2
cmp al, '1'
jz p1
p7:
setpos 18, 8
lea dx, p777
mov ah, 09h
int 21h
jmp stp2
p6:
setpos 18, 8
lea dx, p666
mov ah, 09h
int 21h
jmp stp2
p5:
setpos 18, 8
lea dx, p555
mov ah, 09h
int 21h
jmp stp2
p4:
setpos 18, 8
lea dx, p444
mov ah, 09h
int 21h
jmp stp2
p3:
setpos 18, 8
lea dx, p333
mov ah, 09h
int 21h
jmp stp2
p2:
setpos 18, 8
lea dx, p222
mov ah, 09h
int 21h
jmp stp2
p1:
setpos 18, 8
lea dx, p111
mov ah, 09h
int 21h
jmp stp2
deal2:
; 递增
mov si, offset num
mov al, [si]
cmp al, '5'
jz p25
cmp al, '4'
jz p24
cmp al, '3'
jz p23
cmp al, '2'
jz p22
cmp al, '1'
jz p21
p25:
setpos 18, 8
lea dx, p567
mov ah, 09h
int 21h
jmp stp2
p24:
setpos 18, 8
lea dx, p456
mov ah, 09h
int 21h
jmp stp2
p23:
setpos 18, 8
lea dx, p345
mov ah, 09h
int 21h
jmp stp2
p22:
setpos 18, 8
lea dx, p234
mov ah, 09h
int 21h
jmp stp2
p21:
setpos 18, 8
lea dx, p123
mov ah, 09h
int 21h
jmp stp2
deal3:
; 没中奖
setpos 18, 8
lea dx, lose
mov ah, 09h
int 21h
jmp stp2
;***********获取随机数*****************
RAND proc near
push cx
push dx
push ax
sti
mov ah, 0
int 1ah
mov ax, dx
and ah, 3
mov dl, 7
div dl
mov bl, ah
ADD BL, 1
ADD BL, 30H
pop ax
pop dx
pop cx
ret
RAND ENDP
;----------------
rand1 proc near
push cx
push dx
push ax
mov ax, 0h ;间隔定时器
out 43h, al ;经过端口43h
in al, 40h ;读取端口取得随机数
in al, 40h ;随机数在al中
mov bl, 7
div bl
mov bl, ah
add bl, 1
add bl, 30h
pop ax
pop dx
pop cx
ret
rand1 endp
rand2 proc near
push cx
push dx
push ax
mov ax, 0h
out 43h, al
in al, 41h
in al, 41h
mov bl, 7
div bl
mov bl, ah
add bl, 1
add bl, 30h
pop ax
pop dx
pop cx
ret
rand2 endp
;利用int 1ah,ah = 0 获取bios系统累加时数
rand3 proc near
push cx
push dx
push ax
mov ah, 0
int 1ah
mov ax, dx
and ah, 3 ; 更随机
mov dl, 7
div dl
mov bl, ah
add bl, 1
add bl, 30h
pop ax
pop dx
pop cx
ret
rand3 endp
;**********************************
delay proc
push ax
push cx
mov ax, 2 ;调整这两个参数能够改变延时时间
delay1:
mov cx, 65535
delay2:
nop ;空指令,但占用一个指令时间
loop delay2
dec ax
jnz delay1
pop cx
pop ax
ret
delay endp
exit:
mov ax, 0600h
mov bh, 006eh
mov cx, 0e10h
mov dx, 123ch
int 10h
setpos 15, 8
lea dx, endstr1
mov ah, 09h
int 21h
setpos 17, 8
lea dx, endstr2
mov ah, 09h
int 21h
mov ah, 4ch
int 21h
code ends
end start
展开阅读全文