回転可胜なビットボヌド叀いアむデアの新しいラりンド

画像



簡単な説明



この蚘事では、「ビットボヌド」各ビットが1぀のチェッカヌボヌドフィヌルドを衚す64ビット敎数を䜿甚する堎合のニュアンスに぀いお説明したす。 1994幎、ニュヌゞャヌゞヌ州ケヌプメむでACMが䞻催したチェスシンポゞりムの埌、私はCray BlitzCrayスヌパヌコンピュヌタヌ甚にRobert Hyatt、Harry Nelson、Albert Goverによっお曞かれたコンピュヌタヌプログラムを完党に眮き換えるこずにしたした。翻蚳。。 私はチェス4.xむリノむ州ノヌスりェスタン倧孊で開発され、20䞖玀の70幎代に支配されたチェスプログラム-玄翻蚳でテストされたビットボヌド法を詊しおみるこずに興味がありたした。チェスに適しおいるかどうかを自分で決めおください。 この新しいプログラムの開発䞭に、「回転可胜なビットボヌド」の抂念が考案され、このタむプのデヌタ構造を蚱容可胜なパフォヌマンスで動䜜させるために必芁なこずが刀明したした。



1.はじめに



ビットボヌドは、コンピュヌタヌチェスの文献で䜕床も蚀及されおいたす。 1970幎代半ばに、スレヌトずアトキンは12個の64ビット敎数を䜿甚する方法を思い぀き、説明したした。各敎数は、チェス盀䞊の1皮類のチェスの駒癜は6個、黒は6個を衚したした。 ここでは、KAISSAチヌムDonskoyなどが、ノヌスりェスタン倧孊のチヌムずは独立しお同じアむデアを発明したようであり、過去25幎にわたっお同じアプロヌチを䜿甚しお他の倚くのプログラムが䜜成されおいるこずに泚意しおください。



提案された䞀臎ビットをチェス盀のフィヌルドに関連付けたす。 倀が1のビットは、チェス盀䞊の駒の存圚の兆候ずしお機胜し、ビット0はその䞍圚を瀺したした。 したがっお、癜いポヌンが占めるフィヌルドに察応するwhite_pawnビットボヌドでは、倀が1の最倧8ビットがありたすこの蚘事では、フィヌルドには0から63たでの番号が付けられ、䜍眮0はフィヌルドA1に、7はフィヌルドH1に察応、56 64ビット敎数の䜍眮0にあるビットは「最䞊䜍ビット」ず呌ばれ、䜍眮63のビットは「最䞋䜍ビット」ず呌ばれたす最䞊䜍ビット、MSB最䞋䜍ビット、LSB-およその翻蚳。



これらの12の64ビットワヌドでボヌドに䜍眮情報を保存するこずに加えお、スレヌトずアトキンは、異なる皮類の情報を察象ずしたビットボヌドの2぀の远加セットを生成し、その埌曎新する方法を説明したした。 attack_from [64]-各フィヌルドの倀が1であるビットボヌドの配列。特定のフィヌルドに立っおいるフィギュアによっお攻撃される可胜性がありたす。 たずえば、attacks_from [E4]は、フィヌルドE4に立っおいる人物によっお盎接攻撃されたフィヌルドを提䟛したす。 さらに、attacks_to [64]配列には、このフィヌルドを攻撃するフィギュアが占めるすべおのフィヌルドのビット1を持぀ビットボヌドが含たれおいたす。 たずえば、attacks_to [E4]は、ボヌド䞊のすべおのフィヌルドにビット1を含むビットボヌドで、印象的なフィヌルドE4の数字がありたす。



この2セットのビットボヌドはこの蚘事の䞻題であり、実行速床を倧幅に䜎䞋させるこずなくattack_from []ビットボヌドを動的に蚈算する新しい非垞に高速な方法を説明したす。これはSlateずAtkinが説明した曎新方法の堎合です。 Slate / Atkinはシヌケンシャルアップデヌトを䜿甚したこずに泚意しおください。以䞋に説明する手順は、「オンザフラむ」で長距離フィギュアの攻撃を蚈算するには遅すぎるためです。ビットボヌドを動䜜させるず同時に高い蚈算コストを回避するために、シヌケンシャルアップデヌトを䜿甚したした



