Giới thiệu game Game c vua mờ ột người chơi, đối th là bot ủ chơi cờ vua tự động sau đây gọi là Chess bot, có th tể ự đưa ra các nước đi hợp lý tương đương với một người chơi cờvua có ch
Tổng quan v game 6 ề 1.1 Giới thi u game 6ệ 1.2 Ý tưởng
Pitch
Cờ vua là trò chơi phổ biến toàn cầu với giao diện 2D thân thiện và thao tác kéo thả đơn giản, giúp người chơi dễ dàng tham gia Ứng dụng tích hợp nhiều khai thác phổ biến, cho phép người chơi triển khai chiến thuật nhanh chóng, đồng thời có chức năng đánh giá lợi thế và gợi ý nước đi tiếp theo Đối tượng người chơi từ 3 tuổi trở lên, biết chơi cờ vua và sở hữu thiết bị di động Tiềm năng phát triển lớn với giao diện responsive tương thích mọi thiết bị, có khả năng tích hợp thuật toán như Stockfish để nâng cao hiệu suất xử lý logic game và phát triển thành game online.
Rủi ro và biện pháp giảm thiểu ảnh hưởng: Thuật toán xử lý nước đi của game phải đảm bảo độ sâu tính toán hợp lý Nếu không, Chessbot có thể không đưa ra nước đi như mong muốn Tuy nhiên, việc tăng độ sâu tính toán sẽ làm thời gian xử lý kéo dài, có thể lên đến vài phút, gây ảnh hưởng đến trải nghiệm của người chơi Để cải thiện, chỉ cần điều chỉnh độ sâu nhánh tính toán ở mức 5, Chessbot đã có thể đưa ra nước đi khá tốt Ngoài ra, việc sử dụng các ngôn ngữ lập trình như C, C++ hoặc Golang có thể giúp thực thi lệnh nhanh hơn.
GDD
Bàn cờ vua 8x8 là nơi diễn ra các trận đấu giữa các quân cờ, nơi người chơi di chuyển các quân theo luật cờ vua Để giành chiến thắng, người chơi cần suy nghĩ chiến lược và áp dụng các chiến thuật hợp lý nhằm tạo ra lợi thế trước đối thủ (Chessbot).
Từng bước di chuyển trong trò chơi cờ vua không chỉ giúp bạn tạo lợi thế cho bản thân mà còn có thể gây bất lợi cho đối thủ Mỗi nước đi có lợi sẽ được hệ thống thông báo điểm số hiện tại trên giao diện, giúp người chơi dễ dàng theo dõi tình trạng hiện tại và suy nghĩ cho nước đi tiếp theo.
Tham nhũng là m ộ t hiện tượng xã hội
Công nghệ thông tin None 11
Báo cáo t ổ ng quát - Báo cáo tổng quát
Công nghệ thông tin None 1 đ ề PPL NCKH kỳ 1
Công nghệ thông tin None 4
BTL - Thi ế t k ế môi tr ườ ng giáo d ụ c ch…
Công nghệ thông tin None15
Các thành phần trong game được chia làm 2 ph n chính: Bàn cầ ờ và các thanh cài đặt Bàn c : Bàn c tiêu chu n 8x8 ờ ờ ẩ
Các quân cờ vua (đen và trắng)
TÀI LI Ệ U H Ọ C T Ậ P KHQL NÂNG CAO
Công nghệ thông tin None 151
Công nghệ thông tin None21
Các cài đặt và tùy chọn
Thanh thông báo và tr ng thái ạ
Phương pháp tiếp cận và giải quyết các vấn đề
Mô hình t ng quan h th ng 9 ổ ệ ố 2.2 Phương pháp xây dựng phần mềm
Trong thể loại boardgame, hầu hết các chức năng trong hệ thống sẽ hoạt động dựa trên tương tác trực tiếp của người chơi trên bàn cờ Khi thực hiện nước đi hoặc thay đổi cài đặt, những tương tác này được ghi nhận xuyên suốt quá trình chơi game và sẽ khởi tạo một trải nghiệm thú vị cho người tham gia.
Sự kiện này sẽ kích hoạt các bộ xử lý sự kiện tương ứng, cho phép chúng thực hiện chức năng đã được cài đặt sẵn với các tham số mà sự kiện truyền đến.
2.2 Phương pháp xây dựng phần m m ề
Game được xây d ng ch yự ủ ếu theo phương pháp hướng chức năng do l i ích c a ợ ủ phương pháp này rất phù hợp với quá trình phát triển game, cụ thể:
• M i chỗ ức năng là một hàm riêng bi t, d dàng s a l i hay thêm, xóa, nâng c p ệ ễ ử ỗ ấ các tính năng trong game
Trong quá trình chờ đợi Chessbot đưa ra nước đi, người chơi có thể thực hiện nhiều thao tác như thay đổi độ khó của Chessbot, undo hoặc redo nước đi, và bắt đầu lại game Do đó, việc xử lý song song và đồng thời là rất cần thiết, nhằm xây dựng game với chức năng đảm bảo các thao tác của người chơi được thực hiện độc lập.
Tăng hiệu suất viết mã nguồn cho các nhà phát triển bằng cách cho phép họ làm việc độc lập, chỉ cần xác định rõ dữ liệu đầu vào và đầu ra cụ thể.
Hàm tái sử dụng và sử dụng các chỗ ẩn chứa thông tin liên quan đến nước đi trong cờ vua, cho phép Chessbot đưa ra nước đi tốt nhất hoặc hỗ trợ người chơi khi chọn chức năng gợi ý nước đi.
• Các đối tượng trong game không quá nhiều, chỉ bao gồm bàn cờ, các quân cờ, thanh tr ng thái, thông ạ báo, các thanh cài đặt
Mỗi đối tượng trong game đều có các thuộc tính và phương thức riêng, như giá trị và quy tắc di chuyển khác nhau Do đó, việc xây dựng hướng đối tượng là cần thiết, giúp xác định rõ các đối tượng cùng thuộc tính và phương thức của chúng Điều này không chỉ làm cho việc điều khiển các đối tượng trở nên dễ dàng hơn mà còn giúp mã nguồn trở nên rõ ràng và dễ hiểu hơn.
Trong mô hình hệ thống, trò chơi chủ yếu dựa vào các thao tác của người chơi tại giao diện Mỗi thao tác sẽ được xử lý và trả về kết quả, như nước đi của Chessbot, thao tác undo, redo, và lựa chọn độ sâu tính toán Các thao tác này diễn ra liên tục trong suốt ván đấu theo thời gian thực Tuy nhiên, thuật toán tính toán nước đi tiếp theo mất thời gian do khối lượng không gian trạng thái lớn Do đó, kiến trúc phần mềm hướng sự kiện (Event-Driven Architecture - EDA) là lựa chọn tối ưu cho việc phát triển trò chơi Các thao tác của người chơi được xem là sự kiện (event producer) và được gửi đến nhiều hàm xử lý sự kiện (event consumer) qua kênh sự kiện (event broker) Các event consumers sau đó sẽ kích hoạt event handler để xử lý các sự kiện này.
Các event handler cho các sự kiện không xác định được thiết lập nhằm tăng cường khả năng xử lý thao tác bất đồng bộ từ người chơi Điều này không làm giảm tính chính xác của game, mà ngược lại, cho phép người chơi thực hiện các hành động như thay đổi nước đi trong khi đang chờ phản hồi từ Chessbot.
2.1.1 Môi trường khởi ch y và phát tri n ạ ể
Chess bot được phát triển để hoạt động trên nền tảng web, sử dụng các ngôn ngữ lập trình như HTML, CSS và JavaScript Mã nguồn của Chess bot sẽ được lập trình trong môi trường phát triển tích hợp (IDE) VsCode, nhờ vào khả năng hỗ trợ lập trình web tốt cùng với các tiện ích mở rộng như live server, tag wrapper và tabnine.
2.1.2 Các ngôn ng s dữ ử ụng
HTML (viết tắt của HyperText Markup Language) là ngôn ngữ đánh dấu được thiết kế để tạo ra các trang web trên World Wide Web Các trình duyệt web nhận tài liệu HTML từ một web server hoặc từ một kho lưu trữ và hiển thị tài liệu đó thành các trang web đa phương tiện HTML mô tả cấu trúc của một trang web và cung cấp các dấu hiệu ban đầu cho sự xuất hiện của tài liệu.
CSS (Cascading Style Sheets) được sử dụng để mô tả cách trình bày các tài liệu viết bằng HTML và XHTML CSS giúp làm rõ mã nguồn của trang web bằng cách quy định kiểu dáng như chữ đậm, chữ nghiêng, chữ gạch chân và màu sắc, từ đó làm cho mã nguồn trở nên gọn gàng hơn Điều này tách biệt nội dung của trang web và định dạng hiển thị, dễ dàng cho việc cập nhật nội dung HTML và CSS sẽ được sử dụng để viết mã hiển thị giao diện người dùng chính cho các thành phần trong game như bàn cờ vua, các thanh cài đặt và thanh trạng thái.
JavaScript (JS) là một ngôn ngữ lập trình thông dụng được phát triển từ ý tưởng lập trình dựa trên nguyên mẫu Trong trình duyệt, JavaScript được sử dụng để thiết kế trang web động và tạo ra các hiệu ứng hình ảnh thông qua DOM Nó chủ yếu xử lý logic của trang web, thực hiện các tác vụ không thể chỉ bằng HTML như kiểm tra thông tin nhập vào và tự động thay đổi hình ảnh Trong đề tài này, JavaScript sẽ được sử dụng để xử lý giao diện người dùng, điều chỉnh chức năng các thanh cài đặt, các nước di chuyển và cập nhật trạng thái thông qua thư viện Chess.js và Chessboard.js Hơn nữa, JavaScript sẽ giúp xây dựng các giải thuật cho Chess bot Để thuận tiện hơn trong việc lập trình giao diện và xử lý logic cần thiết, chúng ta sẽ sử dụng các thư viện hỗ trợ mã nguồn, giúp theo dõi quá trình phát triển mã nguồn, debug và bảo trì dễ dàng, đồng thời rút ngắn độ dài đoạn mã và tối ưu hóa các tác vụ.
Bootstrap là một thư viện HTML, CSS và JavaScript giúp đơn giản hóa việc thiết kế màu sắc, kích thước, phông chữ và bố cục cho các dự án Khi được tích hợp vào một dự án, Bootstrap cung cấp các định nghĩa kiểu cơ bản cho tất cả các phần tử HTML Kết quả là, nó mang đến sự xuất hiện đồng nhất cho các đoạn văn xuôi, biểu mẫu và các yếu tố biểu diễn trên các trình duyệt web.
Trong bài viết này, chúng tôi sẽ sử dụng Bootstrap để định dạng các phần tử HTML theo các định nghĩa có sẵn, giúp giảm thiểu thời gian lập trình giao diện Điều này không chỉ đảm bảo giao diện trang web thân thiện và dễ thao tác mà còn tiết kiệm thời gian, cho phép chúng tôi tập trung vào thiết kế và phát triển thuật toán cho Chess bot.
2.1.3.b jQuery jQuery là một JavaScript Framework được thi t kế ế để đơn giản hóa thao tác và duyệt cây HTML DOM, cũng như xử lý sự kiện, hoạt ảnh CSS và Ajax Cú pháp của jQuery được thiết kế để giúp điều hướng tài liệu HTML d dàng hơn, chọn các thành ễ phần DOM, tạo ho t ạ ảnh, xử lý sự ki n và phát tri n các ng d ng Ajax ệ ể ứ ụ jQuery cũng cung cấp một mô hình để xử lý sự kiện vượt ra ngoài việc lựa chọn và thao tác ph n t ầ ử DOM cơ bản Vi c gán s kiệ ự ện và định nghĩa hàm gọi lại s kiự ện được thực hiện trong một bước duy nh t m t vấ ở ộ ị trí duy nh t trong mã ngu n ấ ồ
Phân tích thiết kế Game
SAN và FEN
Ký hiệu ĐẠI ối s ng n (Short Algebraic Notation - SAN) là phương pháp ghi chép ngắn gọn các nước đi trong cờ vua bằng ký hiệu và chữ cái tắt SAN rất phổ biến trong cờ vua để ghi lại các trận đấu, trong đó mỗi nước đi được thể hiện bằng cách sử dụng ký tự ngắn gọn để diễn tả quân cờ và ô cờ di chuyển đến Các ký tự trong SAN được dùng để mô tả các quân cờ như sau:
Các ký tự trên bàn cờ được sử dụng để mô tả các nước đi, với các cột được đánh dấu từ a đến h (từ trái sang phải) và các hàng từ 1 đến 8 (từ dưới lên trên) Cách ghi tên nước đi đầy đủ là: [Tên quân cờ][Ô xuất phát]-[Ô đích] Ví dụ, quân Trắng đi Hậu từ ô d1 đến ô d5 được ghi là: Hd1-d5.
Nước ăn quân trong cờ vua thường được ký hiệu bằng dấu "×", ví dụ như Hd4×a4 Đối với nước tốt, chỉ cần ghi ký hiệu hai cột trước và sau khi ăn mà không có dấu nhân, như ch ng hẳ ạn gf, bc Tên quân xuất hiện sau khi phong cấp được ghi sau nước đi, có thể sử dụng dấu "/" hoặc "=" để chỉ rõ tên quân phong cấp, ví dụ f8H hoặc f8/H.
Nước nhập thành gần được ký hiệu là 0-0, còn nh p thành xa là 0-0-0 ậ
Nước chiếu vua có ký hi u là d u cệ ấ ộng (+), nước chiếu đôi có kí hiệu là hai dấu c ng ộ (++) và chi u h t có ký hi u là dế ế ệ ấu thăng (#).
Ký hiệu Forsyth Edwards (FEN) là một ký hiệu tiêu chuẩn để mô tả vị trí bàn cờ cụ thể trong ván cờ vua Mục đích của FEN là cung cấp tất cả thông tin cần thiết để bắt đầu lại trò chơi từ một vị trí cụ thể.
Một chu i FEN bao gỗ ồm 6 phần, được ngăn cách nhau bằng 1 d u cách: ấ
1 V trí c a các quân c t bên trị ủ ờ ừ ắng (phía dưới bàn cờ) đến bên đen (phía trên bàn cờ) được bi u di n b i m t chu i ký t Các ký tể ễ ở ộ ỗ ự ự đại di n cho các quân c ệ ờ được trình bày phở ần “Danh mục các ký hiệu và ch vi t tữ ế ắt” Các ký tự được sắp x p theo th t tế ứ ự ừ a đến h, sau đó từ hàng 1 đến hàng 8 Mỗi hàng được ngăn cách bởi dấu / Nếu trên một ô không có quân cờ, sử dụng một số lượng dấu cách tương ứng
Với chu i ỗ FEN rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR, đây là vị trí bắt đầu của các quân cờ trên bàn cờ cờ vua
2 Ký tựw hoặc b đại diện cho lượt đi của người chơi tiếp theo w đại di n cho bên ệ trắng và b đại diện cho bên đen.
3 Các ký tự K, Q, k và q đại diện cho khả năng castling của các bên:
K cho biết bên trắng có thể castling với xe bên phải (khi chưa di chuyển)
Bên trắng có khả năng thực hiện nước đi castling với xe bên trái nếu xe chưa di chuyển Đối với bên đen, có thể thực hiện castling với xe bên phải khi xe chưa di chuyển, và cũng có khả năng castling với xe bên trái trong cùng điều kiện.
Nếu một bên không thể castling, ký tự tương ứng sẽ được thay bằng dấu -
4 Kí t ự đại diện cho v trí En passant (có th b ị ể ỏ qua được) là m t trong các quy t c ộ ắ đặc biệt c a cờ vua Khi một quân tốt củ ủa bên đối phương di chuyển hai ô từ hàng ban đầu của nó và đi qua ô của người chơi, người chơi đối phương có thể bắt quân tốt đó như là một nước ăn En passant Ký tự - đại diện cho trường hợp không có En passant
5 S hi p s cố ệ ố ủa trò chơi, là số nước đi đã thực hi n k t l n cu i cùng m t quân ệ ể ừ ầ ố ộ tốt di chuy n ho c m t quân c bể ặ ộ ờ ị ăn Nó được tính bằng cách đếm số nước đi sau khi xảy ra hành động đó Nếu không có hành động này x y ra trong mả ột nước đi, thì hiệp số được giữ nguyên từ nước đi trước đó Hiệp số được sử dụng để xác định nếu một trận đấu có thể được xác định là hòa bởi luật 50 nước Nếu không có quân tốt được di chuy n ho c quân c bể ặ ờ ị ăn trong vòng 50 nước (100 bước đi của cả hai bên), thì trận đấu sẽ được xác định là hòa bởi luật 50 nước
Số liệu này được cập nhật sau mỗi nước đi của bên đen Mỗi hiệp sẽ bao gồm một nước đi của bên trắng và một nước đi của bên đen.
6 Số lượng nước đi của m i bên, ỗ được lưu trữ ằ b ng m t s nguyên N u giá tr ộ ố ế ị này là 0, nó có nghĩa là chưa có nước đi nào được thực hiện Nếu giá trị này được c p nhậ ật, nó s tăng thêm một đơn vịẽ sau mỗi lượt đi của bên đen.
Như vậy, “rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1” chính là chu i FEN bỗ ắt đầu m t trộ ận đấu trong c vua ờ
Ký hiệu SAN và FEN rất quan trọng trong cờ vua, giúp xác định vị trí của các quân cờ trên bàn cờ và tình trạng của ván đấu Chúng là các tham số đầu vào và kết quả đầu ra trong các phương thức của Chess.js và Chessboard.js Hơn nữa, chuỗi FEN cho phép Chessbot nắm bắt trạng thái hiện tại trên bàn cờ để đưa ra nước đi hợp lý.
Sơ đồ lớp
Game được xây dựng dựa trên các hàm chức năng chính, vì vậy các đối tượng trong game được sắp xếp tổng quát Ví dụ, bàn cờ là một đối tượng với các phương thức tương tác với giao diện, trong khi "điều khiển bàn cờ" lại là một đối tượng khác, bao gồm các phương thức để điều khiển các quân cờ theo luật và kiểm tra trạng thái ván cờ hiện tại Việc chia đối tượng như vậy một phần là nhờ vào các phương thức đã được tích hợp sẵn trong các thư viện Chessboard.js và Chess.js, đồng thời cũng thuận tiện cho việc triển khai mã nguồn và phát triển phần mềm theo hướng chức năng.
Game hoạt động trên nền tảng website, vì vậy trước hết cần tạo một file index.html Giao diện của game sẽ được phát triển trong file này Tiếp theo, tạo một thư mục có tên là css, trong đó chứa file main.css để định kiểu cho các phần tử trong game Sau đó, khởi tạo thư mục js để chứa các đối tượng và phương thức trong game Cuối cùng, tạo thư mục img để lưu trữ hình ảnh các quân cờ trong game.
Tiếp theo, bạn cần liên kết với các thư viện để sử dụng mã nguồn có sẵn của chúng Các thư viện sẽ được nhúng vào game thông qua các thẻ script được đặt trong phần head của file index.html.
Thư viện Chessboard bao gồm các tệp CSS và JavaScript, được nhập trực tiếp trong tệp index.html Thư viện Chess sẽ được cài đặt và lưu trữ các phương thức không sử dụng trong dự án vào thư mục js.
Hình ảnh của bàn cờ và các quân cờ được cung cấp bởi thư viện Chessboard Tất cả hình ảnh các quân cờ sẽ được lưu trữ trong thư mục img/chesspieces/wikipedia/, đã được cấu hình sẵn trong Chessboard.
Các file hình nh sả ẽ được đặt tên theo quy ước: colorPIECE.png Ví d hình nh ụ ả của quân xe đen sẽ có tên là bR.png
Để khởi tạo trò chơi cờ, cần tạo thêm hai đối tượng là Game và Chessbot bên cạnh Chessboard và Chess đã được thiết lập Chessboard sẽ cung cấp các phương thức điều khiển bàn cờ, trong khi Chess đảm nhiệm xử lý logic của trò chơi Chessbot sẽ là đối thủ tự động, đưa ra các nước đi để thi đấu với người chơi Đối tượng Game sẽ quản lý các luồng hoạt động chính và xử lý sự kiện trong trò chơi, đồng thời lưu trữ các thông số cần thiết trong game.
- STACK_SIZE: S l n undo tố ầ ối đa.
- undo_stack: Lưu các move object để ự th c hiện hành động undo và redo
- globalSum: Giá tr l i th hi n t i, cho bi t l i th ị ợ ế ệ ạ ế ợ ế đang nghiêng về bên nào
- board: Biến để kh i tở ạo đối tượng ChessBoard
- $board: Lưu trữ ph n t HTLMDOM c a bàn c ầ ử ủ ờ
- positionCount: Biến đếm số lượng các trường hợp mà Chessbot đã tính toán được
- timer: Biến để lưu trữ vòng l p cho chặ ế độ máy đánh máy
- Các bi n còn lế ại dùng để quy định màu s c cho bàn c khi th c hi n các hành ắ ờ ự ệ động như nhấc quân cờ, đặt quân cờ, highlight nước vừa đi,…
Sau khi kh i t o xong, cở ạ ấu trúc thư mục c a d án s có dủ ự ẽ ạng như sau:
Dựa theo bố cục trong GDD Object, đầu tiên, hãy tạo một container để chứa tất cả các thành phần trong game Container này sẽ tự động điều chỉnh kích thước theo kích thước màn hình hiện tại, đảm bảo giao diện luôn hiển thị rõ ràng và dễ thao tác Cần chú ý để viền không chạm vào rìa màn hình, chia giao diện thành hai phần: bàn cờ và các thanh cài đặt, đồng thời căn giữa các phần tử giữa hai khu vực này.
Tiếp theo ti n hành viế ết mã các thanh cài đặt và thanh thông báo v i các yêu c u v ớ ầ ề bố c c: ụ
Bài viết này tập trung vào việc xác định số lượng trường hợp trong trò chơi, đồng thời phân tích thời gian tính toán các trường hợp và tốc độ xử lý Để thực hiện điều này, cần căn chỉnh chữ ở giữa và gán ID cho bộ đếm số lượng.
Page | 20 là position-count, th i gian tính toán là ờ time, tốc độ tính toán là positions-per- s để có th ể thay đổ ữ ệi d li u trong DOM
Trong phần cài đặt, có ba tùy chọn chính: cài đặt độ sâu tìm kiếm, gợi ý nước đi và cài đặt khai cuộc Ngoài ra, chế độ CompVSComp (máy đấu máy) cũng được tích hợp, tất cả đều nằm trong một thẻ cài đặt chung.
Thanh cài đặt khai cuộc:
Chế độ máy đấu máy:
• Thanh thông báo l i th và tr ng thái: ợ ế ạ
Cuối cùng, để cài đặt giao diện bàn cờ, bạn cần khởi tạo một thẻ DOM với id là myBoard Khi kết nối với đối tượng Chessboard, nó sẽ tự động sinh mã bàn cờ trong thẻ myBoard Giao diện còn có hai nút undo và redo, giúp người chơi dễ dàng quay lại các nước đi trước đó.
Trong file main.css, định kiểu cho các phần tử trong game: Căn chữ ở giữa, màu highlight khi m t quân c di chuyộ ờ ển,…
Sau khi hoàn thành, giao diện của game đã được coi là hoàn chỉnh và có thể sử dụng để gửi các sự kiện đến hệ thống xử lý.
3.4 Chessboard.js và Chess.js API
Chessboard và Chess là hai thư viện quan trọng trong việc phát triển trò chơi cờ Như đã đề cập trong sơ đồ lớp, các thư viện này cung cấp các phương thức cần thiết để điều khiển bàn cờ và tính toán logic cho Chessbot.
Bàn cờ sẽ được nhúng trực tiếp vào file HTML của dự án như đã trình bày Nó bao gồm các phương thức cơ bản để khởi tạo, cấu hình bàn cờ và thực hiện các hành động trên bàn cờ.
+ Constructor: new Chessboard(htmlDOM config) ,
Khởi tạo đối tượng Chessboard bằng cách sử dụng phần tử HTML trong DOM để tạo container hiển thị bàn cờ Trong dự án, phần tử HTML div có id là myBoard sẽ được sử dụng Tham số config là một object để cấu hình các tùy chọn hiển thị và hành vi của bàn cờ.
Đối tượng cấu hình (Config object) chứa các thuộc tính quan trọng để thiết lập bàn cờ Trong đó, thuộc tính "draggable" cho phép người dùng di chuyển các quân cờ bằng cách kéo và thả Thuộc tính "position" xác định vị trí ban đầu của các quân cờ trên bàn cờ.
Giao di n (GUI) 19 ệ Chessboard.js và Chess.js API
Dựa theo bố cục trong GDD Object, trước tiên, cần tạo một container để chứa tất cả các thành phần trong game Container này sẽ tự động điều chỉnh kích thước theo kích thước màn hình hiện tại, đảm bảo giao diện luôn hiển thị rõ ràng và thuận tiện cho thao tác Cần chú ý để viền không chạm vào rìa màn hình, chia giao diện thành hai phần: bàn cờ và các thanh cài đặt, đồng thời căn chỉnh các phần tử ở giữa hai phần này.
Tiếp theo ti n hành viế ết mã các thanh cài đặt và thanh thông báo v i các yêu c u v ớ ầ ề bố c c: ụ
Trong bài viết này, chúng tôi sẽ phân tích số lượng trường hợp đã được tính trong trò chơi, cùng với thời gian cần thiết để thực hiện các phép tính này Bên cạnh đó, chúng tôi sẽ đề cập đến việc căn giữa nội dung và cách đặt ID cho bộ đếm số lượng.
Page | 20 là position-count, th i gian tính toán là ờ time, tốc độ tính toán là positions-per- s để có th ể thay đổ ữ ệi d li u trong DOM
Trong phần cài đặt, có ba tùy chọn chính: cài đặt độ sâu tìm kiếm, gợi ý nước đi và cài đặt khai cuộc, cùng với chế độ CompVSComp (máy đấu máy), tất cả được tổ chức trong một thẻ cài đặt chung.
Thanh cài đặt khai cuộc:
Chế độ máy đấu máy:
• Thanh thông báo l i th và tr ng thái: ợ ế ạ
Cuối cùng, chúng ta sẽ cài đặt giao diện bàn cờ bằng cách khởi tạo một thẻ DOM với id là myBoard Khi kết nối với đối tượng Chessboard, mã bàn cờ sẽ được tự động sinh ra trong thẻ myBoard Giao diện còn bao gồm hai nút undo và redo, giúp người chơi dễ dàng quay lại các nước đi của mình.
Trong file main.css, định kiểu cho các phần tử trong game: Căn chữ ở giữa, màu highlight khi m t quân c di chuyộ ờ ển,…
Sau khi hoàn thành, giao diện của game đã được coi là hoàn chỉnh và có thể sử dụng để gửi các sự kiện đến hệ thống xử lý.
3.4 Chessboard.js và Chess.js API
Chessboard và Chess là hai thư viện quan trọng trong việc phát triển game cờ Như đã đề cập trong sơ đồ lớp, các thư viện này cung cấp các phương thức để điều khiển bàn cờ và thực hiện các phép tính logic cho Chessbot.
Bàn cờ sẽ được nhúng trực tiếp vào file HTML của dự án như đã trình bày Nó bao gồm các phương thức cơ bản để khởi tạo, cấu hình bàn cờ và thực hiện các hành động trên bàn cờ.
+ Constructor: new Chessboard(htmlDOM config) ,
Khởi tạo đối tượng Chessboard bằng cách sử dụng phần tử HTML trong DOM để làm container hiển thị bàn cờ Trong dự án, phần tử HTML div có id là myBoard được sử dụng Tham số config là một object để cấu hình các tùy chọn hiển thị và hành vi của bàn cờ.
Đối tượng Config chứa các thuộc tính quan trọng để cấu hình bàn cờ, bao gồm: draggable, cho phép di chuyển các quân cờ bằng cách kéo và thả; và position, xác định vị trí ban đầu của các quân cờ trên bàn cờ.
Hàm onDragStart được gọi khi người chơi bắt đầu kéo một quân cờ trên bàn cờ Hàm onDrop xử lý sự kiện khi người chơi thả quân cờ trên bàn cờ Hàm onMouseoutSquare được kích hoạt khi con trượt di chuyển ra khỏi một ô trên bàn cờ, trong khi hàm onMouseoverSquare được gọi khi con trượt di chuyển vào một ô Cuối cùng, hàm onSnapEnd xử lý sự kiện khi một quân cờ được kéo và thả vào một vị trí mới trên bàn cờ, hoàn tất quá trình kéo thả.
Chuỗi FEN (Forsyth Edwards Notation) mô tả vị trí của các quân cờ trên bàn cờ Hàm position() sẽ trả về chuỗi FEN hiện tại của bàn cờ nếu không có giá trị nào được đưa vào.
Chess là đối tượng chính điều khiển bàn cờ, với các thuộc tính và giá trị ảnh hưởng đến các phương thức của Chessbot để thực hiện tính toán logic Nó có nhiều thuộc tính và phương thức, nhưng ở đây chỉ trình bày một vài trong số chúng.
- FLAGS: là m t objectộ , dùng để lưu các h ng s bi u th tr ng thái hi n t i ằ ố ể ị ạ ệ ạ
NORMAL: 'n' - Một nướ đi bình thường c
BIG_PAWN: 'b' – Nước đ 2 ô đố ớ ốt(nếu chưa di chuyển) i i v i t
- SQUARES: Mảng lưu các kí hiệu của các ô trên bàn c , ví dờ ụ: ‘a1’, ‘b8’,…
- fen(): Tr v chu i FEN hi n t i c a bàn c ả ề ỗ ệ ạ ủ ờ
- turn(): Tr v kí hiả ề ệu người chơi tiếp theo s th c hiẽ ự ện nước đi (trắng:w, đen:b)
Hàm ugly_moves(options) trả về tất cả các nước đi hợp lệ có thể thực hiện bởi người chơi hiện tại, bao gồm cả những nước đi bất lợi nhưng vẫn hợp lệ.
Các thuộc tính của đối tượng options bao gồm: legal (Boolean) xác định xem các nước đi hợp lệ hay không, mặc định là true; square (String) dùng để tìm kiếm các nước đi của quân cờ trên ô hiện tại; và verbose (Boolean) nếu được đặt thành true, sẽ trả về một mảng chứa thông tin chi tiết về các nước đi, bao gồm tọa độ ban đầu, tọa độ đích, quân cờ bị ăn nếu có, và các tham số khác, mặc định là false.
Hàm `ugly_move(move_obj, options)` thực hiện một nước đi trên bàn cờ với các tham số được truyền vào Tham số `move_obj` là một đối tượng chứa các thuộc tính `from`, `to` và `promote`, tương ứng đại diện cho ô bắt đầu, ô kết thúc và quân để phong cấp nếu nước đi là phong cấp, ví dụ như `{from: ‘e2’, to: ‘e4’}` Tham số `options` là một đối tượng cho phép các tùy chọn bổ sung để điều chỉnh việc di chuyển, chẳng hạn như `{sloppy: true}` để cho phép quân cờ di chuyển bất thường theo quy tắc.
Thi t k logic cho Chess bot 28 ế ế 1 H s l c c a quân c ệ ố ự ủ ờ và đánh giá thế trận
3.6.1 H s l c c a quân cệ ố ự ủ ờ và đánh giá thế ậ tr n Để Chessbot đưa ra một nước đi đủ t t, nó cố ần m t ộ “con s ố” để hiểu được tr ng thái ạ bàn cờ hi n tệ ại, chính xác hơn là một chức năng đánh giá Về cơ bản, ta mu n gán m t ố ộ 'điểm số' cho từng trường hợp bàn cờ (tức là từng tập hợp v trí của các quân cờ trên ị bàn cờ) để Chessbot có th ể đưa ra quyết định v v trí nào thu n lề ị ậ ợi hơn các vị trí khác
Khía cạnh đầu tiên trong quá trình đánh giá là việc ấn định trọng số cho từng quân cờ Nếu Chessbot chơi từ góc nhìn của quân đen, thì mỗi quân đen sẽ góp phần vào điểm số lợi thế của Chessbot, trong khi các quân trắng sẽ trừ vào điểm lợi thế, dựa trên các trọng số cụ thể của mỗi quân cờ.
Các quân cờ đã được "đánh giá sức mạnh", nhưng sức mạnh của mỗi quân cờ thay đổi tùy thuộc vào vị trí của nó trên bàn cờ Ví dụ, quân Mã khi đứng ở f3 có khả năng kiểm soát 6 ô, đặc biệt là các ô trung tâm, giúp làm chậm các cuộc tấn công của quân đen vào khu trung tâm Rõ ràng, quân Mã ở f3 mạnh hơn nhiều so với khi đứng ở g1, nơi nó chỉ kiểm soát được 2 ô góc bàn cờ Thậm chí, khi đứng ở g1, quân Mã trở nên "vô dụng" trong mắt người chơi Do đó, việc đánh giá một quân cờ không chỉ dựa vào giá trị của nó mà còn cần xem xét vị trí của nó trên bàn cờ, từ đó xác định lợi thế mà nó mang lại cho người chơi và Chessbot Các giá trị dưới đây thể hiện giá trị gia tăng của mỗi quân cờ khi đứng ở một vị trí cụ thể (đối với quân trắng), được gọi là bảng giá trị vị trí (Piece Square Tables), dựa trên phần mềm chơi cờ vua nổi tiếng Sunfish Engine.
Đối với quân đen, chỉ cần đảo ngược các giá trị lại Các quân cờ được xử lý như sau: quân tốt (p) được lấy từ pst_w và đảo ngược, tiếp theo là quân mã (n), quân xe (r), quân hậu (q), quân vua (k), và quân vua ở vị trí cuối (k_e) cũng được xử lý tương tự.
Sau khi xác định giá trị của các quân cờ trên bàn cờ, bước tiếp theo là tạo một hàm đánh giá nước đi để Chessbot có thể quyết định lựa chọn nước đi nào Hàm này sẽ đánh giá mọi nước đi khả thi trên cây trò chơi ở một độ sâu nhất định Mục đích của hàm là để đánh giá một nước đi cụ thể Để thực hiện việc đánh giá này, cần truyền vào hàm các tham số: function evaluateBoard(chess, move, prevSum, color).
Di chuyển là một đối tượng chứa các thông tin về nước đi vừa được thực hiện, bao gồm bên trắng hay bên đen thực hiện nước đi, quân cờ được đi là gì, di chuyển từ ô nào đến ô nào, trạng thái cờ sau nước đi đó, ký hiệu SAN của nước đi, và quân ăn được là gì Nếu không có quân nào bị ăn, giá trị capture sẽ là không xác định.
Giá trị prevSum thể hiện sự chênh lệch lợi thế giữa hai bên trong trò chơi, với giá trị dương (+500) cho thấy bên trắng đang dẫn trước bên đen 500 điểm, trong khi giá trị âm (-500) cho thấy bên đen đang có lợi thế hơn bên trắng 500 điểm.
Màu sắc của bên đang thực hiện đánh giá lợi thế rất quan trọng, vì giá trị của quân cờ và vị trí của quân cờ thuộc bên trắng và đen là khác nhau Nếu màu sắc là 'w', số điểm lợi thế sẽ được cộng thêm dựa trên tổng giá trị và vị trí của các quân cờ đang hoạt động, và ngược lại cho bên còn lại.
Có những trường hợp đặc biệt xảy ra sau khi thực hiện một nước đi, và trong những tình huống này, không cần phải đánh giá lại vì giá trị lợi thế đã có thể xác định ngay lập tức.
Chiếu hết là một tình huống quan trọng trong cờ vua, khi một người chơi đang đánh giá lợi thế của quân trắng (color='w') và tính toán một nước đi có thể dẫn đến chiếu hết (in_checkmate()) Nếu nước đi đó thành công, giá trị lợi thế sẽ được xác định là 10^10, phản ánh sự nghiêng về lợi thế của người đi quân trắng.
// Opponent is in checkmate (good for player[color]) if (move.color ===color) { return 10 ** 10;
// Player[color]’s king is in checkmate (bad for player[color]) else { return - (10 ** 10);
Trong cờ vua, một ván đấu được coi là hòa khi không còn quân cờ nào đủ để chiếu hết vua đối phương, không có quân cờ nào bị ăn trong 50 nước đi liên tiếp, hoặc khi lặp lại ba lần thế cờ trước đó Ngoài ra, nếu một người chơi không thể thực hiện bất kỳ nước đi hợp lệ nào nhưng vua vẫn không bị chiếu hết, ván đấu cũng sẽ được công nhận là hòa Khi hòa, giá trị của ván cờ được tính là 0, vì không bên nào có lợi thế hơn bên nào.
- N u vua cế ủa đố phương bịi chiếu, điểm l i th cợ ế ộng thêm cho bên đang chiếu s là ẽ 50: if (chess.in_check()) {
Page | 32 if (move.color ===color) { prevSum += 50;
// Player[color]’s king is in check else { prevSum -= 50;
Tiếp theo, cần tính toán giá trị của quân cờ dựa trên giá trị vị trí của nó trước và sau khi thực hiện nước đi đang được đánh giá Giá trị vị trí của mỗi quân cờ được lưu trữ trong một mảng hai chiều, do đó, ta cần xác định tọa độ của quân cờ đó trước và sau khi di chuyển Đầu tiên, hãy lấy vị trí ban đầu và vị trí kết thúc của nước đi được đánh giá, sau đó chuyển đổi chúng thành tọa độ trong bàn cờ Ví dụ, với tham số move, ta có thể xác định quân cờ di chuyển là quân tốt.
“p”, color: “w”), di chuy n t ô ể ừ “e2” tới ô “e4” Nếu g n bàn c vào tr c tắ ờ ụ ọa độ của m ng, ả tọa độ di chuyển của quân tốt sẽ là từ (6,4) đến (4,4)
Để tính giá trị 6 và 4 từ chuỗi "e2", ta lấy giá trị 8 trừ đi ký tự thứ 2 trong chuỗi “e2” (Integer(“e2”[1])) Giá trị 4 được tính bằng cách lấy giá trị char của ký tự đầu tiên trong chuỗi “e2” ('e') trừ đi giá trị char của ký tự 'a' Cuối cùng, hai giá trị này được lưu vào một mảng.
Ta có from = [6,4]; to = [4,4] var from [ 8 -parseInt(move.from[1]), move.from.charCodeAt(0) - ' 'a.charCodeAt(0),
]; var to [ 8 -parseInt(move.to[1]), move.to.charCodeAt(0) - ' 'a charCodeAt(0),
Trong cờ vua, bảng giá trị vị trí k_e được sử dụng khi tàn cuộc, khi quân cờ trên bàn đã giảm bớt, làm cho nguy hiểm của quân vua giảm và khả năng sử dụng quân vua tăng lên Tàn cuộc được định nghĩa là giai đoạn mà sự chênh lệch điểm lợi thế lớn (thường trên 1500) xảy ra, thường khi một bên đã mất nhiều quân hoặc rơi vào thế bế tắc Khi đó, bên yếu hơn khó có khả năng giành chiến thắng, và chúng ta sẽ áp dụng bảng giá trị cho vua thay vì bảng k.
1500, ta s dùng giá trẽ ị ở ả b ng k_e thay th cho b ng k ế ả if (prevSum < -1500) { if (move.piece ===' 'k ) { move.piece = 'k_e';
Nước đi có thể dẫn đến việc ăn quân (capture) nếu có quân của đối phương bị ăn Để kiểm tra khả năng này, ta xem xét thuộc tính capture của nước đi Nếu quân bị ăn thuộc về đối phương (màu sắc khác với màu sắc của người thực hiện nước đi), thì điểm lợi sẽ được cộng thêm bằng hệ số lực của quân cựu bị bắt và giá trị vị trí của quân đó Ngược lại, nếu quân của người thực hiện nước đi bị ăn, điểm lợi sẽ giảm tương ứng.
// Opponent piece was captured (good for player[color]) if (move.color ===color) { prevSum + weights[move.captured] + pstOpponent[move.color][move.captured][to[ ]][to[0 1]];
// player[color]’s piece was captured (bad for player[color]) else { prevSum - weights[move.captured] + pstSelf[move.color][move.captured][to[ ]][to[0 1]];
X lý các s ki n 49 ử ự ệ 1 Tr chu t vào, di chu t ra kh i ô c 49ỏộộỏờ 2 B ắt đầ u kéo quân c 50ờ 3 Th quân c 50ảờ 4 K t thúc kéo quân c 51ếờ 5 L a ch n khai cu c 51ựọộ 6 B ắt đầ u, reset và ch ế độ Má y đánh máy
Mỗi hành động của người chơi trong trò chơi đều kích hoạt một sự kiện Ví dụ, khi người chơi thực hiện một nước đi, hành động này bắt đầu bằng việc nhấp chuột vào quân cờ, kéo quân cờ đến vị trí mới trên bàn cờ, và cuối cùng là thả quân cờ ra Mỗi hành động này sẽ gửi một sự kiện đến hệ thống, và tùy thuộc vào sự kiện được gửi, hệ thống sẽ kích hoạt các hàm xử lý sự kiện khác nhau Trong dự án này, đối tượng xử lý các sự kiện trong game là đối tượng Game Game điều khiển bàn cờ thông qua đối tượng Chessboard, và hàm khởi tạo của Chessboard nhận một tham số là object cấu hình, giúp xử lý các hành động tương tác cụ thể trên giao diện trò chơi như chỉ vào quân cờ hay kéo quân cờ.
3.8.1 Tr chu t vào, di chu t ra khỏ ộ ộ ỏi ô cờ
Khi chuột di chuyển vào một ô cờ có quân cờ, trò chơi sẽ gợi ý các nước đi hợp lệ bằng cách đánh dấu các vị trí có thể di chuyển Khi di chuột ra khỏi ô cờ, các ô cờ sẽ trở về trạng thái ban đầu.
Khi chuột trượt vào một ô cờ, các nước đi khả thi của quân cờ tại vị trí ô đó sẽ được sinh ra Nếu không có quân cờ nào ở ô đó, sẽ không có hành động nào xảy ra Ngược lại, nếu có quân cờ ở đó, hàm sẽ đánh dấu các nước đi hợp lệ từ ô cờ đó.
// get list of possible moves for this square var moves = chess.moves({ square :square, verbose: true,
// exit if there are no moves available for this square if (moves.length ===0) return;
// highlight the square they moused over greySquare(square);
// highlight the possible squares for this piece for (var i ; i moves.length; i= 0 < ++) { greySquare(moves[i].to);
Khi di chu t ra kh i m t ô cộ ỏ ộ ờ, ch c n xóa bỉ ầ ỏ đánh dấ ởu ô cờ đó và các ô cờ hợp lệ của quân c ô c ờ ở ờ đó. function onMouseoutSquare(square, piece) { removeGreySquares();
Khi người chơi kéo quân cờ, trò chơi sẽ kiểm tra trạng thái bàn cờ để đảm bảo rằng trong một số tình huống nhất định, người chơi sẽ không thể nhấc quân cờ lên Ví dụ, ván đấu có thể kết thúc do bị chiếu hết hoặc không phải lượt của người chơi.
// do not pick up pieces if the game is over if (chess.game_over()) return false;
// or if it's not that side's turn if (
3.8.3 Th quân c ả ờ function onDrop(source, target)
Khi người chơi thả một quân cờ, ô cờ nguồn và ô cờ đích sẽ được xác định, phản ánh bước đi vừa hoàn thành Quá trình này yêu cầu game thực hiện nhiều công việc xử lý để đảm bảo tính chính xác và mượt mà trong trò chơi.
- Reset undo_stack, xóa đánh dấu nước đi hợp lệ: undo_stack []; removeGreySquares();
- Kiểm tra xem nước đi có hợ ệp l hay không: var move = chess.move({ from : source, to: target, promotion : ' 'q, // Always promote to a queen for example simplicity });
Nếu nước đi không hợp lệ, thuộc tính OnDrop trong đối tượng config của Chessboard sẽ trả về giá trị "snapback" Khi thuộc tính OnDrop có giá trị này, quân cờ vừa được thả ra sẽ quay trở lại vị trí ban đầu Đoạn mã kiểm tra nếu nước đi là null thì trả về 'snapback'.
Khi một nước đi được thực hiện, cần tiến hành đánh giá thế trận và cập nhật kết quả liên quan đến giao diện Sử dụng hàm evaluateBoard để đánh giá bàn cờ và cập nhật lợi thế với updateAdvantage.
$board.find(' ' + squareClass).removeClass('highlight-white');
$board.find('.square-' + move.from).addClass('highlight-white');
Page | 51 squareToHighlight move.to; colorToHighlight = 'white';
Người chơi điều khiển quân trắng trong ván cờ, trong khi Chessbot (quân đen) sẽ kiểm tra trạng thái ván cờ Nếu ván cờ chưa kết thúc, Chessbot sẽ tìm kiếm nước đi tốt nhất cho quân đen và thực hiện nước đi đó Sau khi thực hiện, nếu người chơi đang chọn chế độ gợi ý nước đi, Chessbot sẽ tiếp tục tìm kiếm nước đi tốt nhất cho quân trắng và gợi ý cho người chơi.
{ window.setTimeout(function () { makeBestMove(' 'b); window.setTimeout(function () { showHint();
Sự kiện này xảy ra ngay sau khi kết thúc hành động "snap", có nghĩa là sau khi quân cờ đã được đặt vào vị trí của nó Quá trình này sẽ được kích hoạt sau sự kiện "Thả quân cờ", và nó sẽ cập nhật lại vị trí các quân cờ trên giao diện theo chuỗi FEN của Chess Chức năng onSnapEnd() sẽ thực hiện việc này bằng cách sử dụng lệnh board.position(chess.fen()).
Giao diện còn tích hợp các thanh cài đặt khác, cho phép người chơi kích hoạt sự kiện khi chọn tùy chọn trong các thanh này, đồng thời gửi thông tin về hệ thống.
Các vị trí quân cờ trong khai cuộc có sự khác biệt, dẫn đến chuỗi fen cũng sẽ không giống nhau Chỉ cần đưa chuỗi fen vào phương thức load của Chess, sau đó sử dụng phương thức position của Chessboard để hiển thị trên giao diện Một số khai cuộc như Ruy-Lopez và Italia sẽ kết thúc với lượt đi tiếp theo là của quân đen, trong khi khai cuộc Sicilian lại kết thúc với lượt đi tiếp theo là của quân trắng Đối với các khai cuộc mà lượt đi tiếp theo thuộc về quân đen (Chessbot), sau khi đặt các quân cờ đúng vị trí, quân đen cần thực hiện nước đi ngay sau đó.
$('#ruyLopezBtn').on('click', function () { reset(); chess.load(
'r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 0 1' ); board.position(chess.fen()); window.setTimeout(function () { makeBestMove(' 'b );
$('#italianGameBtn').on('click', function () { reset(); chess.load(
'r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 0 1' ); board.position(chess.fen()); window.setTimeout(function () { makeBestMove(' 'b );
$('#sicilianDefenseBtn').on('click', function () { reset(); chess.load('rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 1'); board.position(chess.fen());
3.8.6 Bắt đầu, reset và chế độ Máy đánh máy
Bắt đầu và reset đều thực hiện việc khởi động lại ván cờ từ đầu, vì vậy cần gọi hàm xử lý việc reset Khi người chơi chọn chế độ Máy đánh máy, ván cờ sẽ được reset và hàm xử lý chế độ này sẽ được gọi, bắt đầu với nước đi của quân trắng.
$('#startBtn').on('click', function () { reset();
$('#compVsCompBtn').on('click', function () { reset(); compVsComp(' 'w);
$('#resetBtn').on('click', function () { reset();
Khi người chơi nhấn nút undo, trò chơi sẽ quay lại nước đi trước đó, nhưng cần thực hiện hai nước đi cùng lúc: một của quân đen và một của quân trắng Trước tiên, cần kiểm tra lịch sử ván cờ để xác nhận có ít nhất hai nước đã được đi hay không Nếu có, xóa b điệu của nước vừa đi, sau đó gọi hàm undo hai lần, cách nhau vài mili giây, và kích hoạt hàm showHint để xử lý việc người chơi có chọn gợi ý nước đi hay không Nếu lịch sử ván cờ có ít hơn hai nước đi, sẽ hiển thị thông báo cho người chơi.
$('#undoBtn').on('click', function () { if (chess.history().length >= 2) {
$board.find(' ' squareClass).+ removeClass('highlight-white');
$board.find(' ' squareClass).+ removeClass('highlight-black');
$board.find(' ' squareClass).+ removeClass('highlight-hint');
// Undo twice: Opponent's latest move, followed by player's latest move undo(); window.setTimeout(function () { undo(); window.setTimeout(function () { showHint();
} else { alert('Nothing to undo.');
Để thực hiện chức năng redo, bạn cần kiểm tra undo_stack Nếu có từ hai nước đi trở lên, hãy thực hiện redo hai lần và gợi ý nước đi tiếp theo Nếu số lượng nước đi ít hơn hai, hãy hiển thị thông báo cho người dùng.
$('#redoBtn').on('click', function () { if (undo_stack.length >= ) { 2
// Redo twice: Player's last move, followed by opponent's last move redo(); window.setTimeout(function () { redo(); window.setTimeout(function () { showHint();
} else { alert('Nothing to redo.');
Kiểm thử
Ki m th h ể ử ộp tr ng 53 ắ 1 Ki m th ể ử cây trò chơi 53 2 Ki m th giá tr l i th 55ểửị ợế
4.1.1 Kiểm thử cây trò chơi
Kiểm tra khả năng đánh giá của Chessbot đối với các nước đi trên cây trò chơi với độ sâu tìm kiếm 1 Để tiết kiệm thời gian, ta sẽ điều chỉnh thanh cài đặt độ sâu về giá trị 1 và in ra màn hình console các thuộc tính của quân cờ (piece), ô bắt đầu (from) và ô kết thúc (to) của các nước đi mà Chessbot đánh giá trong thuật toán minimax Sử dụng cú pháp const {piece, from, to} = currPrettyMove và console.log({piece, from, to}) để thực hiện việc này.
Bắt đầu b ng vi c di chuy n quân t t tr ng t e2 lên e4 ằ ệ ể ố ắ ừ
Khi đó thuật toán minimax sẽ được gọi đến và in ra màn hình các nước đi như sau:
1 {piece: 'p', from: 'd7', to: 'd6'}: quân Tốt đi từ 7 đến d6 d
2 {piece: 'p', from: 'g7', to: 'g6'}: quân Tốt đi từ 7 đến g6 g
3 {piece: 'p', from: 'c7', to: 'c5'}: quân Tốt đi từ 7 đến c5 c
4 {piece: 'p', from: 'h7', to: 'h5'}: quân Tốt đi từ 7 đến h5 h
5 {piece: 'p', from: 'd7', to: 'd5'}: quân Tốt đi từ 7 đến d5 d
6 {piece: 'p', from: 'g7', to: 'g5'}: quân Tốt đi từ 7 đến g5 g
7 {piece: 'n', from: 'b8', to: 'c6'}: quân Mã đi từ b8 đến c6
8 {piece: 'p', from: 'e7', to: 'e5'}: quân Tốt đi từ 7 đến e5 e
9 {piece: 'p', from: 'h7', to: 'h6'}: quân Tốt đi từ 7 đến h6 h
10 {piece: 'n', from: 'b8', to: 'a6'}: quân Mã đi từ b8 đến a6
11 {piece: 'p', from: 'b7', to: 'b5'}: quân Tốt đi từ 7 đế b n b5
12 {piece: 'p', from: 'e7', to: 'e6'}: quân T t ố đi từ 7 đế e n e6
13 {piece: 'p', from: 'a7', to: 'a6'}: quân Tốt đi từ a7 đến a6
14 {piece: 'n', from: 'g8', to: 'f6'}: quân Mã đi từ g8 đến f6
15 {piece: 'p', from: 'f7', to: 'f5'}: quân Tốt đi từ 7 đế f n f5
16 {piece: 'p', from: 'c7', to: 'c6'}: quân Tốt đi từ 7 đế c n c6
17 {piece: 'n', from: 'g8', to: 'h6'}: quân Mã đi từ g8 đến h6
18 {piece: 'p', from: 'b7', to: 'b6'}: quân Tốt đi từ 7 đế b n b6
19 {piece: 'p', from: 'a7', to: 'a5'}: quân Tốt đi từ a7 đến a5
20 {piece: 'p', from: 'f7', to: 'f6'}: quân Tốt đi từ 7 đến f6 f
Chú ý: c ác nước đi này đã bị xáo tr n theo th t ng ộ ứ ự ẫu nhiên để tránh vi c Chessbot l a ch n l p l ệ ự ọ ặ ại 1 nướ c đi có cùng giá trị lợi thế
Xem xét các nước đi mà quân đen có thể đi tiếp khi quân trắng đi e4:
Bảy quân Tốt đen có khả năng di chuyển từ hàng 7 xuống hàng 6 hoặc hàng 5, tạo ra tổng cộng 14 nước đi khả thi cho Chessbot Các nước đi này bao gồm: 1, 2, 3, 4.
Một quân Mã đen có thể di chuyển theo hai hướng (a6 hoặc c6, f6 hoặc h6), tổng cộng có 4 nước đi mà Chessbot có thể tạo ra, đó là các nước: 7, 10, 14 và 17 Chessbot đã tính toán đủ 20 nước đi hợp lệ mà quân đen có thể thực hiện khi quân trắng đi nước e4 với độ sâu là 1 Tiếp theo, cần kiểm tra xem với mỗi nước đi, Chessbot có tính toán đúng giá trị lợi thế của thế cờ hiện tại hay không ằằ PASS!
4.1.2 Kiểm thử giá tr lị ợi thế
Trong hàm minimax, sau khi thực hiện xong việc đánh giá lợi ích của một nước đi, ta sẽ thêm lệnh in ra màn hình nước đi và giá trị lợi ích khi thực hiện nước đi đó: const {piece, from, to} = { currPrettyMove} console.log({piece, from, to}, newSum)
Cũng với độ sâu là 1, và cũng bắt đầu với nước đi e4, khi đó màn hình sẽ in ra 20 nước đi cùng giá trị lợi thế như sau:
Nước đi {piece: 'p', from: 'd7', to: 'd5'} mang lại lợi thế 4 cho quân đen, cho thấy rằng đây là nước cờ có giá trị nhất trong các lựa chọn hiện tại Do đó, Chessbot sẽ thực hiện nước đi này.
Tuy nhiên, ta s th c hi n ki m tra xem giá trẽ ự ệ ể ị này có được tính toán đúng với hàm tính toán giá tr l i th (evaluateBoard) hay không ị ợ ế
Khi tr ng th c hiắ ự ện nước đi Tốt e2 - e4:
- Không x y ra chi u, chi u h t hay hòa c ả ế ế ế ờ
- Không phải nước đi ăn quân.
- Không phải nước đi phong cấp
Nước đi e2-e4 trong cờ vua thường được coi là một nước đi cơ bản Chessbot, khi chơi quân đen, sẽ tính toán điểm lợi thế của mình bằng cách lấy tổng điểm lợi thế trước đó, trừ đi giá trị vị trí của quân trắng tại ô cũ và cộng thêm giá trị vị trí của quân đen tại ô mới Cuối cùng, Chessbot sẽ lấy giá trị âm của kết quả đó để đánh giá tình hình.
- Số điểm l i thợ ế trước đó: 0 (do trắng vừa đi nước đầu tiên)
- Giá tr v trí c a quân T t tr ng t i e2: -36 ị ị ủ ố ắ ạ
- Giá tr v trí c a quân T t tr ng l i e4: 6 ị ị ủ ố ắ ạ
Vậy sau nước đi e4, quân trắng hiện đang có lợi thế là 42 điểm
Tiếp theo xét vi c ệ đen thực hiện nước đi Tốt d7 – d5:
- Không x y ra chi u, chi u h t hay hòa c ả ế ế ế ờ
- Không phải nước đi ăn quân.
- Không phải nước đi phong cấp
Vậy nước d7-d5 của đen chỉ là một nước đi bình thường, Chessbot sẽ thực hiện tính toán giá tr l i th theo công th c nêu trên: ị ợ ế ứ
- Số điểm l i thợ ế trước đó: -42
- Giá tr v trí c a quân Tị ị ủ ốt đen tại d7: -37
- Giá tr v trí c a quân T t tr ng l i e4: 9 ị ị ủ ố ắ ạ
Giá trị lãi suất được tính bằng công thức: -42 - (-37) + 9 = 4 Không cần thay đổi giá trị âm vì đây là nước đi hiện tại của bên đen, cùng màu với Chessbot Kết quả này đúng với giá trị lớn nhất mà Chessbot đã xác định.
Kết luận, sau khi thực hiện nước đi e4, Chessbot đã tạo ra cây trò chơi và tính toán giá trị lợi thế tối ưu, xác định rằng nước đi d5 có giá trị lợi thế lớn nhất là 4 Việc thực hiện nước đi này hoàn toàn chính xác theo logic đã được lập trình.
Ki m th h ể ử ộp đen
4.2.1 Thao tác trong trò chơi
Các thao tác kéo thả trong trò chơi diễn ra mượt mà, với các nút cài đặt dễ dàng tương tác Khi lựa chọn, người dùng có thể tick vào ô input và các hành động được thực hiện ngay lập tức mà không cần chờ đợi thời gian tải.
Khi nh c quân c ấ ờ lên, ô c ờ sẽ được highlight dưới chân và ô c ờ đang kéo đến, hiển thị cho cả người chơi và Chessbot Nếu thực hiện một nước đi không hợp lệ, quân c ệ ờ sẽ được snapback về ô c hi n t i và không thực hiện bất kỳ hành vi nào khác Khi một quân tấ ạ ệ ộ ốt di chuyển đến hàng cu i cùng, nó sẽ được phong cấp thành quân Hấ ậu như đã cài đặt.
4.2.3 Lỗi trong xử lý d li u dữ ệ ẫn đến hi n th thông tin sai lể ị ệch
Trong trò chơi, chức năng undo và redo cho phép người chơi quay lại hoặc tiến tới các nước đi trước đó Chức năng này giúp đặt các quân cờ về đúng vị trí và cung cấp gợi ý cho người chơi nếu chế độ gợi ý được bật Tuy nhiên, game chưa cập nhật điểm lợi thế khi người chơi thực hiện undo hoặc redo, dẫn đến việc điểm lợi thế không thay đổi Để cải thiện, có thể phát triển chức năng này bằng cách tạo một stack lưu trữ các giá trị lợi thế trước đó, mỗi khi có nước đi mới sẽ đẩy giá trị lợi thế vào stack để hỗ trợ cho việc undo và redo.
Đánh giá chung
Ưu điểm
Nhìn chung, Chessbot có th ể đưa ra các nước đi khá chính xác và nhanh chóng nh ờ
2 thu t toán Minimax và c t t a Alpha beta ậ ắ ỉ –
Sử dụng thuật toán minimax cho Chessbot là một giải pháp tối ưu trong việc quản lý cây trò chơi Thuật toán này cho phép Chessbot đánh giá tất cả các nút trên cây trò chơi hiện tại, từ đó tìm ra nước đi tốt nhất mà không cần xem xét thứ tự các nút Điều này giúp cải thiện khả năng chơi cờ của bot một cách hiệu quả.
Chào bạn, Alpha ệ ấ ố ắ ỉ – beta là một thuật toán giúp giảm bớt các trường hợp không cần thiết trong quá trình tính toán trên cây trò chơi Điều này giúp Chessbot tối ưu hóa hiệu suất tính toán, đưa ra kết quả nhanh hơn và tiết kiệm tài nguyên hơn.
Việc đánh giá lợi thế trong trò chơi hiện tại là rất quan trọng, giúp người chơi nhận biết được tình hình và xu hướng của ván đấu Điều này cho phép người chơi thực hiện những tính toán hợp lý và đưa ra quyết định chiến lược chính xác hơn.
Nhược điểm
Mặc dù Chessbot đã có thể hoạt động t t, tuy nhiên nó v n còn mố ẫ ột vài nhược điểm nhất định cho các tính chất đặc trưng của 2 thuật toán chính
Thuật toán Minimax và Alpha-beta tiết kiệm thời gian đáng kể trong việc tìm kiếm toàn bộ cây trò chơi Điều này đặc biệt quan trọng khi phải đánh giá một số lượng lớn các nước đi khả thi, nhất là khi độ sâu của cây tìm kiếm tăng lên.
Thuật toán Minimax và Alpha-beta yêu cầu một hàm đánh giá heuristic chính xác để ước lượng giá trị của các quân cờ trong trạng thái ván cờ hiện tại Tuy nhiên, việc thiết kế một hàm đánh giá mạnh mẽ và chính xác để mô tả toàn bộ các tình huống trong ván cờ là một thách thức lớn.
Các trò chơi lớn và phức tạp thường không phù hợp với các thuật toán tìm kiếm truyền thống, vì việc xây dựng cây game hoặc tìm kiếm toàn bộ các nước đi có thể trở nên rất khó khăn Trong những trường hợp này, các phương pháp tìm kiếm khác như Monte Carlo Tree Search hoặc các thuật toán học tăng cường có thể được áp dụng để giải quyết vấn đề hiệu quả hơn.
Chessbot hiện tại đã đủ sức để so sánh với một kỳ thủ có mức elo 1800 - 1900 và có thể đánh bại các kỳ thủ có mức elo 1500 Tuy nhiên, sự so sánh này chỉ mang tính tương đối vì khả năng chơi cờ của con người không chỉ phụ thuộc vào tính toán mà còn vào khả năng suy luận, kinh nghiệm và cảm nhận cá nhân của mỗi kỳ thủ Điều này phản ánh văn hóa chơi cờ vua toàn cầu, nơi mỗi nước đi đều mang tính nghệ thuật, chiến thuật và trí tuệ, cùng với khả năng tư duy vượt trội của con người.