Làm một đối thủ máy không bao giờ thua là việc dễ nhất trên đời: máy biết chính xác quả bóng sẽ rơi ở đâu, biết người chơi vừa bấm nút gì, phản ứng trong một phần triệu giây. Cái khó là làm một đối thủ thua được một cách thuyết phục — mắc lỗi như người, có điểm yếu đọc được, và mạnh lên từng bậc mà không chuyển sang “ăn gian”. Bài này mở mã của hai ứng dụng trong AppGiaiTri, Giao Đấu và Chiến Đấu, để xem đối thủ máy thật sự “nghĩ” thế nào.
Trí tuệ nhân tạo ở đây không phải là thứ bạn đang nghĩ
Nhắc tới trí tuệ nhân tạo, nhiều người hình dung những mô hình khổng lồ học từ hàng triệu dữ liệu. Đối thủ máy trong ứng dụng giải trí gần như không bao giờ là thứ đó. Nó là một bộ luật viết tay, cộng với vài con số điều chỉnh tính cách, cộng với một lượng ngẫu nhiên được kiểm soát chặt. Lý do rất thực tế: người làm cần hiểu và chỉnh được đối thủ. Một mô hình học máy thắng quá dễ hay thua quá ngốc thì rất khó biết vì sao; một bộ luật với con số “thời gian phản ứng 0,2 giây” thì chỉnh một dòng là xong.
Và nguyên tắc số một mà mọi người làm lâu năm đều thuộc: đối thủ máy chỉ được biết những gì người chơi thấy được. Nó không được đọc nút người chơi vừa bấm, chỉ được nhìn động tác đã hiện trên màn hình. Vi phạm nguyên tắc này, đối thủ sẽ đỡ những đòn chưa kịp thành hình, và người chơi cảm thấy ngay — dù không gọi được tên — rằng mình đang bị lừa.
Giao Đấu: đối thủ nhìn trước đường bóng, nhưng chậm một nhịp
Máy “đoán” điểm rơi bằng cách chạy thử tương lai
Khi người chơi đánh bóng sang, đối thủ máy cần biết nên chạy tới đâu. Nó không dùng công thức gần đúng nào cả: nó lấy trạng thái hiện tại của quả bóng — vị trí, vận tốc, độ xoáy — rồi cho chạy thử chính bộ luật vật lý của ứng dụng về phía trước, với bước tính nhỏ 1/120 giây, tối đa khoảng ba giây rưỡi. Trong lúc chạy thử, nó theo dõi bóng chạm lưới chưa, nảy lần thứ nhất ở đâu, và tìm khoảnh khắc bóng rơi về ngang hông — điểm đánh đẹp nhất.
Đây là lợi ích trực tiếp của việc tách nhịp tính toán cố định khỏi nhịp vẽ (có bài riêng về chuyện đó): vì vật lý luôn cho ra cùng kết quả với cùng đầu vào, “chạy thử tương lai” cho ra đúng tương lai. Cũng chính hàm dự đoán này được dùng để vẽ vòng tròn thời điểm cho người chơi — hai bên nhìn cùng một thông tin.
Nếu dự đoán cho thấy bóng sẽ rơi ra ngoài sân, đối thủ đứng yên để bóng ra. Người chơi tinh ý sẽ học được: đánh sát vạch mà ra thì máy không cứu, đánh sát vạch mà vào thì máy phải chạy xa.
Thời gian phản ứng: con số làm nên tính cách
Biết điểm rơi rồi, nhưng đối thủ không được chạy ngay. Nó phải đợi hết thời gian phản ứng của mình mới bắt đầu di chuyển. Mỗi đối thủ trong môn tennis có một con số riêng: người mới chơi phong trào đợi 0,3 giây, nhà vô địch ở cuối giải chỉ đợi 0,15 giây. Nghe chênh lệch nhỏ, nhưng với quả bóng bay 25 mét mỗi giây, 0,15 giây là gần bốn mét đường bóng — đủ để phân biệt “với tới” và “không với tới”.
Ngoài phản ứng, mỗi đối thủ còn có một bộ số mô tả lối đánh:
| Thông số | Ý nghĩa | Người chơi cảm nhận thế nào |
|---|---|---|
| Tốc độ chạy | Di chuyển nhanh bao nhiêu | Cú góc có “ăn” hay bị cứu |
| Tỉ lệ lỗi | Khả năng cú đánh hỏng: vào lưới, ra ngoài | Có tự mắc lỗi khi mình chỉ cần giữ bóng không |
| Độ chuẩn | Độ tản mát quanh điểm nhắm | Bóng về đúng góc hay lệch vào giữa |
| Lực, độ sâu | Bóng nhanh và sát vạch cuối tới đâu | Có bị ép lùi sân không |
| Lên lưới, lốp, bỏ nhỏ, đánh góc | Xác suất chọn từng kiểu cú | “Tính cách” — người thích lên lưới, người trộn nhịp |
Nhờ đó mỗi đối thủ có một điểm yếu học được. Người thích lên lưới sẽ thua cú lốp qua đầu; người giữ cuối sân sẽ lúng túng trước cú bỏ nhỏ. Mỗi đối thủ đi kèm một lời mách nước nhắm đúng điểm yếu đó, và màn hình kết thúc trận chỉ ra lỗi bạn hay mắc nhất: vung sớm, vung muộn hay đánh ra ngoài. Người chơi không đấu với một “độ khó”, mà với một con người có thói quen.
Mắc lỗi như người thật
Tỉ lệ lỗi không đứng yên. Mỗi cú đánh, đối thủ cộng thêm lỗi khi: bóng tới quá nhanh, phải với người ra xa, bóng xoáy cắt khó chịu, người chơi vừa đánh một cú hoàn hảo, và — chi tiết hay nhất — khi pha bóng kéo dài. Mỗi chạm bóng trong một pha dài làm đối thủ run tay thêm một chút, có giới hạn trên. Người chơi kiên nhẫn giữ bóng sẽ được thưởng bằng lỗi tự đánh hỏng của máy, đúng như ngoài sân thật.
Độ lệch của cú đánh cũng không phải ngẫu nhiên đều. Nó theo phân bố hình chuông: phần lớn cú đi gần điểm nhắm, thỉnh thoảng lệch xa. Ngẫu nhiên đều cho cảm giác máy “đánh bừa”; hình chuông cho cảm giác một người có tay nghề nhưng không hoàn hảo.
Chiến Đấu: nhìn thấy đòn, rồi mới phản ứng
Trong Chiến Đấu, nguyên tắc “chỉ biết những gì người chơi thấy” được viết thẳng thành một dòng chú thích trong mã: đối thủ nhận ra đòn của người chơi sau thời gian phản ứng — không đọc thao tác bấm. Cụ thể, máy chỉ ghi nhận khi nhân vật của người chơi bắt đầu động tác ra đòn trên màn hình, rồi đếm đủ thời gian phản ứng mới được quyết định đỡ, lùi hay né.
Mạnh dần theo vòng giải
Trong chế độ giải đấu, năm vòng đấu có năm mức. Thời gian phản ứng giảm dần từ 0,34 giây ở vòng đầu xuống 0,18 giây ở vòng cuối; tỉ lệ sai lầm giảm từ 0,3 xuống 0,08; một hệ số “tay nghề” tăng dần làm đối thủ tấn công chủ động hơn. Không có vòng nào mà máy được thêm máu hay thêm sức đánh — nó chỉ nhanh hơn và ít sai hơn. Đây là khác biệt giữa “khó” và “bất công”.
Sáu lối đánh, sáu cách nghĩ
Mỗi đối thủ được gán một lối đánh, mỗi lối đánh là một bộ số: khoảng cách ưa thích, độ hăng tấn công, xu hướng đỡ, xu hướng phản công, xu hướng lùi. Lối ép sân thích đứng gần và ra đòn liên tục; lối phản công đứng chờ, đỡ nhiều, rồi trừng phạt sơ hở; lối giữ cự ly luôn lùi về khoảng cách xa. Có cả lối né góc, ôm vật cho những môn có kỹ thuật đó, và lối biến thế tự đổi thế theo cự ly.
Đối thủ không suy nghĩ liên tục mà “ra quyết định” theo nhịp: cứ khoảng 0,14 đến 0,32 giây một lần, với độ dài ngẫu nhiên. Nhịp đều tăm tắp sẽ tạo ra một nhịp điệu máy móc mà người chơi bắt được; nhịp lệch chút ít làm đối thủ khó đoán như người.
Những chi tiết làm đối thủ “có hồn”
- Trừng phạt sơ hở. Khi người chơi ra đòn hụt và đang thu tay, hoặc đang choáng, đối thủ có xác suất lao vào phản công. Đó là cách máy dạy người chơi đừng vung đòn bừa.
- Lùi hồi sức. Khi thể lực thấp, hầu hết lối đánh sẽ lùi ra xa để hồi — trừ lối ép sân, vốn không biết lùi. Người chơi đọc được và có thể tận dụng.
- Đỡ hoàn hảo rất hiếm. Người chơi đỡ đúng khoảnh khắc sẽ mở cửa phản công. Máy cũng làm được, nhưng xác suất thấp và chỉ khi thật sự “thấy” đòn — không bao giờ đọc trước.
- Thỉnh thoảng ra đòn hụt. Mã có hẳn một nhánh cho đối thủ tung đòn khi chưa tới tầm, với xác suất bằng tỉ lệ sai lầm — như người thật nôn nóng.
Ngẫu nhiên có kiểm soát
Mọi lần đối thủ “tung xúc xắc” đều dùng một bộ sinh số ngẫu nhiên có hạt giống, không dùng số ngẫu nhiên tự do của trình duyệt. Về nguyên tắc, cùng hạt giống và cùng chuỗi thao tác thì đối thủ hành xử y hệt. Điều này giúp người làm tái hiện được một pha lỗi mà người dùng báo, và mở đường cho việc kiểm lại lượt chơi về sau.
Những thứ chúng tôi cố ý không làm
- Không “bắt kịp” giả tạo. Nhiều ứng dụng đua xe cho xe của đối thủ máy tự tăng tốc khi người chơi dẫn xa, chậm lại khi người chơi tụt lại. Nó giữ trận đấu gay cấn nhưng lấy mất ý nghĩa của tay nghề. Đối thủ trong Giao Đấu và Chiến Đấu có thông số cố định trong suốt trận.
- Không đọc nút bấm. Như đã nói, máy chỉ phản ứng với hình ảnh đã hiện.
- Không để chế độ hỗ trợ lên bảng. Người chơi có thể bật hỗ trợ điều khiển để dễ hơn, nhưng trận đó không lên bảng xếp hạng.
Câu hỏi thường gặp
Đối thủ máy trong ứng dụng giải trí có dùng trí tuệ nhân tạo học máy không?
Phần lớn là không. Đối thủ máy thường là bộ luật viết tay kèm các thông số tính cách và một lượng ngẫu nhiên có kiểm soát, vì cách này dễ hiểu, dễ chỉnh và chạy nhẹ trên điện thoại.
Đối thủ máy có biết trước tôi sắp bấm gì không?
Trong Giao Đấu và Chiến Đấu thì không. Đối thủ chỉ phản ứng với động tác đã hiện trên màn hình và phải đợi hết thời gian phản ứng của mình, giống một người đang nhìn bạn.
Thời gian phản ứng của đối thủ máy là bao nhiêu?
Tuỳ đối thủ. Trong tennis của Giao Đấu, từ 0,3 giây với người chơi phong trào tới 0,15 giây với nhà vô địch; trong giải đấu của Chiến Đấu, từ 0,34 giây ở vòng đầu xuống 0,18 giây ở vòng cuối.
Vì sao đối thủ máy đôi khi đánh hỏng những cú dễ?
Vì tỉ lệ lỗi được thiết kế để giống người: nó tăng khi bóng nhanh, khi phải với xa và khi pha bóng kéo dài. Giữ bóng kiên nhẫn là một chiến thuật hợp lệ để đối thủ tự mắc lỗi.
Đối thủ ở vòng sau mạnh hơn bằng cách nào?
Họ phản ứng nhanh hơn, ít sai hơn và chủ động hơn. Không có đối thủ nào được thêm máu hay thêm sức đánh chỉ vì ở vòng sau, nên thắng được là nhờ tay nghề của bạn.
Có cách nào đánh bại đối thủ khó nhất không?
Mỗi đối thủ có lối đánh và điểm yếu riêng, và ứng dụng có lời mách nước cho từng người. Quan sát họ phản ứng thế nào với cú lốp, cú bỏ nhỏ hay đòn đánh từ xa, rồi đánh vào đúng chỗ đó.