模拟老虎机汇编程序课程设计报告+代码.docx

上传人:b****6 文档编号:3382725 上传时间:2022-11-22 格式:DOCX 页数:22 大小:77.23KB
下载 相关 举报
模拟老虎机汇编程序课程设计报告+代码.docx_第1页
第1页 / 共22页
模拟老虎机汇编程序课程设计报告+代码.docx_第2页
第2页 / 共22页
模拟老虎机汇编程序课程设计报告+代码.docx_第3页
第3页 / 共22页
模拟老虎机汇编程序课程设计报告+代码.docx_第4页
第4页 / 共22页
模拟老虎机汇编程序课程设计报告+代码.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

模拟老虎机汇编程序课程设计报告+代码.docx

《模拟老虎机汇编程序课程设计报告+代码.docx》由会员分享,可在线阅读,更多相关《模拟老虎机汇编程序课程设计报告+代码.docx(22页珍藏版)》请在冰豆网上搜索。

模拟老虎机汇编程序课程设计报告+代码.docx

模拟老虎机汇编程序课程设计报告+代码

微机原理课程设计报告

模拟实现老虎机游戏

__

__

__

一.设计任务及要求

1.任务:

模拟实现老虎机游戏。

2.要求:

老虎机的游戏规则规定如下:

Ø每个滚筒上有7个数字1~7,三个滚筒在启动老虎机后开始旋转,经过一段时间后滚筒静止,根据静止时的数字确定输赢。

Ø大小比较为:

3个7>3个6>……>3个1>567>456>345>234>123,赔率情况可以由自己确定。

Ø通过按某键模拟老虎机的启动、旋转。

Ø通过按某键可停止老虎机旋转。

Ø通过按某键可正常退出模拟程序。

Ø有较完整的程序运行界面。

二.题目分析

该题目主要是实现模拟老虎机的效果,这个题目对我来说是一个有趣的题目,可以在游戏中的去完成任务,让我有更多的动力去做这个事情。

首先,虽然要求中对老虎机玩法有简单的介绍,但为了更好的完成任务,我需要查找资料去了解老虎机更多的信息,根据题目要求,我首先需要打印一些欢迎信息和提示信息,布置友好的界面,当用户按下"R"键时,老虎机滚筒开始旋转,直到按下"S"时滚筒停止,然后判断滚筒停止后的三个数字来决定玩家的奖金,根据大小,三个7,三个6……,123的奖金分别为12倍,11倍……1倍,然后打印获奖信息。

用户可以重复按下"R"和"S"来进行娱乐,直到按下"E"之后,游戏退出。

三.设计思路

为了实现要求的功能,本设计可以用模块化设计,产生随机数程序和延时程序可以作为一个函数来实现,像有些功能需要传递参数的,我可以用宏来实现,比如说设置光标位置,设置字符颜色等,用这些模块来设计可以减少代码量,同时也使程序变得简单,可读性大大增强。

我的思路是这样的,程序首先输出玩法的信息,告诉玩家应该按哪些键进行操作。

然后等待玩家的输入,当玩家按下开始玩的键后,老虎机滚筒开始旋转,旋转过程的实际上就是产生三个随机数,并存放在定义了三个字符的NUM中,旋转的速度通过延时子程序来决定,通过设置延时子程序中的参数来决定延时的长久,然后隔一些时间,玩家按下停止键后,滚筒静止,比较NUM和有奖金的数字,如果玩家中奖,打印恭喜玩家的语句并显示赢的数量,否则告诉玩家失败。

四.方案设计

1.程序主框架

 

图1.程序主框架

如图1所示,这个框架主要是实现了设计思路的构造,程序刚开始需要清屏,因为masm5运行之前屏幕中有其它的字符,所以首先要清除这些不必要的字符,以免影响界面的美观性。

清屏之后首先打印欢迎信息和操作方法,此时,一切就绪,等待玩家的输入,根据玩家的按键进行操作,操作流程在设计思路中已讲述,此处不再介绍

2.滚筒工作流程

 

图2.滚筒工作流程

滚筒工作流程如图2所示,程序是在用户按"R"键后进入的,开始的时候,清除上次玩家运行的结果,比如清除上次玩家的中奖信息,然后产生第一个随机数,显示在三个滚筒位置的最左边,同时存放在NUM的第一个字符位置,在数段中,定义了:

NUMDB''

NUM包括三个空格字符,存放第一个位置的时候只要进行如下操作:

