Cải tiến của thuật toán này là thuật toán cắt tỉa Alpha-Beta Alpha - Beta Pruning rất hay được sử dụng làm chiến lược cho tìm kiếm nước đi trong không gian tìm kiếm của trò chơi có tính
Trang 1BÁO CÁO BÀI TẬP LỚN
Đề tài:
Chiến lược Minimax – Alpha-Beta Pruning
Game cờ Caro
Nhóm 8
• Lê Phương Nam 20093538
• Hoàng Mạnh Tiến 20092693
• Trịnh Văn Thắng 20202223
• Bùi Xuân Trường 20092906
• Lê Hồng Văn 20093231
• Lê Anh Vi 20093679
Trang 2MỤC LỤC
I Giới thiệu thuật toán minimax và cắt tỉa alpha-bêta 3
1 Thuật toán Minimax 3
a Hàm Minimax 4
b Hàm lượng giá 6
2 Cắt tỉa Alpha-Beta 7
II Xây dựng chương trình chơi cờ caro 10
1 Các vấn đề khi xây dựng chương trình 10
2 Áp dụng thuật toán min–max và cắt tỉa alpha-bêta 11
a Hàm lượng giá eval(): 11
b Xây dụng hàm minimax và cắt tỉa alpha-beta 14
3 Các chiến lược phụ trợ 19
a Khoanh vùng xét duyệt tính toán 20
b Thủ tục nhận định trạng thái 23
III Hoạt động của game cờ CARO 25
1 Các tùy chọn 25
2 Tính năng save game và load game 27
a Lưu game đang chơi: 27
b Tải Game đã lưu trước đó: 27
IV Kết luận 29
Trang 3I Giới thiệu thuật toán minimax và cắt tỉa alpha-bêta
1 Thuật toán Minimax
Thuật toán Minmax hay còn gọi là Minimax là một thuật toán dùng trong tìm kiếm
có đối thủ Cải tiến của thuật toán này là thuật toán cắt tỉa Alpha-Beta (Alpha - Beta Pruning) rất hay được sử dụng làm chiến lược cho tìm kiếm nước đi trong không gian tìm kiếm của trò chơi có tính chất đối kháng (vd cờ Tướng, cờ Vua, cờ caro ) Nói một cách dễ hiểu, thì ý nghĩa của thuật toán này bạn có thể hiểu một cách đơn giản như sau: Giả sử bạn đang đánh cờ với máy, thì cả bàn cờ sẽ được biểu diễn trong một cái gọi là không gian trạng thái (KGTT) - bạn có thể hình dungKGTT chính là cách mà máy tính biểu diễn bàn cờ thực lên bộ nhớ máy tính Với mỗi nước đi (mỗi thay đổi) sẽ làm cho KGTT của bàn cờ thay đổi thành một
KGTT mới Như vậy, đến nước đi của máy Chiến lược tìm kiếm nước đi Minimax
sẽ được sử dụng để làm sao tìm ra nước đi tốt nhất cho máy Để có được nước đi tốt thì cần có một sự lượng giá tốt - là kết quả từ một hàm lượng giá (tức là cách đánh giá, như lúc mình tính ở trong đầu í == độ uyên thâm) Độ sâu (depth) là số nước mà máy sẽ tính trước Như vậy giả sử với độ sâu là 4 thì sẽ tìm với tầm nhìn
là 4 nước đi Nút có kết quả lượng giá cao nhất ở mức gốc (mức 0) sẽ được chọn
để đi (trong hình ở mức 0 chỉ có 1nút thôi, nên bạn hình dung là như vậy)
Mức 0, 2, 4 là lượt đi của máy - mức MAX (kết quả lượng giá càng lớn càng tốt) Mức 1, 3 là lượt đi của người - mức MIN (kết quả lượng giá càng nhỏ càng tốt)
Trang 4a Hàm Minimax
Quá trình chơi cờ là quá trình Trắng và Đen thay phiên nhau đưa ra quyết định, thực hiện một trong số các nước đi hợp lệ Trên cây trò chơi, quá trình
đó sẽ tạo ra đường đi từ gốc tới lá Giả sử tới một thời điểm nào đó, đường đi
đã dẫn tới đỉnh u Nếu u là đỉnh Trắng (Đen) thì Trắng (Đen) cần chọn đi tới một trong các đỉnh Đen (Trắng) v là con của u Tại đỉnh Đen (Trắng) v mà Trắng (Đen) vừa chọn, Đen (Trắng) sẽ phải chọn đi tới một trong các đỉnh Trắng (Đen) w là con của v Quá trình trên sẽ dừng lại khi đạt tới một đỉnh là
có giá trị càng lớn càng tốt cho Trắng, đỉnh có giá trị càng nhỏ càng tốt cho Đen Để xác định giá trị các đỉnh của cây trò chơi gốc u, ta đi từ mức thấp nhất lên gốc u Giả sử v là đỉnh trong của cây và giá trị các đỉnh con của nó đã được xác định Khi đó nếu v là đỉnh Trắng thì giá trị của nó được xác định là giá trị lớn nhất trong các giá trị của các đỉnh con Còn nếu v là đỉnh Đen thì giá trị của nó là giá trị nhỏ nhất trong các giá trị của các đỉnh con.
Ví[i] dụ:[/i] Xét cây trò chơi trong hình trên, gốc a là đỉnh Trắng Giá trị của các đỉnh là số ghi cạnh mỗi đỉnh Đỉnh i là Trắng, nên giá trị của nó là max(3,-2) = 3, đỉnh d là đỉnh Đen, nên giá trị của nó là min(2, 3, 4) = 2 Việc gán giá trị cho các đỉnh được thực hiện bởi các hàm đệ qui MaxVal và MinVal Hàm MaxVal xác định giá trị cho các đỉnh Trắng, hàm MinVal xác định giá trị cho các đỉnh Đen
function MaxVal(u);
begin
if u là đỉnh kết thúc then MaxVal(u) ¬ f(u)
else MaxVal(u) ¬ max{MinVal(v) | v là đỉnh con của u}
Trang 5function MinVal(u);
begin
if u là đỉnh kết thúc then MinVal(u) ¬ f(u)
else MinVal(u) ¬ min{MaxVal(v) | v là đỉnh con của u}
end;
Trong các hàm đệ quy trên, f(u) là giá trị của hàm kết cuộc tại đỉnh kết thúc u Sau đây là thủ tục chọn nước đi cho trắng tại đỉnh u Trong thủ tục Minimax(u,v), v là biến lưu lại trạng thái mà Trắng đã chọn đi tới từ u
procedure Minimax(u, v);
begin
val ¬ -¥;
for mỗi w là đỉnh con của u do
if val <= MinVal(w) then
Thuật toán Minimax là thuật toán tìm kiếm theo độ sâu, ở đây ta đã cài đặt thuật toán Minimax bởi các hàm đệ quy Bạn đọc hãy viết thủ tục không đệ quy thực hiện thuật toán này
Về mặt lí thuyết, chiến lược Minimax cho phép ta tìm được nước đi tối ưu cho Trắng Song nó không thực tế, chúng ta sẽ không có đủ thời gian để tính được nước đi tối ưu Bởi vì thuật toán Minimax đòi hỏi ta phải xem xét toàn bộ các đỉnh của cây trò chơi Trong các trò chơi hay, cây trò chơi là cực kỳ lớn Chẳng hạn, đốivới cờ vua, chỉ tính đến độ sâu 40, thì cây trò chơi đã có khoảng 10120 đỉnh! Nếu cây có độ cao m, và tại mỗi đỉnh có b nước đi thì độ phức tạp về thời gian của thuật
Trang 6Để có thể tìm ra nhanh nước đi tốt (không phải là tối ưu) thay cho việc sử dụng hàm kết cuộc và xem xét tất cả các khả năng dẫn tới các trạng thái kết thúc, chúng
ta sẽ sử dụng hàm đánh giá và chỉ xem xét một bộ phận của cây trò chơi
b Hàm lượng giá
Hàm đánh giá eval ứng với mỗi trạng thái u của trò chơi với một giá trị số eval(u), giá trị này là sự đánh giá “độ lợi thế” của trạng thái u Trạng thái u càng thuận lợi cho Trắng thì eval(u) là số dương càng lớn; u càng thuận lợi cho Đen thì eval(u) là
số âm càng nhỏ; eval(u) » 0 đối với trạng thái không lợi thế cho ai cả
Chất lượng của chương trình chơi cờ phụ thuộc rất nhiều vào hàm đánh giá Nếu hàm đánh giá cho ta sự đánh giá không chính xác về các trạng thái, nó có thể hướng dẫn ta đi tới trạng thái được xem là tốt, nhưng thực tế lại rất bất lợi cho ta Thiết kế một hàm đánh giá tốt là một việc khó, đòi hỏi ta phải quan tâm đến nhiều nhân tố: các quân còn lại của hai bên, sự bố trí của các quân đó, ở đây có sự mâuthuẫn giữa độ chính xác của hàm đánh giá và thời gian tính của nó Hàm đánh giá chính xác sẽ đòi hỏi rất nhiều thời gian tính toán, mà người chơi lại bị giới hạn bởi thời gian phải đưa ra nước đi
[i]Ví dụ 1:[/i] Sau đây ta đưa ra một cách xây dựng hàm đánh giá đơn giản cho cờ vua Mỗi loại quân được gán một giá trị số phù hợp với “sức mạnh” của nó Chẳng hạn, mỗi tốt Trắng (Đen) được cho 1 (-1), mã hoặc tượng Trắng (Đen) được cho 3 (-3), xe Trắng (Đen) được cho 5 (-5) và hoàng hậu Trắng (Đen) được cho 9 (-9) Lấy tổng giá trị của tất cả các quân trong một trạng thái, ta sẽ được giá trị đánh giá của trạng thái đó Hàm đánh giá như thế được gọi là hàm tuyến tính có trọng số, vì
nó có thể biểu diễn dưới
Trang 7Thuật giải:
2 Cắt tỉa Alpha-Beta
Minimax yêu cầu phải có sự phân tích qua hai bước đối với không gian tìm kiếm: Bước đầu truyền xuống đến độ sâu của lớp áp dụng heuristic và bước sau để truyềnngược các giá trị trên cây Minimax lần theo tất cả các nhánh trong không gian baogồm cả những nhánh mà một thuật toán thông minh hơn có thể bỏ qua hay tỉa bớt Các nhà nghiên cứu trong lĩnh vực chơi game đã xây dựng một kỹ thuật tìm kiếm gọi là cắt tỉa alpha –beta nhằm nâng cao hiệu quả tìm kiếm trong các bài toán trò chơi hai đối thủ
Trang 8Ý tưởng của tìm kiếm alpha – beta rất đơn giản: Thay vì nếu như tìm kiếm toàn bộ không gian đến một độ sâu lớp cố định, tìm kiếm alpha – beta thực hiện theo kiểu tìm kiếm sâu Có hai giá trị, gọi là alpha và beta được tạo ra trong quá trình tìm kiếm Giá trị alpha liên quan với các nút MAX và có khuynh hướng không bao giờ giảm Ngược lại giá trị beta liên quan đến các nút MIN và có khuynh hướng không bao giờ tăng Giả sử có giá trị alpha của một nút MAX là 6, MAX không cần phải xem xét giá trị truyền ngược nào nhỏ hơn hoặc bằng 6 có liên quan với một nút MIN nào đó bên dưới Alpha là giá trị thấp nhất mà MAX có thể nhận được sau khi cho rằng MIN cũng sẽ nhận giá trị tốt nhất của nó Tương tự nếu MIN có giá trịbeta là 6 nó cũng không cần xem xét các nút nằm dưới nó có giá trị lớn hơn hoặc bằng 6.
Để bắt đầu thuật toán tìm kiếm alpha – beta, ta đi xuống hết độ sâu lớp theo kiểu tìm kiếm sâu, đồng thời áp dụng đánh giá heuristic cho một trạng thái và tất cả các trạng thái anh em của nó Giả thuyết tất cả đều là nút MIN Giá trị tối đa của các nút MIN này sẽ được truyền ngược lên cho nút cha mẹ (là một nút MAX) Sau đó giá trị này được gán cho ông bà của các nút MIN như là một giá trị beta kết thúc tốt nhất Tiếp theo thuật toán này sẽ đi xuống các nút cháu khác và kết thúc việc tìm kiếm đối với nút cha mẹ của chúng nếu gặp bất kỳ một giá trị nào lớn hơn hoặcbằng giá trị beta này Quá trình này gọi là cắt tỉa beta (β cut) Cách làm tương tự cũng được thực hiện cho việc cắt tỉa alpha (α cut) đối với các nút cháu của một nút MAX
Hai luật cắt tỉa dựa trên các giá trị alpha và beta là:
1 Quá trình tìm kiếm có thể kết thúc bên dưới một nút MIN nào có giá trị beta nhỏhơn hoặc bằng giá trị alpha của một nút cha MAX bất kỳ của nó
2 Quá trình tìm kiếm có thể kết thúc bên dưới một nút MAX nào có giá trị alpha lớn hơn hoặc bằng giá trị beta của một nút cha MIN bất kỳ của nó
Việc cắt tỉa alpha – beta như vậy thể hiện quan hệ giữa các nút ở lớp n và các nút ởlớp n+2 và do quan hệ đó toàn bộ các cây con bắt nguồn ở lớp n+1 đều có thể loại khỏi việc xem xét Chú ý rằng giá trị truyền ngược thu được hoàn toàn giống như kết quả Minimax, đồng thời tiết kiệm được các bước tìm kiếm một cách đáng kể
Trang 9Thuật giải :
Trang 10II Xây dựng chương trình chơi cờ caro
1 Các vấn đề khi xây dựng chương trình
Chương trình có hai phần:
Trang 112 Áp dụng thuật toán min–max và cắt tỉa alpha-bêta
Sử dụng hàm minimax như sau:
Xây dựng các hàm chính:
score(): Hàm lượng giá một trạng thái bàn cờ
min(int n): Trả về giá trị score() thấp nhất cho bên Min (bên X) sau n nước cờ.max(int n): Trả về giá trị score() cao nhất cho bên Max (bên O) sau n nước cờ
a Hàm lượng giá eval():
Sau đây là quy ước hàm lượng giá đối với bên Max, bên Min cũng vậy nhưng thêmdấu “-” cho mỗi giá trị đạt được
Trả về 100000 nếu bên Max thắng;
Trả về 10000 đối với:
Trạng thái dãy 4 mở hai đầu (openFour):
Trang 12Hai dãy 4 mở 1 đầu (halfOpenFour):
Trả về 5000 đối với 1 dãy 3 mở hai đầu + 1 dãy 4 mở 1 đầu:
Trả về 3000 đối với Hai dãy 3 mở hai đầu:
Trả về 1000 điểm đối với 1 dãy 3 mở hai đầu + 1 dãy ba mở một đầu:
Trang 13Trả về 500 điểm đối với 1 dãy 4 mở 1 đầu:
200 điểm cho trạng thái có 1 dãy 3 mở hai đầu
100 điểm cho trạng thái có 1 cặp dãy 2 mở hai đầu:
Trang 1450 điểm nếu trạng thái chỉ có 1 dãy 3 mở một đầu:
10 điểm cho trạng thái có 1 cặp dãy 2 mỗi dãy chỉ mở 1 đầu:
5 điểm cho trạng thái có 1 dãy 2 mở hai đầu:
3 điểm cho 1 dãy 2 mở một đầu:
0 điểm Các trạng thái còn lại và trạng thái hòa
b Xây dụng hàm minimax và cắt tỉa alpha-beta
Minimax:
Trang 15Ban đầu chỉ mục tiêu xây dựng hàm min(n) và hàm max(n) chứ chưa chú ý đến cắttỉa anpha-betha:
max(n):
Hàm này tính giá trị cho trạng thái sau khi bên Min vừa đánh xong
Vì bên Max sẽ đánh tiếp theo nên Max nhất định sẽ chọn nước đánh đưa đến trạng
thái có giá trị cao nhất có thể Vậy hàm max(n) được xây dụng như sau:
Xét tất cả các trạng thái tiếp theo, tính giá trị min(n-1) đối với mỗi trạng thái, trả
về giá trị lớn nhất.
min(n):
Hàm này tính giá trị cho trạng thái sau khi bên Max vừa đánh xong
Vì bên Min sẽ đánh tiếp theo nên Min nhất định sẽ chọn nước đánh đưa đến trạng
thái có giá trị thấp nhất có thể Vậy hàm min(n) được xây dụng như sau:
Xét tất cả các trạng thái tiếp theo, tính giá trị max(n-1) đối với mỗi trạng thái, trả
updateArea(); //Cập nhật lại trạng thái
if(n==0){ //Nếu n=0 thì trả về giá trị của hàm lượng giá
return eval();
}
Trang 17Hàm đưa ra quyết định cho bên Max:
public void maxPlay(int n){
updateArea();
int i,j,im,jm,k,top,max,temp;
top = openArea.top;
if(top==-1) {
b[11][11] = 2;
u[11][11].setNO();
updateArea();
return;
}
max = -100000;
im = 0;
jm = 0;
for(k=0;k<=openArea.top;k++){
i = openArea.a[0][k];
j = openArea.a[1][k];
b[i][j] = 2; //Thử các nước đi
closeArea.push(i, j);
updateArea();
temp = min(n,max);
b[i][j] = 0;
Trang 18updateArea();
if(temp>max){ //Chọn nước đi có giá trị min(n-1) cao nhất
max = temp;
im = i;
jm = j;
}
}
closeArea.push(im, jm); b[im][jm] = 2; u[im][jm].setNO(); if(im==12-size/2||jm==12-size/2||im==11+size/2||jm==11+size/2){ resize(size+2); }
updateArea(); System.out.println("Max("+n+"): "+max); }
Cắt tỉa alpha-beta
Xét hàm maxPlay(n) :
Trong khi xét các trạng thái tiếp theo, giả sử trạng thái đầu tiên cho giá trị max(n)
= x;
Như vậy trong các trạng thái tiếp theo ta chỉ quan tâm đến các trạng thái cho giá trị
max(n) < x; nếu biết trước một trạng thái nào đó có max(n) >x, ta có thể bỏ qua
trạng thái này
Trang 19Bởi vì nguyên tắc hoạt động trong hàm max(n) là chọn ra giá trị lớn nhất trong các
trạng thái kế tiếp, nên chỉ cần tồn tại 1 trạng thái kế tiếp cho giá trị > x thì ta có thể
bỏ qua không cần tính tiếp hàm này nữa và quy cho kết quả max(n) = x+1, bởi ta
không cần quan tâm kết quả chính xác của hàm này, chỉ cần nó > x ta không chọn phương án đó
Từ đây ta có thể xây dựng hàm minimax kết hợp cắt tỉa alpha-betha hoàn chỉnh như sau:
min( n, prunValue) // Tham số đầu vào là độ sâu n và giá trị cắt prunValue
{
m = 100000; //Khởi tạo m vô cùng lớn
for each: Các trạng thái tiếp theo
if(max(n-1,m)<prunValue) //Nếu giá trị < prunValue thì cắt tỉa
Trang 20a Khoanh vùng xét duyệt tính toán.
Để khoanh vùng xét duyệt, máy lưu vị trí các nước đi sau đó chỉ duyệt các nước đi lân cận các nước đi đã đánh trước đó
Stack lưu vị trí đã đánh: closeArea
Stack lưu miền xét duyệt: openArea
if(closeArea.isEmpty()){ //Nếu vùng chơi rỗng tạo vùng xét
openArea.push(11, 11); // duyệt gồm 1 ô giữa bàn cờ.
Trang 21u[i+1][j+1].area = 1;
Trang 22}
if(i<23){
if(b[i+1][j]==0&&u[i+1][j].area==0){ openArea.push(i+1, j);
u[i-1][j-1].area = 1;
}
}
Trang 23Ví dụ trong trường hợp khi đối thủ là MIN đã tạo được một hàng 4 mở 1 đầu, thì hiển nhiên MAX cần phải chặn, lúc này có thể bỏ qua không cần xét duyệt bằng MIMAX Hoặc trường hợp MIN tạo được một hàng 3 mở hai đầu thì hoặc MAX phải chặn một đầu ngay, hoặc MAX phải tạo được một hàng 4 ngay, lúc này hàm MIMAX chỉ cần xét duyệt trong các trường hợp này xem trường hợp nào cho giá trị cao nhất chứ không cần phải duyệt hết tất cả các trạng thái.
Từ ý tưởng trên chúng ta xây dựng hàm một số hàm đánh giá trạng thái, thu
nhỏ vùng xét duyệt openArea thành vùng xét duyệt thu nhỏ miniArea:
Định nghĩa:
Trạng thái thắng: Là trạng thái hình thành 1 hàng 5 ô liên tiếp.
Trạng thái thắng sau 1 nước: Là trạng thái tồn tại ít nhất 1 dãy 4 mở hai đầu
hoặc 2 dãy 4 mở một đầu Bởi vì thời gian tồn tại của đối thủ tối đa chỉ là 1 nước
chặn, sau đó phía mình sẽ đat đến trạng thái thắng.