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

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áchLuật
RandomWinner(p)Trúng với xác suất p = 0.1
PityWinnerBắt đầu 5%, mỗi lượt không trúng cộng thêm 2%, trúng thì về 5%
ProfitGuard10% 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áchHành vi
RandomPlayerMỗi lượt 50% mua tiếp, 50% rời đi
QuitterPlayerRời đi sau 3 lượt liên tiếp không trúng
GrinderPlayerChơ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)

  1. Thêm trạng thái Maintenance: sau 500 lượt quay, máy khóa tới khi gọi service(). Chỉ thêm 1 lớp và 1 chỗ chuyển trạng thái.
  2. Vẽ sơ đồ trạng thái đầy đủ (Mermaid).
  3. 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 Maintenance khô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.

Bớt paste mù, hiểu sâu từng dòng mình viết.

180 Days Challenge. 180 ngày cai nghiện vibe code.