チェスプログラムで非垞に圹立぀ビットボヌドには、他にも䟿利なプロパティがありたす。 これらのプロパティの1぀は、「ビット䞊列」操䜜ず呌ばれるものです。 たずえば、埓来のチェスプログラムでは、ポヌンがE4フィヌルドにあり、それがチェックポむントであるかどうかを確認する堎合、D5、E5、F5、D6、E6、F6、D7、E7、F7フィヌルドをチェックする必芁がありたす敵の駒がないこずを確認しおください。 これには、9぀の比范操䜜が必芁です。 ビットボヌドを䜿甚しお、ポヌンが立぀こずができる各フィヌルドのマスクの配列を事前に蚈算し、is_passed_white [E4]マスクを取埗しお、ビットポヌンず黒ポヌンのビット単䜍の「AND」挔算を実行するだけです。 マスクを正しく蚈算しお、䞊郚の9぀のフィヌルドのそれぞれに単䜍がある堎合、1぀のAND挔算により、黒のポヌンが存圚しないか、逆にそれらの存圚が刀定され、E4の癜のポヌンが通過できなくなりたす。 実際、9぀の異なるチェックを䞊行しお実行し、1぀のAND挔算で9぀の質問に同時に回答したした。



他の利点もありたすが、この蚘事のトピックは回転可胜なビットボヌドであり、必芁に応じお、連続曎新による制限なしで耇雑な/遅いサむクルなしで、attacks_from [64]およびattacks_to [64]配列からデヌタを取埗する方法です。 。



2.通垞のビットボヌドを䜿甚したAttacks_from配列[64]の蚈算



回転ビットボヌドの方法に進む前に、attacks_from []の蚈算の耇雑さに泚意する必芁がありたす。 短距離の数字の堎合、これはもちろん非垞に簡単です。 たずえば、knight_attacks [64]配列を事前に準備しお、銬がF6フィヌルドにいる堎合、knight_attacks [F6]は、銬がF6フィヌルドから攻撃できるすべおのフィヌルドにビット1を含むビットボヌドになるようにするこずができたす。銬に攻撃された堎合、チェス盀䞊の駒の配眮に䟝存しないでください。 同じ考え方がキングずポヌンにも機胜したすポヌンは斜めにヒットするため、1぀たたは2぀のフィヌルドを前方に移動するこずなく、わずかな倉曎を加えたす。



ただし、長距離フィギュアの堎合、長距離フィギュアは動きの方向でのみ攻撃し、この方向で最初に遭遇する数字だけを攻撃するため、アレむぞの単玔なアピヌル䞊蚘のようには機胜したせん。 では、これをどのように蚈算するのでしょうか



最初に、占領された正方圢ず呌ばれるビットボヌドが必芁です。これは、任意の色の圢状があるすべおのフィヌルドに単䜍が衚瀺されたビットボヌドにすぎたせんたずえば、ビット単䜍の「OR」OR図のタむプごずに12個のビットボヌドすべおの間で、実際にはそのような2぀のビットボヌドを栌玍したす1぀は黒甚、もう1぀は癜甚-必芁に応じおそれらの間でOR挔算を䜿甚し、占領された正方圢のビットボヌドを取埗したす。



図1は、占有フィヌルドに「X」のマヌクが付けられ、非占有フィヌルドに「-」のマヌクが付けられたチェッカヌボヌドの䜍眮の䟋を瀺しおいたす。







長距離のフィギュアは、どんな皮類のフィギュアに出䌚っおも停止するため、フィヌルドに䜕があるかは問題ではありたせん。 象がフィヌルドF5に立぀ず図2でBでマヌクされおいる、次のフィヌルドセットを盎接攻撃しおいるこずがわかりたす{B1、C2、D3、E4、G6、H3、G4、E6、D7}。 攻撃ビットボヌドを蚈算した埌これがこの䜍眮からの蚱容される象の動きを䜿甚する堎合、自分の駒を打぀すべおの動きを陀倖する必芁がありたす。 前述のwhite_occupiedビットボヌドを䜿甚しお、補数挔算ビットごずの吊定を適甚し、次に攻撃ビットボヌドずAND挔算を適甚できたす。これにより、象の攻撃ビットボヌド内の自分のピヌスに察する攻撃に察応するビットがリセットされたす。これらは無効な動きです。



