From 84fad9abb8df1e31af0c7d46309001a9cbe73258 Mon Sep 17 00:00:00 2001 From: MrGeorgen Date: Sat, 23 Mar 2024 20:39:12 +0100 Subject: [PATCH] fixed move generation --- include/chess/print.h | 3 +++ src/chess/magicNumber.h | 4 ++-- src/chess/move.c | 34 +++++++++++++---------------- src/common/bitboard.c | 5 ++++- src/common/print.c | 33 +++++++++++++++++++++++++++++ src/findMagicNumber.c | 15 ++++++++----- src/generateCode/moveConsts.c | 7 ++++-- test/moveGen.c | 40 ++++++++++++++++++++++++++++------- 8 files changed, 104 insertions(+), 37 deletions(-) diff --git a/include/chess/print.h b/include/chess/print.h index 90e9eca..ce72321 100644 --- a/include/chess/print.h +++ b/include/chess/print.h @@ -1,5 +1,6 @@ #include #include +#include #define fprintArray(file, printer, arr) \ do { \ @@ -25,3 +26,5 @@ void printerll(FILE *file, long long num); void printerull(FILE *file, unsigned long long num); void printPieceMask(uint_least64_t mask); +void fieldToString(uint_least8_t field, char *output); +void printMove(const struct move_t move); diff --git a/src/chess/magicNumber.h b/src/chess/magicNumber.h index f26273a..a8d4c8d 100644 --- a/src/chess/magicNumber.h +++ b/src/chess/magicNumber.h @@ -1,3 +1,3 @@ #include -static struct magic_t rookMagic[64] = {{ 0, 126u, 585504314899303506u, 58}, { 0, 144680345676153468u, 9241404028087189504u, 53}, { 0, 289360691352306810u, 612524733837086720u, 53}, { 0, 578721382704613494u, 72092812853645312u, 53}, { 0, 1157442765409226862u, 1188953050539099136u, 53}, { 0, 2314885530818453598u, 72058693583372296u, 53}, { 0, 4629771061636907070u, 1188970094051459328u, 53}, { 0, 126u, 585504314899303506u, 58}, { 0, 32256u, 4573969545971713u, 58}, { 0, 144680345676184578u, 9223442680478961664u, 54}, { 0, 289360691352336900u, 2392606057169024u, 54}, { 0, 578721382704641544u, 140806208356480u, 54}, { 0, 1157442765409250832u, 1153062791918127104u, 54}, { 0, 2314885530818469408u, 140754676613632u, 54}, { 0, 4629771061636906560u, 14411660094863311104u, 54}, { 0, 32256u, 4573969545971713u, 58}, { 0, 8257536u, 4035243133187982848u, 58}, { 0, 144680345684148738u, 9223442680478961664u, 54}, { 0, 289360691360039940u, 71468792942848u, 54}, { 0, 578721382711822344u, 143486535927808u, 54}, { 0, 1157442765415387152u, 1153062791918127104u, 54}, { 0, 2314885530822516768u, 141287311278592u, 54}, { 0, 4629771061636776000u, 4398063813136u, 54}, { 0, 8257536u, 4035243133187982848u, 58}, { 0, 2113929216u, 9799832806609265699u, 58}, { 0, 144680347722973698u, 35186523766912u, 54}, { 0, 289360693332018180u, 2324376172109952u, 54}, { 0, 578721384550107144u, 8798241554560u, 54}, { 0, 1157442766986285072u, 8798248895488u, 54}, { 0, 2314885531858640928u, 4400202383872u, 54}, { 0, 4629771061603352640u, 9223513925395025944u, 54}, { 0, 2113929216u, 9799832806609265699u, 58}, { 0, 541165879296u, 8623489186u, 58}, { 0, 144680869662163458u, 211174972989440u, 54}, { 0, 289361198158447620u, 422349979521024u, 54}, { 0, 578721855151015944u, 8798248898560u, 54}, { 0, 1157443169136152592u, 8798248895488u, 54}, { 0, 2314885797106425888u, 176196872635408u, 54}, { 0, 4629771053046972480u, 864693334524825672u, 54}, { 0, 541165879296u, 8623489186u, 58}, { 0, 138538465099776u, 1152923704242602112u, 58}, { 0, 144814486094742018u, 87961467109376u, 54}, { 0, 289490433724384260u, 35184640557184u, 54}, { 0, 578842328983668744u, 17592320295040u, 54}, { 0, 1157546119502237712u, 1152930300767010944u, 54}, { 0, 2314953700539375648u, 2199090397312u, 54}, { 0, 4629768862613651520u, 71477114437768u, 54}, { 0, 138538465099776u, 1152923704242602112u, 58}, { 0, 35465847065542656u, 145139880169537u, 58}, { 0, 179020292834853378u, 35186523766912u, 54}, { 0, 322574738604164100u, 71468792942848u, 54}, { 0, 609683630142785544u, 2305880667756036608u, 54}, { 0, 1183901413220028432u, 4400194519168u, 54}, { 0, 2332336979374514208u, 3458905259899093120u, 54}, { 0, 4629208111683485760u, 123149731628032u, 54}, { 0, 35465847065542656u, 145139880169537u, 58}, { 0, 9079256848778919936u, 145139880169537u, 58}, { 0, 8935706818303361538u, 22548582572802u, 53}, { 0, 8792156787827803140u, 9223443505379549185u, 53}, { 0, 8505056726876686344u, 281492694499337u, 53}, { 0, 7930856604974452752u, 3298862563377u, 53}, { 0, 6782456361169985568u, 576478370259304706u, 52}, { 0, 4485655873561051200u, 17715716818948u, 53}, { 0, 9079256848778919936u, 145139880169537u, 58} }; -static struct magic_t bishopMagic[64] = {{ 0, 18049651735527936u, 450387485566996608u, 58}, { 0, 70506452091904u, 292736183996786692u, 59}, { 0, 275415828992u, 15764799564551168u, 59}, { 0, 1075975168u, 633872748382213u, 59}, { 0, 38021120u, 565217696169988u, 59}, { 0, 8657588224u, 571754770663745u, 59}, { 0, 2216338399232u, 564393097077764u, 59}, { 0, 567382630219776u, 4647745618985488384u, 58}, { 0, 4620710844295151618u, 151878701417476u, 59}, { 0, 18049651735527428u, 9605338177241346u, 59}, { 0, 70506452221962u, 9223495332494639169u, 59}, { 0, 275449643028u, 9223446873539363073u, 59}, { 0, 9733406760u, 572125077307650u, 59}, { 0, 2216342585424u, 2305915585839759872u, 59}, { 0, 567382630203424u, 576608090351732752u, 59}, { 0, 145249953336262720u, 154635866112u, 59}, { 0, 2310355422147510788u, 18084841411575936u, 59}, { 0, 4620710844295021576u, 4516828160236544u, 59}, { 0, 18049651768822288u, 9225629402954698769u, 57}, { 0, 70515108615202u, 2251975928381472u, 57}, { 0, 2491752130628u, 4611967513004083360u, 57}, { 0, 567383701868552u, 281550407600400u, 57}, { 0, 145249953332076560u, 6920908969368159235u, 59}, { 0, 290499906664153120u, 703829253328896u, 59}, { 0, 1155177711057110024u, 1143497474336784u, 59}, { 0, 2310355422114220048u, 317758928062976u, 59}, { 0, 4620710852818505760u, 1155175507755663872u, 57}, { 0, 18051867805491776u, 5764897794523414784u, 55}, { 0, 637888545440770u, 4785350622855232u, 55}, { 0, 145250227678349316u, 570096847160448u, 57}, { 0, 290499905592496136u, 9223519374650978432u, 59}, { 0, 580999811184992272u, 1153062792136247296u, 59}, { 0, 577588851267340304u, 4521260600263744u, 59}, { 0, 1155177702534680608u, 3124159228940288u, 59}, { 0, 2310357604126171200u, 74775381671976u, 57}, { 0, 4621278158205894656u, 4647717016617615488u, 55}, { 0, 163299467632837120u, 9277415507529629952u, 55}, { 0, 290570138238321666u, 4503917455229184u, 57}, { 0, 580999536840804356u, 36600586291970176u, 59}, { 0, 1161999073681608712u, 2261146400784640u, 59}, { 0, 288793334762704928u, 1127136992038912u, 59}, { 0, 577586669525409856u, 1695455559819264u, 59}, { 0, 1155736297594175488u, 13880314514376704u, 57}, { 0, 2455587783297728512u, 144397496285665280u, 57}, { 0, 4911175566587199488u, 4612011478231285824u, 57}, { 0, 598979094172140032u, 9042384708960320u, 57}, { 0, 1161928841569502210u, 18876832271040768u, 59}, { 0, 2323857683139004420u, 1127275689020928u, 59}, { 0, 144117404414255168u, 72576638388224u, 59}, { 0, 288234808828510208u, 720646618495844352u, 59}, { 0, 720587004756099072u, 146371669538381824u, 59}, { 0, 1441174018093744128u, 11538239838684184576u, 59}, { 0, 2882348034073559040u, 9223975260183924736u, 59}, { 0, 5764695518391435264u, 4899987047395164192u, 59}, { 0, 2305878262439739904u, 3461051790072611360u, 59}, { 0, 4611756524879479810u, 72624959419465760u, 59}, { 0, 567382630219776u, 4647745618985488384u, 58}, { 0, 1134765260406784u, 2312598961229660688u, 59}, { 0, 2832480465846272u, 10376295759300608386u, 59}, { 0, 5667157807464448u, 1152930369692107270u, 59}, { 0, 11333774449049600u, 1152930369692107270u, 59}, { 0, 22526811443298304u, 36421940281888u, 59}, { 0, 9024825867763712u, 151878701417476u, 59}, { 0, 18049651735527936u, 450387485566996608u, 58} }; +static struct magic_t rookMagic[64] = {{ 0, 282578800148862u, 2341871894348709888u, 52}, { 0, 565157600297596u, 9961962444465111104u, 53}, { 0, 1130315200595066u, 144133330555126272u, 53}, { 0, 2260630401190006u, 9259418428207792132u, 53}, { 0, 4521260802379886u, 4647717031650001025u, 53}, { 0, 9042521604759646u, 216191473946330112u, 53}, { 0, 18085043209519166u, 2341942724749427200u, 53}, { 0, 36170086419038334u, 4719772959250661632u, 52}, { 0, 282578800180736u, 4775082277841412224u, 53}, { 0, 565157600328704u, 76631837289484288u, 54}, { 0, 1130315200625152u, 307089306986487809u, 54}, { 0, 2260630401218048u, 9288816033529864u, 54}, { 0, 4521260802403840u, 141287378387968u, 54}, { 0, 9042521604775424u, 9570183869903124u, 54}, { 0, 18085043209518592u, 7036891614413312u, 54}, { 0, 36170086419037696u, 1153484593081418770u, 53}, { 0, 282578808340736u, 324259448052785152u, 53}, { 0, 565157608292864u, 5908793355000619010u, 54}, { 0, 1130315208328192u, 76632662458041361u, 54}, { 0, 2260630408398848u, 630514944024117264u, 54}, { 0, 4521260808540160u, 141287378387968u, 54}, { 0, 9042521608822784u, 18718635740693504u, 54}, { 0, 18085043209388032u, 5066825540829440u, 54}, { 0, 36170086418907136u, 2199095673988u, 53}, { 0, 282580897300736u, 2326742528381978032u, 53}, { 0, 565159647117824u, 288318340303167488u, 54}, { 0, 1130317180306432u, 436857960485093408u, 54}, { 0, 2260632246683648u, 4613937854749343874u, 54}, { 0, 4521262379438080u, 1173196501178909696u, 54}, { 0, 9042522644946944u, 4632519566898102400u, 54}, { 0, 18085043175964672u, 8813273026561u, 54}, { 0, 36170086385483776u, 4683747469346218057u, 53}, { 0, 283115671060736u, 324259448052785152u, 53}, { 0, 565681586307584u, 11712879804977004544u, 54}, { 0, 1130822006735872u, 4611826893363089413u, 54}, { 0, 2261102847592448u, 4611826790283874304u, 54}, { 0, 4521664529305600u, 1173196501178909696u, 54}, { 0, 9042787892731904u, 595038117954585216u, 54}, { 0, 18085034619584512u, 18016597549580292u, 54}, { 0, 36170077829103616u, 2306687435234357382u, 53}, { 0, 420017753620736u, 2902889407696764937u, 53}, { 0, 699298018886144u, 45038538897113088u, 54}, { 0, 1260057572672512u, 40532551399383040u, 54}, { 0, 2381576680245248u, 5773898465009008672u, 54}, { 0, 4624614895390720u, 1126176932759552u, 54}, { 0, 9110691325681664u, 4612248977037885568u, 54}, { 0, 18082844186263552u, 5119360519897218u, 54}, { 0, 36167887395782656u, 18295875671621634u, 53}, { 0, 35466950888980736u, 1477468785259610624u, 53}, { 0, 34905104758997504u, 76631633278533760u, 54}, { 0, 34344362452452352u, 436857960485093408u, 54}, { 0, 33222877839362048u, 166635419663892608u, 54}, { 0, 30979908613181440u, 1128648753545344u, 54}, { 0, 26493970160820224u, 595038117954585216u, 54}, { 0, 17522093256097792u, 2252969152611328u, 54}, { 0, 35607136465616896u, 5764607800395235840u, 53}, { 0, 9079539427579068672u, 2378464662405522454u, 52}, { 0, 8935706818303361536u, 2378464662405522454u, 53}, { 0, 8792156787827803136u, 167073095052427521u, 53}, { 0, 8505056726876686336u, 38843564238571554u, 53}, { 0, 7930856604974452736u, 324540682508174387u, 53}, { 0, 6782456361169985536u, 9288708625006593u, 53}, { 0, 4485655873561051136u, 1153484456724793346u, 53}, { 0, 9115426935197958144u, 1153484593081418770u, 52} }; +static struct magic_t bishopMagic[64] = {{ 0, 18049651735527936u, 19141544795963648u, 58}, { 0, 70506452091904u, 4505253206687752u, 59}, { 0, 275415828992u, 90354593216594048u, 59}, { 0, 1075975168u, 4613973694639800321u, 59}, { 0, 38021120u, 614189463018562176u, 59}, { 0, 8657588224u, 153694142109712388u, 59}, { 0, 2216338399232u, 4611976573233664521u, 59}, { 0, 567382630219776u, 374082743755080256u, 58}, { 0, 9024825867763712u, 18032677916247168u, 59}, { 0, 18049651735527424u, 4611721207162144849u, 59}, { 0, 70506452221952u, 4776012087296u, 59}, { 0, 275449643008u, 9295451711487353344u, 59}, { 0, 9733406720u, 303551645491200u, 59}, { 0, 2216342585344u, 148619346592208512u, 59}, { 0, 567382630203392u, 10953321663308055553u, 59}, { 0, 1134765260406784u, 2306142356220944904u, 59}, { 0, 4512412933816832u, 594475168263569698u, 59}, { 0, 9024825867633664u, 157696373151891552u, 59}, { 0, 18049651768822272u, 1182204866511054880u, 57}, { 0, 70515108615168u, 2256207020834816u, 57}, { 0, 2491752130560u, 704254387965952u, 57}, { 0, 567383701868544u, 562989686202432u, 57}, { 0, 1134765256220672u, 13907256408426942720u, 59}, { 0, 2269530512441344u, 19298778481721888u, 59}, { 0, 2256206450263040u, 4592935417696336u, 59}, { 0, 4512412900526080u, 4919074312566210768u, 59}, { 0, 9024834391117824u, 11529294245282317316u, 57}, { 0, 18051867805491712u, 40536794697302024u, 55}, { 0, 637888545440768u, 2378184277318730784u, 55}, { 0, 1135039602493440u, 2252075798954116u, 57}, { 0, 2269529440784384u, 77128610930233602u, 59}, { 0, 4539058881568768u, 1126449664787468u, 59}, { 0, 1128098963916800u, 4508204168188160u, 59}, { 0, 2256197927833600u, 4632286708805830664u, 59}, { 0, 4514594912477184u, 1297072495799042080u, 57}, { 0, 9592139778506752u, 79199197071873u, 55}, { 0, 19184279556981248u, 1441257709826736384u, 55}, { 0, 2339762086609920u, 6494191214571618368u, 57}, { 0, 4538784537380864u, 3820179484655618048u, 59}, { 0, 9077569074761728u, 155374497589920282u, 59}, { 0, 562958610993152u, 216318261380595712u, 59}, { 0, 1125917221986304u, 9227947141782112256u, 59}, { 0, 2814792987328512u, 9224080139556487425u, 57}, { 0, 5629586008178688u, 1312954725173508u, 57}, { 0, 11259172008099840u, 14195348636979822848u, 57}, { 0, 22518341868716544u, 1243277310774345984u, 57}, { 0, 9007336962655232u, 1345948328394816u, 59}, { 0, 18014673925310464u, 1243277310774345984u, 59}, { 0, 2216338399232u, 4611976573233664521u, 59}, { 0, 4432676798464u, 2397502563287040u, 59}, { 0, 11064376819712u, 36645624251285512u, 59}, { 0, 22137335185408u, 11822019940893327488u, 59}, { 0, 44272556441600u, 1805943519328735744u, 59}, { 0, 87995357200384u, 153694142109712388u, 59}, { 0, 35253226045952u, 4632096321797488644u, 59}, { 0, 70506452091904u, 4505253206687752u, 59}, { 0, 567382630219776u, 374082743755080256u, 58}, { 0, 1134765260406784u, 2306142356220944904u, 59}, { 0, 2832480465846272u, 10953321663308055553u, 59}, { 0, 5667157807464448u, 16141482087675924608u, 59}, { 0, 11333774449049600u, 5260489826817409556u, 59}, { 0, 22526811443298304u, 576531138303525376u, 59}, { 0, 9024825867763712u, 18032677916247168u, 59}, { 0, 18049651735527936u, 19141544795963648u, 58} }; diff --git a/src/chess/move.c b/src/chess/move.c index 5e02696..6c8249d 100644 --- a/src/chess/move.c +++ b/src/chess/move.c @@ -37,8 +37,6 @@ static size_t getTotalMagicSize(const struct magic_t *magic) { return size; } -uint_least64_t *overflowPtr; - static void initMagicHelper(uint_least64_t *attackTable, struct magic_t *magic, const uint_least8_t *direction, const uint_least8_t directionLength) { for(uint_least8_t field = 0; field < TOTAL_BOARD_SIZE; ++field, ++magic) { @@ -48,9 +46,6 @@ static void initMagicHelper(uint_least64_t *attackTable, struct magic_t *magic, do { // https://stackoverflow.com/questions/7277554/what-is-a-good-way-to-iterate-a-number-through-all-the-possible-values-of-a-mask const uint_least64_t attackMask = slidingMovementMask(direction, directionLength, field, pieceArangement); uint_least64_t *ptr = getMagicAttackPtr(pieceArangement, *magic); - if(ptr >= overflowPtr) { - printf("overflow\n"); - } *ptr = attackMask; pieceArangement = (pieceArangement - magic->mask) & magic->mask; } while(pieceArangement != 0); @@ -61,7 +56,6 @@ void initMagicTable() { const size_t rookMagicSize = getTotalMagicSize(rookMagic); const size_t size = rookMagicSize + getTotalMagicSize(bishopMagic); uint_least64_t *attackTable = malloc(size * sizeof *attackTable); - overflowPtr = attackTable + size; if(attackTable == NULL) { perror("failed to allocate memory: "); exit(1); @@ -139,16 +133,17 @@ void undoMove(uint_least64_t *board, struct move_t move, bool color) { bitboardClear(board, dstPiece, move.dst); if(move.capturedPiece != NOT_SELECTED) { const struct piece_t piece = {move.capturedPiece, !color}; - bitboardSet(board, piece, move.dst); + bitboardSet(board, piece, getCapturePos(move.src, move.dst, move.spezialMove)); } castleMoveRook(board, move.spezialMove, color, true); } static void addMove(struct addMoveCtx_t ctx, struct piece_t movedPiece, uint_least8_t src, - uint_least8_t dst, uint_least8_t spezialMove) { + uint_least8_t dst, uint_least8_t spezialMove, uint_least8_t promotionPiece) { uint_least64_t *board = ctx.gameState.board; uint_least8_t *movesLength = ctx.movesLength; uint_least8_t capturedPiece = NOT_SELECTED; + const uint_least8_t dstPiece = promotionPiece == NOT_SELECTED ? movedPiece.type : promotionPiece; const struct piece_t pieceAll = {ALL_PIECES, movedPiece.color}; if(bitboardGet(board, pieceAll, dst)) return; { @@ -164,7 +159,7 @@ static void addMove(struct addMoveCtx_t ctx, struct piece_t movedPiece, uint_lea } } } - const struct move_t move = {src, dst, spezialMove, movedPiece.type, movedPiece.type, capturedPiece}; + const struct move_t move = {src, dst, spezialMove, movedPiece.type, dstPiece, capturedPiece}; makeMove(ctx.gameState, move); { const bool color = ctx.gameState.color; @@ -181,7 +176,7 @@ static void addPreGenMoves(struct addMoveCtx_t ctx, const struct moveDst_t *move uint_least8_t src, struct piece_t piece) { const struct moveDst_t moveDstField = moveDst[src]; for(uint_least8_t i = 0; i < moveDstField.length; ++i) { - addMove(ctx, piece, src, moveDstField.dst[i], 0); + addMove(ctx, piece, src, moveDstField.dst[i], 0, NOT_SELECTED); } } @@ -193,7 +188,7 @@ static void moveSliding(const uint_least8_t *direction, uint_least8_t directionL const int_least8_t modifier = DIRECTION_MODIFIER[direction[j]]; for(uint_least8_t currentField = field + modifier, i = 0; i < getDirectionOffset(field, direction[j]); ++i, currentField += modifier) { - addMove(ctx, movedPiece, field, currentField, 0); + addMove(ctx, movedPiece, field, currentField, 0, NOT_SELECTED); if(bitboardGetAllPieces(board, currentField)) { // ziehe die info wo das nächste piece steht // über bit ops? break; @@ -210,12 +205,11 @@ static void movePawn(struct addMoveCtx_t ctx, bool color, uint_least8_t src, uin const struct piece_t piece = {PAWN, color}; if(promotion && (color == WHITE && dst < BOARD_SIZE || color == BLACK && dst >= BOARD_SIZE * (BOARD_SIZE - 1))) { for(uint_least8_t promotionPiece = QUEEN; promotionPiece < PAWN; ++promotionPiece) { - addMove(ctx, piece, src, dst, spezialMove); // always adds new move - moves[*movesLength].dstPiece = promotionPiece; + addMove(ctx, piece, src, dst, spezialMove, promotionPiece); } } else { - addMove(ctx, piece, src, dst, spezialMove); + addMove(ctx, piece, src, dst, spezialMove, NOT_SELECTED); } } @@ -233,12 +227,14 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece const uint_least64_t allPiecesMask = bitboardMaskAllPieces(board); const uint_least8_t rankShift = piece.color == WHITE ? BOARD_SIZE * (BOARD_SIZE - 1) : 0; const uint_least64_t shortCastleMask = (uint_least64_t)0b11 << (5 + rankShift); + const uint_least64_t shortCastleCheckMask = (uint_least64_t)0b11 << (4 + rankShift); const uint_least64_t longCastleMask = (uint_least64_t)0b111 << (1 + rankShift); - if(canCastle.shortCastle && !(allPiecesMask & shortCastleMask) && !inCheck(board, shortCastleMask, piece.color)) { - addMove(addmoveCtx, piece, src, src + 2 * DIRECTION_MODIFIER[EAST], SHORT_CASTLE); + const uint_least64_t longCastleCheckMask = (uint_least64_t)0b11 << (3 + rankShift); + if(canCastle.shortCastle && !(allPiecesMask & shortCastleMask) && !inCheck(board, shortCastleCheckMask, piece.color)) { + addMove(addmoveCtx, piece, src, src + 2 * DIRECTION_MODIFIER[EAST], SHORT_CASTLE, NOT_SELECTED); } - if(canCastle.longCastle && !(allPiecesMask & longCastleMask) && !inCheck(board, longCastleMask, piece.color)) { - addMove(addmoveCtx, piece, src, src + 2 * DIRECTION_MODIFIER[WEST], LONG_CASTLE); + if(canCastle.longCastle && !(allPiecesMask & longCastleMask) && !inCheck(board, longCastleCheckMask, piece.color)) { + addMove(addmoveCtx, piece, src, src + 2 * DIRECTION_MODIFIER[WEST], LONG_CASTLE, NOT_SELECTED); } break; } @@ -357,7 +353,7 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) { } { const int_least8_t dist = (int_least8_t)move.dst - (int_least8_t)move.src; - gameState.enPassantTo = FUTURE_EN_PASSANT ? move.src + dist / 2 : NOT_SELECTED; + gameState.enPassantTo = move.spezialMove == FUTURE_EN_PASSANT ? move.src + dist / 2 : NOT_SELECTED; } if(move.capturedPiece != NOT_SELECTED || srcPiece.type == PAWN) gameState.halfMoveCounter = 0; else ++gameState.halfMoveCounter; diff --git a/src/common/bitboard.c b/src/common/bitboard.c index a21f3f0..9650069 100644 --- a/src/common/bitboard.c +++ b/src/common/bitboard.c @@ -123,7 +123,10 @@ struct gameState_t newGameState(uint_least64_t *board, char *FEN) { else playerCastle->longCastle = true; } } - if(*++FEN == '-') ++FEN; + if(*++FEN == '-'){ + ++FEN; + gameState.enPassantTo = NOT_SELECTED; + } else { gameState.enPassantTo = *FEN++ - 'a'; gameState.enPassantTo += (BOARD_SIZE - *FEN++) * BOARD_SIZE; diff --git a/src/common/print.c b/src/common/print.c index dfcc362..20240c0 100644 --- a/src/common/print.c +++ b/src/common/print.c @@ -1,3 +1,4 @@ +#include "chess/move.h" #include "chess/types.h" #include #include @@ -20,3 +21,35 @@ void printPieceMask(uint_least64_t mask) { printf("\n"); } } + +void fieldToString(uint_least8_t field, char *output) { + output[0] = 'a' + field % BOARD_SIZE; + output[1] = '0' + BOARD_SIZE - field / BOARD_SIZE; + output[2] = '\0'; +} + +void printMove(const struct move_t move) { + char src[3]; + char dst[3]; + fieldToString(move.src, src); + fieldToString(move.dst, dst); + printf("%s%s", src, dst); + if(move.srcPiece != move.dstPiece) { + char piece; + switch(move.dstPiece) { + case ROOK: + piece = 'R'; + break; + case BISHOP: + piece = 'B'; + break; + case QUEEN: + piece = 'Q'; + break; + case KNIGHT: + piece = 'N'; + break; + } + printf("%c", piece); + } +} diff --git a/src/findMagicNumber.c b/src/findMagicNumber.c index 9f03289..5fe9bf5 100644 --- a/src/findMagicNumber.c +++ b/src/findMagicNumber.c @@ -6,9 +6,9 @@ #include #include #include -#include #include #include +#include #define MAX_BITS 12 #define MAX_SIZE (1 << MAX_BITS) @@ -76,12 +76,17 @@ static bool tryMagicNum(uint_least8_t field, struct magic_t *magic, uint_least64 static void initMagicField(uint_least64_t *attackMask, struct magic_t *magicTable, uint_least8_t field, const uint_least8_t *direction, uint_least8_t directionLength) { + defineDirectionOffset; struct magic_t *magic = magicTable + field; attackMask += field * MAX_SIZE; - - /* & 0x7e... because we dont care about the outer ring of pieces, because the pieces are threated as - enemy pieces. */ - magic->mask = slidingMovementMask(direction, directionLength, field, 0) & 0x7e7e7e7e7e7e7e7e; + const uint_least8_t *localDirectionOffset = DIRECTION_OFFSET + field * DIRECTION_LENGTH; + for(uint_least8_t j = 0; j < directionLength; ++j) { + const int_least8_t modifier = DIRECTION_MODIFIER[direction[j]]; + for(uint_least8_t currentField = field + modifier, i = 0; + i + 1 < localDirectionOffset[direction[j]]; ++i, currentField += modifier) { + magic->mask = bitsetSet(magic->mask, currentField); + } + } magic->shift = 64 - MAX_BITS - 1; uint_least64_t pieceArrangement = 0; size_t i = 0; diff --git a/src/generateCode/moveConsts.c b/src/generateCode/moveConsts.c index e0e6f68..c829037 100644 --- a/src/generateCode/moveConsts.c +++ b/src/generateCode/moveConsts.c @@ -111,11 +111,14 @@ int main() { const uint_least8_t pawnDirection = color == WHITE ? NORTH : SOUTH; const uint_least8_t *fieldDirectionOffset = directionOffset + field * DIRECTION_LENGTH; uint_least64_t checkMask = 0; - if(fieldDirectionOffset[pawnDirection] == 0) continue; + if(fieldDirectionOffset[pawnDirection] == 0) { + pawnCheck[2 * field + color] = 0; + continue; + } const uint_least8_t directions[] = {EAST, WEST}; for(uint_least8_t j = 0; j < LENGTH(directions); ++j) { - uint_least8_t dst = field + directionModifier[directions[j]] + directionModifier[pawnDirection]; if(fieldDirectionOffset[directions[j]] >= 1) { + const uint_least8_t dst = field + directionModifier[directions[j]] + directionModifier[pawnDirection]; checkMask = bitsetSet(checkMask, dst); } } diff --git a/test/moveGen.c b/test/moveGen.c index 926b228..f48b78b 100644 --- a/test/moveGen.c +++ b/test/moveGen.c @@ -4,6 +4,7 @@ #include #include #include +#include struct perf_t { char FEN[256]; @@ -11,11 +12,12 @@ struct perf_t { uint_least64_t nodes; }; -uint_least64_t perft(const struct gameState_t gameState, const uint_least8_t depth) { +static uint_least64_t perft(const struct gameState_t gameState, const uint_least8_t depth) { struct move_t moves[MAX_VALID_MOVES]; uint_least64_t nodes = 0; const uint_least8_t movesLength = validMoves(gameState, moves); if(depth == 1) return movesLength; + //if(depth == 0) return 1; for(uint_least8_t i = 0; i < movesLength; ++i) { const struct gameState_t newGameState = makeMove(gameState, moves[i]); nodes += perft(newGameState, depth - 1); @@ -24,6 +26,27 @@ uint_least64_t perft(const struct gameState_t gameState, const uint_least8_t dep return nodes; } +static void test(struct perf_t perf, const uint_least8_t i) { + uint_least64_t board[BITBOARD_LENGTH]; + const struct gameState_t gameState = newGameState(board, perf.FEN); + const uint_least64_t nodes = perft(gameState, perf.depth); + if(perf.nodes != nodes) { + printf("Test %" PRIuLEAST16 " failed: FEN: %s, depth: %" PRIuLEAST8 " calculated nodes: %" PRIuLEAST64 + ", expected nodes: %" PRIuLEAST64 "\n", i, perf.FEN, perf.depth, nodes, perf.nodes); + struct move_t moves[MAX_VALID_MOVES]; + const uint_least8_t movesLength = validMoves(gameState, moves); + for(uint_least8_t j = 0; j < movesLength; ++j) { + const struct gameState_t newGameState = makeMove(gameState, moves[j]); + const uint_least64_t nodes = perft(newGameState, perf.depth - 1); + undoMove(gameState.board, moves[j], gameState.color); + { + printMove(moves[j]); + printf(" %" PRIuLEAST64 "\n", nodes); + } + } + } +} + int main() { struct perf_t testPos[] = { {"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", 5, 4865609}, // start Position 0 @@ -32,15 +55,16 @@ int main() { {"r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1", 4, 422333}, // 3 {"rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8", 4, 2103487}, // 4 {"r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10", 4, 3894594}, // 5 + {"5k2/5pp1/1b3pP1/6P1/rN3P2/p5Nn/3r4/5n1K w - - 0 1", 5, 3949613}, // 6 + {"8/r2q2rQ/1b1pbkPp/BPPnNB2/pP2ppRP/n2pPpp1/PKR4P/1N6 w - - 0 1", 4, 2349215}, // 7 + {"n2Q2R1/K1B1pkbP/2p2P1P/2rPpB2/pq1p1Ppn/1PRN1bP1/P2p1p2/Nr6 w - - 0 1", 4, 4382892}, // 8 + {"B3n2N/1p1p3p/1Pr1P2B/3ppk2/P2q1p1p/Pbr1p1PP/P4NP1/b2RKnRQ w - - 0 1", 4, 1185726}, // 9 + {"8/1P2Q3/7R/3P4/R7/5p2/K7/2k4n w - - 0 1", 5, 5509638}, // 10 + {"8/N6P/K7/8/2RP4/p2n4/r7/5k2 w - - 0 1", 5, 4119222}, // 11 + {"n7/6kq/8/4P1p1/K7/3P4/3p1p2/8 w - - 0 1", 6, 11762127}, // 12 }; initMagicTable(); for(uint_least16_t i = 0; i < LENGTH(testPos); ++i) { - uint_least64_t board[BITBOARD_LENGTH]; - const struct gameState_t gameState = newGameState(board, testPos[i].FEN); - const uint_least64_t nodes = perft(gameState, testPos[i].depth); - if(testPos[i].nodes != nodes) { - printf("Test %" PRIuLEAST16 " failed: FEN: %s, depth: %" PRIuLEAST8 " calculated nodes: %" PRIuLEAST64 - ", expected nodes: %" PRIuLEAST64 "\n", i, testPos[i].FEN, testPos[i].depth, nodes, testPos[i].nodes); - } + test(testPos[i], i); } }