Tiến Lên Miền Nam: Game bài dân gian trên nền Web
Nhắc đến bộ bài Tây 52 lá ở Việt Nam thì chắc chắn Tiến Lên Miền Nam là bộ môn "quốc dân" số 1 không cần bàn cãi. Từ những ngày Tết sum vầy bên khay mứt hạt dưa cho đến những buổi tụ tập trà đá vỉa hè cùng bạn bè, chỉ cần xòe bộ bài ra là không khí rôm rả hẳn lên.
Nhưng ngặt nỗi ngày thường muốn làm vài ván giải trí nhanh trên điện thoại hay laptop thì mở mấy cổng game online lên lại thấy hơi phiền: hết banner quảng cáo nhấp nháy khắp 4 góc màn hình, lại đến popup nạp thẻ giục giã liên hồi. Đã thế bot máy trong mấy app đó thường đánh kiểu ngẫu nhiên, ngây ngô chẳng có tí chiến thuật hay cảm xúc nào.
Dạo này công việc trên công ty cũng hòm hòm, task tủng được dọn dẹp gọn gàng nên mình ngứa tay muốn dựng một con game Tiến Lên Miền Nam chạy thẳng trên trình duyệt Web: bật lên là chiến ngay, không cần cài đặt, không quảng cáo, giao diện sạch sẽ và hiệu năng mượt mà 60 FPS.
Cơ mà nếu chỉ code chia bài rồi người với máy đánh qua lại thì hơi đơn điệu. Đã làm thì mình muốn đầu tư thêm phần đối thủ máy với nhiều cấp độ khác nhau, phân chia theo từng bậc xếp hạng và phong cách rõ ràng để người chơi có cảm giác thử thách thực sự.
🃏 1. Bộ luật Tiến Lên Miền Nam "chuẩn cơm mẹ nấu"
Luật chơi Tiến Lên Miền Nam thoạt nghe qua thì ai cũng tưởng đơn giản, nhưng khi thực sự xắn tay áo vào code chuẩn hóa từng trường hợp mới thấy sự phong phú của nó:
- Tổ hợp bài đầy đủ: Đánh lẻ, Đôi, Sám cô, Sảnh (từ 3 đến 12 lá liên tiếp, nghiêm cấm chứa quân 2).
- Bộ nhận diện "Hàng" & Chặt Heo: 3 Đôi Thông, Tứ Quý, 4 Đôi Thông (đặc biệt 4 Đôi Thông có thể chặt tự do mà không cần vòng chờ).
- Cơ chế sát phạt thực tế: Chặt chồng liên hoàn (Heo đè Heo, Hàng đè Heo, Hàng đè Hàng tính tiền theo cấp số nhân), Cóng (cháy bài khi không tẩu nổi một lá nào), Thối Heo/Hàng khi ván đấu kết thúc.
- Tới Trắng ngay sau khi chia bài: Tự động nhận diện Sảnh rồng, Tứ quý 2, 5 hoặc 6 đôi thông...
- Luật phụ dân gian: Cấm đánh 2 về chót, thưởng ăn 3 bích về cuối, và cơ chế chống đền bài khi người kế tiếp đã báo chỉ còn đúng 1 lá trên tay.
Để việc tùy biến luật chơi trở nên linh hoạt mà không làm rối loạn mã nguồn, mình gom toàn bộ các tùy chọn luật vào một cấu hình tập trung, cho phép bật tắt từng điều luật một cách trực quan:
// Cấu hình một bàn chơi Đếm Lá sát phạt linh hoạt
const rules = configureRules({
mode: 'Đếm Lá',
choppingMultiplier: 2, // Phạt chặt heo nhân đôi
allowFourPairsCutAnytime: true, // 4 đôi thông chặt tự do
congPenalty: 26, // Cháy bài đền 26 lá
prohibitEndingWithTwo: true, // Cấm đánh 2 về chót
threeSpadesEndingBonus: true // Thưởng ăn 3 bích về cuối
});
Mọi thông số luật đều được đóng gói rõ ràng, giúp hệ thống dễ dàng thích ứng với bất kỳ bàn đấu nào.