これたでのずころ良い。 しかし、ピヌスが移動できる4本たたはクむヌンの堎合は8本の光線をすべお列挙せずに、攻撃されたビットをどのように刀断するのでしょうか 䞀般に、これはそれほど難しくありたせんが、各方向でルヌプの個別の反埩が必芁になるため、あたり効果的ではありたせん。



最初に、フィギュアが移動できる8぀の方向それぞれにマスクのセットを䜜成したす。 プラス1 [64]、プラス7 [64]、プラス8 [64]、プラス9 [64]、マむナス1 [64]、マむナス7 [64]、マむナス8 [64]、マむナス9 [64]ず呌びたす。 これらのビットボヌドには、特定の方向でSQフィヌルドから象を攻撃できるフィヌルドのビット1が含たれおいたす。 この䟋では、F5の叞教がplus7方向これらのフィヌルドはF5-E6-D7-C8ですで、plus7 [F5]は図3のようになりたす。



これにより、象ずボヌドの端の間に障害物がなければ、象が+7方向に攻撃できるすべおのフィヌルドが埗られたす。 しかし、我々はそれらが存圚する可胜性があるこずを知っおおり、もしそうなら、私たちはこの方向の劚害人物を芋぀けなければなりたせん。 これを行うために、䞊蚘のビットボヌドを取埗し、それず占領された正方圢のビットボヌドの間でANDを実行したす。 象がこの方向でブロックされおいる堎合、ビット1が各フィヌルドを衚し、象のC8ぞの斜めの動きをブロックする図がある空でないビットボヌドを取埗したす。 最初のブロック図のみが必芁なため、FirstOne関数を䜿甚したす。これは、倀1の最初のビットのむンデックスを返したす。たずえば、象がC8およびD7でブロックされた堎合、FirstOneはフィヌルド番号D751を返す必芁がありたす。



これで、この察角線に沿っお攻撃されたフィヌルドのリストず、長距離フィギュアがブロックされおいるフィヌルドができたした。 私たちがやるべきこずは、ブロッキング数字の埌に攻撃されたフィヌルドを削陀するこずだけです。 そしお、これは最も簡単な郚分です。 これを行う方法を次のコヌド䟋で説明したす。



  diag_attacks = plus7 [F5];
	ブロッカヌ= diag_attacks占領された正方圢;
	 blocking_square = FirstOneブロッカヌ;
	 diag_attacks ^ = plus7 [blocking_square]; 


これが、1぀のビヌムに察しお行う必芁があるすべおです。 コヌドをわかりやすくするため、diag_attacksは䞊蚘のビットボヌドで、F5フィヌルドからの攻撃フィヌルドが+7方向に含たれおいたす。 ブロッカヌには、すべおのピヌスがこの察角線䞊にあるビットボヌドがありたす。 最初のブロック図を芋぀け、plus7 [blocking_square]ずdiag_attacksの間の排他的「OR」を䜜成したす。これにより、それに続くすべおの攻撃フィヌルドが実際に遮断されたす。 それを理解しおみたしょう。F5の叞教がE6でブロックされおいる堎合、この堎合のplus7 [E6]は次のようになりたす。ナニットのビットはD7ずC8のみです。D7/ C8ビットは䞡方のビットボヌドでれロではないため、排他的な "たたは「ビットボヌド間で、これらのおよびこれらのビットのみがリセットされたす。



最埌のブロック図を芋぀ける必芁があるため、マむナス方向の堎合はFirstOneを䜿甚しないずいう違いだけで、4぀の方向すべおに぀いおこれを繰り返したす。 これの代わりに、LastOneに切り替えたす。 これで、4぀の方向すべおで象の攻撃をカりントするコヌドは次のようになりたす。



  diag_attacks = plus7 [F5];
	ブロッカヌ= diag_attacks占領された正方圢;
	 blocking_square = FirstOneブロッカヌ;
	 bishop_attacks = diag_attacks ^ plus7 [blocking_square];
	 diag_attacks = plus9 [F5];
	ブロッカヌ= diag_attacks占領された正方圢;
	 blocking_square = FirstOneブロッカヌ;
	 bishop_attacks | = diag_attacks ^ plus9 [blocking_square];
	 diag_attacks = minus7 [F5];
	ブロッカヌ= diag_attacks占領された正方圢;
	 blocking_square = LastOneブロッカヌ;
	 bishop_attacks | = diag_attacks ^ minus7 [blocking_square];
	 diag_attacks = minus9 [F5];
	ブロッカヌ= diag_attacks占領された正方圢;
	 blocking_square = LastOneブロッカヌ;
	 bishop_attacks | = diag_attacks ^ minus9 [blocking_square]; 


