Trong mỗi ô cờ có thể xác định được: - Vị trí ô cờ theo hàng, theo cột - Trạng thái ô cờ: Đang trống 0, nước đi của người chơi 1, nước đi của máy 2 - Độ nguy hiểm của ô cờ tùy theo trạ
Trang 1Giảng Viên Hướng Dẫn : Ths Nguyễn Đỗ Công Pháp
Sinh Viên Thực Hiện : Phan Thanh Tùng 18IT2
Đà Nẵng, tháng 1 năm 2021
Trang 2LỜI MỞ ĐẦU
Hiện nay việc ứng dụng Trí tuệ nhân tạo (AI) vào việc phát triển game đã trở nênrất phổ biến, đặc biệt là những game mang tính trí tuệ cao Điển hình là game Caro
là một trò chơi quen thuộc đối với nhiều đối tượng, dễ chơi, giảm căng thẳng,… CờCaro là một trong số những trò chơi rất phổ biến, đặc biệt là trong giới học sinh, sinhviên Đây cũng là một trò chơi mà em cũng rất thích, chính vì vậy em chọn đề tàilàm game Caro cho môn Trí tuệ nhân tạo
Trong quá trình hoàn thành đề tài này, em đã tìm hiểu được các thuật toán đãđược học trong môn Trí tuệ nhân tạo như thuật toán tìm kiếm nước đi MiniMax, giảithuật Alpha-Beta cắt tỉa cũng như kỹ năng lập trình ngôn ngữ Java Với sự hướngdẫn tận tình của thầy Nguyễn Đỗ Công Pháp, người đã có những đóng góp ý kiến để
em có thể hoàn thành đồ án này Mặc dù đã tìm hiểu kĩ và phân tích thiết kế nhưngkhó tránh khỏi những thiếu sót không mong muốn Em xin kính mong nhận được sựthông cảm và góp ý của các quý thầy cô
Em xin kính chúc quý thầy cô dồi dào sức khỏe, tiếp tục đào tạo ra những thế hệtrẻ, nguồn nhân lực chất lượng tốt cho đất nước Em xin chân thành cảm ơn!
Trang 3NHẬN XÉT CỦA GVHD
………
………
………
………
………
………
………
………
………
………
………
………
………
………
………
………
Đà Nẵng, tháng 1 , năm 2021
CHỮ KÍ GVHD
THS NGUYỄN ĐỖ CÔNG PHÁP
Trang 4MỤC LỤC
Trang
Chương 1 TỔNG QUAN 1
1.1 Mục tiêu 1
1.2 Phạm vi nghiên cứu 1
1.3 Ngôn ngữ và công cụ lập trình được sử dụng: 1
1.3.1 Ngôn ngữ Java 1
1.3.2 Công cụ lập trình Eclipse IDE 2
1.4 Tổng quan về Trí tuệ nhân tạo (AI) 2
1.4.1 AI là gì? 2
1.4.2 Mục đích của AI 2
1.5 Giới thiệu về Cờ Caro 2
Chương 2 PHÂN TÍCH BÀI TOÁN 4
2.1 Phân tích yêu cầu 4
2.2 Phương pháp giải quyết 4
2.2.1 Giới thiệu về không gian tìm kiếm 4
2.2.2 Thuật toán Minimax 5
2.2.3 Thuật toán Minimax với độ sâu hạn chế 7
2.2.4 Giải thuật cắt tỉa Alpha-Beta 8
Chương 3 XÂY DỰNG CHƯƠNG TRÌNH 12
3.1 Cài đặt chương trình 12
3.2 Demo chương trình 15
3.2.1 Giao diện chương trình 15
3.2.2 Cửa sổ Console 15
3.2.3 Giao diện chiến thắng 16
Chương 4 KẾT LUẬN 18
4.1 Kết quả đạt được 18
4.2 Hướng phát triển 18
TÀI LIỆU THAM KHẢO 19
Trang 5DANH MỤC HÌNH ẢNH
Trang
Hình 2-1 Giới thiệu Cờ Caro 3
Hình 3-1 Ví dụ cây trò chơi Caro 3x3 5
Hình 4-1 Giao diện chương trình 15
Hình 4-2 Console bàn cờ 16
Hình 4-3 Người chiến thắng 16
Hình 4-4 Máy chiến thắng 17
Trang 61.2 Phạm vi nghiên cứu
Ứng dụng thuật toán Minimax và cắt tỉa Alpha trong chương trình game Cờ Caro cho phép người chơi với máy Với phạm vi luật chơi là người đi trước và ai có 5 nước đi liên tiếp theo hàng ngang, dọc hoặc chéo sẽ chiến thắng kể cả chặn 2 đầu
1.3 Ngôn ngữ và công cụ lập trình được sử dụng:
1.3.1 Ngôn ngữ Java
Java là một trong những ngôn ngữ lập trình hướng đối tượng Nó được sử dụng trong pháttriển phần mềm, trang web, game hay ứng dụng trên các thiết bị di động Java được khởi đầubởi James Gosling và bạn đồng nghiệp ở Sun MicroSystem năm 1991 Ban đầu Java được tạo
ra nhằm mục đích viết phần mềm cho các sản phẩm gia dụng, và có tên là Oak Java được pháthành năm 1994, đến năm 2010 được Oracle mua lại từ Sun MicroSystem Java được tạo ra vớitiêu chí “Viết (code) một lần, thực thi khắp nơi” (Write Once, Run Anywhere – WORA).Chương trình phần mềm viết bằng Java có thể chạy trên mọi nền tảng (platform) khác nhauthông qua một môi trường thực thi với điều kiện có môi trường thực thi thích hợp hỗ trợ nềntảng đó
Trang 71.3.2 Công cụ lập trình Eclipse IDE
Eclipse là một môi trường phát triển tích hợp cho Java, được phát triển ban đầu bởi IBM, vàhiện nay bởi tổ chức Eclipse NgoàiJava, Eclipse còn hỗ trợ nhiều ngôn ngữ lập trình khác nhưPHP, C, C++, C#, Python, HTML, XML, JavaScript khi dùng thêm trình bổ sung (plug-in)
1.4 Tổng quan về Trí tuệ nhân tạo (AI)
dễ hiểu thì AI là việc sử dụng, phân tích các dữ liệu đầu vào nhằm đưa ra sự dự đoán rồi
đi đến quyết định cuối cùng
1.4.2 Mục đích của AI
Tạo ra các hệ thống chuyên gia - là các ứng dụng máy tính được phát triển để giải quyết các vấn đề phức tạp trong một lĩnh vực cụ thể, ở mức độ thông minh và chuyên môn củacon người
Thực hiện trí thông minh của con người trong máy móc - Tạo ra các hệ thống có thể hiểu, suy nghĩ, học hỏi và hành xử như con người
1.5 Giới thiệu về Cờ Caro
Cờ caro là một loại cờ cổ xưa của người Trung Quốc, một trong những trò chơi logic lâu đời nhất được biết đến trên thế giới
Cờ caro được chơi trên toàn thế giới, ở mỗi nơi nó lại có tên gọi khác nhau: ở Nhật là Gomoku, ở Nga và các nước Đông Âu gọi là Five in a row, ở Hàn Quốc là Omok, ở Trung Quốc là Wuziqi, Anh là Connect5… và dĩ nhiên ở Việt Nam là Caro
Trang 8Game gồm có 2 người chơi, một người cầm quân X, một người cầm quân O Hai người chơi sẽ lần lượt đánh quân tương ứng của mình trên mặt bàn cờ MxN ô (thường thì M = N)
Luật chơi: Quân X là quân đánh trước Hai người chơi có thể đánh vào bất kỳ ô nào trên
bàn cờ, miễn là ô đó chưa được đánh Trò chời kết thúc khi người chơi có 5 quân thẳng hàng
liên tiếp nhau (ngang, dọc hoặc chéo)
Hình 2-1 Giới thiệu Cờ Caro
Trang 9Chương 2 PHÂN TÍCH BÀI TOÁN
2.1 Phân tích yêu cầu
Mô phỏng bàn cờ
Bàn cờ bao gồm các ô cờ được đặt trong một mảng hai chiều (kích thước 20x20) Trong mỗi ô cờ có thể xác định được:
- Vị trí ô cờ theo hàng, theo cột
- Trạng thái ô cờ: Đang trống (0), nước đi của người chơi (1), nước đi của máy (2)
- Độ nguy hiểm của ô cờ tùy theo trạng thái của ô cờ có thể thay đổi được
Đánh giá giá trị các ô cờ
Giống như trong thực tế người chơi thường đánh giá một số nước cờ là nguy hiểm, bình thường hoặc ít nguy hiểm, máy tính cũng đánh giá như thế nhưng cụ thể hơn bằng các con số
2.2 Phương pháp giải quyết
2.2.1 Giới thiệu về không gian tìm kiếm
Trong trò chơi Caro, cứ sau mỗi nước cờ, mỗi đối thủ sẽ chọn ra từ những ô trống để đi, do
đó, sau 1 mỗi nước đi thì số ô trống còn lại sẽ giảm Như vậy, việc tìm nước đi tiếp theo chotrạng thái có sẵn chỉ là việc tìm kiếm những ô trống còn lại, đồng thời, không gian tìm kiếm sẽthu hẹp theo số nước đi đã tạo
Không gian chọn nước đi từ mỗi trạng thái ban đầu là hữu hạn, nhưng không gian tìm kiếm
1 nước đi dẫn đến chiến thắng là rất lớn Do đó ta không thể vét sạch không gian tìm kiếmnước đi này mà ta phải giới hạn không gian tìm kiếm
Một không gian tìm kiếm có thể hiện theo 1 cây đa phân và đuợc gọi là cây tìm kiếm haycây trò chơi Ví dụ:
Trang 10Hình 3-2 Ví dụ cây trò chơi Caro 3x3
Dựa vào cái cây trò chơi đã định nghĩa ở trên, việc tìm kiếm nước đi là chọn 1 nút trên cây (
ở mức 1) sao cho nước đó là tốt Theo thông thường khi chơi, một nước đi tốt hay không là phụthuộc vào khả năng dành chiến thắng là cao hay thấp sau khi nước đi này đuợc đi Do đó, muốnchọn 1 nước đi tốt thì nếu chỉ dựa vào thế cờ hiện tại là chưa đủ, mà phải biết thông tin của những thế cờ sau khi chọn nước này để đi
2.2.2 Thuật toán Minimax
Quá trình chơi cờ là quá trình mà Trắng và Đen thay phiên nhau đưa ra các nước đihợp lệ cho đến khi dẫn đến trạng thái kết thúc cuộc chơi Quá trình này biểu diễn bởiđường đi từ nút gốc tới nút lá trên cây trò chơi Giả sử tại một đỉnh u nào đó trên đường
đi, nếu u là đỉnh Trắng (Đen) thì cần chọn một nước đi nào đó đến một trong các đỉnh conĐen (Trắng) v của u Tại đỉnh Đen (Trắng) v sẽ chọn đi tiếp đến một đỉnh con Trắng(Đen) w của v Quá trình này tiếp tục cho đến khi đạt đến một đỉnh lá của cây
Chiến lược tìm nước đi của Trắng hay Đen là luôn tìm những nước đi dẫn tới trạngthái tốt nhất cho mình và tồi nhất cho đối thủ Giả sử Trắng cần tìm nước đi tại đỉnh u,nước đi tối ưu cho Trắng là nước đi dẫn tới đỉnh con v sao cho v là tốt nhất trong số cácđỉnh con của u Đến lượt Đen chọn nước đi từ v, Đen cũng chọn nước đi tốt nhất chomình Để chọn nước đi tối ưu cho Trắng tại đỉnh u, cần xác định giá trị các đỉnh của câytrò chơi gốc u Giá trị của các đỉnh lá ứng với giá trị của hàm kết cuộc Đỉnh có giá trị
Trang 11cà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 (các đỉnh lá) lên gốc u Giả sử cầnxác định giá trị của đỉnh v mà các đỉnh con của nó đã xác định Khi đó, nếu v là đỉnhTrắng thì giá trị của nó là giá trị lớn nhất trong các đỉnh con, nếu v là đỉnh Đen thì giá trịcủa nó là giá trị nhỏ nhất trong các đỉnh con.
Sau đây là thủ tục chọn nước đi cho Trắng tại đỉnh u Minimax(u, v), trong đó v là đỉnhcon được chọn của u:
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;
Function MaxVal(u); { hàm xác định giá trị cho các đỉnh Trắng}
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}
end;
Trong các thủ tục và hàm trên, f(u) là giá trị của hàm kết cuộc tại đỉnh kết thúc u
Thuật toán Minimax là thuật toán tìm kiếm theo chiều sâu Về lý thuyết, chiến lượcMinimax cho phép tìm nước đi tối ưu cho Trắng Tuy nhiên trong thực tế, ta không có đủthời gian để tính toán nước đi tối ưu này Bởi vì thuật toán tính toán trên toàn bộ cây tròchơi (xem xét tất cả các đỉnh của cây theo kiểu vét cạn) Trong các trò chơi hay thì kíchthước của cây trò chơi là cực lớn Chẳng hạn, trong cờ vua, chỉ tính đến độ sâu 40 thì câytrò chơi đã có đến 10120 đỉnh Nếu cây có độ cao m và tại mỗi đỉnh có b nước đi thì độ
Trang 12phức tạp về thời gian của thuật toán Minimax là O(bm).
Trong thực tế, các trò chơi đều có giới hạn về thời gian Do đó, để có thể tìm nhanhnước đi tốt (không phải tối ưu) thay vì sử dụng hàm kết cuộc và xét tất cả các đỉnh củacây trò chơi, ta sử dụng hàm đánh giá và chỉ xem xét một bộ phận của cây trò chơi
2.2.3 Thuật toán Minimax với độ sâu hạn chế
Thuật toán
Để hạn chế không gian tìm kiếm, khi xác định nước đi cho Trắng tại u, ta chỉ xem xét cây gốc u tại độ cao h nào đó Áp dụng thủ tục Minimax cho cây trò chơi gốc u, độ cao h và sử dụng hàm đánh giá để xác định giá trị cho các lá của cây
Procedure Minimax(u, v, h);
begin
val ←-∝;
for mỗi w là đỉnh con của u do
if val(u) <= MinVal(w, h-1) then
{val ← MinVal(w, h-1); v ← w}
end;
Function MinVal(u, h); {hàm xác định giá trị cho các đỉnh Đen}
begin
if u là đỉnh kết thúc or h = 0 then MinVal(u, h) ← eval(u)
else MinVal(u, h) ← min{MaxVal(v, h-1) | v là đỉnh con của u}
end;
Function MaxVal(u, h); { hàm xác định giá trị cho các đỉnh Trắng}
begin
if u là đỉnh kết thúc or h =0 then MaxVal(u, h) ← eval(u)
else MaxVal(u, h) ← max{MinVal(v, h-1) | v là đỉnh con của u}
end;
Hàm đánh giá:
Hàm đánh giá eval cho mỗi đỉnh u là đánh giá “mức độ lợi thế” của trạng thái u Giátrị của eval(u) là số dương càng lớn thì trạng thái u càng có lợi cho Trắng, giá trị của
Trang 13eval(u) là số dương càng nhỏ thì trạng thái u càng có lợi cho Đen, eval(u)=0 thì trạng thái
u không có lợi cho đối thủ nào, eval(u)=+∞ thì u là trạng thái thắng cuộc cho Trắng,eval(u)=-∞ thì u là trạng thái thắng cuộc cho Đen
Hàm đánh giá đóng vai trò rất quan trọng trong các trò chơi, nếu hàm đánh giá tốt sẽđịnh hướng chính xác việc lựa chọn các nước đi tốt Việc thiết kế hàm đánh giá phụ thuộcvào nhiều yếu tố: các quân cờ còn lại của hai bên, sự bố trí các quân cờ này,… Để đưa rahàm đánh giá chính xác đòi hỏi nhiều thời gian tính toán, tuy nhiên, trong thực tế ngườichơi bị giới hạn thời gian đưa ra nước đi Vì vậy, việc đưa ra hàm đánh giá phụ thuộc vàokinh nghiệm của người chơi Sau đây là một số ví dụ về cách xây dựng hàm đánh giá:
Ví dụ 1: Hàm đánh giá 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, quân tốt Trắng (Đen) được gán giá trị 1 (-1), mã hoặctượng Trắng (Đen) được gán giá trị 3 (-3), xe Trắng (Đen) được gán giá trị 5 (-5) và hậuTrắng (Đen) được gán giá trị 9 (-9) Hàm đánh giá của một trạng thái được tính bằng cáchlấy tổng giá trị của tất cả các quân cờ trong trạng thái đó Hàm đánh giá này được gọi làhàm tuyến tính có trọng số, vì có thể biểu diễn dưới dạng:
s1w1 + s2w2 + … + snwn
Trong đó, wi là giá trị của quân cờ loại i, si là số quân loại đó
Đây là cách đánh giá đơn giản, vì nó không tính đến sự bố trí của các quân cờ, các mốitương quan giữa chúng
Ví dụ 2: Hàm đánh giá trạng thái trong trò chơi Dodgem Mỗi quân Trắng được gán giá trịtương ứng với các vị trí trên bàn cờ như trong hình bên trái Mỗi quân Đen được gán giá trị ởcác vị trí tương ứng nhu hình bên phải:
-10 -25 -40-5 -20 -35
0 -15 -30
Trang 14● ○
Trắng cản trực tiếp Đen được thêm 40 điểm Trắng cản gián tiếp Đen được thêm 30 điểm
Áp dụng cách tính hàm đánh giá nêu trên, ta tính được giá trị của các trạng thái ở các hình dưới như sau:
● ○
2.2.4 Giải thuật cắt tỉa Alpha-Beta
Trong chiến lược Minimax với độ sâu hạn chế thì số đỉnh của cây trò chơi phải xét vẫn
còn rất lớn với h>=3 Khi đánh giá đỉnh u tới độ sâu h, thuật toán Minimax đòi hỏi phải đánh giá tất cả các đỉnh của cây gốc u với độ sâu h Tuy nhiên, phương pháp cắt cụt alpha-beta cho phép cắt bỏ những nhánh không cần thiết cho việc đánh giá đỉnh u.
Phương pháp này làm giảm bớt số đỉnh phải xét mà không ảnh hưởng đến kết quả đánh
Trang 15min
max
Cắt bỏ cây con gốc a nếu eval(u)>eval(v)
Khi đó ta có giá trị đỉnh Trắng c ít nhất là giá trị của u, giá trị của đỉnh Đen b nhiều nhất là giá trị của v Do đó, nếu eval(u) > eval(v) ta không cần đi xuống để đánh giá đỉnh
a nữa mà vẫn không ảnh hưởng đến đánh giá đỉnh c Hay nói cách khác, ta có thể cắt bỏ
cây con gốc a.
Lập luận tương tự cho trường hợp a là đỉnh Đen, trường hợp này nếu eval(u)<eval(v)
ta cũng cắt bỏ cây con gốc a.
Để cài đặt kỹ thuật này, đối với các đỉnh nằm trên đường đi từ gốc tới đỉnh hiện thời,
ta sử dụng tham số để ghi lại giá trị lớn nhất trong các giá trị của các đỉnh con đã đánhgiá của một đỉnh Trắng, tham số để ghi lại giá trị nhỏ nhất trong các giá trị của các đỉnhcon đã đánh giá của một đỉnh Đen
Trang 17Chương 3 XÂY DỰNG CHƯƠNG TRÌNH
3.1 Cài đặt chương trình
Hàm lấy ma trận từ UI
public int[][] getMatrixBoard() {
int matrix[][] = new int[row][col];
for (int i = 0; i < Buttons.length; i++) {
for (int j = 0; j < Buttons.length; j++) {
int value = Buttons[i][j].value;
matrix[i][j] = value;
} }
return matrix;
}
Hàm chơi giả lập với Move truyền vào
public int[][] playNextMove(int[][] board, int[] move, boolean isUserTurn) {
int i = move[0], j = move[1];
int [][] newBoard = new int[row][col];
for (int h = 0; h < row; h++) {
for (int k = 0; k < col; k++) {
newBoard[h][k] = board[h][k];
} }
newBoard[i][j] = isUserTurn ? 2 : 1;
return newBoard;
}
Lấy tất cả các Move có thể được chơi
public ArrayList<int[]> generateMoves(int[][] boardMatrix) {
ArrayList<int[]> moveList = new ArrayList<int[]>();
return moveList;
}
Trang 18 Hàm đánh giá
public int getScore(int[][] board, boolean forX, boolean blacksTurn) {
return evaluateHorizontal(board, forX, blacksTurn) +
evaluateVertical(board, forX, blacksTurn) + evaluateDiagonal(board, forX, blacksTurn);
}
public double evaluateBoardForWhite(int[][] board, boolean userTurn) {
double blackScore = getScore(board, true, userTurn);
double whiteScore = getScore(board, false, userTurn);
Duyệt không gian trạng thái
public Object[] minimaxSearchAB(int depth, int[][] board, boolean max, double alpha, double beta) {
for(int[] move : allPossibleMoves) {
int[][] dummyBoard = playNextMove(board, move, false);
Object[] tempMove = minimaxSearchAB(depth-1, dummyBoard, !max, alpha, beta);
}