MOVSI,OFFSETNUM

MOV[SI],BL

其中BL为随机数产生函数产生随机数存放的位置,当取第二个随机数的时候,只需要在操作第一随机数的基础上对SI加1即可,同理,当取第三个随机数的时候,只需要在操作第一随机数的基础上对SI加2即可,这样,三个随机数就以字符串的形式存放在NUM中。

取完三个随机数后,如果玩家没有按下了"S"键则从取第一个随机数开始重新运行。

否则,就开始进行比较,在数据段定义了:

TABLEDB'777666555444333222111567456345234123'

只要从TABLE中不断取出"777","666"……等字符串与NUM比较即可知道NUM中的字符是否为了中奖的字符,比较程序的流程如图3所示:

 

图3.比较程序的流程图

在程序的一开始将BL置为11,BL是用来移动SI指向TABLE的位置,CX=3表示比较三个字符,然后将TABLE的偏移地址加上44赋给SI,加为44是为了从TABLE最右边的三个字符〔123开始比较,NUM的偏移地址赋给DI,再将[SI]赋给AH,[DI]赋给AL,如果AH等于AL,说明NUM与TABLE中某个中奖子字符串的三个字符中的某同一位置字符一样,那么就比较三个字符中的下一个字符,直到CX=0时,三个字符都比较完,如果三个字符都相等,说明滚筒的三个数字是中奖数字,只要三个字符中有一个不相等,那么就要取TABLE中下一个中奖的子字符串进行比较,获取TABLE中下个中奖字符串的方法就是先将BL自减1,判断BL的值,当BL=0时,说明NUM与TABLE中存放的中奖字符串没有匹配的,也就是玩家没有中奖。

如果BL不等于0,那么在TABLE偏移地址的基础上加上BL*4,因为每个获奖字符串为三个字符,再加上一个空格字符一共四个字符,所以加上BL*4也就指的是下一个中奖字符串的第一个字符的偏移地址。

根据BL的值可以判定NUM与TABLE中哪个中奖的字符串一样,由此决定玩家的奖金。

五.软件设计

1.程序中使用的DOS和BIOS功能

INT10H功能

AH

功能

调用参数

00

设定显示模式

AL=03<80*25分辨率>

02

置光标位置

BH=页号DH=行DL=列

09

设置字符属性

BL=属性CX=字符重复次数

表1.INT10H功能表

INT16H功能

AH

功能

调用参数

返回参数

01

读取缓冲区字符

AL=读取的字符

表2.INT16H功能表

INT21H功能

AH

功能

调用参数

返回参数

08

键盘输入

AL=输入字符

09

显示字符串

DX=串地址

0C

清除输入缓冲区

4C

带返回码结束

AL=返回码

表1.INT21H功能表

2.光标位置设置程序

为了使界面美观,在特定位置输出字符非常重要,为了在程序可以简单的设置光标位置,在程序中设置了一个宏,宏的程序如下:

CURPOSMACROROW,COM;ROW表示行,COM表示列

PUSHAX

PUSHBX

PUSHDX

MOVAH,2;表示调用第10H号中断的2号子程序,用来置光标位置

MOVBH,0;表示第0页

MOVDH,ROW;光标的行

MOVDL,COM;光标的列

INT10H;第10H号中断功能

POPDX

POPBX

POPAX

ENDM

程序中首先将AX,BX,DX压入栈,然后在程序的结尾弹出栈,因为在宏中改变了这三个寄存器的值,这样保证了程序在这个宏运行完之后,不影响AX,BX,DX的值,否则会影响程序的正确运行。

将这三个寄存器压入栈之后,开始设置IN10H的02号子程序的参数,每个参数在程序在有注释。

在以后的程序中如果要设置光标位置,只要调用CURPOSx,y即可改变光标位置,能在一定程度上使程序简洁明了。

整个程序中一共设置了四个宏:

SETCOLOR用来设置字符颜色的,CURPOS用来设置光标位置,PRINT用来打印单个字符,PRINTRESULT用来打印获奖结果,前三个宏的原理相似,PRINTRESULTx,是用来比较x的值来打印不同的获将结果.

3.清除某行字符程序

界面在设置时,不同的行的功能是不一样的,以第11行为例,第11行是用来显示获奖结果,那么如果重新开始游戏后,前一次的获奖结果应当被清除,但不能用清屏的方式来解决问题,我的想法是这样的,在DATA段定义了一空字符串:

CLEARWINDB'','$'