これは、ANDおよびORを䜿甚した倚数の操䜜ずマスキングの必芁性に加えお、FirstOne/ LastOne関数を䜿甚しおブロッキングフィヌルドを怜出するこずになりたす。 これは非垞に高䟡ですが、ブヌル挔算子ではほずんどの䜜業が䞊行しお行われるため、それでも正圓化できたす。 ただし、FirstOne/ LastOneの呌び出しを削陀するより良い方法があり、このメ゜ッドのように2段階ではなく、1段階で察角線/æ°Žå¹³/垂盎党䜓を凊理したす。



FirstOne/ LastOne関数は、Cでプロシヌゞャずしお実行するず非垞に高䟡になるこずに泚意する必芁がありたす。最初たたは最埌のビットを芋぀けるこずは、䞊蚘の攻撃の蚈算に倚くの時間を必芁ずする重芁なタスクだからです。 幞いなこずに、最新のマむクロプロセッサにはこれらの倀を蚈算するためのハヌドりェア呜什がありたすIntelはX86アヌキテクチャにBSF / BSR [ビットスキャンフォワヌド、ビットスキャンリバヌス]呜什を備えおいたす。 他のタむプのアヌキテクチャも同様の指瀺を提䟛したす。



3.回転可胜なビットボヌド



1994幎9月にビットボヌドを䜿甚したCraftyバヌゞョンが登堎した埌、私はUABでセミナヌを開始したしたCrafty-Robert Hyattによっお曞かれたチェスプログラム、UAB-バヌミンガムのアラバマ倧孊-およその翻蚳。効率を高めるための新しい方法に取り組み、開発したす。 最初の議論の1぀は、氎平面に沿っお長距離の人物の動きを生成するこずがいかに簡単かずいうこずでした。



特定の氎平線チェス盀のフィヌルドの氎平列のフィヌルドを取る堎合、長距離の駒の動きは非垞に簡単に取埗できたす。これは、占領された正方圢のビットボヌドの8ビットによっお氎平が決定されるためです。 このビットボヌドを右に移動しお、その䞋䜍ビットに氎平方向の8ビットが含たれるようにし、次に数倀255ずANDを実行するず、この氎平方向のフィヌルドに察応する8ビットが埗られたす。



これを念頭に眮いお、rank_attacks [64] [256]ビットボヌドの配列を怜蚎しおください。 この配列を初期化するには、A1などのフィヌルドを䜿甚したす。 どのフィヌルドが占有され、どのフィヌルドが占有されおいないかに応じお、その氎平には256の異なる状態しかないこずがわかりたす。 ゲヌムを開始する前に、この氎平の単䞀ビットの256のすべおの組み合わせを考慮しお、A1のルヌクがどのフィヌルドに進むこずができるかを事前に蚈算できる堎合、ビットボヌドrank_attacks [A1] [contents]を参照するだけで、この氎平のフィヌルドを攻撃するこずができたす。ここで、contentsは䞎えられた氎平の状態の8ビット衚珟です。 必芁なのは、64個のフィヌルドのそれぞれず、これらのフィヌルドが配眮されおいる氎平線の256の異なる状態すべおに察しおビットボヌドのセットを蚈算するこずですそう、考えおみれば、氎平線は128状態しか持おたせん。フィヌルドの1぀はルヌクですが、この単玔化を無芖する方が簡単です。 ここで、氎平には8぀のステヌタスビットがありたすが、2぀の極端なビットLSBずMSBは、数字があるかどうかに関係なく攻撃されるため、䜕も倉わりたせん。 その結果、各氎平のテヌブルサむズを75削枛するために、それらを以降の蚈算から削陀したす。 したがっお、rank_attacks配列のサむズをrank_attacks [64] [64]に枛らしたす。 他のすべおの同様の配列は、同じ単玔化を䜿甚したす。



これたでのずころ、rank_attacks配列でメモリにアクセスするだけで、ルヌク攻撃の半分を埗るこずができたす。 しかし、象の垂盎攻撃ず2぀の察角線はどうでしょうか。 そこでは、ビットは占領された正方圢のビットボヌドで隣接しおいないため、等高線以倖には適甚できたせん。



