Lập trình bot Viblo battle như thế nào? (phần 1)
Vì sao có bài viết này?
Tôi đã tham gia một vài lần các sự kiện của nền tảng Viblo, tuy nhiên lần này là lần đầu tiên xuất hiện thử thách trên nền tảng Viblo battle. Nghe tên khá ngầu đó, tôi bắt đầu tìm hiểu cách chơi của nền tảng này. Sau khi đọc qua hướng dẫn tại https://battle.viblo.asia/games/matrix thì ... khá là mông lung. Do bài viết hướng dẫn chưa phải quá chi tiết (quan điểm cá nhân), cộng thêm bản thân tôi là một người không quá thông minh, gặp những thứ mới phải đọc kỹ, nghiên cứu đi nghiên cứu lại mới hiểu được chứ không tiếp thu nhanh, haizzzz.
Tôi tin rằng sẽ có một số bạn (chắc là thiểu số) cũng khá "lơ mơ" khi tiếp xúc tới nền tảng mới lạ này (Chắc là tôi không cô đơn đâu) - cũng chính là lý do bài viết này ra đời. Bài viết sẽ giải thích chi tiết hơn về nền tảng, luật chơi, cách lập trình bot, ... theo góc nhìn trực diện của tôi. Mong rằng bài viết sẽ giúp ích cho các bạn trong sự kiện này!
Lời khuyên: Hãy đọc kỹ luật chơi tại https://battle.viblo.asia/games/matrix, nếu chưa hiểu lắm, bài viết này có lẽ sẽ giúp bạn đó! Ngược lại, vui lòng bỏ qua để không lãng phí thời gian =)))
Luật chơi
Các bạn có thể chơi thử chế độ người vs bot để trải nghiệm trước.
Người chơi được cung cấp một bảng 9x9, mỗi lượt có một bộ 1x3 với 3 số ngẫu nhiên (từ 7 đến 10) đưa ra, người chơi được xếp vào một trong 27 vị trí, ví dụ xếp vào vị trí 13 như dưới:
Con bot cũng làm việc tương tự, và trò chơi tính điểm nếu có 3 số liền nhau giống nhau (theo 3 hàng ngang, dọc hoặc chéo):
Sau 27 lượt, ai được điểm cao hơn sẽ thắng. Đối với người vs người hoặc người vs bot thì cứ kéo thả là OK! Hãy chơi thử và đưa ra chiến thuật hợp lý nhé!
Lập trình bot vs bot? - Đọc input?
Đây là phần chính của bài viết, tập trung vào cách lập trình tự động để 2 con bot solo với nhau. Trong phần 1 tôi sẽ giải thích chi tiết các giá trị input trong mỗi turn, phần 2 sẽ hướng dẫn lập trình một bot đơn giản.
Trong mỗi turn, chúng ta có input (với 2 người chơi) như sau:
2
7 8 10
9 9 8 9 -1 9 9 -1 -1 7 10 7 7 -1 9 7 -1 -1 9 10 8 9 -1 10 10 -1 -1 -1 10 7 9 9 -1 -1 -1 8 -1 10 9 9 8 -1 -1 -1 10 -1 8 8 8 8 -1 -1 -1 7 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
7 9 9 9 -1 7 9 -1 -1 10 10 7 10 -1 9 7 -1 -1 9 10 8 9 -1 10 10 -1 -1 -1 10 7 9 9 -1 -1 -1 8 -1 10 9 9 8 -1 -1 -1 10 -1 8 8 7 8 -1 -1 -1 7 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
Đối với 2 người chơi, input gồm 4 dòng:
- Dòng 1: số lượng người chơi (tính bot là 1 người)
- Dòng 2: Thẻ 1x3 và 3 giá trị trên thẻ (theo thứ tự từ trên xuống dưới)
- Dòng 3: Trạng thái bảng 9x9 hiện tại của người chơi, số -1 nghĩa là ô trống đó đang không có giá trị nào
- Dòng 4: Trạng thái bảng 9x9 của đối thủ
Như vậy chương trình của chúng ta cần đọc hết 4 dòng giá trị này. Tôi sử dụng ngôn ngữ C++ quen thuộc
Khai báo một biến N
để lưu số người chơi, mảng now[3]
để lưu 3 giá trị hiện tại trên thẻ 1x3 của turn, mảng userboard[81]
lưu 81 giá trị, do chúng ta chưa cần quan tâm đến bảng hiện tại của đối thủ, nên tạm thời sử dụng một biến temp
để nhập vào 81 lần lưu các giá trị trong bảng hiện tại của đối thủ.
Giải thích thêm về biến temp
: Thực ra, trong dự liệu input có số liệu của bảng đối thủ là để chúng ta tạo ra chiến thuật hợp lý dựa vào "tình hình hiện tại". Đây là phần nâng cao hơn, tôi sẽ nhắc đến sau. Hiện tại chúng ta chỉ cần quan tâm làm sao đọc được và đọc đúng dữ liệu thôi =))))
#include <iostream>
using namespace std;
int main() {
int N, now[3], userboard[81], temp;
cin >> N;
cin >> now[0] >> now[1] >> now[2];
for (int i = 0; i < 81; i++) {
cin >> userboard[i];
}
for (int i = 0; i < 81; i++) {
cin >> temp;
}
}
Tuy nhiên, hãy để ý rằng thực tế các thẻ của chúng ta có kích thước 1x3. Trong số 27 turn, chúng ta đặt vào bảng 9x9 là 27 thẻ. Để thống nhất từng thẻ gồm 3 giá trị không bị rời rạc (vì sau này chúng ta còn sử dụng đến các thẻ thì khó điều khiển giá trị). Chúng ta nên tạo biến mảng lưu giá trị bảng hiện tại là mảng 2 chiều userboard[27][3]
gồm 27 biến, mỗi biến lưu được 3 giá trị.
Khi đó sửa lại chương trình thành:
#include <iostream>
using namespace std;
int main() {
int N, now[3], userboard[27][3], temp;
cin >> N;
cin >> now[0] >> now[1] >> now[2];
for (int j = 0; j < 3; j++)
for (int i = 0; i < 9; i++)
cin >> userboard[i][0];
for (int j = 0; j < 3; j++)
for (int i = 9; i < 18; i++)
cin >> userboard[i][0];
for (int j = 0; j < 3; j++)
for (int i = 18; i < 27; i++)
cin >> userboard[i][0];
for (int i = 0; i < 81; i++) {
cin >> temp;
}
return 0;
}
Tạm thời phần 1 tới đây đã đi, phần sau chúng ta sẽ cùng xem xét phương thức xử lý output và phân tích một số chiến thuật đơn giản nhé!
All rights reserved