游戏设计需求:
随机给出4个数字,玩家通过输入由这4个数字以及加减乘除括号运算符组成的表达式,若表达式结果为24则分数加一,玩家可以通过查询答案查询最少一组答案
程序截图:
开始界面
游戏界面
回答正确
回答错误
防错处理
程序设计
游戏准备:随机生成4个1~9的数字,通过穷举法列举所有可能的表达式若,若没有结果为24则重新生成,若有记录第一次的表达式并记录下来作为玩家可以用来查询的答案
游戏过程:由玩家输入一个表达式,利用栈运算求值判断是否正确
程序内容
引用的头文件
Windows——使用函数ZeroMemory()使指针所指内容清0
algorithm——使用函数next_permutation()生成数列的全排列,用于穷举法寻找答案栈运算
https://blog.csdn.net/believe_s/article/details/76473908——栈在表达式中的应用
玩家输入一个表达式,如何计算这个表达式是游戏的核心内容,难点在于传统的运算表达式为中缀表达式,例如4*(2+2*2),,运算符是包含在数字之间(中缀的含义),有先乘除后加减的优先级顺序,以及有括号能够改变优先级,通过程序计算的难度比较大,因此选择通过栈将中缀表达式转化为后缀表达式,如4222*+*的形式,这个时候计算就不用考虑括号跟乘除的优先级,简化了计算时需要考虑的因素
//转化函数:将中缀表达式转化后后缀表达式,将表达式以队列的形式返回(使用栈的话需要把最终的结果反过来才是后缀表达式)
queue<char> _24::change(char *expression) {
//error为类中变量代表表达式的输入是否错误,错误则为true
queue<char> exp;
stack<char> sign; //储存符号的栈
char *p = expression;
for (; *p != 0; p++) {
if (*p <= '9'&&*p > '0') exp.push(*p); //若指针的值为数字则入队
else { //若指针的值为符号
if (sign.empty() || *p == '(') {
sign.push(*p); //如果符号栈为空或者遇到左括号符号直接入栈
}
else if ( *p == '+' || *p == '-') {
//若符号为加减,因为加减的优先级是最低的,所以意味着前面的符号运算已经告一段落不需要在栈中储存了,因此将储存栈的符号入队
while ( !sign.empty()&&sign.top() != '(')
{
exp.push(sign.top());
sign.pop();
}
sign.push(*p);
}
else if (*p == '*' || *p == '/') {
//因为乘除的优先级关系,只能代表之前的乘除运算完成,不难代表加减完成,因此只有乘号跟除号出栈入队
while (!sign.empty() && sign.top()!='('&&(sign.top() == '*'||sign.top() == '/'))
{
exp.push(sign.top());
sign.pop();
}
sign.push(*p);
}
else if (*p == ')') {
//遇到右括号,将左括号之前的符号入队,并且让左括号出栈(不用入队),如果找不到左括号则表达错误
while (!sign.empty() && sign.