セミナヌでこれに぀いお議論しおいる間、特殊なチェスの機噚を䜿甚する堎合、レゞスタを割り圓おお64ビットの占領された正方圢の倀を栌玍するこずに気づきたしたが、占領された正方圢にアクセスできる他の3぀の「疑䌌レゞスタ」を匷調衚瀺できたすさたざたな方法で。 たずえば、占領された正方圢の内容党䜓を90床回転しお、同じ垂盎のビットが連続するようにしたす。 事前に蚈算された氎平方向の攻撃ず同じように、これを䜿甚しお垂盎方向の攻撃を芋぀けるこずができたす。 たた、占領された正方圢のビットボヌドを巊右に45床回転させる2぀のレゞスタを区別できるため、これらの回転したビットボヌドの察角線ビットが隣接したす。 図4は、通垞のチェッカヌボヌド䞊のフィヌルドの番号付け方法を瀺しおいたす。







A1がzero_bitビットMSBであり、H8が占領平方ビットボヌドの63番目のビットLSBであるこずを思い出しおください。 最初に、巊に90床回転しお垂盎ビットを連続させたす64ビットのビットボヌドでは巊䞋隅がれロビットのたたであり、右䞊隅には垞にシリアル番号63があるこずに泚意しおください図5。



次に、図6に瀺すように、元の䜍眮を巊に45床回転したす。







この回転したビットボヌドでは、ボトムフィヌルドA1がヌルビットになり、次のものが順番になりたす。 したがっお、たずえば、A2はビット1になり、B1はビット2になり、H8がビット63になるたで続きたす。



䞊蚘のビットボヌドでは、H1からA8たでの察角線ずそれに平行なすべおの察角線䞊のビットが隣接しおいるこずに泚意しおください。 これは、最初の2぀のビットボヌドほど䟿利ではありたせん。 配列のむンデックスずしお䜿甚できるように、特定の氎平たたは垂盎を数倀の右端にどれだけシフトする必芁があるかを簡単に蚈算できたす。 たた、必芁な8ビットを抜出するには、数倀255ずANDを実行する必芁があるこずもわかっおいたした。察角線の堎合、各察角線の長さは異なりたす。぀たり、シフトずマスクの倀を倉えお䜙分なビットを削陀したす。 この問題の解決策に぀いおは埌述したす。



図7のビットボヌドのように、元のビットボヌドを右に45床回転しお、他の察角線䞊に隣接するビットを䜜成したす。



これがすべお揃ったので、すでに考慮されおいるrank_attacks [64] [64]に加えお、攻撃のためにビットボヌドの配列をさらに3぀远加する必芁があるこずが明らかになりたす。 File_attacks [64] [64]、diaga1h8_attacks [64] [64]、およびdiagh1a8_attacks [64] [64]が远加され、元の占領された正方圢のビットボヌドの回転を孊習する堎合、同じむンデックススキヌムを䜿甚できたす。ゟりたたはルヌク甚のテヌブルぞの2回の呌び出しずクむヌン甚の4回の呌び出しの曎新手順。



その埌、占領された正方圢のビットボヌドを回転させる方法に぀いお倚くの議論をした埌、簡単な解決策が芋぀かりたした。 占領された正方圢のビットボヌドのみを保存し、必芁に応じお回転させるのではなく非効率性のためほずんど䞍可胜ず考えられたす、占有フィヌルドに4぀のビットボヌドを保存できたす通垞および90床回転、巊に45床、右に45床。 MakeMoveの図を移動する手順で、占領された正方圢のビットボヌドを曎新する同様のコヌドを芋぀けるこずができるため、これは非垞に簡単です。



占有スク゚ア^ = set_mask [from] | set_mask [to];



これは、opposed_squaresの開始フィヌルド「from」のビットを1に蚭定する必芁があるこずがわかっおいるためですそうでない堎合、移動する図圢はありたせん。 ; たた、occupiced_squaresビットボヌドの最埌の「to」フィヌルドのビットの倀はれロでなければなりたせんそうでなければテむクになりたす。 したがっお、排他的な「OR」を䜿甚しお、開始フィヌルドビットがリセットされ、終了フィヌルドビットが蚭定されたす。



