Thuật toán Alpha -Beta
- Khởi tạo giá trị alpha- beta cho đỉnh gốc, đặt giá trị của alpha là - và beta
là +.
- Nếu quá trình tìm kiếm đạt đến trạng thái lá (là trạng thái kết thúc trò chơi hoặc đạt đến độ sâu giới hạn tìm kiếm), áp dụng hàm tính trọng số để gán giá trị định lượng cho nút.
- Nếu như mức đang xét là của người chơi cực tiểu (MIN):
o Áp dụng thủ tục Alpha-beta với giá trị alpha và beta hiện tại cho một con. Ghi nhớ lại kết quả.
Nếu giá trị đó nhỏ hơn thì đặt beta bằng giá trị mới này. Ghi nhớ lại beta (thu hẹp khoảng [alpha, beta] bằng cách giảm giá trị beta).
Nếu giá trị đó lớn hơn beta thì dừng quá trình tìm kiếm từ cây con này (ở đây ta thực hiện việc cắt tỉa và gọi là cắt tỉa beta
- Nếu như mức đang xét là của người chơi cực đại (MAX):
o Áp dụng thủ tục Alpha-beta với giá trị alpha và beta hiện tại cho một con. Ghi nhớ lại kết quả.
o So sánh giá trị ghi nhớ với giá trị alpha:
Nếu giá trị đó lớn hơn thì đặt alpha bằng giá trị mới này. Ghi nhớ lại alpha (thu hẹp khoảng [alpha, beta] bằng cách tăng giá trị alpha).
Nếu giá trị đó nhỏ hơn alpha thì dừng quá trình tìm kiếm từ cây con này (ở đây ta thực hiện việc cắt tỉa và gọi là cắt tỉa
Giả mã thuật toán Minimax alpha-beta:
Procedure Alpha_beta(u, v); begin
α←-∝; β←-∝;
for (mỗI w là đỉnh con của u) do if α <= MinVal(w, α, β) then { α←MinVal(w,α,β); v← w; } end; ---
Function MinVal(u, α, β); {hàm xác đi ̣nh giá tri ̣ cho các đỉnh Đen} begin
if (u là đỉnh kết thúc or u là lá của cây hạn chế)then MinVal(u, α, β) ← eval(u)
Else
for (mỗI đỉnh v là con của u) do {
β ← min{β, MaxVal(v, α, β)} ;
If α >= β then exit; //cắt bỏ các cây con từ các đỉnh v còn la ̣i }
MinVal(u, α, β) ← β; end;
---
Function MaxVal(u, α, β); { hàm xác đi ̣nh giá tri ̣ cho các đỉnh Trắng} begin
if u là đỉnh kết thúc or là lá của cây hạn chế then MaxVal(u, α, β) ← eval(u)
Else
For (mỗI đỉnh v là con của u) do {
α ← max{α, MinVal(v, α, β)} ;
If α >= β then exit;/*cắt bỏ các cây con từ các đỉnh v còn la ̣i */
}
MaxVal(u, α, β) ← α end;
Thuật toán Alpha-beta nói chung giúp chúng ta tiết kiệm nhiều thời gian so với Minimax mà vẫn đảm bảo kết quả tìm kiếm chính xác. Tuy nhiên số lượng các nút được cắt bỏ sẽ không ổn định mà nó phụ thuộc vào thứ tự duyệt các nút.
Trường hợp lý tưởng: các nút lá có trọng số được sắp xếp tăng dần và lớp lá là lớp Max: Lúc này tất cả các cây con nhánh bên phải sẽ được cắt bỏ Trường hợp xấu nhất: các nút lá có trọng số được sắp xếp tăng dần và lớp
lá là lớp Min. Lúc này thuật toán Minimax alpha-beta vẫn phải duyệt qua toàn bộ các nút giống như Minimax.
CHƢƠNG 3: ÁP DỤNG VÀO TRÕ CHƠI 2048 3.1 Phân tích bài toán
3.1.1 Giới thiệu trò chơi 2048
2048 là một trò chơi giải đố do tác giả Gabriele Cirulli, một lập trình viên web trẻ 19 tuổi người Ý, tạo ra vào tháng 3 năm 2014. Mục tiêu của trò chơi là trượt các khối vuông có mang số trên một lưới vuông để kết hợp chúng lại và tạo ra khối vuông có giá trị 2048.
Cách chơi
2048 chơi trên một lưới vuông 4×4. Mỗi lần di chuyển là một lượt, người chơi sử dụng các phím mũi tên và các khối vuông sẽ trượt theo một trong bốn hướng tương ứng (lên, xuống, trái, phải). Mỗi lượt có một khối có giá trị 2 hoặc 4 sẽ xuất hiện ngẫu nhiên ở một ô trống trên lưới. Các khối vuông trượt theo hướng chỉ định cho đến khi chạm đến biên của lưới hoặc chạm vào khối vuông khác. Nếu hai khối vuông có cùng giá trị chạm vào nhau, chúng sẽ kết hợp lại thành một khối vuông có giá trị bằng tổng giá trị hai khối vuông đó (giá trị gấp đôi). Khối vuông kết quả không thể kết hợp với khối vuông khác một lần nữa trong một lượt di chuyển. Để dễ nhận biết thì các khối vuông giá trị khác nhau sẽ có màu sắc khác nhau.
Bảng điểm ở góc trên bên phải cho biết điểm của người chơi. Ban đầu điểm bằng 0. Khi hai khối vuông kết hợp thì người chơi sẽ tăng điểm là giá trị khối vuông mới. Bên cạnh điểm hiện tại là kỉ lục điểm cao nhất người chơi từng đạt được.
Khi người chơi tạo được ô vuông có giá trị 2048 thì thắng cuộc. Lúc này người chơi có thể lựa chọn tiếp tục chơi để đạt các giá trị cao hơn 2048. Khi không còn nước đi hợp lệ (không còn ô trống và các ô kề nhau đều khác giá trị) thì trò chơi kết thúc.
3.1.2 Áp dụng Minimax Alpha-beta vào trò chơi 2048
Trong trò chơi 2048 trên, ta có thể thấy được việc người chơi di chuyển một nước đi và sau nước đi đó máy tính sẽ sinh ra ngẫu nhiên một số 2 hoặc 4 ở một ô trống bất kỳ. Chính vì thế ta có thể đưa bài toán về bài toán đối kháng giữa người và máy tính để áp dụng thuật toán Minimax (ở đây máy tính sinh ngẫu nhiên nên có thể coi là một người chơi không cao tay).
Hình 3.2: Mô hình bài toán tổng quát
Quy trò chơi 2048 vềbài toán đối kháng:
Đối tượng đối kháng: Người chơi + Máy tính Luật đi của các đối tượng:
Người chơi: Người chơi có thể chuyển bảng theo bốn hướng: Dưới => Trên
Trên => Dưới Trái => Phải Phải => Trái
Máy tính: Sinh ngẫu nhiên một số 2 hoặc 4 ở ô trống bất kỳ
Cách tính điểm ở một trạng thái: từ trạng thái gốc khi khởi tạo bảng chơi đến nước di chuyển ở độ sâu n, ta cần tính điểm của trạng thái ở độ sâu n. Điểm này là tổng điểm ăn được trong quá trình biến đổi trạng thái từ mức 0 đến mức n.
Ta có thể sử dụng điểm thô của một trạng thái để gán cho trọng số của các điểm lá trong mô hình tổng quát.
s
Ví dụ về cách tính điểm của một trạng thái:
Quan sát hình vẽ bên dưới ta thấy điểm số được tính qua từng lượt di chuyển của người chơi.
Ô điểm số là ô ghi nhận điểm tích luỹ được từ bước đi đầu tiên đến trạng thái hiện tại. Điểm số tích luỹ qua các bước đi lần lượt là (nước đi: điểm tích luỹ): (1: 0đ); (2: 0đ); (3: 4đ); (4: 8đ); (5: 16đ); (6: 20đ); (7:20đ); (8: 24đ); (9: 28đ) Mũi tên trên các trạng thái chỉ thị người chơi sẽ chọn cách di chuyển theo hướng mũi tên đó để đến được với trạng thái tiếp theo
3.1.3 Cách tính trọng số nút lá
Như đã biết, hàm tính trọng số của nút lá trong cây tìm kiếm của thuật toán Minimax sinh ra là việc vô cùng quan trọng để có thể đánh giá và đưa ra so sánh cho quá trình tìm kiếm.
Quan sát thấy nhiều trường hợp một cách di chuyển nào đó mang lại điểm số cao hơn tuy nhiên sau đó các ô số bị ứ lại và không thể di chuyển bước tiếp theo được, điều đó có thể nhanh chóng đẩy trò chơi vào thế thua cuộc. Thuật toán sẽ cải thiện được khá nhiều trong những trường hợp như vậy khi mà đối với mỗi bước di chuyển ta có tính thêm thành phần: số ô số còn có thể di chuyển ở bước tiếp theo. Ngoài ra còn một số yếu tố quan trọng tác động đến việc nhìn nhận một trạng thái là tốt hay xấu, chi tiết hơn ta xét ở bên dưới:
Công thức:
Score = smoothness * smoothWeight + monotonicity * monoWeight
+ log(emptyCellCount) * emptyWeight + maxLevel * maxWeight;
Trong đó:smoothWeight = 0.1, monoWeight = 1.0, emptyWeight = 2.7, maxWeight = 1.0; Ý nghĩa của các tham số trong công thức:
1. Smoothess: Độ mịn của bảng số tốt sẽ giúp cho mỗi bước di chuyển sẽ dễ dàng hợp nhất các ô số vào nhau. Để tính được độ mịn của bảng thì ta căn cứ vào sự chênh lệch giữa các ô số đứng cạnh nhau trong bảng. Khi mà sự chênh lệch không lớn thì độ mịn tốt, ngược lại nếu độ chênh lệch lớn thì độ mịn kém. Ví dụ trong hình dưới đây là một trạng thái có độ mịn tối ưu
Hình 3.4(a): Trạng thái có độ mịn tối ưu
2. Monotonicity: Tính đơn điệu này đảm bảo rằng trong một bảng, mọi ô số được sắp theo một thứ tự từ nhỏ đến lớn hoặc từ lớn đến nhỏ theo một hướng cố định nào đó. Có thể là từ phải sang trái và từ trên xuống dưới
như hình
Hình 3.4(b): Trạng thái có tính đơn điệu tốt
3. EmptyCell: Một cách trực quan chúng ta cũng thấy rằng khi có nhiều ô trống hơn thì ta sẽ dễ dàng di chuyển trạng thái hiện tại hơn và trò chơi còn có thể tiếp tục được lâu dài. Chỉ số này đặc biệt quan trọng và được đánh giá cao đối với trò chơi 2048
4. MaxLevel: Với mỗi bảng, maxlevel biểu thị ô số lớn nhất mà trạng thái đó có được. Maxlevel khi chạm tới 2048 thì trò chơi kết thúc và người chơi dành chiến thắng.
Các trọng số smoothWeight = 0.1, monoWeight = 1.0, emptyWeight = 2.7, maxWeight = 1.0; được lấy theo thực nghiệm sau những lần chạy chương trình và ghi nhận lại kết quả.
3.2 Cài đặt chƣơng trình
3.2.1 Môi trƣờng phát triển và công nghệ sử dụng
Ứng dụng cài đặt trên hệ điều hành iOS >= 7.0 Sử dụng Xcode 5.1.1
Sử dụng SpriteKit, và new 2-D game engine của Apple cho iOS
3.2.2 Giao diện của chƣơng trình
Màn hình chính có các lựa chọn:
Cài đặt: cho phép cấu hình một số thông số liên quan đến ứng dụng, ví dụ như màu sắc, kích thướng bàn chơi, và cấu hình chơi tự động Chơi lại: bắt đầu chơi một phiên mới
Gợi ý: chức năng này chỉ cho người chơi một hướng di chuyển phù hợp với trạng thái hiện tại
Tự động: khi lựa chọn tự động thì máy sẽ tự thực hiện các bước di chuyển
Màn hình cài đặt
- Cho phép chọn kích thước bàn chơi, có các lựa chọn 3x3 4x4 5x5 - Sắc thái của game: Mặc định, Rực rỡ và tươi tắn
- Cấu hình cho máy chơi tự động
Màn hình cấu hình chơi tự động
- Cho phép chọn độ cao giới hạn của cây tìm kiếm tìm kiếm Minmax - Thời gian giới hạn cho một quá trình tìm kiếm
- Lưu trữ kết quả.
Hình 3.5(a): giao diện cài đặt cho trò chơi
3.2.3 Chi tiết cài đặt
Lớp M2GameManager điều khiển logic của trò chơi, di chuyển và kiểm tra kết thúc (thắng, thua)
Lớp M2Grid là cấu trúc dữ liệu lưu trữ một trạng thái của bảng, sử dụng mảng một chiều
Lớp M2AI là lớp chính, đầu vào là một trạng thái và phải trả về cách di chuyển tốt nhất
Hình 3.5(b): giao diện cấu hình cho việc chơi tự động
Bắt đầu
Khởi tạo trạng thái ban đầu với 2 ô chứa số 2
Tính bước di chuyển tiếp theo (Sử dụng Minimax)
Kiểm tra kết thúc ( đã xuất hiện sô 2048)
Kết thúc
Tạo ra trạng thái mới sử dụng cách đi vừa tìm được
Yes
No
i ni t Wi t hGr i d: (M2Gr i d * ) gr i d;
(M2Vect or * ) best Move;
(voi d) moveToDi r ect i on: (M2Di r ect i on) di r ect i on
(BOOL) i sWi nni ngBoar d
Sơ đồ khối biểu diễn quá trình tìm kiếm tương ứng với những function bên phải
Hình 3.6: Sơ đồ khối của quá trình chơi tự động
3.2.4 Thống kê kết quả
Chương trình được thực hiện trên Simulator của Xcode 5.1.1. Chạy trên máy MACBOOK 2012 sử dụng chip Core i7 2.6GHz thu được kết quả sau:
Rằng buộc đầu vào:
- Với mỗi bước sinh ngẫu nhiên các số 2 hoặc 4 với tỉ lệ, số 2: chiếm 90% số 4 chiếm 10%
Kết quả thu đƣợc:
Hình 3.7: Màn hình hiển thị kết quả trong quá trình chạy thử nghiệm
Độ sâu Mục tiêu Số lần
chạy Tổng thời gian trung bình Thời gian chiến Tỉ lệ thắng
2 2048 50 93.5’ 1.876’ 67%
4096 40 3h43’ 5.575’ 11%
3 2048 30 2h41’ 5.3’ 98%
4096 10 1h37’ 9.7’ 70%
Thời gian trong bảng trên bao gồm cả thời gian cho quá trình đồ hoạ của trò chơi, các hiệu ứng vẽ và di chuyển các trạng thái trong trò chơi từ trạng thái
ban đầu đến trạng thái kết thúc (dành chiến thắng hoặc thất bại). Chính vì thế đó không chỉ là thời gian tính toán của giải thuật Minimax alpha-beta mà còn gồm cả thời gian của việc đồ hoạ cho trò chơi.
3.2.5 Quan sát quá trình chơi tự động và một số kinh nghiệm thu đƣợc
Trong quá trình máy tự động chơi, ta quan sát được các quyết định di chuyển tối ưu ở độ sâu định trước. Trong những bước tính toán tối ưu đó các trạng thái của trò chơi 2048 thường biến đổi theo một số quy luật và có những điểm chung nhất định. Từ đó ta có thể đúc kết lại một số kinh nghiệm cho người chơi để khả năng dành chiến thắng của người chơi là cao nhất. Dưới đây là một số kinh nghiệm quan sát được trong quá trình cho máy chơi tự động.
1. Di chuyển theo 3 hƣớng định sẵn.
Hình 3.8(a): Màn hình hiển thị một trạng thái kết quả của việc chọn cách di chuyển và xây dựng nền tảng các con số ở hàng dưới cùng
Người chơi sẽ cố gắng di chuyển bảng số theo ba hướng nhất đi ̣nh ví dụ: trái, phải và xuống. Nếu theo ba hướng này, người chơi sẽ có thể xây dựng được một nền tảng khá tốt ở phía dưới và sau đó ngư ời chơi chỉ sẽ mất một chút thời gian với mô ̣t vài chuyển đô ̣ng đôi cùng mô ̣t chuỗi dây chuyền kết nối sẽ giúp những con số gô ̣p la ̣i với nhau thì mô ̣t số có giá tri ̣ lớn . Hãy ưu tiên di chuyển theo ba
hướng định trước và lặp lại nó như một chiến thuật để liên kết các con số giống nhau la ̣i với nhau.
Khi đã định rõ chiến lược chơi cho việc di chuyển theo ba hướng nhất định thì phải hạn chế tối đa việc di chuyển theo hướng thứ tư. Di chuyển theo hướng thứ tư có thể sẽ làm mất lợi thế và rời rạc hoá những con số đang có giá trị cao mà người chơi đã mất rất nhiều công để tạo ra và những con số ấy đang ở những vị trí thuận lợi có khả năng hợp nhất với nhau.
2. Cố gắng cân bằng giá trị của các con số trong bảng
Hình 3.8(b): Màn hình hiển thị một trạng thái kết quả của việc chọn cách di chuyển để cố gắng cân bằng các con số
Đây là mô ̣t chiến lược tốt khi ngư ời chơi cân bằng được sự tăng trưởng của các con số, khi trong ván chơi không có sự chênh lê ̣ch quá nhiều giữa các con số lớn nhất và nhỏ nhất . Hãy cố gắng để nhận được 2 con số trả về cao nhất ta ̣i mo ̣i thời điểm, theo sau đó là mô ̣t số lượng con số nhỏ hơn xuất hiê ̣n theo că ̣p sẵn sàng kết hợp với nhau trong mo ̣i thời điểm. Nếu người chơi có thể duy trì được tính cân bằng trong trò chơi, người chơi sẽ có rất nhiều cơ hội để dành chiến thắng. Rõ ràng việc cân bằng giá trị các con số là nền tảng giúp việc hợp nhất
được dễ dàng. Nếu trong khi chơi, người chơi không tạo được sự cân bằng mà để giả trị các con số khác biệt và rời rạc thì khả năng thua cuộc là rất lớn
3. Giảm số lần di chuyển không có hợp nhất
Hình 3.8(c): Màn hình hiển thị một trạng thái kết quả của việc chọn cách chơi