然后在程序中实现如下:

CURPOS11,0;第11行用来显示获将情况

LEADX,CLEARWIN;将第11行清空,CLEARWIN为一长串空格字符串

MOVAH,09H;调用第21H中断9号功能,打印字符串

INT21H

先调用CURPOS这个宏来设置光标的位置,从第11行的第1个字符开始打印这个空字符串,那么这行之前的字符就被空字符覆盖,以达到清除这一行字符的效果。

4.设置滚筒数字

CURPOS9,33;滚筒第一个数字的位置

SETCOLOR1,84H;84H表示红色用高亮

CALLRAND;获取一个随机数

PRINTBL;打倒该随机数

MOVSI,OFFSETNUM;将随机数放在NUM中的第1个位置

MOV[SI],BL

程序首先调用CURPOS来设置数字要显示的位置,在本程序中,三个滚筒的位置<行,列>为:

<9,33>、<9,35>、<9,37>,然后设置该字符的颜色,因为只有一个字符,SETCOLOR中的字符数量参数为1,再调用RAND这个函数产生一随机数,该函数将产生的随机数存放在BL中,那么在调用这个随机函数后,直接调用PRINT这个宏打印BL即可,最后取NUM字符串的偏移地址放在SI中,将BL存放在[SI]中。

在打印第二和第三个滚筒数字的时候与第一个数字基本一样,不同的是实现第二个滚筒数字需要:

INCSI;将随机数放在NUM中的第2个位置

第三个滚筒数字需要:

ADDSI,2;将随机数放在NUM中的第3个位置

这样可以将三个数字存放在NUM这个字符串中,方便以后比较判定是否中奖。

5.中奖与否判定程序

COMPARE:

MOVBL,11;用来比较NUM和TABLE各项的值,BL用来移动TABLE的字符的位置

MOVCX,3;每次只比较三个字符

MOVSI,OFFSETTABLE;将TABLE的偏移地址存入在SI中

ADDSI,44;从TABLE中最右边的三个字符开始比较

MOVDI,OFFSETNUM;将NUM的偏移地址存放在DI中

NUMP:

MOVAH,[SI];将[SI]存放在AH中,SI存放的是地址,[SI]则表示该地址的字符

MOVAL,[DI];将[DI]存放在AL中

CMPAH,AL;比较两个字符

JNZJ1;如果不相等,则取TABLE的另三个字符进行比较

INCSI;取下一个字符地址

INCDI;取下一个字符地址

LOOPNUMP;循环比较,当CX=0时会停止比较,

CMPCX,0

JZJ2

J1:

CMPBL,0

JZLOST

DECBL;BL自减1,表示从TABLE中向左另取三个字符

MOVCX,3;重新将CX置为3,表示比较三个字符,

MOVAL,4;因为TABLE第个字符项为4个字符

MULBL;AL*BL代表要移动的量

MOVAH,0

MOVSI,OFFSETTABLE

ADDSI,AX

MOVDI,OFFSETNUM

JMPNUMP

这段代码是本次设计的核心程序,在程序流程图中有了详细的介绍,这段代码也是根据比较程序的流程图来实现的,程序中的J2是用来打印中奖信息的程序标号,LOST是用来打印未中奖的程序标号。

6.随机数产生函数程序

RANDPROCNEAR

PUSHCX

PUSHDX

PUSHAX

MOVAX,7MOVDX,41H;用端口41H

OUTDX,AX;产生从1到AX之间的随机数了

INAL,DX;产生的随机数AL

MOVBL,AL

ADDBL,30H

POPAX

POPDX

POPCX

RET

RANDENDP

这个方法来自网络,可以方便的产生随机数。

程序像宏一样,还是先将在程序中会改变的寄存器压入栈,然后在结尾弹出栈,保证寄存器在程序运行完之后值不变。

端口41H为8253可编程定时/计时器的第2个计数器通道,第2个计数器使用的是8253的方式二,方式二计数的特点是,计数器从初值开始进行减1操作,直到减到0,然后重新载入初值进行重复操作,当设置了新初值后,并不会影响当前的计数,从下次计数开始才使用新的初值。

有了这样的特点,那么我们可以在41H端口写入初值7,初值7写完之后,计数器不会产即从7开始进行减1操作,只有当前计数完成之后才会有效,这样避免了写初值到读计数器的间隔太短而导致随机数效果不良好,因为用INAL,41H读取计数器中的值时,这个值会因程序的执行时间不同而有变化,而程序执行时间不是一个固定的值,所以计数器的值也是随机的,执行时间越长随机性越强,由此便产生了随机数。