set_mask [64]ビットボヌド配列のすべおの芁玠には、察応する䜍眮に1ビットのみが蚭定されおいたす。 たずえば、set_mask [0]には巊端のビットセットれロビットがあり、set_mask [63]には最䞋䜍ビットセット63番目のビットがありたす。 回転可胜なビットボヌドを䜿甚するために、set_mask_rl90 [64]、set_mask_rr45 [64]、set_mask_rl45 [64]ずいう3぀の新しいマスクセットを䜜成したした。 これらはそれぞれ、フィヌルド番号をむンデックスずしお䜿甚し、ビットマップを返したす。ビットボヌドでは、察応するビットが占領䞋の回転可胜なビットボヌドに蚭定されおいたす。 たずえば、set_mask_rl90 [0]は実際に7番目のビットを蚭定したす。これは、rotated_leftビットボヌドで画像を芋るず、ビット0が7番目になるためです。



これが、すべおを機胜させるために必芁な゜リュヌションでした。 占領された正方圢のビットボヌドを回転させる代わりに、4぀の占領された正方圢のビットボヌドを同時に保存し、これらのタむプのフィギュアの攻撃を受ける必芁があるずきはい぀でもビショップ/ルヌク甚に2぀、たたは女王甚に4぀䜿甚できたす。



象の堎合、䜿甚できる最適化が1぀ありたすが、メモリに比べお高䟡です。 ルヌクの堎合、察応する氎平たたは垂盎を数倀の右端に移動し、255ずANDを実行しおこの氎平たたは垂盎の内容を取埗したこずを思い出しおください。 これは、各氎平たたは垂盎に8ビットが含たれおいるため機胜したした。 しかし、察角線の堎合、それぞれの長さは隣のものずは異なりたす。



このアルゎリズムを単玔化するために、察角線の堎合にAND 255を実行したす。これにより、明らかに、目的の察角線が埗られたすが、隣接する察角線察角線からの䜙分なビットがいく぀かありたす。 察象の察角線に3ビット合蚈8぀の䞀意の状態しかない堎合、これらの8぀の状態のそれぞれに32ビットの䜙分なビットが結合されたす。 ぀たり、必芁な3ビットの状態があり、32回繰り返されたす。 したがっお、远加の5ビットに䜕が含たれおいるかは関係ありたせんが、3ビットの察角線に察しお正しい攻撃ビットボヌドを取埗できたす。



4.回転可胜なビットボヌドを䜿甚したattack_from [64]の蚈算



攻撃を蚈算するために、4぀の異なる配列を䜿甚したす。1぀は氎平攻撃、1぀は垂盎攻撃、もう1぀はフィヌルドを通過する2぀の察角線です。 これらのアレむには、rank_attacks [64] [64]、file_attacks [64] [64]、diaga1h8_attacks [64] [64]、diagh1a8_attacks [64] [64]ずいう名前を付けたした。



これらの配列を初期化するためにこれはアプリケヌションの起動時に行われ、それ以降は配列は倉曎されたせん、問題の方向たずえば、女王に移動できるフィヌルドに長距離の数字があるず単玔に仮定したした。 次に、各フィヌルドにrank_attacks [square] [rank_contents]を導入したした。この氎平のフィヌルドがrank_contents番号の8ビットに埓っお占有されおいる堎合、正方圢の正方圢に立぀ルヌク/クむヌンがどの氎平線を移動できるかを瀺すビットボヌド「。 たずえば、以前に怜蚎された占領された正方圢のビットボヌドを取り䞊げたすが、前の䟋のようにF5フィヌルドの叞教の代わりに、そこにルヌクを眮きたす図8。 rank_attacks [37] [100]を初期化しようずしおいるず仮定したす37はフィヌルドF5で、100はこの氎平方向の占有フィヌルド-01100100に察応したす。 図9に瀺すように、このrank_attacks芁玠を初期化したす。これは、䞊蚘のように、ピヌスがF5にあり、氎平が3぀のピヌスで占められおいる堎合、ルヌク/クむヌンが5番目の氎平で攻撃できるフィヌルドに完党に察応したす。







たあ、悪くない。 これを行うこずにより、氎平に沿っおルヌク攻撃をすばやく取埗できたす。 しかし、氎平方向ではなく垂盎方向に攻撃を蚈算する必芁がありたす。 これを行うには、占領されたrl90ビットボヌドを䜿甚したす。これは、前の占領された正方圢の正確なコピヌですが、図10に瀺すように90床回転されおいたす。



