save code

This commit is contained in:
xsl
2026-05-16 11:09:02 +08:00
parent 478b3451a1
commit a169ceb263
45 changed files with 2226 additions and 0 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
#include <iostream>
int main() {
std::cout << "欢迎来到抽卡世界!\n";
return 0;
}
BIN
View File
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
#include <iostream>
int main() {
int pulls = 1083;
std::cout << "你还剩 " << pulls << " 次抽卡机会\n";
int coins = 50;
std::cout <<"你的金币:" << coins << "\n";
std::cout << "抽卡次数" << pulls << " ,金币" << coins << "\n";
pulls = pulls - 1;
return 0;
}
BIN
View File
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
#include <iostream>
int main() {
int pulls = 0;
std::cout << "你想抽几次?";
std::cin >> pulls;
std::cout << "好,我们准备抽 " << pulls << "\n";
return 0;
}
BIN
View File
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int r = std::rand() % 101;
std::cout << " 随机数 " << r << "\n";
return 0;
}
BIN
View File
Binary file not shown.
+23
View File
@@ -0,0 +1,23 @@
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int r =std::rand() % 101;
std::cout << " 随机数 " << r << "\n";
if ( r < 70)
{
std::cout << " 普通卡 " << "\n";
}
else if (r < 95)
{
std::cout << " 稀有卡" << "\n";
}
else
{
std::cout << " 传说卡 " << "\n";
}
return 0;
}
BIN
View File
Binary file not shown.
+29
View File
@@ -0,0 +1,29 @@
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int n = 0;
int i = 0;
std::cout << " 抽几次?" << "\n";
std::cin >> n;
for(i =1;i <= n;i++)
{
int r = std::rand() % 101;
std::cout << "" << i << "" << r << "\n";
if(r < 70)
{
std::cout << " 普通卡" << "\n";
}
else if( r < 95)
{
std::cout << " 稀有卡" << "\n";
}
else
{
std::cout << " 传说卡" << "\n";
}
}
}
BIN
View File
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
#include <iostream>
#include <string>
int main() {
std::string cards[3];
cards[0] = "小火龙";
cards[1] = "皮卡丘";
cards[2] = "妙蛙种子";
int id = 0;
std::cin >> id;
std::cout << "你选中的卡:" << cards[id] << "\n";
return 0;
}
BIN
View File
Binary file not shown.
+20
View File
@@ -0,0 +1,20 @@
#include <iostream>
#include <cstdlib>
#include <ctime>
void draw_once() {
int r = std::rand() % 100;
if (r < 70) std::cout << "普通\n";
else if (r < 95) std::cout << "稀有\n";
else std::cout << "超稀有\n";
}
int main() {
std::srand(std::time(nullptr));
int n = 0;
std::cout << "抽几次?";
std::cin >> n;
for ( int i =1; (i <= n && i < 100 && n<=100); i++)
{
std::cout << "" << i << "";
draw_once();
}
return 0;}
BIN
View File
Binary file not shown.
+100
View File
@@ -0,0 +1,100 @@
#include <iostream>
#include <cstdlib>
#include <ctime>
void draw_once() {
int r = std::rand() % 111;
if (r < 50) std::cout << "R\n";
else if (r < 80) std::cout << "SR\n";
else if (r < 100) std::cout << "SSR\n";
else if (r < 105) std::cout << "UR\n";
else if (r < 109) std::cout << "TR\n";
else std::cout << "USR\n";
}
int main() {
int coins = 0;
std::srand(std::time(nullptr));
while (true) {
flag:
std::cout << "现在有:" << coins << "金币" << "\n";
std::cout << "\n===== 抽卡小游戏 =====\n";
std::cout << "1 抽一次\n";
std::cout << "2 说明\n";
std::cout << "3 增加金币\n";
std::cout << "4 稀有度查看\n";
std::cout << "0 退出\n";
std::cout << "请选择:";
int choice = 0;
std::cin >> choice;
if (choice == 1){
std::cout << "抽几次?(最大100" << "\n";
int n = 0;
std::cin >> n;
if (coins < n*10){
std::cout << "金币不足,请增加金币,或者减少遍数" << "\n";
std::cout << "将跳转到菜单,请按回车" << "\n";
std::cin.ignore();
std::cin.get();
continue;
}
for ( int i =1; (i <= n && i <= 100 && n<=100 ); i++)
{
std::cout << "" << i << "";
draw_once();
coins -= 10;
}
}
if (choice == 2){
std::cout << "说明:这是一个抽卡游戏,你可以通过抽卡来获得各种等级的卡牌。\n"
"有普通稀有传说,并且还可以查看稀有度分配,每抽一次花费10金币。\n"
"若金币不够,可以去菜单增加金币,或者减少抽卡遍数。并且抽卡遍数最高100。\n";
std::cout << "将跳转到菜单,请按回车" << "\n";
std::cin.ignore();
std::cin.get();
continue;
break;
}
if (choice == 3){
std::cout << "请输入增加金币的数量(最大10000" << "\n";
int add = 0;
std::cin >> add;
coins += add;
std::cout << "增加成功,现在有:" << coins << "金币" << "\n";
std::cout << "将跳转到菜单,请按回车" << "\n";
std::cin.ignore();
std::cin.get();
continue;
break;
} if (choice == 4){
std::cout <<"R45.05% SR27.03% SSR18.02% UR4.50% TR3.60% USA1.80%\n";
std::cout << "将跳转到菜单,请按回车" << "\n";
std::cin.ignore();
std::cin.get();
continue;
break;
}
if (choice == 0){
choice:
std::cout << "你确定吗?(确定选0 返回菜单选1" << "\n";
int confirm = 0;
std::cin >> confirm;
if (confirm == 0){
goto end;
}
else if (confirm == 1){
goto flag;
}
else{
std::cout << "输入错误,请重新输入。" << "\n";
goto choice;
}
}
std::cout << "将跳转到菜单,请按回车" << "\n";
std::cin.ignore();
std::cin.get();
continue;
}
end:
return 0;
}
+81
View File
@@ -0,0 +1,81 @@
# 学习进度与状态
用来记录 **每一课的学习状态**、**课堂练习**和**课后作业**是否完成。建议每学完一课或做完作业后 **马上改一次**,避免忘记。
---
## 状态说明
### 学习状态(`学习状态`
| 填写值 | 含义 |
|--------|------|
| `未开始` | 还没打开这一课的文档或视频。 |
| `进行中` | 正在学,还没认为「这一课学完了」。 |
| `已完成` | 这一课的内容已学完,理解主要目标。 |
### 课堂练习(`课堂练习`
| 填写值 | 含义 |
|--------|------|
| `未完成` | 文档里的「课堂小练习」还没做完。 |
| `已完成` | 课堂小练习已做完(可简单写一句在备注里)。 |
| `无` | 该课没有单独列课堂练习(可填 `无``-`)。 |
### 课后作业(`课后作业`
| 填写值 | 含义 |
|--------|------|
| `未完成` | 有布置作业但还没做。 |
| `已完成` | 作业已做。 |
| `无` | 该课没有课后作业或选择不做。 |
| `选做未完成` | 作业是选做,还没做。 |
| `选做已完成` | 选做作业已完成。 |
---
## 总览表(请按需修改)
| 课次 | 学习状态 | 课堂练习 | 课后作业 | 备注 | 最后更新 |
|------|----------|----------|----------|------|----------|
| 第01课 欢迎来到抽卡世界 | 已完成 | 已完成 | 已完成 | 第1课含选做作业已完成 | 2026-04-11 |
| 第02课 小盒子与数字 | 已完成 | 已完成 | 已完成 | 第2课含选做作业已完成 | 2026-04-11 |
| 第03课 听玩家的话 | 已完成 | 已完成 | 选做未完成 | `lession3.cpp`:cin 读入 pulls 已完成;选做作业见第3课文档 | 2026-04-11 |
| 第04课 运气来了 | 已完成 | 已完成 | 选做未完成 | `lession4.cpp`;选做作业见第4课文档 | 2026-04-11 |
| 第05课 稀有度与判断 | 已完成 | 已完成 | 选做未完成 | `lession5.cpp`;选做作业见第5课文档 | 2026-04-11 |
| 第06课 循环与多抽 | 已完成 | 已完成 | 选做未完成 | `lession6.cpp`;选做作业见第6课文档 | 2026-04-11 |
| 第07课 卡片与数组 | 已完成 | 已完成 | 选做未完成 | `lession7.cpp`;选做作业见第7课文档 | 2026-04-11 |
| 第08课 函数与抽一次 | 已完成 | 已完成 | 选做未完成 | `lession8.cpp`;选做作业见第8课文档 | 2026-04-11 |
| 第09课 菜单与循环 | 未开始 | 未完成 | 未完成 | 详见 `第09课-菜单与循环.md` | |
| 第10课 综合项目 | 未开始 | 未完成 | 未完成 | | |
> **说明**:第 10 课独立讲义见 `第10课-综合小项目.md`(若尚未创建,可先对照总教程 `教程-抽卡游戏-C++-10课.md` 第 10 节)。
---
## 快速记录区(可选)
把最近几次学习用一两句话写在这里,方便回顾:
```
日期:2026年04月11日 学了第3课,完成 lession3.cppcin 输入抽卡次数)
日期:____________________ ____________________________________
```
---
## 文件对应关系
| 文件 | 用途 |
|------|------|
| `教程-抽卡游戏-C++-10课.md` | 10 课总目录与全部示例代码摘要 |
| `第01课-欢迎来到抽卡世界.md` | 第 1 课详细步骤与练习 |
| `第02课-小盒子与数字.md` | 第 2 课:变量 `int`、赋值、与抽卡相关的命名 |
| `第03课-听玩家的话.md` | 第 3 课:`std::cin` 读入整数、提示语、连续输入 |
| `第04课-运气来了.md` | 第 4 课:`rand` / `srand` / `time``%` 限定范围 |
| `第05课-稀有度与判断.md` | 第 5 课:`if` / `else if` / `else`、稀有度区间 |
| `第06课-循环与多抽.md` | 第 6 课:`for`、输入 `n`、每抽独立 `r` |
| `第07课-卡片与数组.md` | 第 7 课:`string` 数组、下标、`rand % n` 抽名 |
| `第08课-函数与抽一次.md` | 第 8 课:`void`、自定义函数、`draw_once`、与 `for` 配合 |
| `第09课-菜单与循环.md` | 第 9 课:`while (true)``break`、菜单与 `draw_once` |
| `学习进度与状态.md` | 本文件:进度与作业勾选 |
+259
View File
@@ -0,0 +1,259 @@
# 用 C++ 做命令行抽卡游戏 · 10 课时教程
面向 **8 岁左右** 学习者,只在 **命令行** 用输入输出完成抽卡游戏,并系统练习 C++ 基础。每课约 **2040 分钟**,建议家长陪同。
---
## 总说明(给家长)
- **工具**:安装 C++ 编译器(例如 Mac 上 Xcode Command Line Tools 的 `clang++`)。
- **原则**:先能运行出字,再变好玩;报错很正常,改一行再编译。
- **抽卡**:用随机数模拟概率,不涉及真实金钱或充值。
---
## 第 1 课:程序和「打招呼」
**目标**:理解程序是一行行指令;能编译运行,屏幕出现一句话。
**要点**`main`、花括号 `{}``std::cout`、分号 `;`、字符串用双引号。
详见:`第01课-欢迎来到抽卡世界.md`
---
## 第 2 课:数字和「小盒子」(变量)
**目标**:用 `int` 存数,例如「还剩几次抽奖机会」。
**要点**:变量名、赋值 `=``int`
详见:`第02课-小盒子与数字.md`
```cpp
#include <iostream>
int main() {
int pulls = 3;
std::cout << "你还剩 " << pulls << " 次机会\n";
return 0;
}
```
---
## 第 3 课:听玩家的话(输入)
**目标**:用键盘输入数字,程序记住。
**要点**`std::cin``>>`
详见:`第03课-听玩家的话.md`
```cpp
#include <iostream>
int main() {
int pulls = 0;
std::cout << "你想抽几次?";
std::cin >> pulls;
std::cout << "好,我们准备抽 " << pulls << "\n";
return 0;
}
```
---
## 第 4 课:运气来了(随机数)
**目标**:每次运行可能得到不同结果,为「抽到什么」做准备。
**要点**`rand()``srand()``time()`;随机种子在程序开始时设一次。
详见:`第04课-运气来了.md`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int r = std::rand() % 100;
std::cout << "随机数:" << r << "\n";
return 0;
}
```
---
## 第 5 课:稀有度(条件判断)
**目标**:根据随机数决定普通 / 稀有 / 超稀有。
**要点**`if``else if``else`、比较运算符。
详见:`第05课-稀有度与判断.md`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int r = std::rand() % 100;
std::cout << "你抽到了:";
if (r < 70) {
std::cout << "普通卡\n";
} else if (r < 95) {
std::cout << "稀有卡\n";
} else {
std::cout << "超稀有卡!!\n";
}
return 0;
}
```
---
## 第 6 课:一口气抽很多次(循环)
**目标**:按玩家说的次数重复「抽一次」。
**要点**`for``while`、循环变量。
详见:`第06课-循环与多抽.md`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int n = 0;
std::cout << "抽几次?";
std::cin >> n;
for (int i = 1; i <= n; i++) {
int r = std::rand() % 100;
std::cout << "" << i << "抽:";
if (r < 70) std::cout << "普通\n";
else if (r < 95) std::cout << "稀有\n";
else std::cout << "超稀有\n";
}
return 0;
}
```
---
## 第 7 课:给卡片起名字(数组)
**目标**:用编号对应卡名,抽中编号再打印名字。
**要点**:数组 `[]`、下标从 0 开始、`std::string`
详见:`第07课-卡片与数组.md`
```cpp
#include <iostream>
#include <string>
int main() {
std::string cards[3];
cards[0] = "小火龙";
cards[1] = "皮卡丘";
cards[2] = "妙蛙种子";
int id = 1;
std::cout << cards[id] << "\n";
return 0;
}
```
进阶:把第 6 课的随机结果映射到 `cards[id]`
---
## 第 8 课:把「抽一次」变成积木(函数)
**目标**:用函数让代码更短、更好读。
**要点**`void`、自定义函数名。
详见:`第08课-函数与抽一次.md`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
void draw_once() {
int r = std::rand() % 100;
if (r < 70) std::cout << "普通卡\n";
else if (r < 95) std::cout << "稀有卡\n";
else std::cout << "超稀有卡\n";
}
int main() {
std::srand(std::time(nullptr));
draw_once();
draw_once();
return 0;
}
```
---
## 第 9 课:像游戏一样玩(简单菜单)
**目标**:循环显示菜单:抽卡 / 说明 / 退出。
**要点**`while (true)``break`、用整数表示选项。
详见:`第09课-菜单与循环.md`
流程:显示菜单 → 读选项 → 选抽卡则调用抽卡函数 → 选退出则结束。
---
## 第 10 课:小项目整合(迷你抽卡游戏)
**目标**:把前面内容串成可玩的一版。
建议包含:欢迎语与菜单、抽奖次数或「金币」、随机与稀有度、可选统计稀有数量、退出。
不要求:图形界面、网络、文件存档(本教程以命令行为主)。
---
## 知识点对照表
| 课次 | 主要语法与概念 |
|------|----------------|
| 1 | 程序结构、`#include``main``cout`、字符串 |
| 2 | `int`、变量 |
| 3 | `cin`、输入 |
| 4 | `rand` / `srand``%``ctime` |
| 5 | `if` / `else`、比较 |
| 6 | `for` 循环 |
| 7 | `string`、数组、下标 |
| 8 | 自定义函数、`void` |
| 9 | `while`、菜单与流程 |
| 10 | 综合与小项目习惯 |
---
## 给小朋友的简单比喻
- 程序像 **乐高说明书**:一行一行,电脑照做。
- 变量像 **贴了名字的小盒子**
- `if`**岔路口**
- 函数像 **拼好的积木块**,需要时拿来用。
- 抽卡是 **随机数假装运气**,和扭蛋类似,只是在电脑里。
---
*进度与每课作业完成情况请见:`学习进度与状态.md`*
+103
View File
@@ -0,0 +1,103 @@
# 第 1 课:欢迎来到抽卡世界
**本课目标**:写出第一个 C++ 程序,让屏幕「打招呼」。学会保存代码、编译、运行。
---
## 1. 这一课要搞懂什么
- 程序就是给电脑的一串指令,电脑从上到下执行。
- 我们写的文字要放在一个叫 **源文件** 的东西里,一般用 `.cpp` 结尾,例如 `hello.cpp`
- 电脑看不懂 `.cpp` 直接运行,要先 **编译**:把人类写的代码变成电脑能执行的程序。
---
## 2. 第一个程序长什么样
复制下面代码到 `hello.cpp`(名字可以自定,只要是 `.cpp`):
```cpp
#include <iostream>
int main() {
std::cout << "欢迎来到抽卡世界!\n";
return 0;
}
```
### 每一部分在说什么(不用背,多看几次)
| 代码 | 意思(小朋友版) |
|------|------------------|
| `#include <iostream>` | 请把「在屏幕上写字」的工具拿来用。 |
| `int main() { ... }` | 程序从这里开始跑,`main` 像大门。 |
| `std::cout << ...` | 往屏幕上输出文字。 |
| `"...\n"` | 一串字;`\n` 表示换一行。 |
| `return 0;` | 告诉系统:正常结束啦。 |
| `;` | 一句话结束要像中文句号一样写分号。 |
---
## 3. 怎么编译和运行(Mac 举例)
在终端里进入你放 `hello.cpp` 的文件夹,然后:
```bash
clang++ -std=c++17 -o hello hello.cpp
./hello
```
如果装了 `g++`,也可以:
```bash
g++ -std=c++17 -o hello hello.cpp
./hello
```
屏幕上应出现:`欢迎来到抽卡世界!`
---
## 4. 本课课堂小练习
1.`"欢迎来到抽卡世界!"` 改成你自己编的一句欢迎语。
2. 再写一行 `std::cout`,让程序多说一句话(比如你的名字或你喜欢的动物)。
示例(第二句要自己改内容):
```cpp
#include <iostream>
int main() {
std::cout << "欢迎来到抽卡世界!\n";
std::cout << "我是某某某,我们开始吧!\n";
return 0;
}
```
---
## 5. 本课课后作业(选做)
- 让程序连续输出 **三行** 不同的字,像小海报一样。
- 问家长:如果少了一个分号 `;`,编译器会报什么错?把错误信息读一遍(不用懂每个词,习惯「有错就改」即可)。
---
## 6. 常见小问题
- **找不到命令 `clang++`**:需要先安装 Xcode Command Line Tools(可请家长搜索安装方法)。
- **改完代码还是旧输出**:确认保存了文件,并且重新编译再运行。
- **中文乱码**:终端编码问题,本课可先全用英文测试;需要中文时再和家长一起调终端编码。
---
## 7. 下一课预告
第 2 课会学 **变量**:用「小盒子」记住数字,比如还剩几次抽奖机会。
---
*学完请家长在 `学习进度与状态.md` 里更新第 1 课的状态与作业完成情况。*
**下一课文档**`第02课-小盒子与数字.md`
+136
View File
@@ -0,0 +1,136 @@
# 第 2 课:小盒子与数字(变量)
**本课目标**:学会用 **`int` 变量** 在程序里「记住一个整数」,并把它显示出来。为后面的「还剩几次抽卡」「有多少金币」打基础。
**复习**:第 1 课你已经会用 `std::cout` 输出文字。本课在输出里加上 **会变的数字**
---
## 1. 这一课要搞懂什么
- 有时候程序要记住一个数,比如「还能抽几次」——这个数会变化,不能写死在引号里。
- 在 C++ 里可以用 **`变量`**:像贴了小纸条的 **小盒子**,盒子里放一个整数。
- 整数类型常写作 **`int`**(integer 的缩写,先记住这三个字母即可)。
---
## 2. 第一个用变量的例子
把下面保存为 `lesson2.cpp`(文件名可自定,扩展名用 `.cpp`):
```cpp
#include <iostream>
int main() {
int pulls = 3;
std::cout << "你还剩 " << pulls << " 次抽卡机会\n";
return 0;
}
```
### 每一部分在说什么
| 代码 | 意思(小朋友版) |
|------|------------------|
| `int pulls = 3;` | 准备一个装整数的盒子,名字叫 `pulls`,里面先放 **3**。 |
| `pulls` | 变量名,像盒子上写的名字,方便我们引用。 |
| `=` | 把右边的值放进左边的盒子里(叫「赋值」)。 |
| `std::cout << "你还剩 " << pulls << " 次..."` | 先输出前半句,再输出 **盒子里的数**,再输出后半句。 |
运行后应看到类似:`你还剩 3 次抽卡机会`
---
## 3. 改一改盒子里的数
变量的好处:**改一个数字,整段话跟着变**。
```cpp
#include <iostream>
int main() {
int pulls = 10;
std::cout << "你还剩 " << pulls << " 次抽卡机会\n";
return 0;
}
```
`10` 改成 `0``100`,重新编译运行,看屏幕上的数字是否跟着变。
---
## 4. 变量名的小规矩(先记这几条)
- 只能用字母、数字、下划线 `_`**不能以数字开头**。
- 同一个 `{ ... }`**不要** 起两个一模一样的名字。
- 名字要有意义:抽卡次数用 `pulls``cishu` 比叫 `a` 更容易看懂(拼音也可以,但以后大项目更推荐英文习惯)。
---
## 5. 和抽卡游戏的关系(先预告)
| 以后会用到的想法 | 用变量表示 |
|------------------|------------|
| 还剩几次抽奖 | `int pulls``int chouka_cishu` |
| 有多少金币 | `int coins` |
| 抽到了几张稀有 | `int rare_count` |
本课只练 **`int`**,能存正负整数;小数以后再说。
---
## 6. 怎么编译和运行
在终端进入源码所在文件夹:
```bash
clang++ -std=c++17 -o lesson2 lesson2.cpp
./lesson2
```
---
## 7. 本课课堂小练习
1. 新建一个变量 `coins`(金币),初始值设为 `50`,输出一句:`你的金币:50`(数字要用变量,不要手写 50 两次在引号里)。
2. 在同一程序里再输出一行:用 `pulls``coins` 两个变量,各显示一次(可以编一句自己的话,比如「抽卡次数 ___ ,金币 ___」)。
**参考结构**(数字和文案可自己改):
```cpp
#include <iostream>
int main() {
int pulls = 3;
int coins = 50;
std::cout << "抽卡次数 " << pulls << " ,金币 " << coins << "\n";
return 0;
}
```
---
## 8. 本课课后作业(选做)
-`pulls` 先设为 `5`,再在下一行写 `pulls = pulls - 1;`,输出一次 `pulls`,想想为什么变成 4(第 3 课会大量用到「改变变量」)。
- 问家长:如果写成 `int pulls = 3.5` 会怎样?(先猜,再编译试试,把结果记到 `学习进度与状态.md` 的备注里也行。)
---
## 9. 常见小问题
- **忘了写 `int`**:只写 `pulls = 3` 可能报错,第一次声明盒子一般要写类型。
- **用了中文标点**:代码里引号、分号请用英文半角。
- **想存小数**:本课用 `int` 存不下「3.5」,编译器可能警告或截断,这是正常的,以后会学 `double`
---
## 10. 下一课预告
第 3 课会学 **`std::cin`**:让玩家从键盘输入数字,程序把数放进变量里——你的抽卡游戏就可以「问你想抽几次」了。
---
*学完请家长在 `学习进度与状态.md` 里更新第 2 课的状态与作业完成情况。*
**下一课文档**`第03课-听玩家的话.md`
+138
View File
@@ -0,0 +1,138 @@
# 第 3 课:听玩家的话(键盘输入)
**本课目标**:学会用 **`std::cin`** 从键盘读入数字,存进已经学过的 **`int` 变量** 里。这样游戏可以问「你想抽几次?」「你有多少金币?」而不是写死在代码里。
**复习**:第 1 课 `cout` 输出;第 2 课 `int` 变量。本课把 **玩家输入****变量** 连起来。
---
## 1. 这一课要搞懂什么
- **`std::cout <<`**:程序 **往外说**(屏幕上看得到)。
- **`std::cin >>`**:程序 **往里收**(你在键盘上打字,程序读进来)。
- `>>` 像一个小漏斗:右边的变量名表示「读到的数放进哪个盒子」。
顺序很重要:一般先 **`cout` 写一句提示**,再 **`cin` 读入**,玩家才知道该输入什么。
---
## 2. 第一个会「听人话」的程序
保存为 `lesson3.cpp`(或你喜欢的名字,扩展名 `.cpp`):
```cpp
#include <iostream>
int main() {
int pulls = 0;
std::cout << "你想抽几次?";
std::cin >> pulls;
std::cout << "好,我们准备抽 " << pulls << "\n";
return 0;
}
```
### 每一部分在说什么
| 代码 | 意思(小朋友版) |
|------|------------------|
| `int pulls = 0;` | 先准备一个整数盒子,里面暂时当 0(读入后会被覆盖)。 |
| `std::cout << "你想抽几次?";` | 屏幕上显示问题,**不换行**也可以,光标停在同一行等输入。 |
| `std::cin >> pulls;` | 等你按回车,把输入的 **整数** 放进 `pulls`。 |
| 下一行 `cout` | 把盒子里的数说出来,确认程序真的记住了。 |
编译运行后,输入一个整数(例如 `5`),回车,应看到:`好,我们准备抽 5 次`
---
## 3. 提示语要清楚
玩家不知道要输入什么时会发呆,所以:
- 问题用 **`cout`** 写清楚。
- 可以在提示里写「请输入整数」或「输入数字后按回车」。
```cpp
std::cout << "请输入你想抽的次数(整数),然后按回车:";
std::cin >> pulls;
```
---
## 4. 一次读两个数(进阶)
抽卡可以既要「次数」又要「金币」,可以连着写两次 `cin`
```cpp
#include <iostream>
int main() {
int pulls = 0;
int coins = 0;
std::cout << "抽几次?";
std::cin >> pulls;
std::cout << "现在有多少金币?";
std::cin >> coins;
std::cout << "收到:抽 " << pulls << " 次,金币 " << coins << "\n";
return 0;
}
```
运行时要 **输入两次**:第一次回车后,再问第二个数。
---
## 5. 和抽卡游戏的关系
| 想法 | 做法 |
|------|------|
| 玩家决定抽几次 | `cin >> pulls` |
| 玩家报金币数量 | `cin >> coins` |
| 以后扣金币、减次数 | 用第 2 课的变量和赋值、`pulls - 1` 等 |
本课只保证:**能读进来、能显示出来**。随机抽结果在第 4 课。
---
## 6. 怎么编译和运行
```bash
clang++ -std=c++17 -o lesson3 lesson3.cpp
./lesson3
```
输入数字后一定要按 **回车**,程序才会继续。
---
## 7. 本课课堂小练习
1. 只用一个程序:先 `cout` 问「你叫什么名字?」——名字是 **文字**,本课先不学 `string`,可以改成问「你的幸运数字是几?」用 `int lucky` + `cin` 读入并打印。
2. 做「抽几次 + 金币」两段提问(用上文第 4 节的结构),最后输出一句自己编的话,里面必须用到 `pulls``coins`
---
## 8. 本课课后作业(选做)
- 故意在问「整数」时输入 **字母****符号**,看程序会怎样(可能卡住或出错,先观察,以后会学更稳妥的写法)。
- 问家长:`cin >> pulls` 后面的 `>>``cout` 里的 `<<` 方向为什么相反?(一个往里收,一个往外送,像箭头方向。)
---
## 9. 常见小问题
- **输入完没反应**:检查是否按了回车;是否在等待第二个数(读两次就要输入两次)。
- **想输入中文名字**:要用 `std::string`,下几课会用到时再扩展;本课整数输入用数字即可。
- **一次想输入多个数**:可以在一行里用空格隔开两个整数,例如 `3 50`,然后 `std::cin >> pulls >> coins;`(试一试当拓展)。
---
## 10. 下一课预告
第 4 课会学 **随机数**:每次抽卡结果不一样——`rand``srand` 和「种子」,为真正的 **抽卡运气** 做准备。
---
*学完请家长在 `学习进度与状态.md` 里更新第 3 课的状态与作业完成情况。*
**下一课文档**`第04课-运气来了.md`
+121
View File
@@ -0,0 +1,121 @@
# 第 4 课:运气来了(随机数)
**本课目标**:让程序每次运行(或每次「抽一下」)得到 **不一样的整数**,为后面的「抽到普通 / 稀有卡」做准备。学会使用 **`rand`**、**`srand`** 和 **`%` 取余**。
**复习**:第 3 课用 `cin` 读入数据;本课的数据来自 **程序内部的随机**,不靠键盘。
---
## 1. 这一课要搞懂什么
- **`std::rand()`**:返回一个很大的随机整数(每次调用会变)。
- **「种子」`std::srand(...)`**:告诉电脑「从哪一串运气开始乱」。种子一般在 **`main` 里、第一次 `rand` 之前只设一次**。
- **常用种子**:用当前时间 `std::time(nullptr)`,这样每次运行程序,种子不同,随机序列也不同。
- **`%`(取余)**:把很大的数 **缩到你想要的范围**。例如 `% 100` 得到 **099**
需要多两个头文件:
- `#include <cstdlib>` —— `rand``srand`
- `#include <ctime>` —— `time`
---
## 2. 第一个随机数程序
保存为 `lesson4.cpp`(或 `lession4.cpp`,和编译命令一致即可):
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int r = std::rand() % 100;
std::cout << "随机数:" << r << "\n";
return 0;
}
```
多运行几次 `./程序名`,观察:**数字会变**。
---
## 3. `srand` 为什么要写?(先有个印象)
如果 **不写** `std::srand(...)`,有些环境下每次运行程序,`rand()` 出来的顺序可能 **一模一样**。加了用时间当种子,更像「每次开游戏运气不同」。
本课记住:**在 `main` 开头写一次 `std::srand(std::time(nullptr));` 就对了。**
---
## 4. `%` 怎么帮你「限定范围」
| 写法 | 结果范围(整数) |
|------|------------------|
| `std::rand() % 100` | 099 |
| `std::rand() % 10` | 09 |
| `std::rand() % 6` | 0~5(像六面骰的 0~5 版) |
以后要 **1100** 可以以后再学「加偏移」:`% 100` 再加 1 等;本课先掌握 **0 起头** 即可。
---
## 5. 和抽卡游戏的关系
下一课会把随机数放进 **`if` 判断**:数字落在不同区间 → 普通 / 稀有 / 超稀有。本课只练:**能生成一个 0~99 的 `r` 并打印**。
---
## 6. 怎么编译和运行
```bash
clang++ -std=c++17 -o lession4 lession4.cpp
./lession4
```
(若你的源文件叫 `lesson4.cpp`,把命令里的名字一起改掉,保持 **源文件名、` -o` 名字、`./` 名字** 一致。)
---
## 7. 本课课堂小练习
1.`% 100` 改成 `% 10`,看多运行几次是不是都落在 09。
2. 连续输出 **3 个** 随机数(调用三次 `std::rand() % 100`,分三行 `cout`),看三次是不是一般互不相同。
示例结构(数字和换行可自己调整):
```cpp
std::srand(std::time(nullptr));
int a = std::rand() % 100;
int b = std::rand() % 100;
int c = std::rand() % 100;
std::cout << a << " " << b << " " << c << "\n";
```
---
## 8. 本课课后作业(选做)
- 注释掉 `std::srand(std::time(nullptr));` 这一行,多运行几次程序,观察随机数是否还容易变化(记下现象即可)。
- 问家长:`nullptr` 是什么可以以后再学,本课先当「固定写法配合 `time` 用」。
---
## 9. 常见小问题
- **忘了 `#include <cstdlib>``<ctime>`**:可能报 `rand` / `time` 未声明。
- **`srand` 写了很多次**:一般只在开头写一次;循环里反复 `srand` 可能让随机性变差,本课先别在循环里设种子。
- **想要小数**:本课都是整数随机;小数以后用 `double` 等再扩展。
---
## 10. 下一课预告
第 5 课学 **`if` / `else if` / `else`**:根据 `r` 落在哪个区间,打印「普通 / 稀有 / 超稀有」——抽卡的核心逻辑就来了。
---
*学完请家长在 `学习进度与状态.md` 里更新第 4 课的状态与作业完成情况。*
**下一课文档**`第05课-稀有度与判断.md`
+130
View File
@@ -0,0 +1,130 @@
# 第 5 课:稀有度与判断(`if` / `else`
**本课目标**:根据第 4 课得到的随机整数 **`r`**,用 **`if` / `else if` / `else`** 判断「抽到哪种稀有度」,并在屏幕上打印出来。这是抽卡游戏的 **核心逻辑**
**复习**:第 4 课 `rand` + `% 100` 得到 099 的 `r`。本课不问键盘,先专注 **分支判断**
---
## 1. 这一课要搞懂什么
- **`if (条件) { ... }`**:条件成立,就执行大括号里的语句。
- **`else if (条件) { ... }`**:前面都不成立,再试这一个条件。
- **`else { ... }`**:上面所有条件都不成立,就走这里(最后一档)。
- **比较运算符**(本课常用):`<` 小于、`>` 大于、`<=` 小于等于、`>=` 大于等于、`==` 等于、`!=` 不等于。
条件外面要加 **圆括号** `()`,语句块外面要加 **花括号** `{}`(本课先养成「每档都写 `{}`」的习惯)。
---
## 2. 稀有度怎么和数字对应?
下面用 **099**`r` 分成三档(概率只是举例,以后你可以改数字):
| `r` 的范围 | 约占比 | 结果 |
|------------|--------|------|
| 069 | 约 70% | 普通卡 |
| 7094 | 约 25% | 稀有卡 |
| 9599 | 约 5% | 超稀有卡 |
代码里写成:
- `r < 70` → 普通(069
- `r < 95` → 稀有(70~94)——注意:能进到这里时,`r < 70` 已经不成立了,所以实际是 70~94
- 剩下的 → 超稀有(9599
---
## 3. 完整示例程序
保存为 `lession5.cpp`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int r = std::rand() % 100;
std::cout << "你抽到了:";
if (r < 70) {
std::cout << "普通卡\n";
} else if (r < 95) {
std::cout << "稀有卡\n";
} else {
std::cout << "超稀有卡!!\n";
}
return 0;
}
```
多运行几次,观察三种结果都会出现(超稀有会较少,属正常)。
---
## 4. 调试小技巧:先看 `r` 是多少
不确定区间对不对时,可以先打印随机数:
```cpp
std::cout << "本次点数 r = " << r << "\n";
```
加在 `if` 之前,方便对照「数字落在哪一档」。
---
## 5. 和抽卡游戏的关系
| 本课学会 | 以后可以 |
|----------|----------|
| 分档判断 | 普通 / 稀有 / 传说 |
| 改数字 | 调概率(更难或更容易出稀有) |
| 加 `else if` | 多加一档「史诗」等 |
第 6 课会加 **循环**,按次数连续抽;第 7 课用 **数组** 给每档起卡名。
---
## 6. 怎么编译和运行
```bash
clang++ -std=c++17 -o lession5 lession5.cpp
./lession5
```
---
## 7. 本课课堂小练习
1.`if` 前增加一行,输出本次的 `r`(或「点数」),再运行多次,对照上一节的表格看是否合理。
2. 把「超稀有」条件改严一点:例如只有 `r >= 98` 才是超稀有(想想 `else` 里要对应哪一段 `r`)。
---
## 8. 本课课后作业(选做)
- 把三档概率改成你自己喜欢的比例(例如更容易出稀有),记录你改的 `<` 旁边的数字。
- 问家长:**为什么要先写 `r < 70` 再写 `r < 95`**,而不能把两个条件反过来?(提示:判断顺序像从上往下筛。)
---
## 9. 常见小问题
- **`if (r < 70);`** 后面多写了分号:可能导致大括号里的内容**总是**执行或逻辑错乱,本课每档用 `{ }` 包住最清晰。
- **用 `=` 代替 `==`**`if (r = 70)` 是赋值不是比较,容易出 bug;比较数字是否相等要用 `==`
- **想判断「是否等于 100」**:本课 `r` 最大是 99,若要 1~100 的范围要改 `rand` 那一行,以后可以再扩展。
---
## 10. 下一课预告
第 6 课学 **循环**`for`):按玩家输入的次数,连续抽很多次,不用复制粘贴很多遍 `if`
---
*学完请家长在 `学习进度与状态.md` 里更新第 5 课的状态与作业完成情况。*
**下一课文档**`第06课-循环与多抽.md`
+138
View File
@@ -0,0 +1,138 @@
# 第 6 课:循环与多抽(`for`)
**本课目标**:把第 3 课的「输入次数」、第 4~5 课的「随机 + 稀有度」合在一起:玩家输入 **`n`**,程序用 **`for` 循环** 连续抽 **`n` 次**,每次结果可以不同。
**复习**`cin` 读整数;`srand` 只设一次;`rand` % 100 与 `if` 判断。
---
## 1. 这一课要搞懂什么
- **循环**:同一段代码想做很多遍,不用复制粘贴很多行。
- **`for` 句型(本课用这个)**
```text
for (起点; 是否继续; 每轮结束时做什么) { 循环体 }
```
- 本课常用写法:
```cpp
for (int i = 1; i <= n; i++) { ... }
```
含义可以记成:「`i` 从 1 开始,只要 `i` 还小于等于 `n`,就执行大括号里的话,每做完一轮让 `i` 加 1」。
- **`i`** 常用来当「第几抽」的序号,正好可以打在屏幕上:`第1抽`、`第2抽`……
---
## 2. 随机数要放在循环里面还是外面?
- **`std::srand(std::time(nullptr));`**:仍在 **`main` 开头只写一次**(和前面一样)。
- **`int r = std::rand() % 100;`**:要写在 **`for` 的循环体里面**——**每抽一次,重新得到一个 `r`**。若写在循环外,`r` 只算一次,多抽就全一样了。
---
## 3. 完整示例(输入次数 + 连抽 + 稀有度)
保存为 `lession6.cpp`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(std::time(nullptr));
int n = 0;
std::cout << "抽几次?";
std::cin >> n;
for (int i = 1; i <= n; i++) {
int r = std::rand() % 100;
std::cout << "第" << i << "抽:";
if (r < 70) {
std::cout << "普通\n";
} else if (r < 95) {
std::cout << "稀有\n";
} else {
std::cout << "超稀有\n";
}
}
return 0;
}
```
运行后输入一个整数(如 `5`),应看到 5 行结果,**每行稀有度可不同**。
---
## 4. `for` 三格分别是什么?(对号入座)
以 `for (int i = 1; i <= n; i++)` 为例:
| 位置 | 本课含义 |
|------|----------|
| `int i = 1` | 循环变量 `i` 从 1 开始。 |
| `i <= n` | 只要 `i` 不超过 `n` 就继续抽。 |
| `i++` | 每抽完一轮,`i` 加 1`++` 表示加 1)。 |
---
## 5. 和抽卡游戏的关系
| 本课组合 | 游戏效果 |
|----------|----------|
| `cin >> n` | 玩家决定十连、百连等 |
| `for` 里每次新的 `r` + `if` | 每一抽独立判稀有度 |
| 打印 `i` | 清楚是第几抽 |
第 7 课会给卡片 **起名字(数组)**;本课先熟练「多抽」。
---
## 6. 怎么编译和运行
```bash
clang++ -std=c++17 -o lession6 lession6.cpp
./lession6
```
输入正整数。若输入 `0`,循环体一次都不执行,属于正常;负数本课不专门处理,可和家长讨论「该做哪些判断」当拓展。
---
## 7. 本课课堂小练习
1. 在每一抽的输出里,顺便打印本次的 **点数 `r`**(和 `i` 一起),多运行几次,对照第 5 课区间是否一致。
2. 把 `for` 里 `i` 从 **1 开始** 改成从 **0 开始**、条件改成 `i < n`(需同时改 `cout` 里显示第几抽,如 `i + 1`)。能做出来说明你在思考「下标从 0」。
---
## 8. 本课课后作业(选做)
- 统计这一轮里 **出了几次「超稀有」**:在 `main` 里加一个 `int` 变量,在 `else`(超稀有的分支)里加 1,循环结束后 `cout` 打印总次数。
- 问家长:**`while` 和 `for` 有什么不一样?** 本课只用 `for` 就够;知道「另一种循环名」即可。
---
## 9. 常见小问题
- **只随机了一次**:检查 `r = ...rand...` 是否在 `for` 的 `{ }` 里。
- **想抽「固定 10 次」不写 `cin`**:可以把 `n = 10;` 写死,仍然用 `for` 循环。
- **输入很大的 `n`**:会打印很多行,可以先用小数字测。
---
## 10. 下一课预告
第 7 课学 **数组** 和 `std::string`:用编号对应「皮卡丘、小火龙」等名字,抽到稀有时打印具体卡名。
---
*学完请家长在 `学习进度与状态.md` 里更新第 6 课的状态与作业完成情况。*
**下一课文档**`第07课-卡片与数组.md`
+120
View File
@@ -0,0 +1,120 @@
# 第 7 课:卡片与数组(`string` 数组)
**本课目标**:用 **数组** 存好多张卡的名字,用 **编号(下标)** 取出其中一张。学会 **`std::string`** 和 **下标从 0 开始**
**复习**:第 6 课里每次有一张「结果」;本课在随机数上再往前一步,让结果变成 **某一张具体卡** 的名字。
---
## 1. 这一课要搞懂什么
- **一张卡有名字**(文字),在 C++ 里常用 **`std::string`** 表示一串字(不是本课的整数 `int`)。
- **很多张卡** 可以排成一行放进 **数组**里:`std::string cards[3]` 表示有 **3 个格子**(编号 `0、1、2`)。
- **下标永远从 0 开始**
- 第 1 张是 `cards[0]`
- 第 2 张是 `cards[1]`
- 第 3 张是 `cards[2]`
- 若有 **3 张卡**,有效下标是 **02****没有** `cards[3]`(会越界,程序可能出错)。
头文件:写 `std::string` 前要加一行 **`#include <string>`**。
---
## 2. 最简示例:三张卡、打印其中一张
保存为 `lession7.cpp`
```cpp
#include <iostream>
#include <string>
int main() {
std::string cards[3];
cards[0] = "小火龙";
cards[1] = "皮卡丘";
cards[2] = "妙蛙种子";
int id = 1;
std::cout << "你选中的卡:" << cards[id] << "\n";
return 0;
}
```
运行会打印 **皮卡丘**(因为 `id` 是 1,对应下标 1)。把 `id` 改成 `0``2` 再试。
---
## 3. 随机从三张里抽一张(和抽卡最相关)
3 个下标是 0、1、2,随机一个下标用:
```cpp
int id = std::rand() % 3; // 0 或 1 或 2
std::cout << "抽到:" << cards[id] << "\n";
```
**注意**:若用随机,要在 `main` 最前面先写 `std::srand(std::time(nullptr));`(和前几课一样),并加上 `#include <cstdlib>``#include <ctime>`
---
## 4. 和稀有度、多抽怎么拼?(进阶思路)
- 本课可以只做:**在「普通 / 稀有」某一档里**,再随机出 **具体卡名**(用 `cards[id]`)。
- 也可以先生成 `r` 判稀有度,**分支里** 用 **不同的小数组****同数组不同下标范围**(慢慢加,不着急一次写完)。
**第 6 课** 的拼法:在 `for` 的每一轮里,除了打印「普通/稀有」,再打印 `cards[某个 id]`
---
## 5. 本课必须记住的规矩
| 点 | 说明 |
|----|------|
| 3 格数组 | 合法下标是 `0、1、2` |
| `% 3` | 得到 0~2,正好当这三张的编号 |
| `string``int` 不同 | 算卡名用 `string`;第几张、下标、随机 0/1/2 用 `int` |
---
## 6. 怎么编译和运行
```bash
clang++ -std=c++17 -o lession7 lession7.cpp
./lession7
```
(若和随机数、循环写在同一个 `.cpp` 里,**所有**需要的 `#include` 都写上。)
---
## 7. 本课课堂小练习
1.`cards[3]` 改成 **4 张卡**`cards[4]`),自己写四个名字,用 `std::rand() % 4` 随机抽一张并打印名字。
2.`for``i = 0``i < 3`,在循环里 **`cout` 打印** `cards[i]`,看是否按顺序列出一排卡名。
---
## 8. 本课课后作业(选做)
- 在每一张卡名后面,再存一个 **等级数字** 太麻烦,以后可以用 **结构体**;本选做可改成:**两张表**—`std::string cards[3]``int level[3]`,下标相同表示同一张卡的名字和等级,打印时两个一起输出。
- 问家长:生活中哪些东西像「下标从 0 开始」?(例如有的小区楼层、有国家的年级说法不同——先当聊天即可。)
---
## 9. 常见小问题
- **忘了 `#include <string>`**:可能报错找不到 `string` 类型。
- **写了 `cards[3]` 只有三格,却用 `id = 3`**:越界,要改成 `id` 在 02,或把数组开大一点。
- **中文在终端乱码**:与系统编码有关,可先全用 **英文/拼音** 当卡名测试,再让家长和终端设置一起调。
---
## 10. 下一课预告
第 8 课学 **函数**`void`):把「抽一次」打成一包,用 **`draw_once()`** 多次调用,代码更整齐。
---
*学完请家长在 `学习进度与状态.md` 里更新第 7 课的状态与作业完成情况。*
**下一课文档**`第08课-函数与抽一次.md`
+136
View File
@@ -0,0 +1,136 @@
# 第 8 课:函数与「抽一次」(`void`)
**本课目标**:把「随机一次 + 判断稀有度并打印」收成 **一个函数**,需要抽卡时 **调用函数名加括号** 即可,让 `main` 更短、更好读。
**复习**:第 57 课已经会写随机数、`if`、打印结果;本课不学新概念语法难度,学 **怎么把代码打包复用**
---
## 1. 这一课要搞懂什么
- **函数**:一块有名字的代码,写一次,到处可以 **调用**
- **`void`**:表示这个函数 **不返回数值给调用者**(先记住:打印抽卡结果就够了,不必 `return` 一个数)。
- **函数名**:用小写字母和下划线也可以,本课用 **`draw_once`**(抽一次)。
- **调用**:在 `main` 里写 **`draw_once();`** 就像按一下「抽一次」按钮。
### 顺序要注意
在 C++ 里,`main` 里如果出现 **`draw_once()`**,编译器要先 **认识** `draw_once` 是什么。有两种常见写法(二选一即可):
1. **把整个函数写在 `main` 上面**(本课推荐,最简单)。
2. 或者在 `main` **上面** 写一行 **`void draw_once();`**(声明),再把 `{ ... }` 写在 `main` **下面**(以后再熟练)。
---
## 2. 示例:`draw_once` + 在 `main` 里抽两次
保存为 `lession8.cpp`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
void draw_once() {
int r = std::rand() % 100;
if (r < 70) {
std::cout << "普通卡\n";
} else if (r < 95) {
std::cout << "稀有卡\n";
} else {
std::cout << "超稀有卡\n";
}
}
int main() {
std::srand(std::time(nullptr));
draw_once();
draw_once();
return 0;
}
```
运行应看到 **两行** 抽卡结果(各随机)。
---
## 3. 为什么要写成函数?
| 好处 | 说明 |
|------|------|
| **少重复** | 不用把一大段 `rand` + `if` 复制很多遍 |
| **好改** | 改概率只改 `draw_once` 里面一处 |
| **接菜单** | 第 9 课菜单里「选抽卡」只要调用 `draw_once()` |
---
## 4. 和第 6 课的 `for` 怎么配合?
多抽不必手写多个 `draw_once();`,可以:
```cpp
int n = 0;
std::cout << "抽几次?";
std::cin >> n;
for (int i = 1; i <= n; i++) {
std::cout << "" << i << "抽:";
draw_once();
}
```
(把 `srand` 留在 `main` 开头**一次**,不要放进 `draw_once` 里反复执行。)
---
## 5. 能不能把卡名(数组)也放进函数?
可以。当函数里要用 `cards` 时,要么:
- 把数组写在 **`main` 外面**(全局,下一小阶段再细讲),要么
- 以后学 **参数** 把数组传进函数。
本课 **最低目标**:先掌握 **`void draw_once()` 无参数版本**;卡名进阶可当练习。
---
## 6. 怎么编译和运行
```bash
clang++ -std=c++17 -o lession8 lession8.cpp
./lession8
```
---
## 7. 本课课堂小练习
1. 把函数名改成你喜欢的英文(例如 `chou_yi_ci`),记得 **`void` 那一行** 和 **`main` 里的调用** 一起改。
2.**`for`** + **`cin >> n`**,循环里调用 **`draw_once()`**,实现和第 6 课类似的「连抽」,但 **`main` 里尽量不要重复写判稀有的大段 `if`**。
---
## 8. 本课课后作业(选做)
-`draw_once` 里增加打印本次 **`r`**(点数),方便对照区间。
- 问家长:**「调用函数」和「复制粘贴同一段代码」相比,哪个更像现实中「按按钮」?**
---
## 9. 常见小问题
- **`draw_once` 写在 `main` 下面且没有声明**:可能报错「找不到这个名字」,把它整块移到 `main` **上面**,或加前置声明。
- **在 `draw_once` 里写 `srand`**:每抽一次都重置种子的话,随机性可能变差;种子只在程序开始时设一次更好。
- **函数末尾忘了 `}`**:大括号要配对,和 `main` 一样。
---
## 10. 下一课预告
第 9 课做 **菜单**:用 **`while (true)`** 反复显示「抽卡 / 说明 / 退出」,选抽卡就调用 **`draw_once()`**,选退出用 **`break`** 结束循环。
---
*学完请家长在 `学习进度与状态.md` 里更新第 8 课的状态与作业完成情况。*
**下一课文档**`第09课-菜单与循环.md`
+139
View File
@@ -0,0 +1,139 @@
# 第 9 课:菜单与循环(`while` + `break`
**本课目标**:让程序像小游戏一样 **反复显示菜单**,玩家输入数字选择:**抽一次卡 / 看说明 / 退出**。学会 **`while (true)`** 以及 **`break`** 跳出循环。
**复习**:第 8 课的 **`draw_once()`**;第 3 课的 **`cin`**。本课把「输入选项」包在一个 **一直转的大圈** 里。
---
## 1. 这一课要搞懂什么
- **`while (条件)`**:条件成立就反复执行 `{ ... }` 里的代码。
- **`while (true)`**`true` 永远成立 → **无限循环**,除非里面用 **`break`** 强行离开。
- **`break`**:用在循环里,表示 **立刻结束这一层循环**,继续执行循环后面的代码(通常是 `return 0` 结束程序)。
- **菜单**:每一圈先 **`cout` 打印选项**,再 **`cin >> choice`**,再用 **`if` / `else if` / `else`** 判断选了哪一项。
---
## 2. 推荐选项编号(示例)
| 输入数字 | 动作 |
|----------|------|
| `1` | 调用 **`draw_once()`** 抽一次 |
| `2` | 打印几句游戏规则说明 |
| `0` | **`break`** 退出循环(说再见) |
你也可以改成 `3` 退出,只要在文档里写清楚即可。
---
## 3. 完整示例程序
保存为 `lession9.cpp`
```cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
void draw_once() {
int r = std::rand() % 100;
if (r < 70) {
std::cout << "普通卡\n";
} else if (r < 95) {
std::cout << "稀有卡\n";
} else {
std::cout << "超稀有卡\n";
}
}
int main() {
std::srand(std::time(nullptr));
while (true) {
std::cout << "\n===== 抽卡小游戏 =====\n";
std::cout << "1 抽一次\n";
std::cout << "2 说明\n";
std::cout << "0 退出\n";
std::cout << "请选择:";
int choice = 0;
std::cin >> choice;
if (choice == 1) {
draw_once();
} else if (choice == 2) {
std::cout << "随机出普通/稀有/超稀有,选 1 抽一次,选 0 退出。\n";
} else if (choice == 0) {
std::cout << "再见!\n";
break;
} else {
std::cout << "没有这个选项,请重新输入。\n";
}
}
return 0;
}
```
### 程序是怎么跑的?
1. 进入 **`while (true)`**,显示菜单。
2. 等你输入 **`choice`**。
3. 若选 **`0`**:打印再见 → **`break`** → 循环结束 → 执行 **`return 0`**。
4. 否则再回到步骤 1(又是新的一圈菜单)。
---
## 4. 两个循环的区别(回忆)
| 循环 | 适合干什么 |
|------|------------|
| **`for`** | 次数明确,例如「抽 `n` 次」 |
| **`while`** | 次数不固定,例如「一直显示菜单直到选退出」 |
菜单用 **`while`** 很自然;菜单里选「抽十次」可以再写一个 **`for`** 调用 **`draw_once()`**。
---
## 5. 怎么编译和运行
```bash
clang++ -std=c++17 -o lession9 lession9.cpp
./lession9
```
---
## 6. 本课课堂小练习
1. 增加菜单项 **`3`****先问「抽几次?」**,读入 **`n`**,用 **`for`** 调用 **`draw_once()`** `n` 次(把第 6、8 课合在一起)。
2. 把菜单文字改成你喜欢的标题和选项说明。
---
## 7. 本课课后作业(选做)
- 加一个 **`int coins`**:每抽一次扣 10 金币,金币不够时提示并禁止抽卡(需要 **`if (coins >= 10)`** 再抽)。
- 问家长:**为什么退出要用 `break`,而不是直接写 `return 0` 在分支里?**(两种有时都能用;本课先理解 `break` 只跳出 **`while`**。)
---
## 8. 常见小问题
- **退出不了**:检查退出分支里有没有 **`break`**;条件是不是写成了赋值 **`=`** 而不是比较 **`==`**。
- **菜单刷屏**:每一圈开头加一点点分隔线(示例里用了 `\n``=====`)会好看一些。
- **`cin` 输入错了类型**:输入字母可能导致菜单卡住,选做以后再学清理输入流;本课先用数字测试。
---
## 9. 下一课预告
第 10 课是 **综合小项目**:把欢迎语、菜单、金币或次数、统计超稀有等整理成你自己的「迷你抽卡游戏」版本。
---
*学完请家长在 `学习进度与状态.md` 里更新第 9 课的状态与作业完成情况。*
**下一课文档**`第10课-综合小项目.md`(创建后将放在工作区;也可先对照 `教程-抽卡游戏-C++-10课.md` 第 10 节)。