Chương trình sẽ quản lý các trạng thái bàn cờ và thực hiện các thao tác cần thiết để AI chơi cờ vua một cách hiệu quả.. Yêu cu: Xây dựng các lớp đói tượng trên các phương thức:
Trang 1BỘ GIAO THÔNG VẬN TẢI BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC HÀNG HẢI VIỆT NAM
Đinh Quang Dũng - 96670 Đào Trung Long Đặng Đình Phong
BÀI TẬP LỚN
XÂY DỰNG CHƯƠNG TRÌNH AI CỜ VUA
HẢI PHÒNG - 2024
Trang 2BỘ GIAO THÔNG VẬN TẢI BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC HÀNG HẢI VIỆT NAM
ĐINH QUANG DŨNG – 96670
ĐÀO TRUNG LONG – Mã sv ĐẶNG ĐÌNH PHONG -Mã sv BÀI TẬP LỚN XÂY DỰNG CHƯƠNG TRÌNH AI CỜ VUA
NGÀNH: CÔNG NGHỆ THÔNG TIN; MÃ SỐ: D114
CHUYÊN NGÀNH: CNTGiảng viên hướng dẫn: T.s Nguyễn Hạnh Phúc
HẢI PHÒNG - 2024
Trang 3LỜI CẢM ƠN
Tác giả Bài tập lớn bày tỏ tình cảm của mình đối với các cá nhân, tập thể cơ quan, gia đình, các đơn vị đã giúp đỡ, cộng tác và tài trợ trong quá trình nghiên cứu, thực hiện và hoàn thành luận văn
Trang 4LỜI CAM ĐOAN
Tôi xin cam đoan rằng đây là công trình nghiên cứu của tôi, có sự hỗ trợ từ Giáo viên hướng dẫn là T.s Nguyễn Hạnh Phúc Các nội dung nghiên cứu và kết quả trong đề tàinày là trung thực và chưa từng được ai công bố trong bất cứ công trình nghiên cứu nào trước đây Những số liệu trong các bảng biểu phục vụ cho việc phân tích, nhận xét, đánh giá được chính tác giả thu thập từ các nguồn khác nhau có ghi trong phần tàiliệu tham khảo
Nếu phát hiện có bất kỳ sự gian lận nào tôi xin hoàn toàn chịu trách nhiệm trước Hội đồng cũng như kết quả bài tập lớn của mình
ĐINH QUANG DŨNG – 96670
(ký) ĐÀO TRUNG LONG - Mã sv
(ký) ĐẶNG ĐÌNH PHONG - Mã sv
(ký)
Trang 5MỘT SỐ TỪ VIẾT TẮT SỬ DỤNG TRONG ĐỒ ÁN/KHÓA LUẬN DANH MỤC CÁC BẢNG
DANH MỤC CÁC HÌNH VẼ
Trang 6MỤC LỤC
Trang MỘT SỐ TỪ VIẾT TẮT SỬ DỤNG TRONG ĐỒ ÁN/KHÓA LUẬN
DANH MỤC CÁC BẢNG
DANH MỤC CÁC HÌNH VẼ
PHẦN MỞ ĐẦU
CHƯƠNG 1 CƠ SỞ LÝ THUYẾT
1.1 Các lớp cần thiết
1.1.1 Lớp GameState
1.1.2 lớp CastleRights
1.1.3 Lớp Move
1.2 Các đối tượng
CHƯƠNG 2 THIẾT KẾ CÁC L|P ĐỐI TƯ}NG
2.1 Lớp GameState
2.2 Lớp Move
2.3 Lớp CastleRights
CHƯƠNG 3 Thiết kế AI
3.1 Mục tiêu của AI
3.2 Phương pháp và các thuật toán
3.3 Lớp Danh
3.4 Hàm chính (main())
KẾT LUẬN VÀ KIẾN NGHỊ
TÀI LIỆU THAM KHẢO
PHỤ LỤC
Trang 7Box Box1;// Khai bao Box1 la cua kieu Box
Box Box2;// Khai bao Box2 la cua kieu Box
Trang 8chieurong
Box2.sdfsdf =2.3;
// thetich of box 1
thetich =Box1.chieucao *Box1.chieudai *Box1.chieurong;
def findMoveNegaMaxAlphaBeta(gs, validMoves, depth, alpha, beta,turnMultiplier):
global nextMove, counter
Trang 9PHẦN MỞ ĐẦU
Bi ton:
Để xây dựng một chương trình AI chơi cờ vua sử dụng lập trình hướng đối tượng Chương trình sẽ quản lý các trạng thái bàn cờ và thực hiện các thao tác cần thiết để AI chơi cờ vua một cách hiệu quả
Yêu cu:
Xây dựng các lớp đói tượng trên các phương thức:
Các hàm trạng thái, quản lý,
Cách thức di chuyển của các quân cờ
Xây dựng các thuật toán phù hợp dể có thê tối ưu bước đi tiếp theo
Phân tích hoạt động của chương trình:
1 Bắt đầu ván cờ
Khởi tạo bàn cờ với các nước đi cần thiết
2 AI thực hiện nước đi
Sinh nước đi hợp lệ
Tính toán nước đi tốt nhất bằng thuật toán MiniMax
Cập nhật bàn cờ
3 Kiểm tra trạng thái ván cờ
Kiểm tra ván cờ đã kết thúc hay chưa (hòa hoặc chiếu bí)
4 Lặp lại cho đến khi kết thúc
Trang 10CHƯƠNG 1 CƠ SỞ LÝ THUYẾT
1.1 Các lớp cần thiết
1.1.1 Lớp GameStates
- Chức năng: Quản lý trạng thái cờ vua
- Thuộc tính:
board: Mảng 2D chứa trạng thái của bàn cờ
whiteToMove: Xác định lượt chơi (trắng hoặc đen)
moveLog: Nhật ký lưu lại các nước đi
whiteKingLocation, blackKingLocation: Vị trí của Vua trắng và Vua đen
checkMate, staleMate: Xác định tình trạng chiếu hết hoặc hòa cờ
enpassantPossible: Ghi nhận ô mà nước bắt tốt qua đường có thể xảy ra
currentCastlingRight: Ghi nhận quyền nhập thành hiện tại
castleRightsLog: Lịch sử quyền nhập thành
- Phương thức:
makeMove: Thực hiện một nước đi
undoMove: Hoàn tác một nước đi
getValidMove: Trả về các nước đi hợp lệ
inCheck, squareUnderAttack: Xác định xem có bị chiếu hay không
getAllPossibleMoves: Tìm tất cả nước đi hợp lệ
updateCastleRights: Cập nhật quyền nhập thành
Các hàm phụ trợ như getPawnMoves, getRookMoves,
getKingMoves… để tính nước đi cho từng quân cờ
1.1.2 Lớp CastleRights
- Chức năng: Ghi nhận và quản lý quyền nhập thành (castling).
- Thuộc tính:
wks: Nhập thành cánh vua cho quân trắng
bks: Nhập thành cánh vua cho quân đen
wqs: Nhập thành cánh hậu cho quân trắng
bqs: Nhập thành cánh hậu cho quân đen
Phương thức:
init : Hàm khởi tạo lớp.
Trang 111.1.3 Lớp Move
- Chức năng: Định nghĩa một nước đi cụ thể trong bàn cờ
- Thuộc tính:
startRow, startCol: Vị trí bắt đầu của quân cờ.
endRow, endCol: Vị trí kết thúc của quân cờ.
pieceMoved: Quân cờ được di chuyển.
pieceCaptured: Quân cờ bị ăn (nếu có).
isPawnPromotion: Xác định nước phong cấp tốt.
isEnpassantMove: Xác định nước bắt tốt qua đường.
Trong đoạn mã, các đối tượng của lớp được tạo như sau:
1 Đối tượng GameState:
Được tạo khi gọi GameState() trong chương trình chính
Chức năng: Quản lý toàn bộ trạng thái của ván cờ.
python
game_state = GameState()
2 Đối tượng CastleRights:
Được khởi tạo bên trong lớp GameState để lưu thông tin nhập thành
Ví dụ trong init của GameState:
python
self.currentCastlingRight = CastleRights(True, True, True, True)
3 Đối tượng Move:
Được khởi tạo mỗi khi có nước đi được tạo ra
Ví dụ trong các hàm như getPawnMoves, getRookMoves:python
moves.append(Move((r, c), (r - 1, c), self.board))
Trang 12CHƯƠNG 2 THIẾT KẾ CÁC LỚP ĐỐI TƯỢNG
Chương trình bao gồm 4 lớp đối tượng: GameState, Move, CastleRights
2.1 Lớp GameState
Mục đích: Lớp này sẽ quản lý toàn bộ trạng thái của ván cờ, bao gồm bảng cờ, lượt đi của người chơi, các nước đi đã thực hiện, và trạng thái của trò chơi (ví dụ: chiếu hết, hòa cờ)
o undoMove(): Hoàn tác một nước đi trước đó
o getValidMoves(): Trả về các nước đi hợp lệ cho quân hiện tại
o isCheck(): Kiểm tra nếu có tình trạng chiếu
o getGameStatus(): Trả về trạng thái hiện tại của trò chơi (chiếu hết, hòa cờ, hoặc tiếp tục)
Trang 132.2 Lớp Move
Mục đích: Lớp này đại diện cho một nước đi cụ thể trong trò chơi, bao gồm
vị trí bắt đầu, vị trí kết thúc, quân cờ được di chuyển và các thuộc tính liên quan đến nước đi đó (như phong cấp, bắt tốt qua đường)
Thuộc tính:
o startRow, startCol: Vị trí bắt đầu của quân cờ
o endRow, endCol: Vị trí kết thúc của quân cờ
o pieceMoved: Quân cờ bị di chuyển (ví dụ: "P" cho tốt, "R" cho xe)
o pieceCaptured: Quân cờ bị bắt (nếu có)
o isPawnPromotion: Boolean xác định nếu quân tốt phong cấp
o isEnpassantMove: Boolean xác định nếu đây là nước đi bắt tốt quađường
Trang 14o wks: Boolean xác định quyền nhập thành cánh vua cho quân trắng.
o bks: Boolean xác định quyền nhập thành cánh vua cho quân đen
o wqs: Boolean xác định quyền nhập thành cánh hậu cho quân trắng
Trang 15 Phương thức
o init : Khởi tạo các quyền nhập thành mặc định
o str : Trả về chuỗi mô tả quyền nhập thành
Trang 16CHƯƠNG 3 THIẾT KẾ AI 3.1 Mục tiêu của AI
- AI sẽ tính toán và chọn nước đi tốt nhất từ trạng thái hiện tại của bàn cờ để tăng khả năng thắng trận đấu
3.2 Phương pháp và các thuật toán
3.2.1 Thuật toán MinMax
Minimax giả định cả hai bên đều chơi tối ưu Người chơi (AI) sẽ cố gắng tối đa hóa lợi ích của mình (Max), trong khi đối thủ sẽ giảm thiểu lợi ích
đó (Min).
AI thực hiện các nước đi giả lập
Tính toán giá trị của bàn cờ tại độ sâu nhất định dựa trên hàm đánh giá (scoring function)
Lựa chọn nước đi mang lại điểm số tốt nhất
Trang 173.2.2 Thuật toán Negamax
Negamax là phiên bản tối ưu của Minimax Thay vì tính toán riêng biệt cho Max và Min, nó dùng một hàm duy nhất với giá trị điểm số được phủ định (-score)
Lợi ích:
Giảm bớt mã nguồn cần viết
Hiệu suất tốt hơn khi triển khai
3.2.3 Cắt tỉa Alpha - Beta
Vấn đề: Minimax và Negamax duyệt tất cả các nước đi có thể dẫn đến tính
toán chậm khi không gian trạng thái quá lớn
Cải tiến: Cắt tỉa Alpha-Beta loại bỏ các nhánh không cần thiết trong cây trò
chơi mà không làm ảnh hưởng kết quả cuối cùng
Alpha: Giá trị tốt nhất mà người chơi Max có thể đảm bảo.
Beta: Giá trị tốt nhất mà người chơi Min có thể đảm bảo.
Trang 18giờ chọn nhánh này), thì dừng xét nhánh đó.
3.3 Hàm đánh giá bàn cờ
3.3.1 Đánh giá dựa trên quân cờ
Mỗi quân cờ trên bàn cờ được gán một điểm số cố định đại diện cho giá trị của nó:
Vua (K) 0 Không thể định giá
Hậu (Q) 10 Quân cờ mạnh nhất
Xe (R) 5 Quan trọng trong endgame
Tượng (B) 3 Đi trên đường chéo
Mã (N) 3 Linh hoạt ở trung tâm
Tốt (p) 1 Giá trị nhỏ nhưng quan trọng
Ví dụ:
Trắng có 1 Hậu, 2 Xe và 5 Tốt → 10 + 5*2 + 1*5 = 25
Trang 19Tổng điểm: 25 - 15 = +10 → Trắng chiếm ưu thế.
3.3.2 Đánh giá vị trí dựa trên vị trí quân cờ
Quân cờ không chỉ có giá trị về mặt "vật chất" mà còn phụ thuộc vào vị trí của nó trên bàn cờ:
Quân cờ ở trung tâm bàn cờ thường mạnh hơn
Quân cờ ở biên hoặc góc ít linh hoạt hơn
Mã (Knight): Thường mạnh ở trung tâm bàn cờ.
Tượng (Bishop): Tốt hơn khi kiểm soát đường chéo dài.
Hàm đánh giá cuối cùng sẽ tổng hợp tất cả các yếu tố trên:
Score=Material Score+Positional Score+Other Factors
Trang 21CHƯƠNG 4: CÀI ĐẶT CÁC LỚP VÀ THUẬT TOÁN 4.1 Lớp GameState
Trang 22self.endCol = endSq[1]
self.pieceMoved = board[self.startRow][self.startCol]
self.pieceCaptured = board[self.endRow][self.endCol]
#kiem tra tot phong cap
self.isPawnPromotion = (self.pieceMoved == 'wp' and self.endRow == 0) or ( self.pieceMoved == 'bp' and self.endRow == 7)
# Trả về ký hiệu nước đi (ví dụ: e2e4)
return self.getRankFile(self.startRow, self.startCol) +
Trang 234.4 Thuật toán Minmax
def findBestMoveMinMaxNoRecursion(gs, validMoves): turnMultiplier = 1 if gs.whiteToMove else -1
4.5 Thuật toán Megamax
def findMoveNegaMax(gs, validMoves, depth, turnMultiplier): global nextMove, counter
counter += 1
if depth == 0:
return turnMultiplier * scoreBoard(gs)
Trang 244.6 Thuật toán cắt tỉa Alpha – Beta
def findMoveNegaMaxAlphaBeta(gs, validMoves, depth, alpha, beta, turnMultiplier):
global nextMove, counter
Trang 25from Chess import SmartMoveFinder
from Chess import ChessEngine
# Kích thước cửa sổ và cấu hình bàn cờ
IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece +
sqSelected = None # Ô vuông được chọn
playerClicks = [] # Theo dõi lần nhấp chuột
Trang 26if e.type == p.QUIT:
running = False
# Điều khiển chuột
elif e.type == p.MOUSEBUTTONDOWN:
if not gameOver and humanTurn:
location = p.mouse.get_pos()
col = location[0] // SQ_SIZE
row = location[1] // SQ_SIZE
if sqSelected == (row, col):
elif e.type == p.KEYDOWN:
if e.key == p.K_z: # Hoàn tác nước đi
Trang 27#Tạo bước đi AI
if not gameOver and not humanTurn:
AIMove = SmartMoveFinder.findBestMoveMinMaxNoRecursion(gs, validMoves)
if AIMove is None:
AIMove = SmartMoveFinder.findRandomMove(validMoves) gs.makeMove(AIMove)
winner = 'Black' if gs.whiteToMove else 'White'
drawText(screen, f'{winner} wins by checkmate')
def highlightSquares(screen, gs, validMoves, sqSelected):
if sqSelected is not None:
Trang 28for move in validMoves:
if move.startRow == r and move.startCol == c:
screen.blit(s, (move.endCol * SQ_SIZE, move.endRow * SQ_SIZE))def drawGameState(screen, gs, validMoves, sqSelected):
def animateMove(move, screen, board, clock):
colors = [p.Color("white"), p.Color("gray")]
coords = []
dR = move.endRow - move.startRow
dC = move.endCol - move.startCol
framesPerSquare = 10
frameCount = (abs(dR) + abs(dC)) * framesPerSquare
for frame in range(frameCount + 1):
r, c = (move.startRow + dR * frame / frameCount, move.startCol + dC * frame / frameCount)
drawBoard(screen)
drawPieces(screen, board)
color = colors[(move.endRow + move.endCol) % 2]
endSquare = p.Rect(move.endCol * SQ_SIZE, move.endRow * SQ_SIZE,
Trang 29p.draw.rect(screen, color, endSquare)
if move.pieceCaptured != ' ':
screen.blit(IMAGES[move.pieceCaptured], endSquare) p.display.flip()
clock.tick(60)
def drawText(screen, text):
font = p.font.SysFont("Helvetica", 32, True, False)
textObject = font.render(text, 0, p.Color('Gray'))
textLocation = p.Rect(0, 0, WIDTH, HEIGHT).move(WIDTH / 2 - textObject.get_width() / 2, HEIGHT / 2 - textObject.get_height() / 2) screen.blit(textObject, textLocation)
textObject = font.render(text, 0, p.Color("Black"))
screen.blit(textObject, textLocation.move(2, 2))
if name == ' main ':
main()
Trang 30KẾT LUẬN VÀ KIẾN NGHỊ
1 Kết luận
- Nhóm đã giải quyết được những gì theo yêu cầu của bài tập lớn
- Những điểm gì nhóm chưa làm được
- Hướng phát triển
2 Kiến nghị
Trang 31TÀI LIỆU THAM KHẢO
[1] Phạm Văn Ất, Lập trình Hướng đối tượng với C++, Nhà xuất bản KHKT,2015
[2] Allan B Downey , Think Python