六.调试问题

在编程程序的时候,我也遇到过很多问题,这些问题都是通过查找书籍资料或者网上搜索来解决的,主要遇到的问题如下:

1.输出字符串时发现有乱码

原来字符串没有结束标志’$’,在DATA段定义字符串的时候,在最后面加一个’$’即可。

2.使用JZ跳转的时候出现:

jumpoutofrangebyxxxbytes错误

根据字面意思应该是跳转超出范围,通过查找资料发现JZ是短跳转指令,而JUMP是长跳转指令,那么解决办法可以是先在JZ附近设置一标号JTEMP,JZ可以先跳到JTEMP,然后从JTEMP中利用JUMP指令跳到JZ需要跳到的地方,如此便解决了问题

3.在滚筒旋转的过程中,输入"S",调用第16H中断的1号功能,读取输入缓冲区的字符后,滚筒停止转动,等待玩家开始下一次游戏,但是字符"S"仍然影响这个等待过程中的输入,会提示用户输入错误,因为在等待游戏开始的时候只有"R"和"E"是有效的,其它的都是错误输入。

出现这样的错误,最初怀疑是"S"仍然在缓冲区中,我想查找资料看有没有可以清除输入缓冲区的办法,发现调用第21H中断的0C号功能,可以用来清空输入缓冲区,后来调用该DOS功能即可解决问题。

七.运行效果

1.程序进入时运行效果

程序刚进入时,清空屏幕,显示一些欢迎信息和操作方法,字符均为白色,等待玩家输入。

2.按错键运行效果

在等待玩家输入的时候,如果输入除"R"和"E"之外的键都算是输入错误,提示玩家输入错误,请重新输入。

3.滚筒工作运行效果

三个滚筒的数字不断的变化,同时状态用绿色符"RUNNING"来表示。

4.未能得奖效果

当滚筒的三个数字不属于中奖的数字时,用红色字体告诉玩家未能中奖信息。

5.得奖运行效果

为了测试这个效果,在产生随机数的函数中,将存放随机数的BL直接赋7,以模拟最高奖的情况,一共有12个中奖的情况,三个7是最高的,所以得到12倍的奖金,同时以绿色来显示中奖信息。

6.退出的运行效果

玩家按"E"退出时,友好的告诉玩家已经退出,并欢迎下次光临。

八.总结

此次课程设计花费了我很多的精力和时间,我需要学习很多的新知识,由于课堂时间有限,很多东西老师是不可能讲到的,比如老师不可能在课堂上讲完所用BIOS和DOS功能的调用,为了使做出的效果更好,只有靠自己去查找资料来解决,这些努力给我带来了许多的提升,只有在实践中才能更加理解各种指令的用法,巩固了我的理论知识,同时极大的提高了我的学习兴趣,尤其是在程序可以正确运行的时候,那种成就感让我更加有信心学习汇编语言,同时我发现,一种良好的软件设计思维对任务效果的好坏有着很大的影响,所有不管用什么计算机语言去实现同一功能,但这种思维不会变化,在今后的学习过程中多多培养这种思维。

然而,学无止境,虽然对这次设计总体上感觉上还可以,但是我知道未来的学习将会更加有深度和难度,这次仅仅是开始,未来的挑战只有勇敢的去迎接。

附:

程序清单:

DATASEGMENT

HEADMSG1DB'*******************SLOTMACHINE*******************','$'

HEADMSG2DB'HELLO,WELCOMETOYOU,GOODLUCK!

','$'

HEADMSG3DB'PLEASEPRESS"R"TORUN,"S"TOSTOP,"E"TOEXIT','$'

HEADMSG4DB'*****************************************************','$'

CLEARWINDB'','$'

RESULTDB'RESULT:

','$'

RUNNINGDB'RUNNING','$'

STOPINGDB'STOPING','$'

EXITSTRDB'YOUHAVEEXITTED,WELCOMENEXTTIME!

','$'

LOSTSTRDB'YOUGETNONE,COMEON!

','$'

INPUTERRORDB'INPUTERROR,INPUTAGAINPLEASE!

','$'

TABLEDB'777666555444333222111567456345234123','$'

WIN1DB'01TIMES','$'

WIN2DB'02TIMES','$'

WIN3DB'03TIMES','$'

WIN4DB'04TIMES','$'

WIN5DB'05TIMES','$'

