第3章 作业
1.题目回顾:
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
1. 程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。
2.题目分析:
本次题目要求实现24点游戏,每次随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.算法设计:
对于基本要求,可以每次只运算两个数,第二次运算建立在第一次运算的结果作为其中一个数的基础上,第三次运算以此类推,这样就能将4张牌都运算完,用for循环并筛选出满足条件的情况进行运算,关于表达式重复的情况,可以用集合保存运算结果为24的表达式,每次在输出表达式前判断是否和之前的表达式重复,不重复才输出。
对于提高要求,计时器可以采用多线程的方法来进行设计,自定义一个继承Thread或实现Runnable接口的类,在run方法中具体设计实现,关于计算器,可以采用栈来进行设计,最后可以用FileWriter类对象将数据输出到文件中。
4.调试及测试:
一开始输出结果中发现表达式有重复的情况:
这是因为当时并未考虑到要将表达式与之前输出的表达式进行比较,只有当新的表达式与之前所有的表达式不同的时候才能输出。
修改前代码:
修改后代码:
输出结果:
发现并无重复的表达式,结果正确!
后来在设计线程的时候出现了新的问题,我将用于保存游戏规定时间的变量定义在了自己设计的线程类中,但是很快就发现主函数中需要访问这个变量,这样就行不通,仔细想想后,我将这个变量以静态的方式又定义在了一个专门的类中,为了便于统一数据,我将生命值以及得分变量一并定义在这个类中:
运行程序,用户输入一个表达式:
控制台中提示线程在休眠中被中断,这是因为当用户在规定的时间内输入表达式时,程序中就会让这个线程中断以停止计时,代码如下:
而run方法如下:
这样当线程被中断后就会退出循环,线程终止。
游戏结束将数据输出到文件中时发现文件中没有数据,经检查发现是因为write方法适用于对字符串进行操作。
修改前:
修改后:
修改后文件中终于有了数据。
程序最终结果:
5.总结:
24点游戏不愧是经典的游戏,其中囊括的知识不可谓不多,数组的运用,循环的巧妙结合,线程的设计,栈的设计,输入流,输出流,集合,随机数,这样一个小小的游戏竟是像麻雀一般,虽小,却五脏俱全,综合运用的能力通过这个题得到一个大的提升,线程的设计一开始令我苦不堪言,如何正确的终止一个线程困扰了我许久,最后经过查阅多方面的资料终于解决了这个问题,如何对这4张牌进行运算也是让我头疼不已,最后用结合数组以及循环的方法解决了这个问题,如何让表达式不重复又是一个问题,将表达式保存在集合中,当要输出表达式前遍历这个集合中的元素并进行比较,只有在不存在该表达式的情况下才输出这个表达式。
这次作业让我看清了一个事实,我的不足之处还有许多,还要多加学习并运用才行。