Phần 1 : Lập Trình Auto Game Với C#

     

Xin chào các bạn. Lần này mình quay trở lại với một bài hướng dẫn các bạn lập trình một tool nho nhỏ nhưng có tính ứng dụng cao. Tool này là tool tự động chơi game Lyto Different Color hiện đang làm mưa làm gió trên facebook.

Bạn đang xem: Phần 1 : Lập Trình Auto Game Với C#

Giới thiệu

Game này khá đơn giản và vui vẻ. Đại khái là có một bảng hình vuông chứa nhiều hình tròn nhỏ, trong đó có 1 hình tròn có màu khác biệt với tất cả các hình tròn khác. Nhiệm vụ của bạn là tìm kiếm hình tròn có màu khác biệt này và qua bài thật nhanh.

Mình đã chơi thử game này trong 1 tiếng. Kết quả tốt nhất của mình là bài 42, khi số hình tròn trong một ô vuông là 49 hình và có màu rất giống nhau. Bạn có thể thử chơi để biết

Sau 1 ngày chơi game, mình quyết định sẽ làm một cái tool để tự động chơi. Vấn đề không chỉ là điểm số cao, vấn đề là chúng ta cần liên tục "rèn luyện kỹ năng lập trình". Nếu hứng thú và say mê lập trình, hãy thử làm tool này theo hướng dẫn của mình nhé

Ý tưởng và phác thảo, chuẩn bị công nghệ

Để xây dựng tool tự chơi này, bạn cần phải code được các đoạn mã chạy theo chu trình như sau:

Lấy được ảnh màn hình/cửa sổ gameLấy được vùng ảnh chứa các hình tròn (bỏ qua các vùng khác như điểm số, thời gian)Phát hiện ra được hình tròn có màu khác biệt (tìm được tọa độ tâm của hình tròn này)Điều khiển chuột nhảy tới tọa độ của hình tròn trên, sau đó click rồi quay về bước đầu tiên

*

Ý tưởng thì khá rõ ràng rồi. Vấn đề là chúng ta sẽ code bằng ngôn ngữ gì, công nghệ gì?

Trước hết bạn cần chơi được game trên windows và chrome. Chơi được game trên chrome, bạn sẽ dễ dàng sử dụng các công cụ thứ 3 để can thiệp vào game hơn. Cách chơi đc game này trên chrome thì quá dễ, mình bỏ qua.

Đối với việc phát triển tool, mình lựa chọn C#, vì ngôn ngữ C# cung cấp các hàm rất mạnh để lấy được ảnh màn hình và điều khiển chuột, cũng support việc duyệt ảnh dễ dàng qua lớp Bitmap. Nếu sử dụng ngôn ngữ lập trình C++, bạn sẽ gặp khó khăn trong vấn đề tạo giao diện, phân tích ảnh (duyệt ảnh để tìm hình tròn). Nếu chọn Java, mình nghĩ bạn sẽ gặp khó khăn với các API điều khiển chuột hay lấy ảnh màn hình

Ở đây mình muốn nhấn mạnh với các bạn rằng, việc lựa chọn công nghệ/công cụ/ngôn ngữ là khá cần thiết. Bởi vì nếu chọn sai, bạn sẽ đi vào bế tắc khi không tìm được các hàm mà mình cần

Tạo project C# Winform và chuẩn bị màn hình Game

Hướng dẫn của mình chỉ nêu ý tưởng và các hàm quan trọng, nên những cái đơn giản mình sẽ nói rất nhanh. Ở đây chỉ nói ngắn gọn, các bạn tạo ra một project C# Winform đơn giản trên IDE visual studio nhá.

Xem thêm: Hướng Dẫn Cách Download The Youtube App Store, ‎Youtube: Watch, Listen, Stream On The App Store

Bạn cũng có thể tìm hiểu thêm một dự án/ứng dụng nhỏ mà mình đã hướng dẫn ở đây:lập trình game winform với C#

Các bước thực hiện

Step 1: Code phần lấy ảnh của cửa sổ chơi game