WIN6DB'06TIMES','$'

WIN7DB'07TIMES','$'

WIN8DB'08TIMES','$'

WIN9DB'09TIMES','$'

WIN10DB'10TIMES','$'

WIN11DB'11TIMES','$'

WIN12DB'12TIMES','$'

NUMDB''

WINDB'CONGRATULATION,YOUWIN:

','$'

DATAENDS

STACKSEGMENTSTACK

DB64DUP

>

STACKENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA,SS:

STACK

SETCOLORMACRONUM,COLOR;设置字体颜色,NUM:

设置的字数,COLOR:

要设置的颜色

PUSHAX

PUSHBX

PUSHCX

MOVCX,NUM;将字数存放在CX中

MOVBL,COLOR;颜色存放在BL中

MOVAH,09H;调用第10H中断的9号功能,设置在光标位置显示字符及其属性

INT10H

POPCX

POPBX

POPAX

ENDM

CURPOSMACROROW,COM;ROW表示行,COM表示列

PUSHAX

PUSHBX

PUSHDX

MOVAH,2;表示调用第10H号中断的2号子程序,用来置光标位置

MOVBH,0;表示第0页

MOVDH,ROW;光标的行

MOVDL,COM;光标的列

INT10H;第10H号中断功能

POPDX

POPBX

POPAX

ENDM

PRINTMACROC;宏定义定义之后要显示的数字,输出字符

PUSHAX

PUSHDX

MOVDL,C;显示M这个字符,

MOVAH,02H;DL=输出字符

INT21H

POPDX

POPAX

ENDM

PRINTRESULTMACROC;输出获将情况

PUSHAX

PUSHDX

CURPOS11,0;第11行用来显示获将情况

LEADX,CLEARWIN;将第11行清空,CLEARWIN为一长串空格字符串

MOVAH,09H;调用第21H中断9号功能,打印字符串

INT21H

CURPOS11,22

SETCOLOR31,0AH

MOVAH,09H

MOVDX,OFFSETWIN

INT21H

CASE777:

CMPC,0;如果C=0,表示获得最高获

JNZCASE666;如果C不等于0,进行下等级获项的比较

MOVAH,09H;第21号中断的09号功能,输出字符串

MOVDX,OFFSETWIN12;输出所获得的奖项

INT21H

CASE666:

CMPC,1

JNZCASE555

MOVAH,09H

MOVDX,OFFSETWIN11

INT21H

CASE555:

CMPC,2

JNZCASE444

MOVAH,09H

MOVDX,OFFSETWIN10

INT21H

CASE444:

CMPC,3

JNZCASE333

MOVAH,09H

MOVDX,OFFSETWIN9

INT21H

CASE333:

CMPC,4

JNZCASE222

MOVAH,09H

MOVDX,OFFSETWIN8

INT21H

CASE222:

CMPC,5

JNZCASE111

MOVAH,09H

MOVDX,OFFSETWIN7

INT21H

CASE111:

CMPC,6

JNZCASE567

MOVAH,09H

MOVDX,OFFSETWIN6

INT21H

CASE567:

CMPC,7

JNZCASE456

MOVAH,09H

MOVDX,OFFSETWIN5

INT21H

CASE456:

CMPC,8

JNZCASE345

MOVAH,09H

MOVDX,OFFSETWIN4

INT21H

CASE345:

CMPC,9

JNZCASE234

MOVAH,09H

MOVDX,OFFSETWIN3

INT21H

CASE234:

CMPC,10

JNZCASE123

MOVAH,09H

MOVDX,OFFSETWIN2

INT21H

CASE123:

CMPC,11

JZP123;如果C=12,表示结果为123,则输出获奖结果

JNZEXITP;如果C不等于12,什么也不输出,退出宏

P123:

MOVAH,09H

MOVDX,OFFSETWIN1

INT21H

EXITP:

POPDX

POPAX

ENDM

START:

MOVAX,DATA

MOVDS,AX

MOVAH,00h;用来清屏

MOVAL,03H

INT10H

;******************输出程序信息量********************

CURPOS2,0;设置光标位置,此处设为第二行

SETCOLOR66,0FH;设置该行字符颜色,66表示要设置的字符个数,0FH表示为白色

LEADX,HEADMSG1;存放字符串的地址

MOVAH,09H;调用21H中断的第9号功能,显示字符串

INT21H

CURPOS3,0

SETCOLOR52,0FH

LEADX,HE

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1