Báo cáo đồ án trí tuệ nhân tạo: Mô tả không gian trạng thái trò chơi cờ tướng theo giải thuật minimax

14 1.1K 9
Báo cáo đồ án trí tuệ nhân tạo: Mô tả không gian trạng thái trò chơi cờ tướng theo giải thuật minimax

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

LỜI MỞ ĐẦU C ờ tướng là một trò chơi giải trí mang tính tư duy logic cao. Ván cờ được tiến hành giữa hai đấu thủ, một người cầm quân đỏ, một người cầm quân đen. Mục đích của mỗi đấu thủ là tìm mọi cách đi quân trên bàn cờ đúng luật để chiếu tướng của đối phương và giành thắng lợi. Bàn cờ là một hình chữ nhật do 9 đường dọc và 10 đường ngang cắt vuông góc tại 90 điểm hợp thành. Một khoảng trống gọi là sông nằm giữa bàn cờ, chia bàn cờ thành hai phần đối xứng bằng nhau. Mỗi ván cờ mở đầu phải có đủ 32 quân, gồm 7 loại chia đều cho mỗi bên gồm 16 quân đỏ và 16 quân đen. Ở đây em thực hiện mô tả không gian trạng thái trò chơi cờ tướng theo giải thuật minimax.Mặc dù em đã cố gắng mô tả các luật đi của các quân cờ, xong vẫn không thể tránh khỏi các thiếu sót. Rất mong sự giúp đỡ tận tình của Thầy để chương trình của em có thể được hoàn thiện. Em xin chân thành cảm ơn Thầy!