Như trình bày ở trên, trước hết bạn cần lấy ra khu vực màn hình game có chứa các hình tròn. Bạn cần:

Dùng hàm để lấy ảnh (gần như việc capture screen ý)Tạo 1 picturebox trên ứng dụng của bạn, rồi load cái ảnh bạn vừa lấy (mục đích để kiểm tra xem nó có đúng không)

Sau bước này, bạn cần làm ra được cửa sổ giống như mình nè:

*

Đối với việc tạo pictureBox, mình không hướng dẫn nữa (có ở bài game Pikachu rồi)

Đối với việc lấy được ảnh màn hình, bạn có thể tham khảo và chạy thử đoạn mã sau:

Bitmap destBitmap = new Bitmap(width, width);using (Graphics g = Graphics.FromImage(destBitmap)){ g.CopyFromScreen(new Point(startX, startY), Point.Empty, new Size(width, width));}px.Image = destBitmap;​Bạn cần tự xác định độ rộng cũng như tọa độ góc trên trái của vùng màn hình cần lấy (startX, startY và width). Để xác định đc vùng game chính xác, bạn có thể hard code một số con số (tự căn chỉnh trong code) hoặc có thể cho nhập từ textBox, hoặc có thể dựa vào 1 số công thức để tự tính ra

Step 2: Tạo sự kiện để lặp đi lặp lại chu trình lấy ảnh, phân tích ảnh theo chu kì thời gian

Nếu bạn nghĩ đơn giản, bạn có thể dùng while-true để lặp lại chu trình trên.

Tuy nhiên trong lập trình giao diện, ko ai làm như vậy cả. Nó sẽ khiến chương trình và CPU của bạn bị đơ cứng, không thao tác được

Ở đây chúng ta sẽ sử dụng Timer:

