如何用 GPT-4 帮你写游戏(以24点游戏举例)

news/2024/11/28 20:35:51/

目录

给我一个24点游戏

游戏规则

 GPT给的代码

​改进

 再改进


最近呢掀起了一阵GPT-4的热潮,很多人都想用GPT-4,这里呢我就打一个广告(嘿嘿),如果不知道国内如何使用GPT的,可以看看这个博客:GPT-4的免费使用方法分享(续)_我爱OJ的博客-CSDN博客

目前你想要用上 GPT-4,主要的渠道是 ChatGPT Plus 。作为交了订阅费的用户,你可以在对话的时候选择模型来使用。

另一种渠道,就是申请官方 API 的排队。我在申请通义千问的时候,耐心被折磨了4,5 天了,每天回家都兴致勃勃的看手机有没有短信。所以这次申请完就放在一边了。啥时候通过申请,听天由命吧。(所以这次我就拿国内的GPT-3.5来为大家测试)

给我一个24点游戏

游戏规则

“24点”是一种扑克牌游戏,正如象棋、围棋一样是一种人们喜闻乐见的娱乐活动。

它以自己独具的数学魅力和丰富的内涵正逐渐被越来越多的人们所接受。这种游戏方式简单易学,能健脑益智,是一项极为有益的活动。

具体内容及操作方法

一副牌中抽去大小王剩下52张,任意抽取4张牌,利用四则运算把牌面上的数算成24。每张牌能且只能用一次。

游戏技巧

1.利用3×8=24、4×6=24、2×12=24求解。

把牌面上的四个数想办法凑成3和8、4和6、2和12,再相乘求解。实践证明,这种方法是利用率最大、命中率最高的一种方法。

2.利用0、1的运算特性求解。

如3、4、4、8可组成3×8×(4÷4)=24。又如4、7、1、1可组成4×1(7-1)×1=24。

3.看4张牌中是否有2,3,4,6,8,Q,

如果有,考虑用乘法,将剩余的3个数凑成对应数。如果有两个相同的6,8,Q,比如已有两个6,剩下的只要能凑成3,4,5都能算出24,已有两个8,剩下的只要能凑成2,3,4,已有两个Q,剩下的只要能凑成1,2,3都能算出24,比如(9,J,Q,Q)。如果没有2,3,4,6,8,Q,看是否能先把两个数凑成其中之一。总之,乘法是很重要的,24是30以下公因数最多的整数。

4、将4张牌加加减减得到24。

5、先相乘再加、减去某数。

6、在计算过程中有分数出现。有一个规律,设4个数为a,b,c,d。必有ab+c=24或ab-c=24 d=a或b。若d=a 有a(b+c/a)=24 或 a(b-c/a)=24。只能用此法的只有17种。

7、在计算过程中有较大数(30以上)出现。相对较难,但有时也只有该解法。比如(6,9,9,10)为9×10÷6+9。

 GPT给的代码

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
double eval(string s) // 计算字符串表达式的值
{int len = s.size();int p = 0; // 指向当前遍历到的位置double ans = 0.0; // 累计所有项的和int op = 1; // 当前符号的正负号,1表示加法或正号,-1表示减法或负号int last_op = 1; // 上一个符号的正负号double num = 0.0; // 当前遍历到的数值while(p < len){char c = s[p];if(c == '+' || c == '-') // 遇到加减号{ans += op * last_op * num;num = 0.0;last_op = op = (c == '+') ? 1 : -1;}else if(c == '*' || c == '/') // 遇到乘除号{double next_num = 0.0;++p;while(p < len && '0' <= s[p] && s[p] <= '9')next_num = next_num*10 + s[p++] - '0';num = (c == '*') ? num * next_num : num / next_num;}else if(c == '(') // 遇到左括号{int cnt = 1;int q = p + 1;while(q < len && cnt > 0){if(s[q] == '(')++cnt;else if(s[q] == ')')--cnt;++q;}num = eval(s.substr(p+1, q-p-2));p = q;}else if(c == ' ') // 空格分隔符{++p;continue;}else // 遇到数字{num = num*10 + c - '0';++p;}}ans += op * last_op * num;return ans;
}
int main()
{srand(time(NULL)); // 初始化随机数生成器int a = rand()%9+1, b = rand()%9+1, c = rand()%9+1, d = rand()%9+1; // 生成四个1~9之间的整数cout << "请使用加、减、乘、除以及括号使得以下四个数构成算式的结果为24:" << endl;cout << a << " " << b << " " << c << " " << d << endl;bool found = false; // 标记是否找到合法的算式char ops[5] = {'+', '-', '*', '/'}; // 运算符集合for(int i=0; i<4 && !found; ++i) // 枚举第一个数到第四个数for(int j=0; j<4 && !found; ++j) // 枚举第二个数到第四个数if(j != i)for(int k=0; k<4 && !found; ++k) // 枚举第三个数到第四个数if(k != j && k != i)for(int l=0; l<4 && !found; ++l) // 枚举第四个数if(l != k && l != j && l != i){// 构造算式string s = "";s += to_string(a) + ops[i] + to_string(b) + ops[j] + to_string(c) + ops[k] + to_string(d);// 枚举中间结果的算式for(int i2=0; i2<4 && !found; ++i2)for(int j2=0; j2<4 && !found; ++j2)if(j2 != i2)for(int k2=0; k2<4 && !found; ++k2)if(k2 != j2 && k2 != i2){// 构造中间结果的算式string s2 = "";s2 += "(" + to_string(a) + ops[i] + to_string(b) + ")" + ops[i2] + "(" + to_string(c) + ops[j] + to_string(d) + ")" + ops[j2] + to_string(ops[k2] - '+' + '*');// 计算结果if(eval(s2) == 24){cout << "恭喜您,找到了一个合法的算式:" << endl;cout << s << " = " << eval(s) << endl;found = true;}}}if(!found)cout << "很遗憾,没有找到合法的算式。" << endl;return 0;
}

