commit 478b3451a1e87524f207ade40b311f59dd610d53 Author: Feast Date: Sun May 10 09:00:14 2026 +0800 init diff --git a/gacha b/gacha new file mode 100755 index 0000000..f69ba0e Binary files /dev/null and b/gacha differ diff --git a/lession1 b/lession1 new file mode 100755 index 0000000..b59ef45 Binary files /dev/null and b/lession1 differ diff --git a/lession1.cpp b/lession1.cpp new file mode 100644 index 0000000..a4366ba --- /dev/null +++ b/lession1.cpp @@ -0,0 +1,6 @@ +#include + +int main() { + std::cout << "欢迎来到抽卡世界!\n"; + return 0; +} \ No newline at end of file diff --git a/lession2 b/lession2 new file mode 100755 index 0000000..ec7b043 Binary files /dev/null and b/lession2 differ diff --git a/lession2.cpp b/lession2.cpp new file mode 100644 index 0000000..1a669a9 --- /dev/null +++ b/lession2.cpp @@ -0,0 +1,11 @@ +#include + +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; +} \ No newline at end of file diff --git a/lession3 b/lession3 new file mode 100755 index 0000000..18ba6d7 Binary files /dev/null and b/lession3 differ diff --git a/lession3.cpp b/lession3.cpp new file mode 100644 index 0000000..3b54022 --- /dev/null +++ b/lession3.cpp @@ -0,0 +1,9 @@ +#include + +int main() { + int pulls = 0; + std::cout << "你想抽几次?"; + std::cin >> pulls; + std::cout << "好,我们准备抽 " << pulls << " 次\n"; + return 0; +} diff --git a/lession4 b/lession4 new file mode 100755 index 0000000..195c040 Binary files /dev/null and b/lession4 differ diff --git a/lession4.cpp b/lession4.cpp new file mode 100644 index 0000000..2f1c4d2 --- /dev/null +++ b/lession4.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +int main() { + std::srand(std::time(nullptr)); + int r = std::rand() % 101; + std::cout << " 随机数 " << r << "\n"; + return 0; +} \ No newline at end of file diff --git a/lession5 b/lession5 new file mode 100755 index 0000000..4ade5ac Binary files /dev/null and b/lession5 differ diff --git a/lession5.cpp b/lession5.cpp new file mode 100644 index 0000000..aaae70f --- /dev/null +++ b/lession5.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +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; +} \ No newline at end of file diff --git a/lession6 b/lession6 new file mode 100755 index 0000000..25a59c7 Binary files /dev/null and b/lession6 differ diff --git a/lession6.cpp b/lession6.cpp new file mode 100644 index 0000000..851d9d2 --- /dev/null +++ b/lession6.cpp @@ -0,0 +1,29 @@ +#include +#include +#include + +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"; + } + } +} \ No newline at end of file diff --git a/lession7 b/lession7 new file mode 100755 index 0000000..63feb07 Binary files /dev/null and b/lession7 differ diff --git a/lession7.cpp b/lession7.cpp new file mode 100644 index 0000000..5c03136 --- /dev/null +++ b/lession7.cpp @@ -0,0 +1,14 @@ +#include +#include + +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; +} \ No newline at end of file diff --git a/lession8 b/lession8 new file mode 100755 index 0000000..6e09112 Binary files /dev/null and b/lession8 differ diff --git a/lession8.cpp b/lession8.cpp new file mode 100644 index 0000000..b31138a --- /dev/null +++ b/lession8.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +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;} \ No newline at end of file diff --git a/lession9 b/lession9 new file mode 100755 index 0000000..0d64001 Binary files /dev/null and b/lession9 differ diff --git a/lession9.cpp b/lession9.cpp new file mode 100644 index 0000000..bf1ce22 --- /dev/null +++ b/lession9.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +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; +} \ No newline at end of file diff --git a/学习进度与状态.md b/学习进度与状态.md new file mode 100644 index 0000000..af019f8 --- /dev/null +++ b/学习进度与状态.md @@ -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` | 本文件:进度与作业勾选 | diff --git a/教程-抽卡游戏-C++-10课.md b/教程-抽卡游戏-C++-10课.md new file mode 100644 index 0000000..de0c81f --- /dev/null +++ b/教程-抽卡游戏-C++-10课.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 +int main() { + int pulls = 3; + std::cout << "你还剩 " << pulls << " 次机会\n"; + return 0; +} +``` + +--- + +## 第 3 课:听玩家的话(输入) + +**目标**:用键盘输入数字,程序记住。 + +**要点**:`std::cin`、`>>`。 + +详见:`第03课-听玩家的话.md` + +```cpp +#include +int main() { + int pulls = 0; + std::cout << "你想抽几次?"; + std::cin >> pulls; + std::cout << "好,我们准备抽 " << pulls << " 次\n"; + return 0; +} +``` + +--- + +## 第 4 课:运气来了(随机数) + +**目标**:每次运行可能得到不同结果,为「抽到什么」做准备。 + +**要点**:`rand()`、`srand()`、`time()`;随机种子在程序开始时设一次。 + +详见:`第04课-运气来了.md` + +```cpp +#include +#include +#include + +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 +#include +#include + +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 +#include +#include + +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 +#include + +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 +#include +#include +#include + +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`* diff --git a/第01课-欢迎来到抽卡世界.md b/第01课-欢迎来到抽卡世界.md new file mode 100644 index 0000000..67d5456 --- /dev/null +++ b/第01课-欢迎来到抽卡世界.md @@ -0,0 +1,103 @@ +# 第 1 课:欢迎来到抽卡世界 + +**本课目标**:写出第一个 C++ 程序,让屏幕「打招呼」。学会保存代码、编译、运行。 + +--- + +## 1. 这一课要搞懂什么 + +- 程序就是给电脑的一串指令,电脑从上到下执行。 +- 我们写的文字要放在一个叫 **源文件** 的东西里,一般用 `.cpp` 结尾,例如 `hello.cpp`。 +- 电脑看不懂 `.cpp` 直接运行,要先 **编译**:把人类写的代码变成电脑能执行的程序。 + +--- + +## 2. 第一个程序长什么样 + +复制下面代码到 `hello.cpp`(名字可以自定,只要是 `.cpp`): + +```cpp +#include + +int main() { + std::cout << "欢迎来到抽卡世界!\n"; + return 0; +} +``` + +### 每一部分在说什么(不用背,多看几次) + +| 代码 | 意思(小朋友版) | +|------|------------------| +| `#include ` | 请把「在屏幕上写字」的工具拿来用。 | +| `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 + +int main() { + std::cout << "欢迎来到抽卡世界!\n"; + std::cout << "我是某某某,我们开始吧!\n"; + return 0; +} +``` + +--- + +## 5. 本课课后作业(选做) + +- 让程序连续输出 **三行** 不同的字,像小海报一样。 +- 问家长:如果少了一个分号 `;`,编译器会报什么错?把错误信息读一遍(不用懂每个词,习惯「有错就改」即可)。 + +--- + +## 6. 常见小问题 + +- **找不到命令 `clang++`**:需要先安装 Xcode Command Line Tools(可请家长搜索安装方法)。 +- **改完代码还是旧输出**:确认保存了文件,并且重新编译再运行。 +- **中文乱码**:终端编码问题,本课可先全用英文测试;需要中文时再和家长一起调终端编码。 + +--- + +## 7. 下一课预告 + +第 2 课会学 **变量**:用「小盒子」记住数字,比如还剩几次抽奖机会。 + +--- + +*学完请家长在 `学习进度与状态.md` 里更新第 1 课的状态与作业完成情况。* + +**下一课文档**:`第02课-小盒子与数字.md` diff --git a/第02课-小盒子与数字.md b/第02课-小盒子与数字.md new file mode 100644 index 0000000..5651bf8 --- /dev/null +++ b/第02课-小盒子与数字.md @@ -0,0 +1,136 @@ +# 第 2 课:小盒子与数字(变量) + +**本课目标**:学会用 **`int` 变量** 在程序里「记住一个整数」,并把它显示出来。为后面的「还剩几次抽卡」「有多少金币」打基础。 + +**复习**:第 1 课你已经会用 `std::cout` 输出文字。本课在输出里加上 **会变的数字**。 + +--- + +## 1. 这一课要搞懂什么 + +- 有时候程序要记住一个数,比如「还能抽几次」——这个数会变化,不能写死在引号里。 +- 在 C++ 里可以用 **`变量`**:像贴了小纸条的 **小盒子**,盒子里放一个整数。 +- 整数类型常写作 **`int`**(integer 的缩写,先记住这三个字母即可)。 + +--- + +## 2. 第一个用变量的例子 + +把下面保存为 `lesson2.cpp`(文件名可自定,扩展名用 `.cpp`): + +```cpp +#include + +int main() { + int pulls = 3; + std::cout << "你还剩 " << pulls << " 次抽卡机会\n"; + return 0; +} +``` + +### 每一部分在说什么 + +| 代码 | 意思(小朋友版) | +|------|------------------| +| `int pulls = 3;` | 准备一个装整数的盒子,名字叫 `pulls`,里面先放 **3**。 | +| `pulls` | 变量名,像盒子上写的名字,方便我们引用。 | +| `=` | 把右边的值放进左边的盒子里(叫「赋值」)。 | +| `std::cout << "你还剩 " << pulls << " 次..."` | 先输出前半句,再输出 **盒子里的数**,再输出后半句。 | + +运行后应看到类似:`你还剩 3 次抽卡机会` + +--- + +## 3. 改一改盒子里的数 + +变量的好处:**改一个数字,整段话跟着变**。 + +```cpp +#include + +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 + +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` diff --git a/第03课-听玩家的话.md b/第03课-听玩家的话.md new file mode 100644 index 0000000..2b16c21 --- /dev/null +++ b/第03课-听玩家的话.md @@ -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 + +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 + +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` diff --git a/第04课-运气来了.md b/第04课-运气来了.md new file mode 100644 index 0000000..8f30b34 --- /dev/null +++ b/第04课-运气来了.md @@ -0,0 +1,121 @@ +# 第 4 课:运气来了(随机数) + +**本课目标**:让程序每次运行(或每次「抽一下」)得到 **不一样的整数**,为后面的「抽到普通 / 稀有卡」做准备。学会使用 **`rand`**、**`srand`** 和 **`%` 取余**。 + +**复习**:第 3 课用 `cin` 读入数据;本课的数据来自 **程序内部的随机**,不靠键盘。 + +--- + +## 1. 这一课要搞懂什么 + +- **`std::rand()`**:返回一个很大的随机整数(每次调用会变)。 +- **「种子」`std::srand(...)`**:告诉电脑「从哪一串运气开始乱」。种子一般在 **`main` 里、第一次 `rand` 之前只设一次**。 +- **常用种子**:用当前时间 `std::time(nullptr)`,这样每次运行程序,种子不同,随机序列也不同。 +- **`%`(取余)**:把很大的数 **缩到你想要的范围**。例如 `% 100` 得到 **0~99**。 + +需要多两个头文件: + +- `#include ` —— `rand`、`srand` +- `#include ` —— `time` + +--- + +## 2. 第一个随机数程序 + +保存为 `lesson4.cpp`(或 `lession4.cpp`,和编译命令一致即可): + +```cpp +#include +#include +#include + +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 ` 或 ``**:可能报 `rand` / `time` 未声明。 +- **`srand` 写了很多次**:一般只在开头写一次;循环里反复 `srand` 可能让随机性变差,本课先别在循环里设种子。 +- **想要小数**:本课都是整数随机;小数以后用 `double` 等再扩展。 + +--- + +## 10. 下一课预告 + +第 5 课学 **`if` / `else if` / `else`**:根据 `r` 落在哪个区间,打印「普通 / 稀有 / 超稀有」——抽卡的核心逻辑就来了。 + +--- + +*学完请家长在 `学习进度与状态.md` 里更新第 4 课的状态与作业完成情况。* + +**下一课文档**:`第05课-稀有度与判断.md` diff --git a/第05课-稀有度与判断.md b/第05课-稀有度与判断.md new file mode 100644 index 0000000..a25f9b4 --- /dev/null +++ b/第05课-稀有度与判断.md @@ -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 +#include +#include + +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` diff --git a/第06课-循环与多抽.md b/第06课-循环与多抽.md new file mode 100644 index 0000000..cc24913 --- /dev/null +++ b/第06课-循环与多抽.md @@ -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 +#include +#include + +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` diff --git a/第07课-卡片与数组.md b/第07课-卡片与数组.md new file mode 100644 index 0000000..e73b96b --- /dev/null +++ b/第07课-卡片与数组.md @@ -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 `**。 + +--- + +## 2. 最简示例:三张卡、打印其中一张 + +保存为 `lession7.cpp`: + +```cpp +#include +#include + +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 ` 与 `#include `。 + +--- + +## 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` 类型。 +- **写了 `cards[3]` 只有三格,却用 `id = 3`**:越界,要改成 `id` 在 0~2,或把数组开大一点。 +- **中文在终端乱码**:与系统编码有关,可先全用 **英文/拼音** 当卡名测试,再让家长和终端设置一起调。 + +--- + +## 10. 下一课预告 + +第 8 课学 **函数**(`void`):把「抽一次」打成一包,用 **`draw_once()`** 多次调用,代码更整齐。 + +--- + +*学完请家长在 `学习进度与状态.md` 里更新第 7 课的状态与作业完成情况。* + +**下一课文档**:`第08课-函数与抽一次.md` diff --git a/第08课-函数与抽一次.md b/第08课-函数与抽一次.md new file mode 100644 index 0000000..cde360a --- /dev/null +++ b/第08课-函数与抽一次.md @@ -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 +#include +#include +#include + +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` diff --git a/第09课-菜单与循环.md b/第09课-菜单与循环.md new file mode 100644 index 0000000..cea5ab6 --- /dev/null +++ b/第09课-菜单与循环.md @@ -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 +#include +#include +#include + +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 节)。