HỌC VIỆN KỸ THUẬT QUÂN SỰ KHOA CÔNG NGHỆ THÔNG TIN BÁO CÁO MÔN HỌC TRÍ TUỆ NHÂN TẠO Giáo viên hướng dẫn: Ngô Hữu Phúc HÀ NỘI 3/2010 LỜI MỞ ĐẦU ờ tướng là một trò chơi giải trí mang tính tư duy logic cao. Ván cờ được tiến hành giữa hai đấu thủ, một người cầm quân đỏ, một người cầm quân đen. Mục đích của mỗi đấu thủ là tìm mọi cách đi quân trên bàn cờ đúng luật để chiếu tướng của đối phương và giành thắng lợi. C Bàn cờ là một hình chữ nhật do 9 đường dọc và 10 đường ngang cắt vuông góc tại 90 điểm hợp thành. Một khoảng trống gọi là sông nằm giữa bàn cờ, chia bàn cờ thành hai phần đối xứng bằng nhau. Mỗi ván cờ mở đầu phải đủ 32 quân, gồm 7 loại chia đều cho mỗi bên gồm 16 quân đỏ và 16 quân đen. Ở đây em thực hiện tả không gian trạng thái trò chơi cờ tướng theo giải thuật minimax.Mặc dù em đã cố gắng tả các luật đi của các quân cờ, xong vẫn không thể tránh khỏi các thiếu sót. Rất mong sự giúp đỡ tận tình của Thầy để chương trình của em thể được hoàn thiện. Em xin chân thành cảm ơn Thầy! Chương trình: I) Giao diện: II). Các hàm sử dụng trong chương trình: Mỗi 1 quân cờ ta đều phải lưu tọa độ, tên và màu sắc của quân cờ. Ở đây em sử dụng mảng Bàn Cờ để lưu mỗi quân cờ với những thuộc tính đó. Các quân cờ thể đi đến bất kì điểm nào trên bàn cờ. Muốn di chuyển được quân cờ ta phải xác định được tọa độ của quân cờ và tọa độ của các vị trí trên bàn cờ. Vì vậy ta phải 1 hàm để xác định tọa độ của quân cờ và lưu các tọa độ đó vào mảng Bàn Cờ như sau: public void XacDinhToaDoDiem() { int i, j; ToaDoDiem td; for (i = 0; i < 10; i++) { for (j = 0; j < 9; j++) { td = new ToaDoDiem(40 + j * D, 40 + i * D1); ArrayToaDoDiem.Add(td); } } } Ở đây em quy định D là độ rộng của ô theo chiều ngang, D1 là độ rộng các ô theo chiều dọc. td là 1 đối tượng thuộc class ToaDoiDiem. Duyệt từng tọa độ của các điểm trên bàn cờ và add nó vào mảng ToaDoDiem. Vậy là tọa độ của các điểm đã được lưu. Tiếp theo, để kiểm tra việc quân cờ click vào đúng 1 điểm nào đó xác định trên bàn cờ hay không em xây dựng hàm kiểm tra như sau: public ToaDoDiem KiemTra(int x, int y) { ToaDoDiem tdChon = null; int dX, dY; double khoangcach; foreach (ToaDoDiem td in ArrayToaDoDiem) { dX = Math.Abs(x - td.x); dY = Math.Abs(y - td.y); khoangcach = Math.Sqrt(Math.Pow(dX, 2) + Math.Pow(dY, 2)); if (khoangcach <= 30) { tdChon = td; break; } } return tdChon; } Quân cờ được quy định ban đầu bán kính bằng 30 cm. Vì vậy khi kích vào bất kì điểm nào trên bàn cờ, hàm KiemTra sẽ tính toán khoảng cách giữa tọa độ của chuột khi đó và tọa độ của điểm gần đó nhất. Nếu khoảng cách giữa điểm đó với tọa độ của chuột nhỏ hơn hoặc bằng bán kính của quân cờ thì di chuyển quân cờ ra vị trí đó. Khi ăn quân cờ, bắt buộc ta phải xóa bỏ quân cờ vừa bị ăn, ở đây em xây dựng hàm xóa quân cờ. Nó sẽ xóa bỏ tên, màu sắc và tọa độ của quân cờ đó ra khỏi màn hình. Hàm xóa được viết như sau: public void XoaQuanCo(QuanCo q) { foreach (QuanCo qc in BanCo) { if (qc.x == q.x && qc.y == q.y) { BanCo.Remove(qc); break; } } } Hàm này thực hiện duyệt từng quân cờ trong mảng bàn cờ và xóa quân cờ đó ra khỏi bàn cờ. Việc di chuyển quân cờ đã thực hiện xong, nhưng các quân cờ ở đây thể di chuyển lung tung trên bàn cờ. Nó vẫn chưa tuân theo đúng luật của cờ tướng. Muốn xây dựng các nước đi đúng cho quân cờ tuân thủ luật cờ tướng Việt Nam hiện hành, ta phải viết các hàm dành riêng cho mỗi quân cờ như sau: Ta nhận thấy quân Tốt nước đi đơn giản nhất, nó chỉ di chuyển lên trên (đối với quân đen) và di chuyển xuống dưới (đối với quân đỏ), khi sang sông nó mới được phép đi ngang mà mỗi nước đi chỉ di chuyển được 1 ô. Hàm cho quân Tốt đi như sau: public bool TotDi(QuanCo qTot, ToaDoDiem tdDich) { if (qTot.isRed) //tốt đỏ { if (tdDich.y > qTot.y) //xác định là đi xuống { if ((tdDich.y - qTot.y) == D1) { return true; } else return false; } else if (tdDich.y == qTot.y) //đi ngang { if ((qTot.y >= (5 * D1 + 40)) && (Math.Abs(tdDich.x - qTot.x) == D)) { return true; } else return false; } else return false; } else //tốt đen { if (tdDich.y < qTot.y) { if ((qTot.y - tdDich.y) == D1) { return true; } else return false; } else if (qTot.y == tdDich.y) { //tot den di ngang if ((qTot.y <= (4 * D1 + 40)) && (Math.Abs(tdDich.x - qTot.x) == D)) { return true; } else return false; } else return false; } } Đầu tiên ta xét với quân đỏ. So sánh tọa độ y của đích đến lớn hơn tọa độ y của quân tốt hay không (vì lúc này Tốt vẫn chưa sang sông nên chỉ thể đi dọc, vì vậy ta chỉ cần quan tâm tới tung độ của nó). Nếu tung độ của đích lớn hơn tung độ của quân tốt chứng tỏ là Tốt đi xuống dưới. Tiếp tục ta xét tung độ của điểm đích lớn hơn tung độ của con Tốt đúng bằng D1 hay không? Nếu đúng thì chứng tỏ nó đang đi dọc xuống 1 bước Nếu tọa độ y của đích bằng tọa độ y của quân tốt chứng tỏ lúc này tốt đang đi ngang. Ta xét xem hoành độ của đích lớn hơn hoành độ của quân tốt đúng bằng khoảng cách D hay không. Nếu đúng thì chứng tỏ Tốt đi sang ngang đúng 1 nước. Hàm trả về true, ngược lại hàm trả về false. Đối với Tốt đen cũng tương tự chỉ khác là quân tốt chỉ được phép đi lên trên và khi nào sang sông nó mới được đi sang ngang. Ta nhận thấy quân Xe và quân Pháo nước đi giống nhau. Vì vậy ta viết hàm XePhaoDi chung cho 2 quân này. Hàm này như sau: public bool XePhaoDi(QuanCo qXe, ToaDoDiem tdDich) { if (qXe.x == tdDich.x) //đi dọc { int step = (tdDich.y - qXe.y) / D1; int i; int x, y; if (step == 1 || step == -1) { return true; } else { if (step >= 2) //xe đi xuống { for (i = 1; i < step; i++) { x = qXe.x; y = qXe.y + i * D1; foreach (QuanCo qc in BanCo) { if (qc.x == x && qc.y == y) { return false; } } } return true; } else if (step <= -2) //xe đi lên { for (i = -1; i > step; i ) { x = qXe.x; y = qXe.y + i * D1; foreach (QuanCo qc in BanCo) { if (qc.x == x && qc.y == y) { return false; } } } return true; } return false; } } else if (qXe.y == tdDich.y) //đi ngang { int step = (tdDich.x - qXe.x) / D; int i, x, y; if (step == 1 || step == -1) { return true; } else { if (step >= 2) //di sang phai { for (i = 1; i < step; i++) { x = qXe.x + i * D; y = qXe.y; foreach (QuanCo qc in BanCo) { if (qc.x == x && qc.y == y) return false; } } return true; } else if (step <= -2) //di sang trai { for (i = -1; i > step; i ) { x = qXe.x + i * D; y = qXe.y; foreach (QuanCo qc in BanCo) { if (qc.x == x && qc.y == y) return false; } } return true; } return false; } } return false; } Ta xét quân đi theo chiều dọc, với biết step là số bước dịch chuyển. Nếu số bước dịch chuyển là 1 hoặc -1 (xuống hoặc đi lên) thì hàm trả về true (đi 1 bước luôn đúng). Nếu số bước dịch chuyển lớn hơn 2 hoặc nhỏ hơn -2 thì ta phải xét xem giữa bước dịch chuyển đến điểm đích quân cờ nào không? Nếu thì không thể đi được. Hàm trả về false. Tương tự đối với đi xuống, đi sang trái hoặc đi sang phải. Nếu quân cờ giữa điểm cần di chuyển và điểm đến thì không thể đi được. lúc này trên màn hình sẽ xuất hiện thông báo: Xét tiếp hàm Sĩ đi. Quân này chỉ thể đi xung quanh để bảo vệ tướng nhưng đi theo đường chéo và mỗi lần đi chỉ đi được 1 bước. Vì vậy độ dịch chuyển theo hoành độ phải bằng D và theo tung độ phải bằng D1. Ở đây ta xét đối với từng trường hợp của quân sĩ bên quân đỏ sau đó ta tịnh tiến vùng này sang quân đen bằng cách cộng thêm 1 khoảng cách distance = 7 ô. Hàm này như sau: public bool SiDi(QuanCo qSi, ToaDoDiem tdDich) { int distance = 0; if (!qSi.isRed) { distance = 7 * D1; } if ((qSi.x == 40 + 3 * D) && (qSi.y == 40 + distance)) { if ((tdDich.x == 40 + 4 * D) && (tdDich.y == 40 + D1 + distance)) { return true; } else return false; } if ((qSi.x == 40 + 5 * D) && (qSi.y == 40 + distance)) { if ((tdDich.x == 40 + 4 * D) && (tdDich.y == 40 + D1 + distance)) { return true; } else return false; } if ((qSi.x == 40 + 3 * D) && (qSi.y == 40 + 2 * D1 + distance)) { if ((tdDich.x == 40 + 4 * D) && (tdDich.y == 40 + D1 + distance)) { return true; } else return false; } if ((qSi.x == 40 + 5 * D) && (qSi.y == 40 + 2 * D1 + distance)) { if ((tdDich.x == 40 + 4 * D) && (tdDich.y == 40 + D1 + distance)) { return true; } else return false; } if ((qSi.x == 40 + 4 * D) && (qSi.y == 40 + D1 + distance)) { if ((tdDich.x == 40 + 3 * D) && (tdDich.y == 40 + distance)) { return true; } if ((tdDich.x == 40 + 5 * D) && (tdDich.y == 40 + distance)) { return true; } if ((tdDich.x == 40 + 3 * D) && (tdDich.y == 40 + 2 * D1 + distance)) { return true; } if ((tdDich.x == 40 + 5 * D) && (tdDich.y == 40 + 2 * D1 + distance)) { return true; } return false; } return false; } Hàm tướng đi, ta đã biết quân tướng chỉ đi trong vùng ô vuông gạch chéo cùng với phần mà Sĩ được đi nhưng Tướng khác Sĩ ở chỗ là nó đi theo đường dọc, ngang chứ không đi chéo như Sĩ. Mỗi lần nó dịch chuyển chỉ được 1 bước. public bool TuongDi(QuanCo qTuong, ToaDoDiem tdDich) { int distance = 0; if (!qTuong.isRed) { distance = 7 * D1; } // int dX, dY; dX = Math.Abs(qTuong.x - tdDich.x); dY = Math.Abs(qTuong.y - tdDich.y); if ((dX == D) && (dY == D1)) { return false; } else { if ((dX == D) || (dY == D1)) { if ((tdDich.x >= 40 + 3 * D) && (tdDich.x <= 40 + 5 * D) && (tdDich.y >= 40 + distance) && (tdDich.y <= 40 + 2 * D1 + distance)) { return true; } } } return false; } Cũng tương tự như hàm sĩ, ta xét quân tướng của phe đỏ sau đó ta tịnh tiến tọa độ theo trục y để xét tiếp với quân tướng của phe đen bằng cách cộng vào tọa độ y của chúng 1 khoảng distance = 7*D1. Xét hàm Tượng đi. Để tránh nhầm lẫn biến qTướng và qTượng ta đặt biến viết với hàm Tượng đi là VoiDi. Mỗi nước đi của Tượng đi chéo hai bước tại trận địa bên mình và không được qua sông. Nếu ở giữa đường chéo quân khác đứng thì quân Tượng bị cản, không đi được. Ta đặt dX và dY là hoành độ và tung độ dịch chuyển của quân Tượng nó phải thỏa mãn là dịch chuyển 2 bước (tức dX = 2*D và dY = 2*D1, xGiữa và yGiữa là tọa độ để ta kiểm tra xem giữa đường chéo quân cờ nào đứng không? Nếu thì hàm trả về false. Nếu không thì ta tiếp tục xét tiếp. Hàm tượng đi như sau: public bool VoiDi(QuanCo qVoi, ToaDoDiem tdDich) [...]... thể nói là hàm rắc rối nhất trong các nước đi của các quân Nó đi theo đường chéo hình chữ nhật của hai ô vuông liền nhau Nếu ở giao điểm liền kề bước thẳng dọc ngang một quân khác đứng thì Mã bị cản, không đi được Ở đây em dùng biến xKt và yKt để kiểm tra xem giữa giao điểm liền kề bước di chuyển dọc ngang quân cờ nào ở đó hay không Nếu thì hàm trà về false Xét hàm pháo ăn: public bool PhaoAn(QuanCo... định ăn nếu gặp bất kì quân nào thì số ngòi được cộng thêm 1 Đặt biến step là biến tính số bước dịch chuyển Nếu số bước này bằng 1 hoặc -1 thì hàm trả về false (vì nếu chỉ dịch chuyển 1 bước thì Pháo không thể ăn được) . CÔNG NGHỆ THÔNG TIN BÁO CÁO MÔN HỌC TRÍ TUỆ NHÂN TẠO Giáo viên hướng dẫn: Ngô Hữu Phúc HÀ NỘI 3/2010 LỜI MỞ ĐẦU ờ tướng là một trò chơi giải trí mang tính tư duy logic cao. Ván cờ được tiến hành. return tdChon; } Quân cờ được quy định ban đầu có bán kính bằng 30 cm. Vì vậy khi kích vào bất kì điểm nào trên bàn cờ, hàm KiemTra sẽ tính toán khoảng cách giữa tọa độ của chuột khi đó và tọa. nhất. Nếu khoảng cách giữa điểm đó với tọa độ của chuột nhỏ hơn hoặc bằng bán kính của quân cờ thì di chuyển quân cờ ra vị trí đó. Khi ăn quân cờ, bắt buộc ta phải xóa bỏ quân cờ vừa bị ăn, ở đây

Ngày đăng: 25/03/2014, 22:26

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan