2012-04-27 27 views
7

Một số cách có thể thể hiện một bảng bitboard cờ vua trong Clojure (/ Java) là gì?Tôi nên đại diện cho một bitboard cờ vua bằng clojure như thế nào?

http://pages.cs.wisc.edu/~psilord/blog/data/chess-pages/rep.html

tôi cần để có thể truy cập vào các bit riêng lẻ và cũng có thể thực hiện các hoạt động trên bit.

Tôi đã nghĩ đến việc sử dụng java.lang.Long nhưng điều này gây ra sự cố với 1x10^63 do biển báo. Tôi cũng không chắc chắn làm thế nào tôi sẽ truy cập bit tại một chỉ số cụ thể?

Tôi cũng đã xem BitSet, nhưng tôi cần một độ dài cố định lý tưởng.

+0

'cách tốt nhất' - hiển thị mã của bạn trên http://codereview.stackexchange.com/; 'Làm thế nào tôi' - không xây dựng. Bạn có mã nào? Yêu cầu của bạn là gì? Bạn bị mắc kẹt ở đâu? – sehe

+0

@sehe Tôi đã thử sử dụng java.lang.Long nhưng gặp sự cố với parseLong() và "10000 ... x63" - 1x10^63) Ngoài ra, tôi không chắc chắn liệu mình có thể truy cập bit tại một địa chỉ cụ thể hay không mục lục? Tôi đang yêu cầu các đề xuất và ý tưởng hợp lý hóa, không nhất thiết là tuyệt đối. – DanS

+0

Bạn nên chỉnh sửa các chi tiết này vào câu hỏi của mình. – sehe

Trả lời

7

Không có lý do gì bạn không thể sử dụng một thời gian dài. Vấn đề, như bạn đã lưu ý, đó là thời gian dài của java (và do đó clojure) được ký, chỉ cho phép 63 bit cho các số dương

Java, cho phép tràn số học mà không có lỗi. Theo mặc định, Clojure không cho phép tràn số học mà không có lỗi (xem *unchecked-math* cờ). Nó cho biết thêm kiểm tra xung quanh hoạt động số học và phôi, vì vậy, ví dụ, (byte 128) sẽ gây ra một ngoại lệ. Kể từ clojure v1.3.0 có chức năng như (unchecked-byte) tương đương với các chức năng java ....

(unchecked-byte 128) 
;=> -128 ; 2s-complement of 10000000 
(unchecked-byte 2r10000001) 
;=> -127 ; 2s-complement of 10000001 

Có một bè toàn bộ unchecked-* hoạt động có sẵn (see clojuredocs).

Nếu bạn sử dụng một thời gian dài và các hoạt động unchecked-* bạn chủ yếu ở đó, và sau đó bạn có thể sử dụng các hoạt động bit-* để kiểm tra/kiểm tra bit.

Cuối cùng lưu trữ bàn cờ của bạn trong một nguyên tử có ý nghĩa, và sau đó bạn nên cập nhật nó với (swap! chessboard fn args)

(cuộc gọi được cập nhật 15/02/13 với swap hơi nhiều thành ngữ!)

ví dụ

(inc Long/MAX_VALUE) ; java.lang.ArithmeticException 

(unchecked-inc Long/MAX_VALUE) ; wraps. 
-9223372036854775808 

(def chessboard (atom 0)) 
@chessboard 
;=> 0 
(bit-test @chessboard 1) 
;=> false 
(swap! chessboard bit-flip 1) 
;=> 2 
(bit-test @chessboard 1) 
;=> true 
@chessboard 
;=> 2 
(reset! chessboard 0) 
;=> 0 
(swap! chessboard bit-flip 63) 
;=> -9223372036854775808 
(bit-test @chessboard 63) 
;=> true 
+0

Cảm ơn, rất hữu ích – DanS

+0

Hmmm, điều này nên được trong lõi nhưng đối với một số lý do tôi nhận được: 'user => (không được kiểm tra-byte 2r100101) java.lang.Exception: Không thể giải quyết biểu tượng: bỏ chọn byte trong ngữ cảnh này (NO_SOURCE_FILE : 4) ' – DanS

+0

Nevermind, tôi đã ở trên 1.2.1. Bây giờ sử dụng 1.4.0 và nó được công nhận ... – DanS

1
=> (def chessboard (byte-array 8)) 
#'user/chessboard 

=> (vec chessboard) 
[0 0 0 0 0 0 0 0] 

=> (for [row (range 8)] (aset-byte chessboard row (rand-int 8))) 
(3 0 6 6 2 3 6 7) 

=> (bigint chessboard) 
216179404987106823N 

=> (defn bigint-to-array 
[bi] 
(.toByteArray (biginteger bi))) 

=> (vec (bigint-to-array 216179404987106823N)) 
[3 0 6 6 2 3 6 7] 

Clojure hỗ trợ hầu hết các chức năng bạn cần theo cách này. Giống như tất cả các số clojure, clojure.lang.BigInt hỗ trợ các hoạt động nhị phân (bit-và vv). Trên một mảng byte, bạn có thể sử dụng tất cả các phương thức từ java.util.Arrays (tìm kiếm, điền, sắp xếp).

Hãy quan tâm rằng bigint fn coerces thành clojure.lang.BigInt và biginteger fn đồng nghĩa với java.math.BigInteger. Nếu bạn muốn sử dụng các phương thức của java.math.BigInteger, bạn cần phải ép buộc mảng bigint hoặc byte của bạn thông qua biginteger.

+0

Cảm ơn bạn, không chắc chắn điều này sẽ so sánh hiệu suất như thế nào so với sử dụng lâu dài? Tôi tưởng tượng nó chậm hơn. – DanS

+1

Clo gợi ý không hỗ trợ thao tác bit. người dùng => (bit-và (bigint 5) (bigint 3)) IllegalArgumentException bit hoạt động không được hỗ trợ cho: class clojure.lang.BigInt clojure.lang.Numbers.bitOpsCast (Numbers.java:1008) – RedDeckWins

Các vấn đề liên quan