Oh tôi thích những trò chơi này!
Vì vậy, điều đầu tiên trước tiên, để máy tính chơi trò chơi, nó cần:
- một cấu trúc để làm việc với
- luật chơi
- một điều kiện để giành chiến thắng
Hãy giải quyết từng mảnh một.
Kết cấu
Vì bảng là một lưới 8 x 8 (nhưng có thể dễ dàng chia tỷ lệ) và mỗi không gian lưới chỉ có thể tồn tại ở một trong năm trạng thái, hãy xác định các trạng thái đó:
[EMPTY, WHITE_PIECE, BLACK_PIECE, WHITE_PIECE_PROMOTED, BLACK_PIECE_PROMOTED]
Tôn trọng ENUM'd để:
[0, 1, 2, 3, 4]
Bây giờ chúng tôi biết mỗi không gian có thể là gì, chúng tôi cần một số cách để đại diện cho tất cả các không gian, hoặc bảng nếu bạn muốn. Hầu như mọi ngôn ngữ mạnh sẽ hỗ trợ một mảng đa chiều (một mảng trong đó mỗi phần tử là một mảng giữ dữ liệu). Vì vậy, lấy mã chùng sau đây để xác định mảng của chúng tôi:
BOARD_ARRAY = array(8, 8)
Điều này sẽ cung cấp cho chúng ta một mảng 8 x 8 trong đó chúng ta có thể lưu trữ các số nguyên (enum của chúng ta từ trước):
(
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
)
Bây giờ bạn có thể thấy làm thế nào mà nó bắt đầu trông giống như một bảng! Tôi chưa bao giờ chơi biến thể được đề cập trong video youtube nhưng có vẻ như bắt đầu với 2 hàng mảnh trắng một hàng từ dưới lên và 2 hàng mảnh màu đen một hàng từ trên xuống. Điều đó có nghĩa là khi chúng tôi bắt đầu một trò chơi, mảng của chúng tôi sẽ trông như thế này:
(
[0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0],
)
(Ghi nhớ 2 đại diện cho 'BLACK_PIECE' và 1 đại diện cho 'WHITE_PIECE')
Vì vậy, bây giờ máy tính có một cấu trúc để làm việc. Bước 1 hoàn tất!
Quy tắc
Hãy tưởng tượng bạn có một bảng thực tế được thiết lập trước mặt bạn, chơi với một người chơi chính. Nếu bạn cố gắng di chuyển một trong những mảnh của anh ấy, bạn sẽ bị tát tay. Nếu bạn cố gắng di chuyển một mảnh theo cách bạn không thể, bạn sẽ bị tát tay. Nếu bạn đã cố gắng gian lận tốt ... bạn sẽ có được ý tưởng. Nhưng vấn đề là, máy tính thì không. Vì vậy, đó là công việc của chúng tôi để cung cấp các quy tắc nghiêm ngặt để chơi trong.
Chúng ta cần tạo ra một cách để kiểm tra xem bất kỳ động thái nhất định nào là 'hợp pháp'. Điều đó có nghĩa là trước tiên chúng ta cần một số cách để thể hiện một 'di chuyển'. Một cách sẽ là sử dụng các vị trí mảng; Ví dụ: để di chuyển một mảnh từ [0, 0] sang [0, 1], chúng ta có thể tạo một chức năng sẽ cập nhật bảng cho di chuyển đó. Vì vậy, trở lại chậm chạp:
MY_MOVE = array( [0, 0], [0, 1] )
Trên đây đại diện cho một mảnh, di chuyển một không gian xuống từ góc trên cùng của bảng (giả sử 0, 0 là góc trên cùng bên trái). Bạn cũng có thể nhận thấy tôi đã chọn sử dụng một mảng nhiều chiều cho việc di chuyển. Điều này là do về mặt lý thuyết có thể di chuyển một số lượng lớn thời gian trong một lượt (đối với các phần khác 'nhảy'). Vì vậy, hãy giả vờ ở 0, 1 có một mảnh đối thủ, có nghĩa là chúng ta sẽ hạ cánh ở 0, 2:
MY_MOVE = array( [0, 0], [0, 2] )
Khá đơn giản nhỉ. Chương trình nên hiểu rằng nếu chúng ta bỏ qua một khoảng trống, chúng ta sẽ nhảy một đoạn khác (hoặc nếu không thì đó là một hành động bất hợp pháp và sẽ gây ra lỗi). Bây giờ hãy nhảy hai mảnh:
MY_MOVE = array ( [0, 0], [0, 2], [0, 4] )
Điều này cho chúng ta một cách để mô tả bất kỳ di chuyển trên bảng. Yay! Bây giờ vì tôi không hiểu đầy đủ các quy tắc của trò chơi chính xác trong câu hỏi (mặc dù tôi đã chơi một chút cờ đam Canada trong ngày của tôi), tính hợp pháp di chuyển chính xác sẽ cần được xác định bởi bạn. Một dòng chảy tốt cho đến thời điểm này sẽ như thế nào:
FUNCTION_FIND_ALL_LEGAL_MOVES( MY_BOARD ) Returns: array ALL_LEGAL_MOVES
FUNCTION_FIND_BEST_MOVE( MY_BOARD, ALL_LEGAL_MOVES ) Returns: array MY_MOVE
FUNCTION_DO_MOVE( MY_BOARD, MY_MOVE ) Throws: error ILLEGAL_MOVE Updates: MY_BOARD
repeat from start for each turn
Các giả định ở trên giả định bạn có thể quay vòng qua từng mảnh để tìm tất cả các động thái hợp pháp của mình, sau đó đưa ra một bộ sưu tập tất cả các động thái hợp pháp bằng cách nào đó chọn cách tốt nhất (chiến lược ở đây). Việc di chuyển sau đó được áp dụng cho bảng hoặc ném lỗi. Sau đó, người chơi tiếp theo lần lượt. Vì vậy, chúng ta có một AI biết chơi! Vui sướng! Tiến lên.
Chiến thắng
Trò chơi đơn giản là tuyệt vời, bởi vì chiến thắng được xác định bởi một trạng thái rất đơn giản. Không có mảnh trắng trên bảng? Tôi đoán bạn đã thắng! Điều này được thực hiện ở bước 2 khi chúng tôi chọn nước đi tốt nhất để đưa chúng tôi đến gần hơn với điều kiện chiến thắng.
Để tạo ra một số AI rất thông minh, bạn có thể giữ một cơ sở dữ liệu lưu trữ mọi bảng có thể dưới dạng trạng thái, với mọi di chuyển có thể từ mọi trạng thái có thể, để tìm chuỗi hướng tới chiến thắng.
Bạn cũng có thể tạo các chiến lược, như: nếu có một mảnh SILL được nhảy, hãy lưu mảnh đó hoặc nếu một mảnh có thể nhảy nhiều hơn một mảnh khác thực hiện bước nhảy đó.
Điều đó sẽ cung cấp cho bạn một điểm nhảy tốt, nó chỉ là một phương pháp của khả năng không giới hạn theo nghĩa đen. Về mặt lý thuyết, bạn có thể chế tạo một con robot khổng lồ để vẽ bằng bút màu sau đó tiến hành phân tích quang phổ trên bản vẽ để chọn di chuyển ... nhưng nó sẽ không hoạt động rất tốt hoặc nhanh. Cách này đã hoạt động trong quá khứ, và hoạt động tốt (: Hy vọng rằng sẽ giúp!
Một vài từ về thực hiện
Cờ đam là những gì được gọi là một trò chơi 'giải quyết', trong đó chúng ta có thể tính toán mọi di chuyển mà không có ẩn số. Nhưng đó là một loạt các động thái! Vì vậy, không có cách nào để làm tất cả bằng tay ... nếu chỉ có một số ... ồ đúng chúng tôi là lập trình viên. bơm nắm tay
SQL là một công cụ tuyệt vời để lưu trữ tất cả những động thái dường như vô tận này. Đối với những người không có kinh nghiệm với SQL, myQuery là một máy chủ SQL mã nguồn mở và miễn phí (khá dễ sử dụng). SQL được sử dụng để quản lý cơ sở dữ liệu, giống như một bảng tính trên steroid. Nó cũng có thể chứa một lượng lớn dữ liệu nghiêm trọng và làm việc với nó rất nhanh.
Vậy làm thế nào chúng ta có thể sử dụng điều này? Vì chúng tôi biết rằng nếu bảng ở trạng thái chính xác (mỗi mảnh ở một vị trí nhất định), chúng tôi có thể tính toán tất cả các di chuyển có sẵn và lưu chúng. Ví dụ:
+Board State+ +All Possible Moves+ +Best Move+
([0,0,1,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([7,6],[7,7])
([0,0,2,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([5,5],[5,4])
([0,0,1,3,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([4,4],[4,3])
etc...
Vì vậy, khi máy tính cần di chuyển, nó chỉ cần tìm trạng thái bảng (được lưu dưới dạng khóa chính) trong cơ sở dữ liệu và có thể chọn nước đi tốt nhất (nên không thể đánh bại) hoặc một trong những động tác khác để thân thiện hơn AI.
Tuyệt vời bây giờ hãy xây dựng cơ sở dữ liệu này. Đầu tiên chúng ta cần tính toán mọi trạng thái của hội đồng. Điều này có thể được thực hiện với một vòng lặp lớn khó chịu lớn, nếu ai đó muốn dành thời gian và làm việc đó sẽ rất tuyệt vời. Nhìn vào mảng là một số lớn, sau đó đếm ngược lên, ngoại trừ trong cơ sở 5 (0, 1, 2, 3, 4) và với điều kiện mỗi người chơi chỉ có thể có 16 quân cờ.
Tại thời điểm này, chúng ta nên lưu trữ mọi trạng thái bảng và có thể tính toán tất cả các di chuyển có thể.
Một khi tất cả các di chuyển có thể được tính toán là phần thú vị của việc tìm đường di chuyển tốt nhất có thể. Đây là lúc kiến thức của tôi bắt đầu thiếu hụt, và những thứ như Minimax hay A * bắt đầu phát huy tác dụng. Xin lỗi tôi không thể giúp đỡ thêm về điều đó: /