不出意外的话意外就要来了 

但是但是,我上网找了半天,终于知道为什么了,因为我的C++版本太低了,解决办法也很简单 ,如下

 依次点击菜单:工具(Tools)->编译选项(Compiler Options) -> 代码生成/优化(Settings) ->代码生成( Code Generation),找到最后一项语言标准(即Language standard),可以看到后面的选项默认是空的。

下拉选项栏,选中ISO C++11,点击确定后再进行编译就不会报错了

 运行后是这样的:

可以看到,没有输出结果,这时我就来气了,就对GPT说

改进

下面是改正后的代码

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stack>
#include <vector>
using namespace std;double eval(vector<string>& tokens) // 计算逆波兰表达式的值
{stack<double> nums;for(string& token: tokens){if(token == "+") // 加法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 + num2);}else if(token == "-") // 减法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 - num2);}else if(token == "*") // 乘法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 * num2);}else if(token == "/") // 除法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 / num2);}else // 数字{nums.push(stod(token)); // stod() 可以将字符串转换为 double 类型}}return nums.top();
}bool solve(vector<int>& nums, vector<string>& tokens) // 递归解决24点游戏
{if(nums.empty()) // 无数字剩余,得出解法{return eval(tokens) == 24;}for(int i=0; i<nums.size(); ++i){int num = nums[i];nums.erase(nums.begin() + i); // 去掉当前数tokens.push_back(to_string(num)); // 转换为字符串并加入逆波兰表达式if(solve(nums, tokens)) // 尝试解决剩余的数字return true;tokens.pop_back();nums.insert(nums.begin() + i, num); // 还原当前数}return false;
}int main()
{srand(time(NULL)); // 初始化随机数生成器vector<int> nums(4);for(int& num: nums)num = rand()%9+1; // 生成四个 1~9 之间的整数cout << "请使用加、减、乘、除以及括号使得以下四个数构成算式的结果为24:" << endl;cout << nums[0] << " " << nums[1] << " " << nums[2] << " " << nums[3] << endl;vector<string> tokens;if(solve(nums, tokens)) // 寻找解法{cout << "恭喜您,找到了一个合法的算式:" << endl;for(string& token: tokens)cout << token << " ";cout << "= 24" << endl;}else{cout << "很遗憾,没有找到合法的算式。" << endl;}return 0;
}

输出结果

 很明显,这边已经强多了,但是我能让它这么轻而易举吗,于是我继续提问题:

 再改进

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stack>
#include <string>
#include <vector>using namespace std;double eval(vector<string>& tokens) // 计算逆波兰表达式的值
{stack<double> nums;for (string& token : tokens) {if (token == "+") // 加法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 + num2);}else if (token == "-") // 减法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 - num2);}else if (token == "*") // 乘法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 * num2);}else if (token == "/") // 除法{double num2 = nums.top();nums.pop();double num1 = nums.top();nums.pop();nums.push(num1 / num2);}else // 数字{nums.push(stod(token)); // stod() 可以将字符串转换为 double 类型}}return nums.top();
}bool solve(vector<int>& nums, vector<string>& tokens, int step) // 递归解决24点游戏
{if (nums.empty()) // 无数字剩余,得出解法{if (eval(tokens) == 24){cout << "恭喜您,找到了一个合法的算式:" << endl;for (string& token : tokens)cout << token << " ";cout << "= 24" << endl;return true;}else{return false;}}if (step == 0) // 已经尝试了 5 次,输出如何用这些数字组成 24{cout << "很遗憾,五次机会已用完。以下是如何用这些数字组成 24。" << endl;return false;}for (int i = 0; i < nums.size(); ++i) {int num = nums[i];nums.erase(nums.begin() + i); // 去掉当前数tokens.push_back(to_string(num)); // 转换为字符串并加入逆波兰表达式if (solve(nums, tokens, step - 1))return true;tokens.pop_back();nums.insert(nums.begin() + i, num); // 还原当前数}return false;
}int main()
{srand(time(NULL)); // 初始化随机数生成器vector<int> nums(4);for (int& num : nums)num = rand() % 9 + 1; // 生成四个 1~9 之间的整数cout << "您有五次机会使用加、减、乘、除以及括号使得以下四个数构成算式的结果为 24:" << endl;cout << nums[0] << " " << nums[1] << " " << nums[2] << " " << nums[3] << endl;vector<string> tokens;bool found_solution = false; // 是否已经找到解法for (int i = 1; i <= 5; ++i) {cout << "第" << i << "次尝试:请输入您的算式(支持加减乘除和括号):" << endl;string input;getline(cin, input);tokens.push_back(input); // 将输入的字符串加入 vector 中if (eval(tokens) == 24){cout << "恭喜您,找到了一个合法的算式:" << endl;cout << input << " = 24" << endl;found_solution = true;break;}else if (i < 5){cout << "计算结果不为 24,请继续尝试。" << endl;}tokens.pop_back(); // 将输入的字符串从 vector 中弹出}if (!found_solution) // 五次机会用完,输出如何用这些数字组成 24{vector<string> empty_tokens;if (solve(nums, empty_tokens, 5)){// 已经在函数中输出了解法}else{cout << "无法组成 24,以下是如何使用这些数字组成 24:" << endl;// 输出如何用这些数字组成 24 的方法// ...}}return 0;
}

 GPT真的很认真修改代码,之后运行效果是这样的

 我不禁感慨了一句感慨:还学啥C++

当然,任何一个有经验的程序员,都可以站出来指出 GPT-4 辅助编程的种种缺点,然后断言它永远替代不了优秀的开发者。

你别忘了, GPT-4 发布才不到一年,目前一众大语言模型还在以狂飙的姿态进化中。再说了,谁说它的目标是替代「优秀的开发者」了?

目前,我还没有答案。想听听你的看法。欢迎留言,咱们一起交流讨论


http://www.ppmy.cn/news/96078.html

相关文章

动态分配内存new和delete

动态分配内存new和delete 栈&#xff1a;存储局部变量、函数参数和返回值。 栈区的效率很高&#xff0c;但是空间很小&#xff0c;如果需要处理大量的数据&#xff0c;就必须使用堆区的内存 动态分配内存new和delete 使用堆区的内存有四个步骤&#xff1a; 1&#xff09;声明…

网络规划与设计实验+配置案例报告+pkt

目录 第一部分&#xff1a;网络规划与设计实验..... 7 实验一 用户需求分析报告的撰写... 7 一、实验目的和要求... 7 二、实验内容... 7 三、实验步骤... 7 3.1 项目背景... 7 3.1.1 信息化发展趋势... 7 3.1.2 学校基本情况介绍... 8 3.1.3 学校对网络建设的基本要求…

Full-Scanner是一个多功能扫描工具,支持被动/主动信息收集,漏洞扫描工具联动,可导入POC和EXP

github项目地址&#xff1a;https://github.com/Zhao-sai-sai/Full-Scanner gitee项目地址&#xff1a;https://gitee.com/wZass/Full-Scanner 工具简介 做挖漏洞渗透测试有的时候要去用这个工具那个工具去找感觉麻烦我自己就写了一个简单的整合工具&#xff0c;有互联网大佬不…

Seata之@GlobalTransactional验证

下订单 -> 减库存 -> 扣余额 -> 改&#xff08;订单&#xff09;状态 1.数据库初始情况&#xff1a; 2.正常下单 http://localhost:2001/order/create?userId1&productId1&count10&money100 3.超时异常&#xff0c;没加GlobalTransactional 模拟Accou…

当下的程序员该如何面对复杂的就业坏境

已经2023年了&#xff0c;我们都知道现在开发趋向于年轻化&#xff0c;大部分都是90后、95后&#xff0c;毕竟&#xff0c;软件开发不像硬件开发一样&#xff0c;年限越高&#xff0c;相对来说越吃香。 31岁,前端工程师&#xff0c;工作经历8年&#xff0c;7年左右都在外包公司…

什么是C语言?

C语言是一种高级编程语言&#xff0c;于1972年由Dennis Ritchie在贝尔实验室开发出来。它是一种通用的、结构化的编程语言&#xff0c;被广泛用于系统软件、嵌入式系统、游戏开发以及科学计算等领域。 C语言的设计目标是提供一种简洁、高效、可移植的编程语言&#xff0c;以便…

Spring 事件相关知识ApplicationEvent

Spring 事件相关知识ApplicationEvent 事件工作流程相关类ApplicationListenerApplicationEvent 我们可以发布自己的事件ApplicationEventPublisher Spring框架中提供了多种事件类型&#xff0c;常用的几个事件类型如下&#xff1a; Spring 事件驱动模型是 Spring 框架中的一个…

SQL查询语言(3) 嵌套查询

如果不进行去重可能会出现一个情况 嵌套查询根据子查询的结果是否依赖于外层循环,分成相关子查询和不相关子查询 分类 IN 笔者总结&#xff1a;一般这种方法适用于查找有共性的元组&#xff0c;同一类事物比如查找和elsa选修相同科目的学生/选修相同科目的女同学。在后面我…