🧭 2. Khám phá 3 chế độ chơi đa dạng
Để trải nghiệm chơi không bị đơn điệu, mình phân chia trò chơi thành 3 chế độ với những mục tiêu trải nghiệm hoàn toàn khác nhau:
┌────────────────────────────────────────────────────────────────────────┐
│ 3 CHẾ ĐỘ CHƠI TRONG TIẾN LÊN MIỀN NAM │
├───────────────────┬────────────────────┬───────────────────────────────┤
│ ⚡ Đấu Hạng Elo │ 🗺️ Chiến Dịch │ 🛠️ Phòng Tùy Biến (Sandbox) │
│ (Ranked Elo & │ (9 Chương Cốt │ (Tự do chỉnh luật, số người, │
│ Quick Play) │ Truyện Bụi Đời) │ tiền cược & mức phạt) │
└───────────────────┴────────────────────┴───────────────────────────────┘

1. ⚡ Đấu Hạng & Chơi Nhanh (Ranked Elo & Quick Play)
Hệ thống tự động xếp bàn với các đối thủ có trình độ tương đương dựa trên công thức tính biến động điểm Elo chuẩn quốc tế. Người chơi có thể lựa chọn giữa 4 kiểu phân định thắng thua:
- Đếm Lá: Thắng ăn theo số lá bài còn lại trên tay đối thủ, cực kỳ hồi hộp.
- Nhất Ăn Tất: Người về Nhất ẵm trọn toàn bộ tiền cược trên bàn.
- Truyền Thống: Phân định rõ ràng 4 thứ hạng Nhất, Nhì, Ba, Bét.
- Solo 1v1: Đối đầu trực diện tay đôi, đọ tài nhớ bài và giữ nhịp độ.
2. 🗺️ Hành Trình Sự Nghiệp (Campaign Story)
Chế độ cốt truyện đưa bạn trải nghiệm hành trình của một tay bài vô danh đi lên đỉnh cao thế giới qua 9 chương dài hơi với độ khó và bối cảnh nâng tầm rõ rệt:
- Chặng 1 – Khởi nghiệp bình dân (Chương 1 – 3): Xuất phát từ Sới Bạc Cây Đa (nhập môn), ghé qua Quán Nhậu Bến Xe Miền Tây (lối đánh liều lĩnh, xả Heo tốc chiến) rồi lên Quán Trà Lão Tướng (bắt đầu biết gom bài, ém bộ).
- Chặng 2 – Chiếu bạc tinh anh (Chương 4 – 6): Đặt chân vào Chiếu Bạc Kỳ Hữu, Câu Lạc Bộ Sài Gòn và sòng bài trên Du Thuyền 5 Sao Sông Sài Gòn. Giai đoạn này đối thủ đếm bài cực chuẩn, biết rình rập săn Heo Đỏ và ép nhịp cờ tàn theo luật Đếm Lá.
- Chặng 3 – Đỉnh cao thế giới & Siêu AI (Chương 7 – 9): Vươn tầm quốc tế tại Sòng Bạc Quý Tộc Monaco, bước vào Hội Kín Vô Cực, và đỉnh điểm là màn quyết đấu tại Đền Thờ Trí Tuệ Tối Thượng ở Chương 9 — nơi bạn đối đầu trực diện Tam Đại Boss Superhuman AI (Alpha Mind, Zero Defeat, Mythic Overlord sở hữu Elo 3200+) với khả năng tính toán trước 12 nước đi để chạm tay vào Ngai Vàng Bá Chủ!
3. 🛠️ Bàn Chơi Tùy Biến (Custom Sandbox)
Dành cho anh em muốn tạo bàn tập luyện hoặc thử nghiệm các thế bài dị. Bạn có thể tự do chỉnh số lượng người chơi (từ 2 đến 4 người), mức tiền cược, phạt Cóng, phạt Thối Heo, bật tắt luật 3 Bích về chót theo ý muốn.
🤖 3. Hệ sinh thái 200 Bot AI: "Xã hội giang hồ" tự tranh tài ngầm
Điểm làm mình hào hứng nhất trong dự án này chính là hệ sinh thái đối thủ ảo. Thay vì chỉ khởi tạo tạm 3 con bot ngẫu nhiên mỗi khi bắt đầu ván đấu rồi xóa sổ khi rời bàn, mình tạo ra hẳn một "xã hội thu nhỏ" gồm 200 đối thủ bot sống động:
┌────────────────────────────────────────────────────────────┐
│ HỆ SINH THÁI 200 BOT AI TỰ VẬN HÀNH NGẦM │
│ │
│ [Luồng chạy ngầm] ── Mô phỏng tự động ──► 200 Bot ghép bàn│
│ │ │ │
│ ▼ ▼ │
│ Vỡ nợ phá sản Lập chuỗi thắng lớn │
│ │ │ │
│ ▼ ▼ │
│ Tuyển Mộ Tân Binh Mới Leo bảng Vàng Elo │
│ (50.000 Xu & 1.000 Elo) │ │
│ │ │ │
│ └───────────► [BẢNG TIN GIANG HỒ] ◄──┘ │
│ Cập nhật tin tức trực tiếp │
└────────────────────────────────────────────────────────────┘
Chạy ngầm đa luồng qua Web Worker
Khi bạn đang thong thả ở sảnh chờ hay xem thông tin nhân vật, ở luồng chạy ngầm phía sau, 200 con bot này vẫn liên tục tự chia bàn, đấu bài và thanh toán tiền cược với nhau hàng trăm ván mỗi phút.
Toàn bộ quá trình mô phỏng chạy tách biệt hoàn toàn khỏi luồng hiển thị, không làm đơ giật giao diện và giúp game luôn duy trì ở mức 60 FPS cực kỳ mượt mà.
Đào thải vỡ nợ & Tuyển mộ tân binh
Trong thế giới này, bot không hề có "tiền vô hạn":
- Con bot nào đánh dở, liên tục bị chặt heo hoặc dính cóng dẫn đến cạn túi tiền sẽ chính thức bị tuyên bố vỡ nợ và cuốn gói khỏi bảng danh sách.
- Hệ thống sẽ ngay lập tức kích hoạt cơ chế tuyển mộ một Tân Binh mới (được cấp 50.000 Xu khởi nghiệp và 1.000 điểm Elo), đồng thời kế thừa ngẫu nhiên một phong cách chiến thuật mới.
- Bảng Tin Giang Hồ tại sảnh chính sẽ nhảy thông báo thời gian thực về những sự kiện nóng hổi:
"Cu Tí vừa vỡ nợ cay đắng và cuốn gói rời sới bài..."
"Thần Bài Cô Ba vừa lập chuỗi 10 trận bất bại, bỏ túi 500.000 Xu!"

