猜数字是经典入门游戏:程序随机生成 1~100 的秘密数字,不断猜测,程序提示"太大"或"太小",直到猜中。本文用面向对象实现——把状态装进类里,代码清晰易扩展,这正是 C++ 的核心思想。
玩法介绍
程序随机生成 1~100 的整数,你每次猜一个数,程序回答"太小/太大";猜中时打印全部猜测历史。二分最多 7 次猜中。
第 1 步:搭好骨架与主循环
先搭大框架:一个无限循环负责输入→判断→提示,逻辑稍后填入:
#include <iostream>
int main() {
std::cout << "猜数字游戏开始!范围 1~100\n";
int n;
while (true) {
std::cout << "请输入你的猜测: ";
std::cin >> n;
// 判断大小并提示(稍后实现)
}
return 0;
}
第 2 步:用类封装游戏状态
把秘密数字、范围、猜测历史这些状态,连同判断、记录等操作,一起装进一个 NumberGuesser 类。私有成员保证外部无法直接篡改秘密数字,只能通过公开接口与游戏交互——这就是封装:
class NumberGuesser {
private:
int secret_ = 0; // 秘密数字
int max_ = 100; // 范围上限
std::vector<int> history_; // 猜测历史
public:
explicit NumberGuesser(int max) : max_(max) { reset(); }
void reset(); // 重新生成秘密数字
bool guess(int n); // 记录猜测并判断
int compare(int n) const; // -1 太小 / 0 猜中 / 1 太大
const std::vector<int>& history() const { return history_; }
};
第 3 步:生成真正的随机数
C 时代的 rand() 质量一般,现代 C++ 用 <random>:std::random_device 提供种子,std::mt19937 是梅森旋转引擎,uniform_int_distribution 生成均匀整数:
void NumberGuesser::reset() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(1, max_);
secret_ = dist(gen);
history_.clear();
}
每次调用 reset(),秘密数字都不同,历史记录也在此清空。
第 4 步:记录猜测历史
用 std::vector 保存每次猜测——自动扩容、按下标访问。把"记录"和"判断"合并进 guess(),调用一次完成两件事:
bool NumberGuesser::guess(int n) {
history_.push_back(n);
return n == secret_;
}
int NumberGuesser::compare(int n) const {
if (n < secret_) return -1;
if (n > secret_) return 1;
return 0;
}
第 5 步:完整代码与编译运行
拼成 guess.cpp 编译运行,猜中后打印完整猜测历史:
#include <iostream>
#include <random>
#include <vector>
class NumberGuesser {
private:
int secret_ = 0;
int max_ = 100;
std::vector<int> history_;
public:
explicit NumberGuesser(int max) : max_(max) { reset(); }
void reset() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(1, max_);
secret_ = dist(gen);
history_.clear();
}
bool guess(int n) {
history_.push_back(n);
return n == secret_;
}
int compare(int n) const {
if (n < secret_) return -1;
if (n > secret_) return 1;
return 0;
}
const std::vector<int>& history() const { return history_; }
};
int main() {
NumberGuesser game(100);
std::cout << "猜数字:1~100,开始吧!\n";
int n;
while (true) {
std::cout << "> ";
std::cin >> n;
if (game.guess(n)) {
std::cout << "恭喜!共猜了 " << game.history().size() << " 次。\n";
break;
}
if (game.compare(n) < 0) std::cout << "太小了!\n";
else std::cout << "太大了!\n";
}
std::cout << "猜测记录:";
for (int h : game.history()) std::cout << " " << h;
std::cout << "\n";
return 0;
}
g++ -std=c++17 -o guess guess.cpp
./guess
把范围改成 1~1000 试试;再想想输入非数字时 std::cin 会怎样?这是你的第一个"健壮性"练习。
💡 改进方向:① 给guess()加输入合法性检查;② 统计平均猜中次数,对比二分最优解;③ 支持"你出题,电脑猜"的反向模式;④ 用std::map统计各数字被猜中次数。