fixed move generation

This commit is contained in:
2024-03-23 20:39:12 +01:00
parent 69790345c5
commit 84fad9abb8
8 changed files with 104 additions and 37 deletions

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdint.h>
#include <chess/move.h>
#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);

View File

@ -1,3 +1,3 @@
#include <chess/types.h>
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} };

View File

@ -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;

View File

@ -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;

View File

@ -1,3 +1,4 @@
#include "chess/move.h"
#include "chess/types.h"
#include <stdio.h>
#include <stdint.h>
@ -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);
}
}

View File

@ -6,9 +6,9 @@
#include <stdint.h>
#include <chess/print.h>
#include <inttypes.h>
#include <assert.h>
#include <chess/magic.h>
#include <chess/generated/moveConsts.h>
#include <chess/bitboard.h>
#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;

View File

@ -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);
}
}

View File

@ -4,6 +4,7 @@
#include <stdint.h>
#include <chess/bitboard.h>
#include <stdio.h>
#include <chess/print.h>
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);
}
}