// ===================================================================== // 第 5 课:卡片名字与布局 —— 起步骨架 // 教程文件:第05课-卡片名字与布局.md // 完整答案:solutions/lesson_gui_5.cpp // 起步状态:第 4 课结束的样子(单抽 + 十连抽 + 稀有度判断,但只有稀有度文字没有卡名) // ===================================================================== #include #include #include #include #include #include #include #include // TODO(步骤 1):在这里声明 3 个卡片名字数组 // std::string normal_cards[5] = { "小火龙", "水跃鱼", "绿草龟", "小电鼠", "土拨仔" }; // std::string rare_cards[5] = { "烈焰飞龙", "冰霜之狼", "暗影豹", "风暴鹰", "水晶鹿" }; // std::string super_cards[3] = { "雷霆神龙", "凤凰王", "深海巨兽" }; Fl_Box *result_box; // TODO(步骤 4):把 info_box 改名成 stats_box(贯穿这一课的命名风格) Fl_Box *info_box; void draw_one_callback(Fl_Widget *w, void *data) { int r = std::rand() % 100; char info[50]; std::sprintf(info, "单抽 | 点数:%d", r); info_box->label(info); if (r < 70) { result_box->label("☆ 普通卡 ☆"); result_box->labelcolor(fl_rgb_color(128, 128, 128)); } else if (r < 95) { result_box->label("★ 稀有卡 ★"); result_box->labelcolor(FL_BLUE); } else { result_box->label("★★★ 超稀有卡!! ★★★"); result_box->labelcolor(FL_RED); } result_box->labelsize(28); // TODO(步骤 2):把上面的 if/else 改造成"先选稀有度文字 → 再随机选一张卡名 → 拼成两行显示" } void draw_ten_callback(Fl_Widget *w, void *data) { std::string all = ""; int rare_count = 0; int super_count = 0; for (int i = 1; i <= 10; i++) { int r = std::rand() % 100; all += "第" + std::to_string(i) + "抽:"; if (r < 70) { all += "普通"; } else if (r < 95) { all += "★稀有★"; rare_count++; } else { all += "★★★超稀有★★★"; super_count++; } // TODO(步骤 3):在每个分支末尾把卡片名字也拼进去 // 比如:all += "普通 " + normal_cards[std::rand() % 5]; all += "\n"; } char stats[100]; std::sprintf(stats, "十连抽结果 | 稀有:%d 超稀有:%d", rare_count, super_count); info_box->label(stats); if (super_count > 0) { info_box->labelcolor(FL_RED); } else if (rare_count > 0) { info_box->labelcolor(FL_BLUE); } else { info_box->labelcolor(fl_rgb_color(128, 128, 128)); } result_box->labelsize(16); result_box->label(all.c_str()); result_box->labelcolor(FL_BLACK); } int main() { std::srand(std::time(nullptr)); // TODO(步骤 4):窗口高度从 480 改成 520 Fl_Window *window = new Fl_Window(420, 480, "抽卡世界 - 第4课"); Fl_Button *btn1 = new Fl_Button(50, 20, 140, 50, "抽一张"); btn1->labelsize(18); btn1->callback(draw_one_callback); Fl_Button *btn10 = new Fl_Button(230, 20, 140, 50, "十连抽"); btn10->labelsize(18); btn10->callback(draw_ten_callback); info_box = new Fl_Box(30, 80, 360, 30, ""); info_box->labelsize(14); result_box = new Fl_Box(30, 120, 360, 330, "点击按钮开始抽卡!"); result_box->labelsize(20); result_box->align(FL_ALIGN_TOP | FL_ALIGN_LEFT); // TODO(步骤 4):result_box 加一个凹陷边框,让它看起来像一张卡片 // result_box->box(FL_DOWN_BOX); // TODO(步骤 4):把 info_box 改成放在底部 (20, 445, 380, 40),加灰色背景,作为"统计区" window->end(); window->show(); return Fl::run(); }