Пример #1
0
void bitbaseInit(void) {
	// Allocate memory.
	bitbase=malloc((FileNB/2)*RankNB*SqNB*ColourNB*sizeof(uint64_t));
	if (bitbase==NULL)
		mainFatalError("Error: Could not allocate memory for KPvK bitbase.\n");

	// Generate bitbase.
	bitbaseGen();
}
Пример #2
0
void ttInit(void) {
	// Setup tt as a HTable.
	tt=htableNew(sizeof(TTCluster), ttDefaultSizeMb);
	if (tt==NULL)
		mainFatalError("Error: Could not allocate transposition table.\n");

	// Add uci options to change size and clear.
	uciOptionNewSpin("Hash", &htableResizeInterface, tt, 1, ttMaxSizeMb, ttDefaultSizeMb);
	uciOptionNewButton("Clear Hash", &htableClearInterface, tt);
}
Пример #3
0
void bitbaseGen(void) {
	// Allocate array to use while generating bitbase.
	BitBaseResultFull *array=malloc((FileNB/2)*RankNB*SqNB*ColourNB*SqNB*sizeof(BitBaseResultFull));
	if (array==NULL)
		mainFatalError("Error: Could not allocate memory for generating KPvK bitbase.\n");

	// Mark positions which are obviously won/drawn/invalid (otherwise mark as unknown).
	Sq wKingSq, bKingSq;
	Colour stm;
	File pawnFile;
	Rank pawnRank;
	for(pawnFile=FileA;pawnFile<=FileD;++pawnFile)
		for(pawnRank=Rank8;pawnRank>=Rank2;--pawnRank) {
			Sq pawnSq=sqMake(pawnFile, pawnRank);

			for(wKingSq=0;wKingSq<SqNB;++wKingSq)
				for(stm=0;stm<ColourNB;++stm)
					for(bKingSq=0;bKingSq<SqNB;++bKingSq) {
						unsigned int index=bitbaseIndexFull(pawnFile, pawnRank, wKingSq, stm, bKingSq);
						array[index]=bitbaseComputeStaticResult(pawnSq, wKingSq, stm, bKingSq);
					}
		}

	// Loop over each pawn file and ranks in backwards order (from 7 to 2).
	// We can do this as different files are independent and, for example, rank 5
	// positions do not depend on any rank 4 positions.
	for(pawnFile=FileA;pawnFile<=FileD;++pawnFile)
		for(pawnRank=Rank7;pawnRank>=Rank2;--pawnRank) {
			Sq pawnSq=sqMake(pawnFile, pawnRank);

			// Compute position results based on child positions.
			bool change;
			do {
				change=false;

				for(wKingSq=0;wKingSq<SqNB;++wKingSq)
					for(stm=0;stm<ColourNB;++stm)
						for(bKingSq=0;bKingSq<SqNB;++bKingSq) {
							// Position already solved?
							unsigned int index=bitbaseIndexFull(pawnFile, pawnRank, wKingSq, stm, bKingSq);
							if (array[index]!=BitBaseResultFullUnknown)
								continue;

							// Try to compute result and update change flag if successful.
							BitBaseResultFull result=bitbaseComputeDynamicResult(array, pawnSq, wKingSq, stm, bKingSq);
							change|=((array[index]=result)!=BitBaseResultFullUnknown);
						}
			} while(change);

			// Update global array.
			// Any positions left 'unknown' are draws (although neither side can 'force' it per se).
			for(wKingSq=0;wKingSq<SqNB;++wKingSq)
				for(stm=0;stm<ColourNB;++stm) {
					unsigned int index=bitbaseIndex(pawnFile, pawnRank, wKingSq, stm);
					bitbase[index]=0;
					for(bKingSq=0;bKingSq<SqNB;++bKingSq) {
						unsigned int fullIndex=bitbaseIndexFull(pawnFile, pawnRank, wKingSq, stm, bKingSq);
						STATICASSERT(BitBaseResultWin==1);
						if (array[fullIndex]==BitBaseResultFullWin)
							bitbase[index]|=(1llu<<bKingSq);
					}
				}
		}

	// Verify counts.
#	ifndef NDEBUG
	unsigned countTotal=0, countWin=0, countDraw=0, countInvalid=0, countUnknown=0;
	for(pawnFile=FileA;pawnFile<=FileD;++pawnFile)
		for(pawnRank=Rank2;pawnRank<=Rank7;++pawnRank)
			for(wKingSq=0;wKingSq<SqNB;++wKingSq)
				for(stm=0;stm<ColourNB;++stm)
					for(bKingSq=0;bKingSq<SqNB;++bKingSq) {
						unsigned int fullIndex=bitbaseIndexFull(pawnFile, pawnRank, wKingSq, stm, bKingSq);
						switch(array[fullIndex]) {
							case BitBaseResultFullWin:
								++countWin;
							break;
							case BitBaseResultFullDraw:
								++countDraw;
							break;
							case BitBaseResultFullInvalid:
								++countInvalid;
							break;
							case BitBaseResultFullUnknown:
								++countUnknown;
							break;
						}
						++countTotal;
					}
	assert(countTotal==196608);
	assert(countWin==111282);
	assert(countInvalid==30932);
	assert(countDraw+countUnknown==54394);
#	endif

	// Free working array.
	free(array);
}