2012-04-27 54 views
7

在Clojure(/ Java)中代表棋盤的一些可能的方式是什麼?我應該如何在clojure中代表象棋棋盤?

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

我需要能夠訪問各個位,並執行按位運算。

我想過使用java.lang.Long,但由於標牌,這導致1x10^63的問題。我也不確定我將如何訪問特定索引處的位?

我也看了一下BitSet,但是我需要一個固定的長度。

+0

'最好的方式' - 在http://codereview.stackexchange.com/上顯示您的代碼; '我應該如何' - 不具有建設性。你有什麼代碼?你有什麼要求?你卡在哪裏? – sehe 2012-04-27 08:27:27

+0

@sehe我試過使用java.lang.Long但遇到了parseLong()和「10000 ... x63」 - 1x10^63的問題)另外,我不確定是否可以訪問特定位指數? 我要求合理化的建議和想法,不一定是絕對的。 – DanS 2012-04-27 09:10:58

+0

你應該在你的問題中編輯這些細節。 – sehe 2012-04-27 09:12:18

回答

7

沒有理由不能使用直長。正如您所指出的那樣,問題在於Java的(因此clojure的)long是有符號的,只允許正數的63位。

默認情況下,Java允許算術溢出而沒有錯誤。默認情況下,Clojure不允許算術溢出而沒有錯誤(參見*unchecked-math*標誌)。它增加了對算術運算和強制轉換的額外檢查,因此,例如,(byte 128)將導致異常。由於Clojure的V1.3.0有像(unchecked-byte)這相當於Java功能的功能....

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

有可用unchecked-*操作(see clojuredocs)的整個筏。

如果你使用直線長和unchecked-*的操作,你大部分都在那裏,然後你可以使用bit-*操作來旋轉/檢查位。

最後儲存您的棋盤中的原子是有道理的,然後你用(swap! chessboard fn args)

(更新15/02/13略有更地道掉!呼叫)更新

例如

(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

非常感謝有幫助 – DanS 2012-04-27 14:21:54

+0

嗯,這應該是在覈心,但由於某些原因,我得到: 'user =>(未檢查字節2r100101) java.lang.Exception:無法解析符號:在此上下文中未檢查字節(NO_SOURCE_FILE :4)' – DanS 2012-04-27 20:28:29

+0

沒關係,我在1.2.1上。現在使用1.4.0,它被認可... – DanS 2012-04-27 20:43:48

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支持您需要的大多數功能。像所有clojure數字一樣,clojure.lang.BigInt支持二進制操作(比特等)。在字節數組上,您可以使用java.util.Arrays(搜索,填充,排序)中的所有方法。

注意bigint fn強制clojure.lang.BigInt,biginteger fn強制java.math.BigInteger。如果你想使用java.math.BigInteger的方法,你需要通過biginteger強制你的bigint或者字節數組。

+0

謝謝,不知道這將如何比較性能方面與使用long?我想它會變慢。 – DanS 2012-04-27 14:26:49

+1

Clojure bigints不支持位操作。 user =>(bit-and(bigint 5)(bigint 3)) IllegalArgumentException位操作不支持:類clojure.lang.BigInt clojure.lang.Numbers.bitOpsCast(Numbers.java:1008) – RedDeckWins 2013-08-13 17:30:28