7

Clojure (/Java) でチェスのビットボードを表すには、どのような方法がありますか?

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

個々のビットにアクセスし、ビットごとの操作も実行できる必要があります。

java.lang.Long を使用することを考えましたが、サイネージのために 1x10^63 で問題が発生します。また、特定のインデックスでビットにアクセスする方法もわかりませんか?

BitSetも見ましたが、理想的には固定長が必要です。

4

2 に答える 2

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-*利用可能な操作はたくさんあります ( clojuredocsを参照してください)。

ストレートロングとunchecked-*操作を使用する場合、ほとんどの場合、bit-*操作を使用してビットをいじったりチェックしたりできます。

最後に、チェス盤をアトムに格納するのは理にかなっており、次のように更新します。(swap! chessboard fn args)

(2013 年 2 月 15 日更新、少し慣用的な swap! 呼び出しを追加)

例えば

(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 
于 2012-04-27T11:45:30.400 に答える
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 はバイナリ操作 (bit-and など) をサポートします。バイト配列では、java.util.Arraysのすべてのメソッド(検索、塗りつぶし、並べ替え) を使用できます。

bigint fn は clojure.lang.BigInt に強制され、biginteger fn は java.math.BigInteger に強制されることに注意してください。java.math.BigIntegerのメソッドを使用する場合は、biginteger を介して bigint またはバイト配列を強制する必要があります。

于 2012-04-27T10:31:15.823 に答える