小さなチェッカーソルバーを作成するという考えで遊んでいました。最初は、非常にコンパクトなチェッカーボードの表現を作ってから、ゲームツリーなどを作っていきます。64ビット整数のすべてのビットと32ビット整数を比較する
標準チェッカーボードは、8行、及び4官能列を(チェッカーだけ対角線移動することができる)を有しています。それは私たちに32ポジションを与えます!各位置は、情報の3ビット... king
ビット、及びcolor
ビットを必要...ので00
は10
が王ブラック、11
は赤色王であり、01
は非キング赤ある、非キングブラックあります。これは私たちに働くいい数である64を与えます(長い整数の正確なサイズ)。
isOccupied
ビット各チェッカーの位置は空でもよいし、上記の4つの状態のいずれかで満たされるので、各チェッカーにも1つの追加ビットが必要です。私は64州を64ビットintに、32州を32ビット整数に変換することにしました。
私たちはいくつかの背景を持っているので、私は次のような問題があります。「このボードには赤チェッカーがいくつあるの?それほど悪くはありません...私たちの64ビット整数はこのようなデータを保持しています:
king_color_king_color_king_color
だから011001
は赤、黒、キング、赤を意味します。
色情報だけを取得するには、01010101 ... 01というビットマスクを使用できます。これは、0x5555555555555555の16進数です。それは王のビットをゼロにし、色のビットを残すだけです。マスクとのANDing後の011001の例では010001です。ビット(popcount
、bitcount
)を数えると、赤の数が得られます。
ああ、待って!これらの色は「使用中」でない場合があります。指定されたチェッカーが使用されているかどうかを調べるには、32ビットintをチェックする必要があります。だから、私たちは占有されている32の整数に対して011を持っていると言っています。つまり、上記の最初のチェッカー01(赤ではない王)...は実際には占有されていません。そこに別のチェッカーを移動する場合、2つのキングカラービットを更新する必要がある場合とそうでない場合があります。だから、
32bit = 011
64bit = 011001
赤が続く黒王に続いて3つのチェッカー位置...前の赤だったと空のチェッカーを、表す一緒にすべてを置きます。私たちは64ビットで010101マスク動作を行うたら我々が得る:
64bitWithMask = 010001
32bit=011
は単純に我々は... 2つの赤を持っているが、我々は実際には1アクティブを持っている...私は何をしたいことは、本質的で奇数ビットを取るされます64ビットの文字列と32ビット文字列の各ビットとの論理和...
1 AND 0, 0 AND 1, 1 AND 1
は、赤チェッカーの数を表す001を返します。
または同等に、011 & 101 = 001
を取得するために64bitWithMask
簡単かつ32ビットとその後 64bitWithMaskOddBits = 101
に変換します。
正式には、長さ2Xのビット列を取り出し、奇数ビットだけを取って長さXに減らす方法はありますか?私は非常にループ、ifsなどを避け、論理(と、またはxor、否定など)を使用することだけを試みています。
もちろん、私の32ビットと64ビットの文字列を使って適切なレッド数を得る別の方法がある場合は、もちろんです。 ありがとう!
EDIT:
私が提起した問題を解決するには、エレガント受け入れ答えに以下の解決が、私の実際のアプリケーションのためのよりよい解決策は私にたくさんの節約2 32への64ビット表現を分割することでしたさ私が必要とするものを抽出する操作の助けを借りてLukeGとTehtmiの両方に感謝します!私はビット操作のこの新しいテクニック「並列」にさらされてうれしいです。
奇数ビットのシフト演算子、適切なマスクとのAND演算 – Ripi2
または、最初にそれらのレイヤーを別々に保存することができます。キングビットに1つ、カラービットに1つ、占有ビットに1つの32ビット整数を使用してみませんか? –
2つの64ビット整数にデータを保存してみませんか?さて、32ビットは未使用のままですが、ビットの使い方や設定方法を整理してビット単位で比較することもできます。あるいは、64ビット変数でインターリーブするのではなく、3つの32ビット整数を使用するだけです。 – Peter