App: AI game kẹo với State và Strategy
Xây game máy bán kẹo có AI: State quản lý vòng đời, Strategy đổi chính sách thưởng, mô phỏng ngàn ván đo doanh thu.
KhóDesign pattern ~120 phút
Ôn lại trước khi học
Giới thiệu
Bài này xây máy bán kẹo có thưởng. Đổi chính sách thưởng là đổi doanh thu ngay.
Kiến thức cần nhớ
State quản vòng đời máy
- 5 trạng thái: chờ xu, có xu, đang nhả, hết kẹo, trúng thưởng.
- Mỗi trạng thái là 1 lớp xử lý 4 việc bỏ xu, nhả xu, quay, nhả kẹo.
- Máy chỉ ủy thác cho trạng thái hiện tại nên gọn if-else.
- Ví dụ đời thường: máy hết kẹo thì nuốt quay và trả xu.
Strategy đổi chính sách thưởng
- RandomWinner trúng tỉ lệ cố định như 10%.
- PityWinner tăng tỉ lệ khi lâu chưa trúng để giữ khách.
- ProfitGuard giảm tỉ lệ khi tồn kho thấp để giữ lãi.
- Ví dụ đời thường: quán cho voucher nhiều hơn khi khách sắp bỏ đi.
Mô phỏng ngàn ván
- 3 kiểu khách: bừa, dễ bỏ cuộc, chơi tới cùng.
- Cùng seed chạy qua 3 chính sách để so công bằng.
- Ghi doanh thu, kẹo phát, tỉ lệ trúng mỗi phiên.
- Thêm trạng thái mới không sửa code cũ.
Ví dụ
- Input: quay khi máy hết kẹo. Output: báo hết và trả xu, không kẹt.
- Giải thích: trạng thái hết kẹo chặn nhả và hoàn xu.
- Input: cùng seed chạy 3 chính sách 1000 ván. Output: 3 bảng số khác nhau, tổng ván bằng nhau.
- Giải thích: cùng khách cùng ván nên so lãi là công bằng.
💻 Bài tập
Ngôn ngữ: C++17 (hoặc Java/Python). Dùng máy kẹo ngày 85, 86. Nộp vào day-147-gumball-ai/.
Bài 1: Máy kẹo với chính sách thưởng thay được
GumballMachine có 5 trạng thái (State pattern) và giữ WinnerPolicy (Strategy pattern).
struct WinnerPolicy { virtual bool isWinner(const MachineStats &s, Rng &rng) = 0; virtual std::string name() const = 0; };
| Chính sách | Luật |
|---|---|
RandomWinner(p) | Trúng với xác suất p = 0.1 |
PityWinner | Bắt đầu 5%, mỗi lượt không trúng cộng thêm 2%, trúng thì về 5% |
ProfitGuard | 10% khi tồn kho trên 50%, 3% khi dưới 50%, 0% khi dưới 10 viên |
Ràng buộc: đổi chính sách lúc chạy bằng setPolicy. Thêm chính sách mới không sửa trạng thái nào.
Bài 2: Mô phỏng khách hàng
| Kiểu khách | Hành vi |
|---|---|
RandomPlayer | Mỗi lượt 50% mua tiếp, 50% rời đi |
QuitterPlayer | Rời đi sau 3 lượt liên tiếp không trúng |
GrinderPlayer | Chơi tới khi trúng hoặc hết 20 xu |
Chạy 10.000 phiên với mỗi tổ hợp 3 chính sách x 3 kiểu khách, cùng seed cho từng tổ hợp. Mỗi xu 5.000đ, giá vốn mỗi viên 2.000đ.
chính_sách kiểu_khách doanh_thu kẹo_phát tỉ_lệ_trúng lượt_chơi_trung_bình lãi
RandomWinner Random ...
...
Bài 3: Thêm trạng thái và báo cáo (nâng cao)
- Thêm trạng thái
Maintenance: sau 500 lượt quay, máy khóa tới khi gọiservice(). Chỉ thêm 1 lớp và 1 chỗ chuyển trạng thái. - Vẽ sơ đồ trạng thái đầy đủ (Mermaid).
REPORT.md: chính sách nào tối ưu lãi, chính sách nào giữ khách lâu nhất, khuyến nghị cho chủ máy. Mọi kết luận gắn với số trong bảng.
✅ Tiêu chí hoàn thành
- 3 chính sách có test riêng với rng giả.
- Bảng 9 tổ hợp có số thật, tái lập được với cùng seed.
- Thêm
Maintenancekhông sửa trạng thái khác ngoài 1 chỗ chuyển. - Sơ đồ trạng thái và báo cáo khuyến nghị.
❓ Câu hỏi ôn tập
- 5 trạng thái máy kẹo mỗi cái làm gì?
- 3 chính sách thưởng khác nhau ở điểm gì?
- Vì sao mô phỏng phải cố định seed?
- State và Strategy khác nhau ở mục đích nào?
🌕 Bạn đã hoàn thành ngày 147. Làm hết bài tập phía trên rồi sang ngày tiếp theo.