第一篇:“24点”游戏说明书
“24点”游戏说明书
名称:“24点”游戏
基本玩法:给定四个自然数,通过+,-,×,÷四则运算,可以交换数的位置,可以随意地添括号,但规定每个数恰好使用一次,连起来组成一个混合运算的算式,使最后得数是24。
“24点”游戏通常是用扑克牌进行的,此时,给定的四个自然数就被限定在1~13范围内了。“数学24”游戏可以1个人玩,也可以多个人玩,比如四个人玩,把扑克牌中的大、小王拿掉,剩下的52张牌洗好后,每人分13张,然后每人出一张牌,每张牌的点数代表一个自然数,其中J,Q,K分别代表11,12和13,四张牌表示四个自然数。谁最先按游戏规则算出24,就把这四张牌赢走。然后继续进行。最后谁的牌最多谁获胜。
要想算得又快又准,这就要靠平时的基本功了。最重要的有两条:一是熟悉加法口诀和乘法口诀,二是利用括号。括号既能改变运算顺序,也可以改变运算符号。
好处:通过玩“24点”的游戏,能把枯燥的基本数字计算变得趣味盎然,能大大提高计算能力和速度。
第二篇:沙盘游戏说明书
你是否感觉和他人交流有障碍,总是词不达意或者被人误解? 你是否感觉自己做得都很好,可别人就是不领情? 你是否总是莫名其妙落入别人的陷阱? 你是否总是遇到同一类人或事让我烦恼? 你我是否总是遇到层出不穷的麻烦?
你是否有焦虑、抑郁、悲伤、愤怒、恐惧等情绪需要处理? 你是否有自杀或自伤倾向需要处理? 你是否害怕与人交往? 你是否不愿意一个人独处? 你是否缺乏亲密的朋友?
你是否有太多的亲戚和朋友需要我费心照顾? 你是否害怕考试?又想念书又念不下去? 你是否过份害怕小动物? 你是否被人指责为爱做白日梦? 你是否网络成瘾,欲罢不能?
你是否感觉付出了很多,却得不到周围人的认可? 你是否自信不足?
你是否对小时候的一些人或事仍有抱怨或怨恨? 你是否感觉伴侣特别不可理喻?特别不能理解自己? 你是否感觉家庭成员之间缺乏温暖和关爱?
你的孩子是否易怒?稍不如意就大喊大叫,大哭大闹? 你的孩子是否过于胆怯,不敢主动和其他孩子交往? 你的孩子是否做事磨蹭,没有时间观念? 你的孩子是否不爱学习,注意力不集中?
你是否感觉下级总是不能圆满完成自己交给的任务? 你是否感觉上级总是下达一些莫名其妙的指令? 你是否感觉同级之间有人在不公平竞争或者刁难自己? 你是否经常有类似的梦境出现?
你是否对未来充满信心?还是已经一眼就望到了尽头? 你是否有员工需要增进团队凝聚力,提高工作效率?
如果你有上面的这些困扰,这些困扰是否严重到你没办法自己处理或克服,困扰是否严重到你愿意花费金钱和时间来找专业人士帮助你处理。如果是的话,你就可以考虑申请参加沙盘游戏。
沙盘游戏只是呈现参加者的行为和行为模式,并不能看到参加者之前经历了什么具体事件,不涉及个人隐私。
指导者的主要功能是陪伴,提供安全和信任的环境,让参加者有充分的机会获得感悟和自愈。在讨论过程中,指导者只就沙盘呈现出来的部分对参加者有针对性的提醒,提醒参加者回忆当时操作时的想法和情绪感受,在参加者的一些情绪关口予以适当的引导,以帮助参加者顺利释放和更深层看清自己。
沙盘游戏现在越来越多被企业用作增强团队协作的有力工具,以及越来越多的个人渐渐喜欢使用这种直观的方式来解决自身的问题,很多企业管理者和需要心理帮助的人士,无论是亲身经验过的还是只是听说过沙盘游戏疗效的人,均对此深感神奇,其中有些人士希望借助沙盘游戏看透别人以满足自己的好奇心,有些人士则希望被旁观者看到以获得帮助,还有些人因为担心泄漏自己的隐私而在内心抵制沙盘游戏,但是更有很多人士希望深入了解沙盘游戏。
沙盘游戏的适用人群(我和周围的人需要做沙盘游戏吗?):
沙盘游戏适用的人群相当广泛,按照分类方法的不同,罗列如下:
(一)按照心理问题分类,沙盘游戏适用于以下情况:
(1)自闭症等言语障碍和交流困难者:言语障碍者因为各种原因不能很好地用语言表达自己的观点或情绪体验、与他人交流。言语面谈式的咨询也不适用于他们。沙盘游戏不需要语言交流,可使参加者的挫败感和心灵创伤都得到适当的表述,并得以减弱甚至治愈。而这些未曾得到表现、宣泄的挫败感和心灵创伤往往是造成学业失败、心理沮丧、社会技能缺乏的主要原因。
(2)焦虑等情绪困难者:学习和考试焦虑是当前学生面临的主要情绪困难之一。沙盘是一种集认知重构、情绪表达、感觉统合、心理动力于一体的心理治疗方法。通过玩沙子和沙具,可以宣泄自己的焦虑情绪,放松身心,并在面对沙盘这一内心镜像时,重构自己的意识和潜意识。沙盘制作过程能够充分挖掘参加者的创造潜力,这种成功创造的感觉和经历又能够进一步提升他们的自信和自尊,使他们具备强大的心理抗击打能力来面对学习和考试以及步入社会之后的挫折。
(3)注意缺陷、多动者:注意缺陷、多动主要表现为注意力分散、多动、易冲动、易激怒以及无法容忍延迟满足等。对注意缺陷的干预一直是临床工作者感到困惑的难题。运用沙盘游戏能帮助注意缺陷者将注意力集中于一种可具体感知到的、自我主导的活动,沙子和玩具的可触性、可移动性通过触觉与运动觉作用于参加者的大脑神经,从而使他们的注意力集中于具体的物件和活动。此外,沙盘的沙箱是一个有边界限制的空间,可以将参加者的注意力集中于这一有限的空间内,有助于训练他们集中注意力。
(4)攻击性行为者:情感宣泄是矫治攻击性行为的重要方法。烦恼、攻击、挫折、愤怒等侵犯性情感是点燃攻击性行为的导火索,侵犯性情感积聚越多,其表现攻击性行为的可能性愈大。宣泄可以减弱侵犯 性情感的强度,而过分压抑侵犯性情感只能使其获得暂时的压制而不会因此消失,反而深入到潜意识中,危害其身心健康。过分压抑的结果,往往会爆发出突然的、猛烈的攻击性行为。沙盘为此类行为者提供了一个表达的机会,可以让他们在虚拟的空间里将其愤怒、攻击性的行为和情感具体地演示出来,以耗散其攻击性心理能量,并从沙盘所建构的故事情境中学会与人相处的适应性行为。
(5)人际关系困难者:人际关系是影响个体主观幸福感的主要因素之一,并可能进一步影响个体的学习、生活质量,所以如何正确处理与他人的关系是个体心理发展的重要课题。团体沙盘游戏在促进团体成员协作能力、增进团体整合、提高人际交往技能、确立自我概念等方面具有非常显著的效果。在沙盘世界中,成员或个体以虚拟而又注入真情实感的角色扮演的方式展开人际关系互动,并在沙盘的帮助下调整社会认知系统,从成员人际交往的成功行为中学会社交适应行为。
(6)网络成瘾者:沙盘游戏可以使网络成瘾者获得充分的内在体验,以及充分的表现和表达,引发成瘾的焦虑内容得以展现,焦虑情绪因之缓解。同时沙盘游戏和网络都能创建出变化无穷的三维图画,能充分发挥网络成瘾者的创造性和动手能力,容易引发他们全身心投入一件事情的愉悦体验,从而把对网络的依赖转移到既能获得成功愉悦体验又能促进心智发展的行为中。
(二)按照年龄分类,沙盘游戏适用于:
(1)幼儿及中小学生:沙盘游戏可以对有需要的幼儿与儿童提供辅导。鉴于幼儿和儿童语言表达不清晰和喜欢玩具与游戏的特点,沙盘游戏特别适用于这样的年龄阶段。沙盘游戏提供了一种自由的情境让儿童的心灵自己产生自我疗愈。
(2)成人:沙盘游戏可使成人提高自信心、完善自我性格、提高人际交往技巧、有效宣泄消极情绪、释放压力等。
成人大多数的创伤或者问题都源于儿童时代,在那时他们感觉被抛弃,受到严格限制,过度的批评和惩罚,或者因失败而被周围的人不接纳。在沙盘游戏中,指导者没有批评和惩罚,而是抱着接纳一切的态度,给予参加者以自由空间,并身临其境,感同身受,和参加者结为同盟,从而使参加者感受到极大的支持,更能激发他的潜力来获得自愈。
沙盘游戏也允许在沙盘内把过去的事件呈现出来。参加者可以现场把事件场景改变,并把这些事件从潜意识和意识层面解决掉。参加者借助沙盘把创伤事件具体化,不断增强自我去面对,并以新的眼光和新的理解方式来看待这些创伤事件,最后达到自愈。
(三)按照参加人数和相互关系分类,沙盘游戏适用于:(1)个体沙盘:可以深入展示个人的内心世界,让参加者与自己的潜意识对话,疏泄积压的情绪,了解自己的深层次需要,从而更了解自己,更清晰自己的目标,更容易达成自己的目标。
(2)伴侣沙盘:可以借助沙盘游戏,清晰双方的行为模式和行为动机,有助于双方深层沟通,冰释前嫌并减少以后误解的产生和情绪的爆发,促进双方更加伉俪情深。
(3)家庭沙盘:可以有效的改善家庭成员关系,呈现成员的潜意识反应,促进成员间深层次的心灵沟通,尤其是对培养孩子的良好性格习惯有积极作用。
(4)团体沙盘:针对学生、教师、医护人员、病人、企业高层管理人员、销售人员、公务员等,可以促进团队精神的升华,提升团队凝聚力,培养协作性人才,加强成员间的精神交流,改善团队气氛,提高工作效率。
(四)按照内容分类,沙盘游戏可应用于:
(1)解梦:以沙盘呈现梦境以及梦境的发生发展过程,在清醒状态下重现相关情绪,有助于参加者明白梦境在提示自己什么,有助于参加者从旁观者的立场看清自己,更加了解自己。
(2)未来展望:以沙盘呈现参加者潜意识层面对未来的憧憬,使潜意识的模糊影像上升到意识层面的清晰意象,让头脑更清晰地看到自己对未来的期待,内心形成一个完整的感受,这种完整感受的体验能使参加者不顾疼痛和焦虑去继续在现实中寻找这一完整,这强大的动力可导致参加者现在就开始制定朝向未来的计划,由于意识层面和潜意识层面目标一致,更有利于现实生活中计划的逐步执行和实现。
(3)EAP(企业员工心理援助)及人力资源开发:沙盘游戏对于人格发展、想象力、创造力的培养以及心理维护、个人成长等都发挥着积极的促进作用,而且简单实用见效快,是企业EAP心理咨询及人力资源开发的核心技术。
(4)职业生涯规划:通过沙盘来呈现个人未来的生活和工作场景,来具象化参加者对于未来职业的展望,使参加者更加清晰未来工作的宏观轮廓和微观细节,联系目前的现状,寻找现在和未来的切合点,激发对于未来工作的向往和对于现状的改造热情,帮助参加者提高现在的学习和工作效率,更快达成一个又一个目标。
第三篇:delphi24点游戏
第3章 “速算24”扑克游戏--单元、异常、逻辑
3.1 “速算24”扑克游戏效果说明
“速算24”是一个考察心算能力、有助于开发智力的扑克游戏。在给出4张扑克牌之后,要求应用这些扑克牌数字做数学运算,迅速构造出一个数学表达式,得出结果24。这个游戏的关键在于迅速判断用户输入的表达式是否正确,并做出相应的反馈,告诉用户是算对了还是算错了。游戏的初始界面如图3.1所示。
图3.1 游戏的初始界面
当用户单击“开始”按钮时,系统开始发牌,随机发出4张牌,如图3.2所示为随机开始的一局游戏,给出的4张纸牌分别为“9”,“8”,“9”,“2”。在文本框中输入运算表达式,比如,输入“8*(2+(9-9))”,单击“计算”按钮,系统会出现提示框,显示“您输入的表达式的计算结果为16!”,告诉你该表达式的结果不是“24”,如图3.3所示。单击“确定”按钮,再次在文本框中输入表达式,比如“8*(2+(9/9))”,单击“计算”按钮,系统会出现提示框,显示“您真行,我服了您!”,表明运算正确,如图3.4所示。
图3.2 系统随机发4张纸牌
图3.3 运算式不正确
图3.4 运算式正确
这个游戏具体的规则如下:
(1)单击“开始”按钮,游戏开始,系统将随机发牌。
(2)请迅速在文本框中输入运算表达式,然后单击“计算”按钮。
(3)这时系统会提示您的运算是对了还是错了,在弹出的对话框中单击“OK”按钮,再次输入新的运算表达式,重复上一步,直到您的运算表达式结果正确,这时系统会恭喜您!
(4)如果结果错了还想继续或者中途想计算另一局扑克牌,就单击“重新开始”按钮,得到新一局扑克牌进行游戏。
下面,我们开始循序渐进地创建这个小游戏。在最开始,游戏的界面和效果都会非常简单,在后面我们会逐渐地完善它。
第3章 “速算24”扑克游戏--单元、异常、逻辑
3.2 生成和建立程序(1)在程序中用到了Image组件,用于放置图片。还用到了Timer组件,用于计算用户操作时间。下面我们来生成游戏的基本框架。
3.2.1 Image组件
Image组件在Additional页上,用来在窗口中显示一幅图片。它拥有如下几个主要属性: 1.Picture属性
可以在picture属性中调入图像文件。Delphi支持多种图像格式,如位图(.BMP)、图标(.ICO)、图元(.WFM)、动画光标(.ANI)、JPEG图片(.JPG、.JPEG)等。
2.AutoSize属性
当AutoSize为True时,Image组件将根据它所包含的图像的大小来调整自身的大小;当AutoSize为False时,不论图像有多大,组件将保持设计时的大小。如果组件比图像小,那么只有一部分图像是可见的。
3.Stretch属性
当Stretch为True时,位图图像将根据组件的大小调整自身的大小,当组件大小改变时,上述三种文件也做相应变化。Stretch属性对图标没有作用。
上述的AutoSize和Stretch属性决定了图像在窗口中的显示尺寸。
图3.5演示的3个Image分别为:AutoSize为True,AutoSize为False,Stretch为True的情形。可以看到,Image的原始尺寸比图片宽,矮,在上面的属性设置下,就会有不同的显示效果。
图3.5 AutoSize和Stretch的设置 3.2.2 Timer组件
在Delphi中,组件分可视组件和非可视组件。可视组件是指那些在运行期间仍然能显示的组件,例如Label,Button,Image组件等。非可视组件是指那些在程序界面设计期间可见,而在程序运行时不可见的组件,例如在System页上的Timer组件。
Timer组件能够有规律地触发OnTimer事件,发送信息给应用程序,它是编制应用程序时最为重要的组件之一。
1.Timer组件的属性
Enabled属性表示Timer是打开还是关闭。用Interval属性设置两个OnTimer事件间的间隔,单位是毫秒。将间隔设置为0相当于关闭计时器,Interval是Cardinal类型的,最大值可到4294967295,当然程序中一般不会把Interval设成很大的值。2.Timer组件的使用
Timer是独立的对象,在启动与Windows无关的逻辑和应用事件时极其有用。可以模拟时钟或计时器,可视地显示经过的时间;可以用作系统延时,Delphi提示信息出现只需在该区域停顿几秒,就是Timer组件应用的一个例子;可以检查系统环境、事件,根据结果进行响应;也可以在窗口中闪烁一段正文或图像,提示某种操作或处理正在进行等等。
尽管Delphi的计时器每秒可以产生1000次激发,在编程中还必须注意程序对Timer触发的响应。如果程序处理OnTimer事件的时间超过Interval的设定值,就可能错过事件,因为当下一次触发到来时,系统正忙于处理上一事件,则这次触发就会被忽略。同时要注意其他的Windows应用程序是否会影响Timer的触发。如果后台正运行着一个占用处理器的程序,就可能会导致Timer的触发不准确,从而使前台程序运行出现错误。
这里要强调的是Timer组件是一个非可视组件,可以把它放置到窗体或者其他容器组件上的任何位置。3.实现游戏计时功能
在本章的游戏中,我们加入一个Timer组件,实现游戏的计时功能。
在窗体中加入一个Label组件,将此组件的Caption属性设置为“使用时间”,然后从组件面板上选择System页中的Timer组件。
在Unit1中加入Form1的一个私有成员SpendTime,记录用户计算所用的时间。代码如下所示:
private { Private declarations } SpendTime:Integer;在Form1的onCreate事件中加入如下代码。将SpendTime设置为0,并将Timer1的Enabled属性设置为False,使Timer1组件不能响应OnTimer事件;并将Timer1的Interval属性设置为1000,表示当Timer1有效时,每间隔1000ms(即1秒)发生一次OnTimer事件:
procedure TForm1.FormCreate(Sender: TObject);var i:integer;begin //初始化,设置数组RandomData的长度为4 //并将每个数组元素初始化为零
setLength(RandomData,4);for i := 0 to 3 do RandomData[i]:=0;SpendTime:=0;Timer1.Enabled:=False;Timer1.Interval:=1000;end;然后在标题为“开始”的“开始”按钮的OnClick事件中,加入如下所示的代码,将Timer1的Enabled属性设置为True,使Timer1组件有效,即现在Timer1能响应OnTimer事件,计时开始。并将SpendTime重新设置为0:
Timer1.Enabled:=True;Timer1.Interval:=1000;SpendTime:=0;//将SpendTime重新设为0 再在“计算”按钮的OnClick事件句柄中,增加下面的语句,使Timer1无效:
Timer1.Enabled:=False;最后双击Timer1组件,创建Timer1的OnTimer事件句柄,在其中加入如下所示的代码,将SpendTime加1,并设置Label5的Caption属性:
procedure TForm1.Timer1Timer(Sender: TObject);begin SpendTime:=SpendTime+1;Label5.Caption:='使用时间:'+IntToStr(SpendTime)+'秒';end;这样,每隔1秒钟,程序就刷新一次使用时间。
3.2.3 设计初始界面
按住Shift键,然后单击组件面板中Additional页中的Image组件,这时该组件边缘出现蓝色的边框,并且凹陷下去,表示可以在窗体上连续加入几个Image组件。选择好Image组件后,在窗体的左上角单击,加入1个Image组件,然后依次向右单击鼠标3次,再加入3个Image组件。最后再单击组件面板中最左边的箭头。
为了排列这4个Image组件,先利用Shift键将它们同时选上,然后右击,选择Align命令,在随后出现的Alignment对话框中的Horizontal选项组中选择Space equally,在Vertical选项组中选择Tops,表示这4个组件顶端对齐,水平方向上间距相等。
按照同样的方法加入4个Label组件、3个Button组件和1个Edit组件。按照表3.1所示设置各个组件的属性。
表3.1 各个组件的属性
组件名 Form1 Label1 属性名 Caption Caption AutoSize WordWrap Caption
属性值 速算24
1.单击“开始”按钮,游戏开始,系统将发出4张扑克牌
False False
2.要求用户利用扑克牌显示的数字,通过加减乘除运算,以最快的速度得出24(可以使用括号),JQKA和“王”算做1。然后在文本框中写好表达式,接
着单击“计算”按钮
Label2
Label3 AutoSize WordWrap Caption
False True
3.这时系统会计算输入表达式的结果,告诉用户是对还是错了。在弹出的对话框中单击“OK”按钮,如果错了可以再次输入新的表达式,重复上一步。直
到您的表达式正确,这时系统会恭喜算对了!
Label4 AutoSize WordWrap Caption AutoSize Caption Caption Caption Text
False True 在下面输入数学表达式
False 开始 计算 退出游戏 空
Button1 Button2 Button3 Edit1
现在同时选择Label1,Label2和Label3,将它们左对齐,垂直方向等距离排列。将Button1,Button2和Button3左对齐,垂直方向等距离排列。
下面放置4个Image组件,用于放置4张纸牌的图片。
先选择Image1,然后切换到对象查看器中的属性编辑器,选择属性选项页中的Picture属性,然后在Picture属性值栏中双击,或单击此属性值旁边的带有省略号的按钮,打开Picture Editor对话框,如图3.6所示。然后单击Load按钮,弹出Load Picture对话框,在此对话框中选择background.bmp文件。最后单击OK按钮,退出Picture Editor对话框。
图3.6 指定图片
使用同样的方法,设定其他3个Image组件的Picture属性。
保存我们的新项目,运行之后界面如图3.7所示,与运行时的界面图3.1稍有不同。这里是设计时界面,只有界面没有事件响应。是程序创建过程中的一个步骤的检验。但是,这个程序还没有什么具体的功能,为了让游戏运行起来,必须添加代码,创建相应的事件处理程序。
第3章 “速算24”扑克游戏--单元、异常、逻辑
生成和建立程序
3.2.4 事件处理
需要添加个事件:第一个用于响应单击开始按钮,在此事件中完成发牌,即随机显示图片;第二个用于响应单击计算按钮,解析用户在文本框中输入的表达式,计算表达式的结果,并判断表达式的结果是否等于;第三个用于响应单击退出游戏按钮,退出游戏(程
序)。
1.数据初始化
创建窗体的事件处理程序,在这里进行必要的初始化。第一步先在Unit1中添加Form1的私有成员数组:
private
{ Private declarations }
RandomData:array of Integer;然后,在对象查看器中选中Form1,选中Event选项卡,在OnCreate一栏对应的右边的空白栏中双击,创建OnCreate函数。添加如下代码。
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin //初始化,设置数组RandomData的长度为4
//并将每个数组元素初始化为零
setLength(RandomData,4);
for i := 0 to 3 do
RandomData[i]:=0;
end;这里使用一个for循环语句,i是循环变量,格式是:for循环变量:=初值to末值do循环体。你也可以借助Delphi的自动完成功能,在输入for之后按下Ctrl+J键,生成如下代码:
procedure TForm1.FormCreate(Sender: TObject);
begin
for := to do
begin end;
end;在上述代码中,程序首先利用setLength函数设定可变数组RandomData的数组长度为4,然后,将数组的每一个单元都设置为0。这样,就完成了数组的数据初始化工作。
2.“开始”按钮的Click事件处理
()功能单击开始按钮时,系统就随机地发出张纸牌,显示在个组件中。
()代码首先,我们需要一个循环变量,一个字符串变量存放随机选取的图片的文件名。创建“开始”按钮的OnClick事件处理程序,在begin前头添加需要的变量,然后在此事件
中加入如下所示的代码。
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
filename:String;
begin
Randomize;//初始化随机数
for i := 0 to 3 do
begin RandomData[i]:=Random(13)+1;//产生一个1到13的随机数
filename:=IntToStr(RandomData[i])+'.bmp';//根据随机数,得到文件名
//根据i的不同为不同的Image组件载入图像文件
case i of 0 : Image1.Picture.LoadFromFile(filename);1 : Image2.Picture.LoadFromFile(filename);2 : Image3.Picture.LoadFromFile(filename);3 : Image4.Picture.LoadFromFile(filename);
end;
edit1.Text:='';
edit1.SetFocus;
end;
end;在Delphi内部,随机数的产生实际上也是在一套算法的控制之下,Randomize函数用于初始化产生随机数的种子,保证两次产生的随机数不同,而Random(i:integer)则利用初始化过后的随机数种子产生一个1~i之间的随机数。这里i设定为13,以配合扑克牌的张数13。
用来将一个整数转换成一个字符串,和上一章中的的功能恰好相反。我们已经预先准备了位图文件,它们都是形式,文件名则是利用数字命名。中特殊的字符串运算符将两个字符串串联起来,产生一个新的字符串,我们需要的位图文件后缀是,因此,在产生文件名的时候,在数字后面加上这个字符串。语句在上一章中已经讲过,单击开始按钮后,准备接受用户的输入,然后利用方法,把焦点设置到上。是提供的方法之一,用于设置输入
焦点到某个指定的组件。
3.“计算”按钮的OnClick事件
双击“计算”按钮,创建此组件的OnClick事件响应句柄,然后在代码编辑器中加入如下所
示的代码,用于计算用户输入的表达式。
procedure TForm1.Button2Click(Sender: TObject);
var
result:integer;
answer:String;
begin
result:=TotalCompute(Edit1.Text);
if(result=24)then Application.MessageBox('您真行,我服了您!','对了',MB_OK)
else
begin answer:='您输入的表达式的计算结果为'+IntToStr(Result)+'!';Application.MessageBox(PChar(answer),'错了',MB_OK);
end;
end;这段程序根据自定义函数的计算结果判断用户的输入正确与否,并且输出相应的结果以提示
用户。
在语句“result:=TotalCompute(Edit1.Text)”中用到了一个自定义的函数TotalComp-ute,我们用它来计算用户输入的表达式。现在我们还没编写这个函数的代码,所以,目前这段代码是无法运行的。没关系,可以先把它用“//”注释掉,然后随便给 result赋一个值,测试这个事件处理程序的其他部分是否运行正常,例如:
//result:=TotalCompute(Edit1.Text);
result:=24;这样,运行后,单击“计算”按钮后的显示如图3.8所示。
图3.8 成功的提示信息
我们用一个类型的变量存放出错信息,但是函数的第一个参数要求是(字符指针)类型,因此,我们用一个强制类型转换将转换
成。4.“退出游戏”按钮的OnClick事件
双击“退出游戏”按钮,创建此组件的OnClick事件处理程序,然后在代码编辑器中加入如
下所示的代码,用于退出程序。
procedure TForm1.Button3Click(Sender: TObject);
begin
Close;
end;在上一章中我们提到可以用代替,但这里使用来结束程序的运行。这样,可以通过事件来指定在什么条件下窗体可以关闭。
第3章 “速算24”扑克游戏--单元、异常、逻辑
生成和建立程序5.OnCloseQuery事件
当调用方法来关闭窗体时,事件发生。利用事件来指定在什么条件下窗体可以关闭。事件包含一布尔型的参量,可以用它来决定窗体是否关闭。的默认值为。可以利用事件来询问用户是否真的希望马上关闭窗体。我们在这里弹出一个对话框,代码如下所示:
procedure TForm1.FormCloseQuery(Sender: TObject;var CanClose: Boolean);begin if(MessageDlg('现在要退出游戏吗?', mtConfirmation, [mbOk, mbCancel], 0)= mrOk)then canClose:=True else canClose:=False;end;MessageDlg是一种提示对话框,第一个参数是对话框询问的讯息,是一个字符串;第二个参数则代表对话框的类型,mtConfirmation是一个TMsgDlgType的枚举类型,表示这个对话框是个确认对话框。TMsgDlgType类型如下所示:
type TMsgDlgType =(mtWarning, mtError, mtInformation, mtConfirmation, mtCustom);以上定义的对话框类型分别表示:警告、错误、提示、确认和自定义类型。
第三个参数是TMsgDlgBtn类型的集合,这个集合包含了类型为TMsgDlgBtn的按钮,TMsgDlgBtn的定义如下:
type TMsgDlgBtn =(mbYes, mbNo, mbOK, mbCancel, mbAbort, mbRetry, mbIgnore, mbAll, mnNoToAll, mbYesToAll, mbHelp);在我们的程序中,利用了一个集合[mbOK, mbCancle],表示在对话框中显示两个按钮:OK和Cancel的组合。
最后一个参数是用来描述帮助索引的长整型变量,用来获取提示用户的帮助信息,这里我们没有任何帮助信息,先不管它。函数和用户交互,返回一个类型的数字,预先定义了一套数字,用来直观地表示对话框返回信息。如果用户单击了按钮,这个对话框返回,效果如图所示。
图3.9 关闭窗口时询问用户
现在,我们已经完成了程序的主体部分。第3章 “速算24”扑克游戏--单元、异常、逻辑
单元间的互相引用3.3.1 单元引用的概念
在第章关于单元的知识里,我们已经知道可以定义不包含窗体的单元,它集中定义了程序中使用的函数,这一节里,我们就要实现这样的一个单元,用来实现上面提到的函数。我们可以在任何单元中编写自己的函数,当然包括与窗体相连的单元。可是我们常常需要用到一些常用的函数,这时最好是创建一个不与窗体相连的独立单元,用它来容纳自己的函数,这称为独立的单元文件。当创建了不与窗体相连的独立单元文件后,项目中的其他单元就能很容易地共享这些函数,其他项目也可以很容易地调用这些函数了。对于单元间的引用,要用到语句。3.3.2 uses语句
语句告诉程序在最终的执行代码中需要用到哪些函数和过程。会自动把一些必须的单元包括进来,例如,,等。对于我们自己编写的单元,如果程序中使用了该单元的函数或代码,也需要包括在部分中。语句具有两种类型:公有引用和私有引用。在部分包含的语句代表的是本单元的公有引用,就是说,这部分的引用可以被其他引用本单元的单元继承性地引用。在部分的语句应包含在部分中的代码所需要的单元,去掉那些可以自动加入到程序中的单元。在部分包含的语句代表的是本单元的私有引用,就是说,这部分的引用只能被本单元内部使用。在部分的语句应只包含在部分中的代码所需的单元的名字。对于单元间的引用,要避免交叉引用。假设有两个单元和,如果出现在的部分的语句中,那么单元便不能出现在单元的的语句中。因为这样会产生对单元的循环访问,编译时会出现错误信息。3.3.3 创建另一个单元
创建一个不与窗体相连的单元文件的方法是,首先选择主菜单的命令,然后选择命令,此时弹出一个对话框,如图所示。在此图中选择选项卡中的,然后单击按钮。此时自动为我们创建一个名为的独立单元文件,并显示在代码编辑器中,我们只需在此加入函数即可。
图3.10 New Items对话框
单元创建之后,就需要实现单元之间的互相引用。这里有两种方法:(1)直接在Unit1中写入uses Unit2,代码如下所示:
var Form1: TForm1;implementation uses Unit2;(2)选择主菜单的File | Use Unit命令,此时Delphi弹出Use Unit对话框,如图3.11所示,在此窗口中列出当前文件没有连接的所有文件,只需选择需要连接的文件即可。当选择了某一文件并单击OK按钮后,当前文件就包含了对所选文件的引用。
图3.11 Use Unit对话框
如果当前文件已经连接了当前项目中所有其他文件,选择命令后,就会弹出如图所示的信息窗口,告诉程序员当前文件已经连接了当前项目中所有其他文件。
图3.12 Information对话框
此时再编译,程序就没有任何错误了。现在我们已经创建了,它将用作我们的数学函数定义单元。在开始定义这个单元之前,需要先了解一下关于的异常处理机制。第3章 “速算24”扑克游戏--单元、异常、逻辑
3.4 异 常 处 理
3.4.1 异常处理的概念 在应用程序开发中如何检测、处理程序的运行错误是一个很重要的问题。在 Delphi 的IDE(集成开发环境)中提供了一个完善的内置调试器,可以发现大部分程序错误。但并不是所有的错误都可以被发现,而且当程序涉及到与外设的数据交换或操作外设,如要求用户输入、读写磁盘等时,错误的发生是程序无法控制的,如输入非法字符、磁盘不能读写等。这些情况不仅会导致应用程序异常中止,而且可能引起系统的崩溃。针对这些问题,Delphi提供了一套强大的异常处理机制。巧妙地利用它,可以使程序更为强健,使用更为友好。
Delphi异常处理机制建立在Protected Blocks(保护块)的概念上。所谓保护块是指用保留字try和end封装的一段代码。保护块的作用是当应用程序发生错误时自动创建一个相应的Exception(“异常”类)。程序可以捕获并处理这个“异常”类,以确保程序的正常结束以及资源的释放和数据不受破坏。如果程序不进行处理,则系统会自动提供一个消息框。“异常”类是Delphi异常处理机制的核心,也是Delphi异常处理的主要特色。Delphi提供的所有“异常”类都是类Exception的子类。用户也可以从类Exception派生一个自定义的“异常”类。
3.4.2 资源保护方式
回收分配的资源是确保程序健壮性的一个关键。但默认情况下异常发生时程序会在出错点自动退出当前模块,因此需要一种特殊的机制来确保即使在异常发生的情况下,释放资源的语句仍能被执行,而Delphi的异常处理正提供了这种机制。
Delphi提供了一个保留字finally,用于实现资源的保护。
{分配资源}
try {资源使用情况} finally {释放资源}
end;try„finally„end就形成了一个资源保护块。finally后面的语句在任何情况下(不论程序是否发生异常)都会执行。
在异常保护的情况下,当异常发生时,系统会自动弹出一个消息框,在框中显示异常的消息。退出当前模块后异常类自动清除。
3.4.3 异常响应方式
异常响应为开发者提供了一个按需进行异常处理的机制。try„except„end形成了一个异常响应保护块。与finally不同的是:正常情况下except 后面的语句并不被执行,而当异常发生时程序自动跳到except处,进入异常响应处理模块。当异常被响应后异常类自动清除。
下面是异常响应方式的一般代码:
try {程序正常功能} except on ESomething do {响应特定异常} else {提供默认响应} end;保留字on„do用于判断异常类型。必须注意的是:except后面的语句必须包含在某一个on„do模块中,而不能单独存在。这是又一个与finally不同的地方。
3.4.4 提供默认响应
在异常响应模块中,一般我们只对希望响应的特定异常进行处理。如果一个异常发生而响应模块并没有包含对它的处理代码,则退出当前响应模块,异常类仍被保留。
为了保证任何异常发生后都能在当前响应模块中被清除,可以定义默认响应:
try {程序正常功能} except on ESomething do {响应特定异常} else {提供默认响应} end;由于else可以响应任何异常,包括我们一无所知的异常,因此在默认响应中最好只包括诸如显示一个消息框之类的处理,而不要改变程序的运行状态或数据。
第3章 “速算24”扑克游戏--单元、异常、逻辑
3.5 数学逻辑单元(1)
此游戏程序最关键的地方是如何将用户输入的字符串表达式解析成数学表达式。为了使程序结构清晰明了,我们将此解析代码和程序的主代码分开,单独编写成一个单元。
3.5.1 算法设计
游戏的难点是如何将一字符串形式的表达式解析成计算机能计算的算术表达式。例如对于字符串“3^(4*(9+4))”,如何让计算机解析、计算。
我们的想法是按照数学四则运算规则,先逐层进入最里层的括号,然后在括号内部计算乘方,接着进行乘(除)法运算,最后按顺序进行加(减)运算,当本层括号内部计算完成后,返回结果,去掉括号内部数据,退出到下一级括号(如果有)内进行计算。
这里面涉及的技术细节主要有下面几点:
(1)层层剥离括号,然后从最里层的括号开始计算。(2)对于每一个运算符号,找到符号两侧的数字,形成一个计算式。
(3)每一个子计算式完成后,运算结果返回到原始数列中,作为子串的一部分,继续进行上述计算。
3.5.2 字符串的相关函数
在游戏中,用户输入的都是字符数据,我们需要从这些字符中分析得到数字和运算符号,因此要用到与字符串操作有关的函数。
function Pos(sub , all:string):integer;这个函数含有两个参数:sub表示要查找的字符,all表示原字符串。函数在字符串all中寻找指定的字符sub的位置,如果字符串中不存在sub字符,则函数结果为0。
function LastDelimiter(sub,all :string):integer 这个函数含有两个参数:sub表示要查找的字符,all表示原字符串。函数返回在字符串all中所有查找到的指定字符sub的最后一个的位置,如果字符串中不存在sub字符,则函数结果为0。
function Copy(allstring:string;first,length:integer):string 这个函数的3个参数的含义分别是:allstring代表原来的字符串,first表示拷贝开始的位置,length表示要拷贝的子串长度。函数返回拷贝成功的子串。
procedure Delete(str:string;ppos,length:integer)这个过程用于删除字符串中的一段字符。参数str代表将要操作的字符串,ppos代表开始删除的位置,length表示将要删除多少个字符。function Length(S): Integer;Length函数返回字符串S的长度。
function Trim(const S: string): string;overload;function Trim(const S: WideString): WideString;overload;Trim函数返回字符串S去掉前面和后面的空格后的字符串。
下面的例子给出一个综合利用字符串处理函数编写的一个处理特定字符串的函数,它的功能是:输入一个字符串后,可以返回字符串中两个单括号之间的子字符串,并去掉前面和后面带着的空格:
function GetMyStr(const S: string): string;begin Result:=Trim(Copy(S,Pos('<',S)+1,Pos('>',S)-Pos('<',S)-1));end;比如我们在程序中写到GetMyStr(‘This is a test < Result to output > end of test’);,会得到字符串“Result to output”。
3.5.3 算法的代码编写
基于上述的考虑和知识基础,我们在声明部分定义下列几个主要函数:
(1)AnyLastPos函数定位最后一个算术运算符的位置。
function AnyLastPos(Str:String):integer;(2)AnyFirstPos函数定位最先一个算术运算符的位置。
function AnyFirstPos(Str:String):integer;(3)AnyFirstF函数判断最先出现的符号是+号、-号、*号还是/号。
function AnyFirstF(Str:String):Char;(4)SubCompute函数用于计算不带()号的加、减、乘、除运算。
function SubCompute(Str:String):integer;(5)TotalCompute函数用于计算表达式的结果。
function TotalCompute(Str:String):integer;1.寻找最后一个算术运算符
定义4个整数变量SubPos,PluPos,MulPos,DivPos,在给定的字符串中寻找+,-,*,/的最后位置,将这些位置存储在上述的4个变量中,然后比较4个符号出现的位置,得到数值最大的运算符;在返回的结果中,返回这个运算符的位置。
程序代码如下所示:
function AnyLastPos(Str:String):integer;var SubPos:integer;PluPos:integer;MulPos:integer;DivPos:integer;Pos:Integer;begin //定位字符串中最后一个运算符的位置
SubPos:=LastDelimiter('-',Str);PluPos:=LastDelimiter('+',Str);MulPos:=LastDelimiter('*',Str);DivPos:=LastDelimiter('/',Str);Pos:=SubPos;if(Pos
分别在给定的字符串中寻找+,-,*,/第一次出现的位置,然后比较4个符号出现的位置,得到数值最小的运算符。在返回的结果中,传递的是这个运算符的位置。
程序代码如下所示:
function AnyFirstPos(Str:String):integer;var SubPos:integer;PluPos:integer;MulPos:integer;DivPos:integer;ForPos:integer;FirstPos:integer;begin //定位字符串中最先一个运算符的位置
SubPos:=Pos('-',Str);PluPos:=Pos('+',Str);MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);ForPos:=Pos('^',Str);FirstPos:=200;if(SubPos=0)then //如果没有-号
SubPos:=200;//将SubPos设置成一个不可能的值
if(PluPos=0)then //如果没有+号
PluPos:=200;//将PluPos设置成一个不可能的值
if(MulPos=0)then //如果没有*号
MulPos:=200;//将MulPos设置成一个不可能的值
if(DivPos=0)then //如果没有/号
DivPos:=200;//将DivPos设置成一个不可能的值
if(ForPos=0)then //如果没有^号
ForPos:=200;//将ForPos设置成一个不可能的值
if(FirstPos>SubPos)then FirstPos:=SubPos;if(FirstPos>PluPos)then FirstPos:=PluPos;if(FirstPos>MulPos)then FirstPos:=MulPos;if(FirstPos>DivPos)then FirstPos:=DivPos;if(FirstPos>ForPos)then FirstPos:=ForPos;
AnyFirstPos:=FirstPos;//结束函数,返回位置
end;第3章 “速算24”扑克游戏--单元、异常、逻辑
3.5 数学逻辑单元(2)
3.得到最先出现的运算符类型
这个函数的返回结果是Char类型,代表这是一个字符变量。实际上,它返回的是+、-、*、/ 这4个符号中最早出现的一个。
程序分别寻找4个符号最早出现的位置,然后判断最先出现的是哪一种符号,再根据符号类型返回代表运算符的字符。
在具体的实现过程中,因为我们要得到最先出现的运算符,所以判断的是每次寻找后各个运算符的位置的最小值。如果不存在这个运算符,则将代表这个运算符位置的相应变量设置为200。对于本程序来说,这是一个搜索过程中不可能达到的值,这样就排除了这个位置的继续比较的可能。
程序代码如下所示:
function AnyFirstF(Str:String):Char;var SubPos:integer;PluPos:integer;MulPos:integer;DivPos:integer;Operator:char;tempPos:integer;begin SubPos:=Pos('-',Str);PluPos:=Pos('+',Str);MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);
if(SubPos=0)then //如果没有-号
SubPos:=200;//将SubPos设置成一个不可能的值
if(PluPos=0)then //如果没有+号
PluPos:=200;//将PluPos设置成一个不可能的值
if(MulPos=0)then //如果没有*号
MulPos:=200;//将MulPos设置成一个不可能的值
if(DivPos=0)then //如果没有/号
DivPos:=200;//将DivPos设置成一个不可能的值
Operator:='-';tempPos:=SubPos;if(tempPos>PluPos)then begin tempPos:=PluPos;Operator:='+';end;if(tempPos>MulPos)then begin tempPos:=MulPos;Operator:='*';end;if(tempPos>DivPos)then begin tempPos:=DivPos;Operator:='/';end;
AnyFirstF:=Operator;//结束函数,返回位置 end;4.计算不带括号的运算表达式
做完上述工作后,我们可以开始进行一些实际的运算了。
包括加、减、乘、除、乘方运算的表达式的程序算法如下所示:
(1)寻找乘方符号“^”,如果存在,则计算一次乘方,去掉计算过的部分,接着循环查找和计算子串的乘方。
(2)寻找乘号“*”或者除号“/”,如果存在,则计算一次乘(除)法,去掉计算过的部分,接着循环计算子串的乘除法。
(3)寻找加号“+”或者减号“-”,如果存在,则计算一次加(减)法,去掉计算过的部分,接着循环计算子串的加减法。
上述算法是严格按照顺序进行的,它体现了数学运算中的优先关系,经过上述的计算,子字符串被分解,计算完毕。
无论是乘方、乘除法还是加减法,内部实现的逻辑是基本一致的。下面,我们设定有一个运算表达式:3+2^5/4。
程序代码如下所示:
function SubCompute(Str:String):integer;var Middle:String;Mul2:String;Right:String;First:integer;tempStr:String;temp:integer;Left:String;Mul1:String;MulPos:Integer;DivPos:Integer;Fuhao:Char;begin Middle:='';Mul2:='';Right:='';
//定位第一个^号位置,计算乘方
First:=Pos('^',Str);While(First<>0)do //循环计算乘方
begin tempStr:=Copy(Str,1,First-1);temp:=AnyLastPos(tempStr);Left:=Copy(Str,1,temp);Mul1:=Copy(str,temp+1,First-temp-1);tempStr:=Copy(str,First+1,Length(str)-First);temp:=AnyFirstPos(tempStr);if(temp=200)then begin Mul2:=tempStr;Right:='';end else begin Mul2 :=Copy(tempStr,1,temp-1);Right:=Copy(tempStr,temp,Length(tempStr)-temp+1);end;Middle:=FloatToStr(IntPower(StrToInt(Mul1),StrToInt(Mul2)));Str:=Left+Middle+Right;First:=Pos('^',Str);end;
//定位第一个*号或/号的位置
MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);First:=MulPos;if(MulPos>DivPos)then First:=DivPos;if((DivPos=0)and(MulPos<>0))then begin First:=MulPos;DivPos:=2000;// 将除号所在位置设置成一个大于MulPos但又不可能的值
end;if((DivPos<>0)and(MulPos=0))then begin First:=DivPos;MulPos:=2000;// 将乘号所在位置设置成一个大于DivPos但不可能的值
end;while(First<>0)do //循环计算乘、除
begin tempStr:=Copy(Str,1,First-1);temp:=AnyLastPos(tempStr);Left:=Copy(Str,1,temp);Mul1:=Copy(Str,temp+1,First-temp-1);tempStr:=Copy(Str,First+1,Length(Str)-First);temp:=AnyFirstPos(tempStr);if(temp=200)then begin Mul2:=tempStr;Right:='';end else begin Mul2 :=Copy(tempstr,1,temp-1);Right:=Copy(tempStr,temp,Length(tempStr)-temp+1);end;if(MulPos>DivPos)then Middle:=IntToStr(StrToInt(Mul1)div StrToInt(Mul2))else Middle:=IntToStr(StrToInt(Mul1)*StrToInt(Mul2));Str:=Left+Middle+Right;
MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);First:=MulPos;if(MulPos>DivPos)then First:=DivPos;
if((DivPos=0)and(MulPos<>0))then begin First:=MulPos;DivPos:=2000;// 将除号所在位置设置成一个大于MulPos但又不可能的值
end;if((DivPos<>0)and(MulPos=0))then begin First:=DivPos;MulPos:=2000;// 将乘号所在位置设置成一个大于DivPos但不可能的值
end;end;//定位+、-号首先出现的位置
First:=AnyFirstPos(Str);if(First=200)then //如果没有+、-号,则可以直接返回结果
begin SubCompute:=StrToInt(Str);exit;end;Fuhao:=AnyFirstF(Str);//确定首先出现的符号是+号还是-号
while(First<>0)do begin //如果找到+号或-号
tempStr:=Copy(Str,1,First-1);temp:=AnyLastPos(tempStr);Left:=Copy(Str,1,temp);Mul1:=Copy(Str,temp+1,First-temp-1);tempStr:=Copy(Str,First+1,Length(Str)-First);temp:=AnyFirstPos(tempStr);if(temp=200)then begin Mul2:=tempStr;Right:='';end else begin Mul2 :=Copy(tempStr,1,temp-1);Right :=Copy(tempStr,temp,Length(tempStr)-temp+1);end;if(Fuhao='+')then Middle:=IntToStr(StrToInt(Mul1)+StrToInt(Mul2))else Middle:=IntToStr(StrToInt(Mul1)-StrToInt(Mul2));Str:=Left+Middle+Right;First:=AnyFirstPos(Str);if(First=200)then break;Fuhao:=AnyFirstF(Str);end;
SubCompute:=StrToInt(Middle);end;程序执行过程如下所示:
(1)定位字符串中第一个乘方符号“^”的位置First。这个式子中的First为4。
(2)如果存在乘方符号,即First不等于0,则继续进行计算,否则退出循环。
(3)进入循环体内部,得到“^”前面的子串tempStr(“3+2”),寻找tempStr中的最后一个运算符temp(这里是“+”),则Temp和First之间的字符就是乘方符号的第一个参数(“2”)。
(4)同样的逻辑,得到“^”后面的子串tempStr(“5/4”),寻找tempStr中的第一个运算符位置temp(“/”),则Temp和First之间的字符就是乘方符号的第二个参数(“5”)。
(5)去掉乘方符号和两个参数,得到左侧子串left(“3+”)和右侧子串right(“/4”)。
(6)利用这两个参数和乘方符号,计算乘方,将结果返回,并插入在left和right之间,得到一次计算后的新字符串(“3+32/4”)。
(7)判断新串内部是否包含“^”,如果包含,则返回到步骤(3),不包含则进入下一种运算。
第3章 “速算24”扑克游戏--单元、异常、逻辑
3.5 数学逻辑单元(3)5.计算整个表达式的值
TotalCompute函数利用循环,找到最内层的一对括号,然后调用SubCompute函数处理这一对括号中的表达式。SubCompute函数处理的表达式中已经没有括号了,因此SubCompute只需处理乘方、加、减、乘、除,返回结果,形成新的字符串。
当整个字符串缩减至空值时,整个表达式计算完成。
程序代码如下所示:
function TotalCompute(Str:String):integer;var First:integer;Last:integer;SubStr:String;LeftStr:String;Middle:String;Right:String;temp:integer;begin First:=LastDelimiter('(',Str);//定位最后一个(号位置 while(First<>0)do begin SubStr:=Copy(Str,First+1,Length(Str)-First);Last:= Pos(')',Str);//Last:=Last+First;//定位最后一个(号以后的最开始的)号位置
LeftStr:=Copy(Str,1,First-1);//(号左边的字符串
Middle:=Copy(Str,First+1,Last-First-1);//()号中间的字符串
Right:=Copy(Str,Last+1,Length(Str)-Last);//)号右边的字符串
temp:=SubCompute(Middle);//进入下面的计算
Middle:=IntToStr(temp);
Str:=LeftStr+Middle+Right;First:=LastDelimiter('(',Str);end;
Result:=SubCompute(Str);end;end.在程序中,“计算”按钮的OnClick事件处理程序中调用TotalCompute函数。函数中使用了一些数学函数和定位字符串的函数,这些函数Delphi已经在相应的系统单元中进行了定义,我们需要把这些系统单元包括到文件里面:
uses Sysutils,Math;将前面调用TotalCompute的注释去掉,把代码改回:
procedure TForm1.Button2Click(Sender: TObject);var result:integer;answer:String;begin result:=TotalCompute(Edit1.Text);if(result=24)then Application.MessageBox('您真行,我服了您!','对了',MB_OK)else begin
第四篇:c++24点游戏
c++24点游戏
#include “iostream” #include “string” using namespace std;
//定义Stack类
const maxsize=20;
enum Error_code { success, overflow, underflow };
template
bool empty()const;bool full()const;int size()const;void clear();
Error_code top(T &item)const;Error_code pop();
Error_code push(const T &item);private: int count;T entry[maxsize];};
template
template
bool Stack
template
bool Stack
template
template
template
Error_code Stack
template
Error_code Stack
template
Error_code Stack
Stack
int set;
// 判断程序中的异常,以便适时退出?//
void process(char c)
//计算两个数的 +-* / 运算// { int k=0;double a,b;sign.pop();
if(num.top(b)==success){
num.pop();
if(num.top(a)==success){ num.pop();k=1;} } if(k){ switch(c){
case '+': num.push(a+b);break;case '-': num.push(a-b);break;case '*': num.push(a*b);break;case '/': if(b==0){ set=4;num.push(-1);} else
num.push(a/b);break;} }
else {set=1;num.push(-1);} }
void get_command(string &str){
cout<<“n请输入要进行运算的表达式,包括” +,-,*,/,=,(,)“和数字,”< <<“注意: 以数字开头,等号结尾,中间括号要匹配.”< double do_command(const string &str){ string s=“"; double outcome=-1;char c; for(int i=0;str[i]!=' ';i++){ if(set!=0)break;//例外 则停止运行 while(1){ //分离数据与运算符 if(str[i]<='9' && str[i]>='0' || str[i]=='.'){ s+=str[i];i++;} else { if(s!=”“){ if(num.push(atof(s.c_str()))==overflow)set=3;s=”“;} break;} } char ch= str[i]; switch(ch){ //处理运算的优先级,并注意例外抛出 case '*': case '/': if(sign.top(c)==success)if(c=='*'||c=='/')process(c);if(sign.push(ch)==overflow)set=3;break;case '+': case '-': while(sign.top(c)==success){ if(c!='(')process(c);else break;} if(sign.push(ch)==overflow)set=3;break;case '(': if(sign.push(ch)==overflow)set=3;break;case ')': while(sign.top(c)==success){ if(c!='(')process(c);else break;} sign.pop();break;case '=': while(sign.top(c)==success){ if(c!='(')process(c);else break;} break; default: set=2;break;} } if(num.size()==1 && sign.size()==0)num.top(outcome);else set=1; if(set==0)cout<<”运算结果是:n“< if(set==1)cout<<”n您输入的不匹配,有错误发生。Result lost!“< if(set==4)cout<<”n 分母为0,不能进行除法运算,出现溢出,Lost result!“< return outcome;} void main()int f(){ double out;do { string str,s;set=0; get_command(str);s=str; if(str[0]=='-')str='0'+str;//处理表达式中的负号 for(int i=1;str[i]!=' ';i++){ if(str[i]=='-' && str[i-1]=='('){ str.insert(i,”0“);i++;} } out= do_command(str); cout< 我gai过此行 cout<<”如果你算的结果不等于24,需要重新计算请输入你算出的结果,程序有漏洞,请合作。“< return out;} int main(void) { int ii,zz,jj; printf(”0-12的4个数字nn“); for(jj=0;jj<2;) { for(ii=0;ii<4;ii++) { zz=rand()()% 12; cout< } cout<<”请用这4个数字算出24“< f(); cout<<”是否继续;是1否2"< cin>>jj; cout< } 双方选择一个角色,角色有攻击力法力值,体力值和生命值(根据不同卡属性不同)和一些特殊技能,种族,职业(有些无职业)。 双方选择自己组建的一副卡组进行对战,卡组由技能卡 法术卡 武器卡 装备卡。将对方生命削减为0则胜利 场地:武器区域,放置武器卡,双方最多装备一张双手武器或者两张单手武器(某些角色技能除外)重复装备武器卡则上一个装备的武器卡进入废卡区 装备区域,放置装备卡,双方最多装备一张装备卡(某些角色技能效果除外)如果重复装备装备卡则上一个装备的装备卡进入废卡区 魔物区域,召唤法术卡召唤的魔物放置在魔物区域,魔物区域只有一个。如果魔物区域已满则不能召唤魔物。 动作卡区域,动作卡区域一共两个,发动技能卡和法术卡时需放置在动作卡区域,如果动作卡区域满了则不能发动技能卡和法术卡。 废卡区域,放置用过的卡牌 回合流程 游戏开始时决定先手后手,先手起始抽3张卡,后手起始抽4张卡。 抽卡阶段:玩家抽2张卡体力值和法力值回复满,抽卡阶段开始和结束时可以判定或发动一些技能 行动阶段1:玩家可以发动角色技能,放置或者使用技能卡和法术卡或者装备武器卡和装备卡,发动技能卡需要消耗对应的体力,发动法术卡需要消耗对应的法力。对方玩家可以在你发动卡的时候使用放置在动作区域的特殊技能卡或者特殊法术卡或者使用角色的及时技能。 攻击阶段:玩家可以选择进入攻击阶段或者直接进入结束阶段。进入攻击阶段可以选择自己或者魔物攻击对方的角色或者魔物,选择攻击对象之后进入伤害计算阶段,伤害计算为双方进行战斗的魔物或者角色的生命值(或者护甲)减去双方对面的魔物或者角色的攻击力。 行动阶段2:同行动阶段1 结束阶段:进入结束阶段前双方可以发动放置在动作区域的特殊技能卡或特殊法术卡或者发动角色的及时技能效果。进入结束阶段后双方可以发动或者结算某些技能。 技能卡:需要消耗对应的体力值 技能卡分为普通技能卡,特殊技能卡,持续技能卡,特殊持续技能卡(既属于特殊技能卡又属于持续技能卡) 普通技能卡,先消耗体力值放置在动作卡区域然后处理效果,效果处理完后进入废卡区。 特殊技能卡,同普通技能卡,不同为可以在对方或者己方发动效果时进行连锁,连锁完之后处理效果顺序为后发动者先处理效果。 持续技能卡,消耗体力后放置在动作区域不尽然废卡区。 特殊持续技能卡,同时拥有特殊技能卡和持续技能卡的特点。 法术卡:需要消耗对应的法力值 法术卡分为普通法术卡,特殊法术卡,持续法术卡,特殊持续法术卡,召唤法术卡 普通法术卡,特殊法术卡,持续法术卡,特殊持续法术卡同技能卡,只是将消耗体力值改为消耗法力值 召唤法术卡,先消耗法力值然后直接放置在魔物区域。召唤法术拥有攻击力和生命值 武器卡,拥有攻击力和一些特殊效果,装备后角色攻击力会增加武器卡的攻击力,武器卡效果需要装备后才能生效。某些武器使用需要一些条件,写在了条件框里面,如兽族,战士。则武器只能给兽族战士装备。 装备卡,不拥有攻击力但有些装备卡有护甲值(在计算伤害是先计算护甲),其他同武器卡。 某些魔物和角色拥有技能,技能分为光环技能,主动技能,被动技能和及时技能。 光环技能:只要在场上就持续发挥效果的技能。 主动技能:在自己回合才能发的的技能 被动技能:在某些条件下必须触发的技能 及时技能:可以在自己回合主动使用也可以连锁在其他效果后面发动也可以在对方回合发动。第五篇:卡牌游戏策划说明书