myTimer = new System.Windows.Forms.Timer();myTimer.Tick += new EventHandler(TimerEventProcessor);....private void TimerEventProcessor(Object myObject, EventArgs myEventArgs){ //process every X miliseconds}Để cấu hình thời gian (tức là timer sẽ được gọi mỗi X miliseconds) và bắt đầu timer, bạn có thể tham khảo:

myTimer.Interval = 45;myTimer.Start();

Được rồi, như vậy hãy thử tích hợp với step1, để tools của bạn có thể cập nhật đc ảnh màn hình liên tục sau mỗi 1 chu kỳ thời gian nào đó (trong ví dụ của mình là 45 ms)

Step 3: Phát hiện vùng hình tròn có màu khác biệt

Đây là bài toán khó khăn nhất trong việc hoàn thiện phần mềm này. Cụ thể, với tất cả các bước khác, mình cần 30". Riêng với bước này, bản thân mình cần tới 6 tiếng (mình phải code và chạy thử 3 thuật toán khác nhau mới tìm ra đc thuật toán tốt nhất)

Bài toán viết lại dưới dạng như sau:

Cho một ảnh vuông (ma trận điểm ảnh) kích thước n*n pixels (n cố định)Trong ảnh có m*m hình tròn được xếp sát vs nhau (m thay đổi qua từng màn chơi)Trong m*m hình tròn, có 1 hình tròn có màu khác vs các hình tròn còn lạiNhiệm vụ của bạn là tìm ra hình tròn có màu khác biệt và tâm của hình tròn đó (để click vào tâm)

Yêu cầu phụ:

Hàm cần xử lý nhanh, dưới 70ms là ổn, nếu trên 1s thì quá không ổnBạn cần chú ý nhiễu, bạn tưởng tượng các pixel có màu giống hệt nhau, nhưng thực tế không phải vậy. Ví dụ một hình tròn có màu chủ đạo là (r,g,b), nhưng xung quanh nó có rất nhiều pixel (r+r", g+g", b+b") để pha loãng

Để làm bài toán này, bạn có thể làm theo các bước sau:

Xác định m bằng bao nhiêu (ở đây mình hard code theo level, ví dụ level1 thì m=2, lv4 thì m=3), nhưng bạn cũng có thể tự nghĩ ra thuật toán quét ảnh để tìm đc mBạn chia ảnh nhỏ thành m*m ảnh con, mỗi ảnh con bạn tính màu trung bình của ảnh con đó (bỏ màu nền đi nhé)duyệt m*m vùng trên, tìm ra vùng có màu trung bình khác biệt vs m*m-1 vùng còn lại

Ý tưởng thực hiện được minh hoạ bằng ảnh dưới đây:

*

Phần này, để phân tích màu, mình gợi ý các bạn duyệt cả ảnh. Sau đó đếm số lượng từng loại pixel rồi dùng 1 vài thuật toán cơ bản để tìm ra vùng có màu khác biệt thôi

Để duyệt ảnh, bạn sử dụng chính tấm ảnh Bitmap đã lấy ra ở phần 4 và tham khảo đoạn mã sau:

public void imageProcessing(Bitmap p){ for (int i = 0; i Step 4: Điều khiển chuột

Giả sử bạn đã phát hiện được vùng hình tròn có màu khác biệt, giờ bạn cần điều khiển chuột tới đó và click. Đúng không?

C# có lẽ là một ngôn ngữ giúp bạn dễ dàng thực hiện điều này.

Xem thêm: Download Video Mở Đầu Clip Hd & 4K Giới Thiệu Miễn Phí, Tải Intro Mở Đầu

Bạn lên google thử search cụm từ "mouse click mouse move c#" và sẽ tìm đc 1 vài hướng dẫn (mình cũng làm như vậy)

Mình không hướng dẫn chi tiết đoạn này, do có nhiều hướng dẫn trên mạng. Đại khái sẽ có mấy đoạn code như thế này (chèn vào đâu thì bạn tự tìm hiểu nhá)

public static extern int SetCursorPos(int x, int y);private const int MOUSEEVENTF_MOVE = 0x0001; /* mouse move */private const int MOUSEEVENTF_LEFTDOWN = 0x0002; /* left button down */private const int MOUSEEVENTF_LEFTUP = 0x0004; /* left button up */private const int MOUSEEVENTF_RIGHTDOWN = 0x0008; /* right button down */DllImport("user32.dll",CharSet = CharSet.Auto, CallingConvention=CallingConvention.StdCall)>public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);......SetCursorPos(dx, dy);//Thread.Sleep(100);mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);Chú ý: Nếu bạn không có các hàm xử lý chuẩn, hoặc không có các đoạn mã để ngắt được điều khiển chuột, thì tool của bạn có thể rơi vào trạng thái chiếm chuột và click liên tục

Để hạn chế điều này bạn có thể thêm các xử lý như sau:

Chỉ click 1 số hữu hạn lần (ví dụ 10 lần, 20 lần rồi thôi)Dùng sự kiện để stop việc điều khiển chuột (ví dụ như bấm nút stop, hoặc dùng phím tắt, ...)

Step 5: làm mịn

Chương trình sơ bộ đã hoàn thành, nhưng chúng ta cần làm mịn để chương trình có kết quả tốt hơn

Thêm nút start/stop để bắt đầu chơi game hoặc dừng chơi gameThêm các cấu hình để tùy chỉnh auto (thời gian chờ của timer, độ rộng của vùng ảnh, ...)Tăng tốc độ xử lý ảnh lên tối đa (nó sẽ giúp bạn đạt điểm số cao hơn)

Tổng kết

Như vậy là mình đã hướng dẫn các bạn gần như đầy đủ các kĩ thuật để giúp bạn có thể làm được auto của game này. Bạn hoàn toàn có thể áp dụng kiến thức đã học vào các game tương tự ví dụ như lấy ảnh màn hình, phân tích rồi click,...

Riêng mình, đây là thành quả của 7 tiếng đồng hồ (mình mất rất nhiều time vào phần phân tích ảnh)

*

Chúc các bạn thành công. Nhớ chia sẻ bài viết và vote 5 sao cho mình để có động lực viết các bài tiếp theo nha các bạn!