目录
记录一下本人一个下午完成的作业(代码量264行,字数近六千)-20230424
一、问题描述
这是一个包含不同小游戏的程序,可以通过选择菜单中的选项进行不同游戏的操作,主要包括三个小游戏,即1.猜数字,2.计算你认为的东西重要性,3.抽奖游戏。其中第二三个小游戏是前面的作业稍作修改,第一个小游戏也是较为常见的猜数游戏,因此实现难度尚可。下面简单介绍一下:
主函数中使用一个无限循环 while(1) 来持续显示游戏菜单并等待用户输入选择。在每个循环中,首先调用 displayMenu() 函数来显示游戏菜单,然后等待用户输入数字选项。用户输入的数字将被存储在 choice 变量中。接下来,使用 switch 语句根据用户选择的数字来调用相应的函数 game1()、game2() 或 game3(),或者当用户选择无效选项时,使用 exit(0) 函数退出程序。
1.game1()猜数字:程序会随机生成一个1到100之间的整数,用户需要猜测这个数字是多少,程序会根据用户猜的数字给出提示,直到用户猜中为止。将结果保存到文件中。
2.game2()计算你认为的东西重要性:用户需要输入一个字符串,程序会计算字符串中每个字符的值(a=1,b=2,以此类推),最后将所有字符的值加起来,得出一个总分数。用户可以重复输入字符串,程序会将每个字符串的得分累加。输出“某个单词的重要性也许是百分之几呢!”并将结果保存到文件中。
3. game3()抽奖游戏:用户需要输入三个数字,分别代表一等奖、二等奖和三等奖的数量。程序会随机生成若干个手机号码,然后随机抽取指定数量的手机号码,分别获得一等奖、二等奖和三等奖。将获奖名单保存至文件中。
代码还含有以下函数:displayMenu用于显示游戏菜单,openit用于打开并读取历史记录文件,letterValue用于计算一个字母的分值,calculatePercent用于计算一个字符串的总分值,generatePhoneNumber用于生成一个随机的手机号码,writeToFile用于将生成的手机号码写入文件,readFromFile用于从文件中读取手机号码,Prize类用于实现抽奖游戏的逻辑。
二、实现代码
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector> //向量
using namespace std;
void displayMenu() {//显示游戏菜单
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
cout << "+ 来玩游戏呀 +\n";
cout << "+ +\n";
cout << "+ 1. 猜数字 +\n";
cout << "+ 2. 计算你认为的东西重要性 +\n";
cout << "+ 3. 抽奖游戏 +\n";
cout << "+ 4. 退出 +\n";
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
}
void openit() { // 打开文件并读取历史记录
ifstream fin("game_history.txt");
if (!fin) {
cout << "File not found!" << endl;
} else {
string line;
while (getline(fin, line)) {
cout << line << endl;
}
fin.close();
}
}
int letterValue(char c) {//计算一个字母的分值
if (c >= 'a' && c <= 'z') {
return c - 'a' + 1;
} else if (c >= 'A' && c <= 'Z') {
return c - 'A' + 1;
} else {
return 0;
}
}
int calculatePercent(string word) {//计算一个字符串的总分值
int sum = 0;
for (char c : word) {// 遍历一个字符串中的每个字符
sum += letterValue(c);
}
return sum ;
}
//生成一个随机的手机号码
string generatePhoneNumber() {
string s = "1871"; // 输出手机号的前4位
for (int i = 0; i < 7; i++) { // 循环7次,生成手机号的后7位
s += to_string(rand() % 10); //随机生成数字,并转为字符串类型,拼接到s上
}
return s; //返回生成的手机号
}
//将生成的手机号码写入文件
void writeToFile(string filename, int n) {
ofstream outfile(filename); //创建输出文件流对象,打开文件
if (!outfile) { //如果无法打开文件,输出错误信息并退出程序
cerr << "无法打开文件" << endl;
exit(1);
}
for (int i = 0; i < n; i++) { // 循环n次,每次生成一个手机号
outfile << generatePhoneNumber() << endl; //将生成的手机号写入文件中
}
outfile.close(); //关闭文件流对象,保存文件
}
//从文件中读取手机号
vector<string> readFromFile(string filename) {
vector<string> result; //创建一个string向量result
ifstream infile(filename); //创建输入文件流对象,打开文件
if (!infile) { //如果无法打开文件,输出错误信息并退出程序
cerr << "无法打开文件" << endl;
exit(1);
}
string line; // 声明字符串变量,用于存储读取的手机号
while (getline(infile, line)) { //循环读取每行数据
result.push_back(line); //将每行数据存入result向量中
}
infile.close(); //关闭文件流对象
return result; //返回result向量
}
class Prize {//实现抽奖游戏
private:
int f, first_prize_num; //一等奖数量,因为后续会对num进行减少,然而最后需要恭喜所有人,所以引入f
int s, second_prize_num; //二等奖数量,同上
int t, third_prize_num; //三等奖数量
vector<string> first_prize;//已经抽到的一等奖向量
vector<string> second_prize;//已经抽到的二等奖向量
vector<string> third_prize;//已经抽到的三等奖向量
vector<string> numbers;//手机号
int total;//号码总数
int remaining;//剩下没抽过的号码
public:
Prize(int first, int second, int third, vector<string> nums) {//构造,赋值
f = first_prize_num = first;
s = second_prize_num = second;
t = third_prize_num = third;
numbers = nums;
total = nums.size();
remaining = total;
}
/*当剩余号码大于0时,随机获取一个号码,将其存入对应的奖项向量中,
并将该号码从号码向量中删除,直到所有奖项的数量都抽完为止。
如果奖项都抽完了,则输出中奖者的名单并退出程序。*/
void chou() {
cout << "按下任意键开始抽奖" << endl;
cin.get();
while (remaining > 0) {
int index = rand() % remaining;
string number = numbers[index];
numbers[index] = numbers[remaining - 1];
remaining--;
if (first_prize_num > 0) {//一等奖
first_prize.push_back(number);//存入
first_prize_num--;//数量-1
cout << "恭喜一等奖获得者:" << number << endl;
cout << "按下任意键继续抽奖" << endl;
cin.get();
} else if (second_prize_num > 0) {//二等奖
second_prize.push_back(number);
second_prize_num--;
cout << "恭喜二等奖获得者:" << number << endl;
cout << "按下任意键继续抽奖" << endl;
cin.get();
} else if (third_prize_num > 0) {//三等奖
third_prize.push_back(number);
third_prize_num--;
cout << "恭喜三等奖获得者:" << number << endl;
cout << "按下任意键继续抽奖" << endl;
cin.get();
} else {
cout << "所有奖项已抽完,感谢您的参与!" << endl;
cout << "再一次恭喜,今日的lucky dog:" << endl;
cout << "恭喜一等奖获得者:" ;
for (int i = 0; i < f; i++) {
cout << first_prize[i] << " ";
}
cout << endl;
cout << "恭喜二等奖获得者:" ;
for (int i = 0; i < s; i++) {
cout << second_prize[i] << " ";
}
cout << endl;
cout << "恭喜三等奖获得者:" ;
for (int i = 0; i < t; i++) {
cout << third_prize[i] << " ";
}
cout << endl;
ofstream fout("game_history.txt", ios::app); // ios::app 表示以追加模式打开文件
if (fout) {
fout << "恭喜一等奖获得者:" ;
for (int i = 0; i < f; i++) {
fout << first_prize[i] << " ";
}
fout << endl;
fout << "恭喜二等奖获得者:" ;
for (int i = 0; i < s; i++) {
fout << second_prize[i] << " ";
}
fout << endl;
fout << "恭喜三等奖获得者:" ;
for (int i = 0; i < t; i++) {
fout << third_prize[i] << " ";
}
fout << endl;
fout.close();
}
break;
}
}
}
};
void game1() {
srand(time(nullptr)); // 用时间作为随机数种子
int target = rand() % 100; // 生成 0-99 的随机数
int guess;
int count = 0;
bool win = false;
cout << "有一个0-99的数字,你猜是啥" << endl;
while (!win) {
cin >> guess;
cin.ignore(); // 忽略输入流中的回车符
if (guess == target) {
win = true;
cout << "恭喜你啦,总共猜了 " << count << " 次。" << endl;
} else if (guess < target) {
cout << "有点小,再猜一次吧" << endl;
} else {
cout << "太大了,再猜一次吧" << endl;
}
// 将猜测记录保存到文件中
ofstream fout("game_history.txt", ios::app); // ios::app 表示以追加模式打开文件
if (fout) {
stringstream ss;
ss << count << ": " << guess << " (" << (guess < target ? "猜小了" : "猜大了") << ")" << endl;
fout << ss.str();
fout.close();
}
count++;
}
}
void game2() {
cout << "游戏仅供参考,请勿迷信哈哈哈哈哈" << endl;
string word;
ofstream fout("game_history.txt", ios::app); // ios::app 表示以追加模式打开文件
if (!fout) { //如果无法打开文件,输出错误信息并退出程序
cerr << "无法打开文件" << endl;
exit(1);
}
cout << "请输入一个字符串(-1结束):" << endl;
while (1) {
cin >> word;
if (word == "-1") {
break;
}
int percent = calculatePercent(word);
cout << word << "的重要性也许是" << percent << "%呢!" << endl;//输出
fout << word << "的重要性也许是" << percent << "%呢!" << endl;//保存记录
}
fout.close(); //关闭文件流对象,保存文件
}
void game3() {
srand(time(NULL));
int n = 10; //生成的手机号数量
string filename = "num.txt";
writeToFile(filename, n);//生成随机手机号码并写入到文件中
vector<string> numbers = readFromFile(filename);//读取文件中的号码
Prize prize(1, 2, 5, numbers);//实例化Prize类
prize.chou();//进行抽奖
}
int main() {
openit();
int choice = 0;
while (1) {
displayMenu();
cout << "看看上面的菜单,请选择你想要进行游戏的数字" << endl;
cin >> choice;
switch (choice) {
case 1:
game1();
break;
case 2:
game2();
break;
case 3:
game3();
break;
default:
exit(0);
break;
}
}
return 0;
}
三、程序运行结果
其中txt文件内容如下,第一个保存的是历史记录,第二个是生成的电话号码