3番目の「氎平」を取埗するず、実際には、垂盎Fでの雇甚に関する情報を取埗したすおそらく、氎平から3番目-およその翻蚳を意味したす。 以前に蚈算された攻撃ビットボヌドが再び䜿甚されたすが、今回はattacks_file [37] [251]もう䞀床、37はフィヌルドF5、およびこの垂盎フォヌム11111011の占有フィヌルドを意味したす、図に瀺すように決定した倀11。







ここで、氎平攻撃ず垂盎攻撃の䞡方の倀を取り、それらの間でORを行うず、フィヌルドF5に立っおいるルヌクの攻撃フィヌルドの完党なセットが埗られたす。 occupied_squares, , OR / . , . :



 BITBOARD attacks=0;
    if (BishopMover(piece)) {
      get diaga1 status (shift/AND); /* 6 bits */
      attacks|=diaga1h8_attacks[square][status];
      get diagh1 status (shift/AND); /* 6 bits */
      attacks|=diagh1a8_attacks[square][status];
     }
    if (RookMover(piece)) {
      get rank status (shift/AND); /* 6 bits */
      attacks|=rank_attacks[square][status];
      get file status (shift/AND); /* 6 bits */
      attacks|=file_attacks[square][status];
     } 


, , . BishopMover() RookMover() «», , ( ), ( ). Crafty , P=1, N=2, K=3, B=5, R=6 Q=7. piece_type&4, , . , piece_type&1 , , piece_type&2 , /.



5. attacks_to[64]



attacks_to[] , , . , attacks_to[28] (28 = E4) , 12, , E4 E8 F6, E1 D3 (E4 T, «target»).







«T» — , 0 . X ( 1) , E4. , E4, AND occupied_squares . 1 , , E4. E4 , AND occupied_squares .



: () () ? (, , , , ), E4, AND / , 1 /, , . /. , AND / . , , OR , , E4.



, , ( ) , (, , , ), .



6.



, , . «/» , , . «» , FirstOne() , «», . . , : (, Crafty 21 . 6 «FROM» (), 6 — «TO» (), 3 — MOVING_PIECE ( ), 3 — PROMOTE_TO, .)



 piecebd=WhiteQueens;
    while (piecebd) {
      from=LastOne(piecebd);
      moves=AttacksQueen(from);
      temp=from+(queen<<12);
      while (moves) {
        to=LastOne(moves);
        move_list[i++]=temp+to<<6;
        Clear(to,moves);
       }
      Clear(from,piecebd);
     } 


, , , , , — . , AND , , , — , . , , , , , ; , , , . , . , .



 piecebd=WhiteQueens;
    while (piecebd) {
      from=LastOne(piecebd);
      moves=AttacksQueen(from) & BlackPieces;
      temp=from+(queen<<12);
      while (moves) {
        to=LastOne(moves);
        move_list[i++]=temp+to<<6;
        Clear(to,moves);
       }
      Clear(from,piecebd);
     } 


, , . , «». , , occupied_squares , ( ).



, attacks_to[]. , (attacks_to[sq]), / . — « ?», , . (/, /, , ) AND ( , , ), , , «», «, ».



, . , , attacks_to[sq], , . , ; AND attacks_to , . AND , , . attacks_to, , AND attacks_to , . , attacks_to .



, , ? . , «» attacks_to, (, , , , , «»). AND, , , . , (/ , / /), OR attacks_to, , . ( plusN[]/minusN[], , , .)



, , , . , . , . . , , (, ), , , . , attacks_to , .



7.結論



, « ». , 64 , , . , CPU 64- , , , 64- . 64- , .



64- (Alpha, HP, MIPS — ) 64- , Intel Merced, , . , (AND, OR, XOR, ) 32- — 64- . 64- , . , , .



, ( ), , ( AND , ), . «Chess 4.0» , , , , Crafty ( . , ), . , , Crafty, , «Chess 4.0», « », . « , ?». . , « » (« , » — . .) , ( ) , , «» , .



:

: http://www.cis.uab.edu/info/faculty/hyatt/bitmaps.html



翻蚳者から


, . , , . , , , .



:

www.frayn.net/beowulf/theory.html#bitboards

www.craftychess.com



«bitboard», «», , « » .



«bitmap» «bitboard» , « » « » . «».



, : AND, OR . ., .



All Articles