我正在尝试制作一个猜谜游戏,问题是我必须说出它花了多少次尝试,但只是为了计算独特的尝试。因此,如果我猜 1、2 和 3,则需要尝试 3 次,但如果我猜 1、1 和 2 或 1、2 和 1,则应该尝试 2 次。这是到目前为止我的游戏部分。
int g = 0;
int tries = 0;
// loop for the user to guess
while (g != numberToGuess) {
printf("Guess a number between 0 and 99: ");
cin >> g;
int t1 = 0, t2 = 0;
tries++;
if (g < numberToGuess) {
printf("The number is higher\n");
}
else if (g > numberToGuess) {
printf("The number is lower\n");
}
else if (g > 100) {
printf("Number has to be lower than 100. ");
}
else {
printf("You guess the correct number. You tried %d ", tries, tries == 1 ? "time" : "times");
break;
}
我正在尝试获取 g,我的猜测,并将其存储以将其与最后的猜测进行比较,以确定它是否相同。
正如已经指出的那样,你不能只存储一个变量,因为用户可以输入 1、2、3、1 等数字......所以你需要存储每个数字,最好的方法是使用数组.
while(g != numberToGuess){
printf("Guess a number between 0 and 99: ");
cin >> g;
//check if number is in array before storing it
//you will either have to write a function or use something like std::find
if(/*checkIfInArray*/) {
triesArray[tries] = g;
tries++;
}
.
.
.
}
如果允许您使用 std::find 搜索来了解如何使用它,如果不是,则只需创建一个函数,如果该元素在数组中,则返回 true,如果不在数组中,则返回 false。
使用 C++ std::set
C++ 提供了 std::set,它是一个包含唯一对象作为 keys 的容器。在您的情况下,对象是来自
0 - 99
的简单整数值,但对象的类型可以是任何类型。关键(没有双关语)是,由于对象存储为 std::set
的键,因此每个对象只能有一个,因此键将始终是唯一的。
因此,在您的情况下,您需要做的就是 std::set::insert 每个用户猜测,完成后该集合将保存用户所做的唯一猜测集。此时您需要做的就是获取该集合的
.size()
来获取用户的唯一条目数。
例如,您可以这样做:
#include <iostream>
#include <set>
int main (void) {
int g = -1, numberToGuess = 23; /* g, numberToGuess */
std::set<int> guesses{}; /* set of int */
/* loop for the user to guess */
while (g != numberToGuess) {
std::cout << "Guess a number between 0 and 99: ";
if (!(std::cin >> g)) {
std::cerr << " error: invalid integer input.\n";
return 1;
}
if (g < 0 || 99 < g) {
std::cout << "Number must be from 0 to 99\n";
continue;
}
guesses.insert(g); /* insert g in set - duplicates ignored */
if (g < numberToGuess) {
std::cout << "The number is higher\n";
}
else if (g > numberToGuess) {
std::cout << "The number is lower\n";
}
else {
size_t tries = guesses.size();
std::cout << "\nYou guessed the correct number. You tried " <<
tries << (tries == 1 ? " time.\n" : " times.\n");
break;
}
}
}
(注意:您正在使用C++,无需将C
stdio.h
输出函数与iostream
函数混合[有时这可能是有利的,但不是这里]。学习C++请注意使用它提供的功能。另请参阅为什么“使用命名空间 std;”被认为是不好的做法? - 对于简短的示例来说是可以的。只是要注意缺点)
示例使用/输出
./bin/numtoguess-set
Guess a number between 0 and 99: 23
You guessed the correct number. You tried 1 time.
或者更多尝试:
$ ./bin/numtoguess-set
Guess a number between 0 and 99: 50
The number is lower
Guess a number between 0 and 99: 25
The number is lower
Guess a number between 0 and 99: 10
The number is higher
Guess a number between 0 and 99: 20
The number is higher
Guess a number between 0 and 99: 22
The number is higher
Guess a number between 0 and 99: 23
You guessed the correct number. You tried 6 times.
始终确保您也处理无效的输入错误,例如
./bin/numtoguess-set
Guess a number between 0 and 99: 40
The number is lower
Guess a number between 0 and 99: What about 30?
error: invalid integer input.
使用简单的频率数组
如果您无法使用 C++ 提供的容器,则可以使用一个简单的 Frequency Array (初始化为全零),其中数组中有一个元素对应您需要跟踪唯一性或计数的每个可能值。当用户输入一个值时,您只需增加数组中该元素的数字即可。 (例如
guesses[g] += 1;
)当您需要确定猜测的唯一数量时,只需循环遍历数组并计算不为零的元素数量即可。1
重写代码以使用频率数组只需将
std::set
替换为您的数组,例如
#include <iostream>
#define VALUES_IN_RANGE 100
int main (void) {
int g = -1, numberToGuess = 23, /* g, numberToGuess */
guesses[VALUES_IN_RANGE] = {0}; /* array of 100 int initialized zero */
/* loop for the user to guess */
while (g != numberToGuess) {
std::cout << "Guess a number between 0 and 99: ";
if (!(std::cin >> g)) {
std::cerr << " error: invalid integer input.\n";
return 1;
}
if (g < 0 || 99 < g) {
std::cout << "Number must be from 0 to 99\n";
continue;
}
guesses[g] += 1; /* add one to the element at g */
if (g < numberToGuess) {
std::cout << "The number is higher\n";
}
else if (g > numberToGuess) {
std::cout << "The number is lower\n";
}
else {
int tries = 0;
/* loop over array to get number of unique tries */
for (int i = 0; i < VALUES_IN_RANGE; i++) {
if (guesses[i]) { /* if element non-zero */
tries += 1; /* add 1 to tries */
}
}
std::cout << "\nYou guessed the correct number. You tried " <<
tries << (tries == 1 ? " time.\n" : " times.\n");
break;
}
}
}
(输出相同)
在这里,由于您不关心每个猜测的计数,只关心用户是否猜测了该数字,因此您可以将数组设为
char
数组,并简单地设置 guesses[g] = 1;
每个节省 3 个字节- 存储中的元素。如果您要处理的值范围很大并且只需要唯一性,则需要考虑一些事情。
最后,这是一个提示,请将代码留出更多空间。这使得它更容易阅读和维护(特别是对于眼睛老的人来说)。您甚至可能会发现,当不查看所有表达式和运算符都紧密包装在一起的代码时,它可以让您更轻松地查找和解决错误。由你决定。
有两种方法可以解决这个问题。如果您还有其他问题,请告诉我。
脚注:
1. 在回答如何删除 C 中字符串中的重复字符时提供了对频率数组
的更完整解释我使用 std::set 得到了它
int g = -1;
int tries;
set<int> guesses{};
while(g != numberToGuess){
printf("Guess a number between 0 and 99: ");
if(!(cin >> g)){
printf("Error: Invalid input\n");
return 1;
}
if (g > 100 || g < 0) {
printf("Number has to be between 0 and 99.\n");
continue;
}
guesses.insert(g);
if (g > numberToGuess) {
printf("The number is lower\n");
} else if (g < numberToGuess) {
printf("The number is higher\n");
} else {
size_t tries = guesses.size();
printf("You guess the correct number. You tried %d %s ", tries, (tries == 1 ? "time\n" : "times\n"));
break;
}
}
虽然 git hub 自动评分不合作
我建议你省点麻烦。 for 循环可以管理递增
tries
并在做出正确猜测时终止循环。
由于循环仅在猜测正确时退出,因此成功消息也可能出现在循环之后。只要
tries
不是循环本地的,之后仍然可以打印。
我展示了如何使用
continue
跳过循环体的其余部分,并在输入不正确时进入下一次迭代。
int g = -1;
int tries;
for (tries = 1; g != numberToGuess, tries++) {
cout << "Guess a number between 0 and 99: ";
cin >> g;
if (g < 0 || g > 99) {
cout << "Number has to be between 0 and 100.\n";
continue;
}
if (g < numberToGuess) {
cout << "The number is higher.\n";
}
else {
cout << "The number is lower.\n";
}
}
cout << "You guessed the correct number. You tried "
<< tries << (tries == 1 ? "time" : "times")
<< endl;