Hệ thống 9 Bậc Rank Elo (Từ Sắt đến Thách Đấu)
200 con bot trong hệ sinh thái ngầm được phân bổ trải dài trên 9 bậc Rank theo chuẩn Elo quốc tế, phản ánh đúng các nấc thang tiến hóa của trí tuệ nhân tạo:
| Bậc Rank | Huy hiệu | Dải Elo | Đại diện tiêu biểu | Đặc trưng chiến thuật & Thuật toán |
|---|---|---|---|---|
| Tier 1: Sắt | ⚙️ | 0 – 899 | Tí Chuột, Tèo Bờ Rào | Đánh theo bản năng, có gì nhỏ nhất đánh nấy, chưa biết nhớ bài |
| Tier 2: Đồng | 🥉 | 900 – 1199 | Bảy Xe Lôi, Năm Xích Lô | Nắm vững luật cơ bản, bắt đầu biết tẩu rác và giữ Heo an toàn |
| Tier 3: Bạc | 🥈 | 1200 – 1499 | Chú Tư Cờ, Rex Bụi Đời | Lối đánh phóng khoáng, biết đếm Heo và gài bẫy nhử mồi cơ bản |
| Tier 4: Vàng | 🥇 | 1500 – 1799 | Cụ Tám, Bác Sáu Toán Học | Già rơ sới bạc, đếm Heo + Át chuẩn xác, chặn đền bài 1 lá quyết liệt |
| Tier 5: Bạch Kim | 💎 | 1800 – 2099 | Thiếu Gia Ken, Sophia | Bán chuyên đẳng cấp, nhớ trọn 52 lá và bắt đầu tung đòn hỏa mù |
| Tier 6: Kim Cương | 🔮 | 2100 – 2399 | Madam Ruby, Raven Ảo Ảnh | Chuyên nghiệp, tự động tái cấu trúc thế bài theo nhịp trận đấu |
| Tier 7: Cao Thủ | 👑 | 2400 – 2699 | Phantom Apex, Alpha-TL Master | Suy luận đỉnh cao, dùng xác suất Bayes đoán chính xác bài ẩn đối thủ |
| Tier 8: Đại Cao Thủ | 🌌 | 2700 – 2999 | Oracle Tiên Tri, Chronos Bất Tử | Khắc tinh cờ tàn, vét cạn cây quyết định tìm chuỗi kết liễu tất thắng |
| Tier 9: Thách Đấu | ⚡ | 3000+ | Tam Đại Boss Superhuman | Siêu AI tối thượng: phối hợp tìm kiếm sâu 12 nước và Cân bằng Nash |
🧠 4. Giải mã "bộ não" AI: Từ đếm bài xác suất đến mô phỏng cây quyết định
Để bot đánh vừa khôn ngoan vừa có cảm giác chân thật như người ngồi đối diện, mình xây dựng kiến trúc AI theo mô hình phân tầng:
1. Chuỗi phân cấp quyết định
Mỗi khi đến lượt ra bài, bot sẽ duyệt qua 5 tầng tư duy tuần tự:
- Tầng Nguy Cấp: Xử lý tình huống khẩn cấp như phá bộ để cứu cóng hoặc ngăn đối thủ sắp về bài.
- Tầng Kết Thúc Ván: Khi trên tay chỉ còn 1-3 lá bài, bot sẽ tìm cách dọn sạch bài nhanh nhất để dứt điểm trận đấu.
- Tầng Chủ Động Ra Bài: Chọn bộ bài có lợi thế nhất khi nắm quyền đi trước (xả rác an toàn hoặc ép vào cửa yếu của đối phương).
- Tầng Đỡ Bài Đối Thủ: Lựa chọn quân bài đè đối thủ với chi phí bài tổn thất nhỏ nhất.
- Tầng Bỏ Lượt An Toàn: Quyết định bỏ lượt để bảo toàn lực lượng cho những vòng sau.
2. Bộ đếm bài & Suy luận xác suất Bayes
Bot theo dõi toàn bộ 52 lá bài trong bộ bài. Dựa trên lịch sử những lá bài đã xuất hiện và các lần bỏ lượt của từng người chơi, bot sẽ tính toán xác suất:
- Liệu đối thủ ngồi kế tiếp có đang ém Tứ Quý hay 3 Đôi Thông không?
- Còn bao nhiêu con Heo chưa xuất hiện trên bàn?
Nếu xác suất đối thủ đang rình rập chặt Heo vượt ngưỡng an toàn, bot cấp cao sẽ chủ động ghìm Heo lại chứ không ra bài một cách ngây ngô.
3. Đòn tâm lý tung hỏa mù (Bluffing)
Không phải cứ có bài đè được là bot sẽ đánh. Ở các bậc cao thủ, thuật toán lý thuyết trò chơi sẽ tính toán để bot thỉnh thoảng chủ động bỏ lượt dù trên tay hoàn toàn có bài đỡ được. Nước đi này nhằm nhử đối phương tưởng mình đã hết bài, từ đó bung quân bài chủ lực ra và dính bẫy phản công.
4. Thuật toán tìm kiếm cây quyết định (MCTS)
Với các đối thủ thuộc hàng Thần Bài và Siêu AI, bot được tích hợp bộ giải mô phỏng cây quyết định. Thuật toán sẽ giả lập hàng trăm kịch bản phân phối bài ẩn khả dĩ và chạy thử nghiệm ván đấu trong vài trăm mili-giây để tìm ra nước bài có tỷ lệ thắng tối ưu nhất.
⚖️ 5. Quá trình tinh chỉnh & sửa lỗi logic cho bot
Việc xây dựng thuật toán trên lý thuyết thì khá suôn sẻ, nhưng khi đưa bot vào chạy thử nghiệm thực tế qua nhiều ván đấu, mình nhận ra một số lỗi logic khiến cách xử lý của bot chưa thật sự hợp lý:
1. Giữ Heo đến cuối khi có luật cấm về bằng 2
Ở các ván chơi có bật luật cấm đánh 2 về cuối, bot ban đầu chưa tính đến trường hợp này nên vẫn quen tay giữ con Heo to nhất lại để làm lá bài dứt điểm. Đến khi trên tay chỉ còn đúng một lá Heo thì luật cấm đánh kích hoạt, khiến bot không thể ra bài và bị xử phạt thối Heo. Sau đó mình đã bổ sung logic nhận diện luật chơi từ sớm: nếu bàn chơi cấm về bằng Heo, bot sẽ chủ động đánh Heo ở thời điểm thích hợp để dọn đường cho các lá bài nhỏ hơn về đích.
2. Xử lý khi bài vừa có đôi vừa có rác lẻ
Ban đầu mình đặt điều kiện nếu bài còn rác lẻ thì bot phải ưu tiên đánh rác trước để thăm dò. Tuy nhiên quy định này lại làm nảy sinh tình huống bất cập: có những ván bot cầm 3–4 đôi rất đẹp nhưng chỉ vì vướng 1–2 lá rác nhỏ mà không dám đánh đôi nào, cứ kiên trì ra từng lá bài lẻ để rồi bị đối thủ đè mất lượt. Sau khi quan sát, mình đã điều chỉnh lại điều kiện: chỉ khi rác lẻ chiếm số lượng áp đảo thì mới giữ đôi lớn để giành lại lượt, còn khi bài đã gom được nhiều bộ thì cứ chủ động đánh bộ để tạo lợi thế.
3. Hạn chế đánh đôi nhỏ khi đi đầu
Một số bot cấp trung khi được quyền đi đầu thường có thói quen đánh ngay các đôi nhỏ (như đôi 4, đôi 5) mà phía sau không có bài lớn bảo vệ. Ở bàn 4 người, nước đi này rất dễ bị người khác đè lại, làm bot mất quyền kiểm soát trận đấu và bị kẹt các lá bài lẻ còn lại. Mình đã điều chỉnh để bot chỉ chủ động ra đôi nhỏ khi bài đã sạch rác hoặc có bài đủ mạnh để giành lại lượt đi tiếp theo.
4. Đánh giá bài ẩn ở bàn 3 người
Ở thể thức 3 người chơi, có 13 lá bài úp không ai cầm. Những bot tính toán sâu đôi khi lại chơi quá cẩn trọng vì phán đoán đối thủ có thể đang giữ Heo hoặc hàng, dù thực tế các quân bài đó đang nằm trong đống bài úp. Việc tinh chỉnh lại cách đánh giá rủi ro giúp bot giữ được lối đánh linh hoạt và tự nhiên hơn tùy theo số lượng người trên bàn.
5. Thử nghiệm và đánh giá qua nhiều ván đấu
Trong game bài, kết quả thắng thua của một vài ván đơn lẻ thường phụ thuộc nhiều vào việc bài chia đẹp hay xấu. Để đánh giá thuật toán một cách khách quan, mình cho các bot hoán đổi ghế ngồi với cùng một bộ bài được chia và chạy mô phỏng hàng trăm ván để thu thập số liệu. Kết quả cho thấy bot ở bậc cao hơn duy trì được thứ hạng ổn định hơn, số lần bị phạt thối Heo giảm hẳn và tỷ lệ về bét cũng thấp hơn rõ rệt.
🏗️ 6. Hậu trường kiến trúc: Tách rời giao diện & Kiểm soát lỗi nghiêm ngặt
Về mặt kỹ thuật, dự án được thiết kế với sự kỷ luật cao để đảm bảo hệ thống vận hành bền bỉ và dễ bảo trì:
┌─────────────────────────────────────────────────────────────┐
│ GIAO DIỆN NGƯỜI DÙNG │
│ (Thuần hiển thị, nhận dữ liệu trạng thái bàn) │
└──────────────────────────────┬──────────────────────────────┘
│ Thao tác người chơi
▼
┌─────────────────────────────────────────────────────────────┐
│ ĐIỀU PHỐI LUỒNG TRẬN ĐẤU │
│ (Quản lý vào bàn, cược tiền, đầu hàng, tổng kết) │
└──────────────────────────────┬──────────────────────────────┘
│ Điều khiển độc lập
▼
┌─────────────────────────────────────────────────────────────┐
│ BỘ ĐIỀU KHIỂN VÁN ĐẤU │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Vòng lặp trận đấu chạy ngoài DOM │ │
│ │ (Quản lý lượt đánh, tính bài, xử lý timer) │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────┘
│ Thực thi logic
▼
┌─────────────────────────────────────────────────────────────┐
│ BỘ LUẬT BÀI & CƠ SỞ DỮ LIỆU │
│ (Thẩm định nước đi, lưu trữ IndexedDB) │
└─────────────────────────────────────────────────────────────┘
Tách rời hoàn toàn logic trận đấu ra khỏi giao diện React
Một trong những vấn đề hay gặp khi viết game bằng React là logic trò chơi dễ bị gắn chặt vào vòng đời của Component, dẫn đến việc dữ liệu bị cũ hoặc các bộ đếm thời gian vẫn chạy ngầm sau khi unmount.
Ở dự án này, toàn bộ vòng lặp ván đấu — từ chia bài, tính lượt đánh cho đến đếm ngược thời gian — được tách riêng hoàn toàn bên ngoài giao diện:
- Bộ điều khiển ván đấu phụ trách trọn vẹn luồng trận đấu mà không phụ thuộc vào React DOM.
- Giao diện chỉ đóng vai trò thuần hiển thị, nhận dữ liệu trạng thái bàn đấu gửi về để vẽ lên màn hình, giúp mã nguồn giao diện cực kỳ tinh gọn.
- Hệ thống tự động giải phóng toàn bộ các tiến trình đếm giờ ngầm ngay khi người chơi rời bàn, triệt tiêu nguy cơ rò rỉ bộ nhớ.
Lưu trữ bền vững với IndexedDB
Thay vì dùng bộ nhớ cục bộ thông thường vốn bị giới hạn dung lượng và dễ gây nghẽn trình duyệt, dự án sử dụng IndexedDB với 8 bảng dữ liệu riêng biệt để quản lý hồ sơ người chơi, bảng xếp hạng Elo, lịch sử đối đầu và hệ thống nhiệm vụ hàng ngày.
Đặc biệt, trạng thái bàn đấu luôn được đồng bộ liên tục: nếu bạn lỡ tay tải lại trang hay bị ngắt kết nối đột ngột, trò chơi sẽ tự động khôi phục đúng ván bài đang chơi dở mà không bị xử thua hay mất tiền oan.
Kỷ luật kiểm soát lỗi nghiêm ngặt
Để dự án vận hành mượt mà và không phát sinh lỗi bất ngờ giữa ván đấu, toàn bộ mã nguồn được thiết lập theo quy chuẩn an toàn cao nhất: cấm tuyệt đối việc dùng các kiểu dữ liệu mập mờ hoặc ép kiểu gượng ép. Mọi tình huống chia bài, kiểm tra tính hợp lệ của nước đi và vị trí ghế ngồi của người chơi đều được xác thực chặt chẽ ngay từ logic nền tảng, giúp triệt tiêu hoàn toàn nguy cơ game bị đứng hình hay phát sinh lỗi lúc đang chơi.
🎯 Lời kết
Xây dựng game Tiến Lên Miền Nam mang lại cho mình rất nhiều niềm vui: vừa được sống lại cảm giác của những ván bài rộn rã tiếng cười ngày Tết, vừa có dịp thử nghiệm nhiều bài toán thú vị về mô phỏng đa luồng và thuật toán trí tuệ nhân tạo.
Đến đây thì cũng mỏi tay gõ phím cmnr. Nếu anh em muốn đổi gió làm vài ván bài giải trí không quảng cáo hoặc muốn thử tài xem mình có trụ nổi trước 200 con bot giang hồ hay không, hãy ghé qua chơi thử nhé!