Chào mọi người. Lời đầu tiên chúc mừng năm mới 2017. Trong năm nay, tôi chân thành hy vọng thành công cho bạn, cho bạn bè và người thân của bạn. Bài viết này sẽ thảo luận về cách python cho phép chúng ta hiện thực hóa ý tưởng của mình thành hiện thực nhanh chóng bằng cách lấy cờ vua làm ví dụ
Đến đây, tất cả chúng ta đều yêu thích trò chơi cờ vua. Đây là một trò chơi đẹp với rất nhiều công việc trí óc cần thiết. Mở đầu, Trò chơi giữa và Trò chơi kết thúc luôn khó để thành thạo. Trong thế kỷ 21, chúng ta có những cỗ máy cờ vua mạnh mẽ có thể cạnh tranh với những kỳ thủ giỏi nhất thế giới. Bạn đã bao giờ nghĩ trò chơi cờ vua được mô phỏng trên máy tính như thế nào chưa?. Các mảnh được nhìn bên dưới như thế nào và sự trừu tượng nào tính toán mọi thứ. Vẻ đẹp của toán học và ngôn ngữ lập trình như Python giúp dễ dàng thực hiện bất kỳ vấn đề nào theo cách tinh tế. Đây không phải là một hướng dẫn để xây dựng một động cơ cờ vua. Nhưng đây là khối xây dựng của bất kỳ trò chơi cờ vua nào
Mã cho hướng dẫn này luôn có sẵn tại liên kết này
https. //github. com/narenaryan/ChessMoves
Khách quan
Phương châm chính của bài viết này là thiết kế một chương trình thực sự lấy đầu vào là ký hiệu cờ vua và trả về tất cả các nước đi có thể có cho một quân cờ nhất định. Ví dụ: “Tất cả các nước đi có thể có của một Hiệp sĩ đóng quân trên “g2” là gì. Nó sẽ trả lại tất cả các di chuyển có thể từ vị trí đó
- e1
- e3
- f4
- h4
Đối với điều này, chúng ta cần
- Bàn Cờ
- Miếng
Giới thiệu
Bàn cờ là một ma trận 8 * 8. Nó có ký hiệu từ A-H và 1-8. Ở đây [1-8] là hàng và [A-H] là cột. Chúng tôi luôn đề cập đến vị trí của một quân cờ bằng ký hiệu cờ vua của nó. Ví dụ “e4” nghĩa là hàng thứ 4, cột thứ 5 của ma trận 8*8
Trong Python, chúng ta có thể tạo một bàn cờ với một dòng
>>> chessBoard = [[1] * 8 for i in xrange[8]]
Điều này thực sự tạo ra một danh sách các danh sách có chính xác 8 phần tử như thế này
>>> print chessBoard [[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]
Bây giờ chúng ta có một bàn cờ. Hãy để chúng tôi bắt đầu mô hình hóa các quân cờ và di chuyển của chúng
Trước khi đi sâu vào từng phần, chúng ta cần suy nghĩ về điều gì đó. Như tôi đã nói, các hàng và cột nằm trong ký hiệu 1-8 & A-H chứ không phải ký hiệu [0-n] của ma trận. Vì vậy, chúng ta nên viết một công thức chuyển đổi để dịch ký hiệu cờ sang ký hiệu chỉ số ma trận thực tế
>>> chess_map_from_alpha_to_index = { "a" : 0, "b" : 1, "c" : 2, "d" : 3, "e" : 4, "f" : 5, "g" : 6, "h" : 7 }
>>> chess_map_from_index_to_alpha = { 0: "a", 1: "b", 2: "c", 3: "d", 4: "e", 5: "f", 6: "g", 7: "h" }
Tôi ở đây thảo luận về 4 quân cờ quan trọng. Bạn có thể triển khai cho những người khác theo cách tương tự
- Hiệp sĩ [Ngựa]
- Xe [Voi]
- Giám mục [Lạc đà]
- Nữ hoàng
Tôi đoán tất cả đều biết quy luật chuyển động của từng quân cờ. Nếu không xin vui lòng tham khảo đoạn giới thiệu ngắn này.
Hiệp sỹ
Bây giờ chúng ta hãy bắt đầu với Hiệp sĩ. Chúng ta đều biết Hiệp sĩ di chuyển theo đường hình chữ L theo mọi hướng có thể. Đầu tiên, chúng ta có thể cho rằng một Hiệp sĩ ở trung tâm. Sau đó, chỉ cần chọn tất cả các vị trí có thể có của ma trận nơi hiệp sĩ có thể di chuyển đến. Chúng ta hãy nghĩ rằng vị trí ban đầu của hiệp sĩ là ở D4. Sau đó, sơ đồ ma trận sẽ như thế này
Trình chiếu này yêu cầu JavaScript
Điều đó có nghĩa là tọa độ của các nước đi lân cận của một hiệp sĩ có thể dễ dàng đưa vào một vài phương trình toán học. Bằng cách quan sát cẩn thận, chúng ta có thể biết rằng tất cả các nước đi đều ở dạng này.
Tất cả các tính toán dưới đây cho chỉ số đã cho cung cấp cho các tọa độ lân cận. Nếu i là chỉ mục hàng và j là chỉ mục cột, thì
- [i + 2] , [j – 1]
- [i – 1], [j + 2]
- [i – 2], [j – 1]
- [i + 2], [j + 1]
- [i + 1], [j + 2]
- [i – 1], [j + 1]
- [i + 1], [j – 1]
- [i – 2], [j + 1]
Bây giờ nếu chúng ta viết một hàm python với các chi tiết đã cho
def getKnightMoves[pos, chessBoard]: """ A function[positionString, board] that returns the all possible moves of a knight stood on a given position """ column, row = list[pos.strip[].lower[]] row = int[row] - 1 column = chess_map_from_alpha_to_index[column] i,j = row, column solutionMoves = [] try: temp = chessBoard[i + 1][j - 2] solutionMoves.append[[i + 1, j - 2]] except: pass try: temp = chessBoard[i + 2][j - 1] solutionMoves.append[[i + 2, j - 1]] except: pass try: temp = chessBoard[i + 2][j + 1] solutionMoves.append[[i + 2, j + 1]] except: pass try: temp = chessBoard[i + 1][j + 2] solutionMoves.append[[i + 1, j + 2]] except: pass try: temp = chessBoard[i - 1][j + 2] solutionMoves.append[[i - 1, j + 2]] except: pass try: temp = chessBoard[i - 2][j + 1] solutionMoves.append[[i - 2, j + 1]] except: pass try: temp = chessBoard[i - 2][j - 1] solutionMoves.append[[i - 2, j - 1]] except: pass try: temp = chessBoard[i - 1][j - 2] solutionMoves.append[[i - 1, j - 2]] except: pass # Filter all negative values temp = [i for i in solutionMoves if i[0] >=0 and i[1] >=0] allPossibleMoves = ["".join[[chess_map_from_index_to_alpha[i[1]], str[i[0] + 1]]] for i in temp] allPossibleMoves.sort[] return allPossibleMoves
Chúng ta cần chuyển chuỗi vị trí và bàn cờ cho hàm này và nó trả về tất cả các nước đi có thể có dưới dạng một chuỗi
>>> print getKnightMoves["D4", chessBoard] [b3, b5, c2, c6, e2, e6, f3, f5]
Đầu ra được cung cấp bởi chức năng này có thể được cung cấp cho bất kỳ công cụ GUI nào để hiển thị tất cả các bước di chuyển hợp lệ có thể
tân binh
Xe di chuyển theo đường thẳng. Nó có nghĩa là nó có thể di chuyển theo chiều ngang hoặc chiều dọc. Logic cho chuyển động khác với Hiệp sĩ. Vì vậy, chúng ta cần quan sát những yếu tố nào chúng ta cần thu thập để mô hình hóa chuyển động của quân Xe
Trong thuật ngữ cờ vua, Xe có thể di chuyển trên Xếp hạng [hàng] và Tệp [cột]. Xe được đặt ở “E6″ có thể di chuyển qua Hàng 6 và hàng E. Vì vậy, tất cả các di chuyển có thể là
- E1, E2, E3, E4, E5, E7, E8, A6, B6, C6, D6, F6, G6, H6
Bây giờ để mô hình hóa nó theo chương trình, chúng tôi lấy các điểm cuối làm tham chiếu và bằng cách loại trừ chỉ mục hiện có, chúng tôi có thể tính toán tất cả các điểm có thể có trong ma trận. Vì vậy, hãy để chúng tôi định nghĩa một chức năng gọi là getRookMoves[]
def getRookMoves[pos, chessBoard]: column, row = list[pos.strip[].lower[]] row = int[row] - 1 column = chess_map_from_alpha_to_index[column] i,j = row, column solutionMoves = [] # Compute the moves in Rank for j in xrange[8]: if j != column: solutionMoves.append[[row, j]] # Compute the moves in File for i in xrange[8]: if i != row: solutionMoves.append[[i, column]] solutionMoves = ["".join[[chess_map_from_index_to_alpha[i[1]], str[i[0] + 1]]] for i in solutionMoves] solutionMoves.sort[] return solutionMoves
>>> getRookMoves["E6", chessBoard] ['a6', 'b6', 'c6', 'd6', 'e1', 'e2', 'e3', 'e4', 'e5', 'e7', 'e8', 'f6', 'g6', 'h6']
Vì vậy, logic là đơn giản. Chúng tôi chỉ lặp lại từ chỉ mục bắt đầu đến chỉ mục cuối cùng của cả hàng và cột hiện đang đặt xe
Để làm cho chương trình này có tính tương tác cao hơn, tôi sử dụng dòng lệnh args để lấy đầu vào để chỉ định loại quân cờ và vị trí của nó. Sau đó, tất cả các di chuyển có thể sẽ được trả lại. Chúng tôi sẽ sử dụng thư viện python có sẵn có tên là argparse để tạo ứng dụng dòng lệnh. Chúng tôi sẽ in chuỗi JSON cho ứng dụng khác để sử dụng nó
________số 8_______
Đầu ra này trông như thế này
Trình chiếu này yêu cầu JavaScript
Bạn cũng có thể xem tùy chọn trợ giúp nếu bạn không biết phải làm gì. Sử dụng tùy chọn -h hoặc –help với chương trình trên dòng lệnh
Vì vậy, ở đây với mục đích minh họa, tôi đã sử dụng Mã và Xe. Theo cách tương tự, chúng ta cũng có thể tính toán các hàm cho Pawn, King, Queen và Bishop. Rằng tôi đang rời đi như một bài tập cho bạn. Mã cho kịch bản và hình ảnh tham khảo ở đây
https. //github. com/narenaryan/ChessMoves
Phần kết luận
Đây là bước khởi đầu cho bất kỳ ván cờ nào. Từ đây bạn sẽ xây dựng logic và thuật toán cho lối chơi. Hy vọng bạn thích điều này và Chúc mừng năm mới một lần nữa