init
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "欢迎来到抽卡世界!\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int pulls = 0;
|
||||||
|
std::cout << "你想抽几次?";
|
||||||
|
std::cin >> pulls;
|
||||||
|
std::cout << "好,我们准备抽 " << pulls << " 次\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;}
|
||||||
+100
@@ -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 <<"R:45.05% SR:27.03% SSR:18.02% UR:4.50% TR:3.60% USA:1.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
@@ -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.cpp(cin 输入抽卡次数)
|
||||||
|
日期:____________________ ____________________________________
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 文件对应关系
|
||||||
|
|
||||||
|
| 文件 | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `教程-抽卡游戏-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` | 本文件:进度与作业勾选 |
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
# 用 C++ 做命令行抽卡游戏 · 10 课时教程
|
||||||
|
|
||||||
|
面向 **8 岁左右** 学习者,只在 **命令行** 用输入输出完成抽卡游戏,并系统练习 C++ 基础。每课约 **20~40 分钟**,建议家长陪同。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 总说明(给家长)
|
||||||
|
|
||||||
|
- **工具**:安装 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`*
|
||||||
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,121 @@
|
|||||||
|
# 第 4 课:运气来了(随机数)
|
||||||
|
|
||||||
|
**本课目标**:让程序每次运行(或每次「抽一下」)得到 **不一样的整数**,为后面的「抽到普通 / 稀有卡」做准备。学会使用 **`rand`**、**`srand`** 和 **`%` 取余**。
|
||||||
|
|
||||||
|
**复习**:第 3 课用 `cin` 读入数据;本课的数据来自 **程序内部的随机**,不靠键盘。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 这一课要搞懂什么
|
||||||
|
|
||||||
|
- **`std::rand()`**:返回一个很大的随机整数(每次调用会变)。
|
||||||
|
- **「种子」`std::srand(...)`**:告诉电脑「从哪一串运气开始乱」。种子一般在 **`main` 里、第一次 `rand` 之前只设一次**。
|
||||||
|
- **常用种子**:用当前时间 `std::time(nullptr)`,这样每次运行程序,种子不同,随机序列也不同。
|
||||||
|
- **`%`(取余)**:把很大的数 **缩到你想要的范围**。例如 `% 100` 得到 **0~99**。
|
||||||
|
|
||||||
|
需要多两个头文件:
|
||||||
|
|
||||||
|
- `#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` | 0~99 |
|
||||||
|
| `std::rand() % 10` | 0~9 |
|
||||||
|
| `std::rand() % 6` | 0~5(像六面骰的 0~5 版) |
|
||||||
|
|
||||||
|
以后要 **1~100** 可以以后再学「加偏移」:`% 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`,看多运行几次是不是都落在 0~9。
|
||||||
|
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
@@ -0,0 +1,130 @@
|
|||||||
|
# 第 5 课:稀有度与判断(`if` / `else`)
|
||||||
|
|
||||||
|
**本课目标**:根据第 4 课得到的随机整数 **`r`**,用 **`if` / `else if` / `else`** 判断「抽到哪种稀有度」,并在屏幕上打印出来。这是抽卡游戏的 **核心逻辑**。
|
||||||
|
|
||||||
|
**复习**:第 4 课 `rand` + `% 100` 得到 0~99 的 `r`。本课不问键盘,先专注 **分支判断**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 这一课要搞懂什么
|
||||||
|
|
||||||
|
- **`if (条件) { ... }`**:条件成立,就执行大括号里的语句。
|
||||||
|
- **`else if (条件) { ... }`**:前面都不成立,再试这一个条件。
|
||||||
|
- **`else { ... }`**:上面所有条件都不成立,就走这里(最后一档)。
|
||||||
|
- **比较运算符**(本课常用):`<` 小于、`>` 大于、`<=` 小于等于、`>=` 大于等于、`==` 等于、`!=` 不等于。
|
||||||
|
|
||||||
|
条件外面要加 **圆括号** `()`,语句块外面要加 **花括号** `{}`(本课先养成「每档都写 `{}`」的习惯)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 稀有度怎么和数字对应?
|
||||||
|
|
||||||
|
下面用 **0~99** 的 `r` 分成三档(概率只是举例,以后你可以改数字):
|
||||||
|
|
||||||
|
| `r` 的范围 | 约占比 | 结果 |
|
||||||
|
|------------|--------|------|
|
||||||
|
| 0~69 | 约 70% | 普通卡 |
|
||||||
|
| 70~94 | 约 25% | 稀有卡 |
|
||||||
|
| 95~99 | 约 5% | 超稀有卡 |
|
||||||
|
|
||||||
|
代码里写成:
|
||||||
|
|
||||||
|
- `r < 70` → 普通(0~69)
|
||||||
|
- `r < 95` → 稀有(70~94)——注意:能进到这里时,`r < 70` 已经不成立了,所以实际是 70~94
|
||||||
|
- 剩下的 → 超稀有(95~99)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
@@ -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
@@ -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 张卡**,有效下标是 **0~2**,**没有** `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` 在 0~2,或把数组开大一点。
|
||||||
|
- **中文在终端乱码**:与系统编码有关,可先全用 **英文/拼音** 当卡名测试,再让家长和终端设置一起调。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 下一课预告
|
||||||
|
|
||||||
|
第 8 课学 **函数**(`void`):把「抽一次」打成一包,用 **`draw_once()`** 多次调用,代码更整齐。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*学完请家长在 `学习进度与状态.md` 里更新第 7 课的状态与作业完成情况。*
|
||||||
|
|
||||||
|
**下一课文档**:`第08课-函数与抽一次.md`
|
||||||
+136
@@ -0,0 +1,136 @@
|
|||||||
|
# 第 8 课:函数与「抽一次」(`void`)
|
||||||
|
|
||||||
|
**本课目标**:把「随机一次 + 判断稀有度并打印」收成 **一个函数**,需要抽卡时 **调用函数名加括号** 即可,让 `main` 更短、更好读。
|
||||||
|
|
||||||
|
**复习**:第 5~7 课已经会写随机数、`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
@@ -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 节)。
|
||||||
Reference in New Issue
Block a user