//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // TreeCache::CacheResize(): // void TreeCache::CacheResize (uint size) { // If cache size decreases, simply reset it if (CacheSize > size) { SetCacheSize(size); return; } cachedTreeT* oldCache = Cache; uint oldSize = CacheSize; #ifdef WINCE Cache = (cachedTreeT*) my_Tcl_Alloc( sizeof(cachedTreeT [size])); #else Cache = new cachedTreeT [size]; #endif CacheSize = size; // Clear all the filters and nodes so they dont contain garbage: for (uint i=0; i < size; i++) { cachedTreeT * ctree = &(Cache[i]); ctree->cfilter = NULL; for (uint count = 0; count < MAX_TREE_NODES; count++) { initTreeNode (&(ctree->tree.node[count])); } } // copy old data to new Cache for (uint i=0; i < oldSize; i++) { cachedTreeT * ctree = &(oldCache[i]); Cache[i] = *ctree; } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Crosstable::AddPlayer() // Adds a player to the crosstable, if that player is not // already listed. errorT Crosstable::AddPlayer (idNumberT id, const char * name, eloT elo) { for (uint i = 0; i < PlayerCount; i++) { if (PlayerData[i]->id == id) { // The player already exists in the crosstable, but // check the elo rating and keep the largest value: if (elo > PlayerData[i]->elo) { PlayerData[i]->elo = elo; } return OK; } } if (PlayerCount == CROSSTABLE_MaxPlayers) { return ERROR_Full; } #ifdef WINCE playerDataT * pdata = (playerDataT *) my_Tcl_Alloc(sizeof( playerDataT)); #else playerDataT * pdata = new playerDataT; #endif PlayerData[PlayerCount] = pdata; pdata->id = id; pdata->name = strDuplicate (name); pdata->elo = elo; pdata->score = 0; pdata->gameCount = 0; pdata->tiebreak = 0; pdata->oppEloCount = 0; pdata->oppEloTotal = 0; pdata->oppEloScore = 0; pdata->title[0] = 0; pdata->country[0] = 0; pdata->birthdate = ZERO_DATE; pdata->ageInYears = 0; for (uint opp = 0; opp < CROSSTABLE_MaxPlayers; opp++) { pdata->firstClash[opp] = pdata->lastClash[opp] = NULL; pdata->clashCount[opp] = 0; } for (uint round = 1; round < CROSSTABLE_MaxRounds; round++) { pdata->roundClash[round] = NULL; } // Find this players title and country if the SpellChecker is defined: // if (SpellCheck != NULL && !strIsSurnameOnly (name)) // makes it need an initial if (SpellCheck != NULL ) { const char * comment = SpellCheck->GetComment (name); // SpellCheck->GetCommentExact // makes it need a full christian name if (comment != NULL) { strCopy (pdata->title, SpellChecker::GetTitle (comment)); strCopy (pdata->country, SpellChecker::GetLastCountry (comment)); pdata->birthdate = SpellChecker::GetBirthdate (comment); if (strEqual (pdata->title, "w")) { strCopy (pdata->title, "w "); } } } PlayerCount++; return OK; }
// scid_TB_init: // Initialises the tablebases given a directory string. All the tables // to be used must be in the directory; subdirectories are not // scanned. However, the directory string may have more than one // dircetory in it, separated by commas (,) or semicolons (;). // Returns the same value as scid_TB_MaxPieces(). uint scid_TB_Init (const char * egtb_path) { EGTB_maxpieces = (uint) IInitializeTb ((char *) egtb_path); #ifdef WINCE if (EGTB_cache != NULL) { my_Tcl_Free( (char *) EGTB_cache); } EGTB_cache = (byte *)my_Tcl_Alloc(sizeof(byte [EGTB_cachesize])); #else if (EGTB_cache != NULL) { delete[] (byte *) EGTB_cache; } EGTB_cache = new byte [EGTB_cachesize]; #endif FTbSetCacheSize (EGTB_cache, EGTB_cachesize); return EGTB_maxpieces; }
void * my_malloc(int size) { void * address; ASSERT(size>0); #ifdef WINCE address = (void*)my_Tcl_Alloc(size); #else address = malloc(size); #endif if (address == NULL) my_fatal("my_malloc(): malloc(): %s\n",strerror(errno)); return address; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // TreeCache::SetCacheSize(): // void TreeCache::SetCacheSize (uint size) { if (CacheSize > 0) { Delete(); } #ifdef WINCE Cache = (cachedTreeT*) my_Tcl_Alloc( sizeof(cachedTreeT [size])); #else Cache = new cachedTreeT [size]; #endif CacheSize = size; NumInUse = 0; MostRecentIndex = 0; // Clear all the filters and nodes so they dont contain garbage: for (uint i=0; i < size; i++) { cachedTreeT * ctree = &(Cache[i]); ctree->cfilter = NULL; for (uint count = 0; count < MAX_TREE_NODES; count++) { initTreeNode (&(ctree->tree.node[count])); } } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Crosstable::AddResult() // Adds a game result to the crosstable. errorT Crosstable::AddResult (uint gameNumber, idNumberT white, idNumberT black, resultT result, uint round, dateT date) { // Find the two players in the player data: int whiteIdx = -1; int blackIdx = -1; uint i; for (i=0; i < PlayerCount; i++) { if (PlayerData[i]->id == white) { whiteIdx = i; break; } } for (i=0; i < PlayerCount; i++) { if (PlayerData[i]->id == black) { blackIdx = i; break; } } // Both players must exist in the crosstable: if (whiteIdx < 0 || blackIdx < 0) { return ERROR_NotFound; } // The two players must actually be different: if (whiteIdx == blackIdx) { return ERROR_Corrupt; } playerDataT * pwhite = PlayerData[whiteIdx]; playerDataT * pblack = PlayerData[blackIdx]; // The number of prior encounters must be consistent: ASSERT (pwhite->clashCount[blackIdx] == pblack->clashCount[whiteIdx]); #ifdef WINCE clashT * whiteClash = (clashT *) my_Tcl_Alloc(sizeof( clashT)); #else clashT * whiteClash = new clashT; #endif if (pwhite->firstClash[blackIdx] == NULL) { // New head of list: pwhite->firstClash[blackIdx] = whiteClash; } else { pwhite->lastClash[blackIdx]->next = whiteClash; } whiteClash->next = NULL; pwhite->lastClash[blackIdx] = whiteClash; #ifdef WINCE clashT * blackClash = (clashT *) my_Tcl_Alloc(sizeof( clashT)); #else clashT * blackClash = new clashT; #endif if (pblack->firstClash[whiteIdx] == NULL) { // New head of list: pblack->firstClash[whiteIdx] = blackClash; } else { pblack->lastClash[whiteIdx]->next = blackClash; } blackClash->next = NULL; pblack->lastClash[whiteIdx] = blackClash; whiteClash->result = result; blackClash->result = RESULT_OPPOSITE[result]; whiteClash->gameNum = gameNumber; blackClash->gameNum = gameNumber; whiteClash->opponent = blackIdx; blackClash->opponent = whiteIdx; whiteClash->color = WHITE; blackClash->color = BLACK; whiteClash->round = round; blackClash->round = round; if (round > 0 && round < CROSSTABLE_MaxRounds) { pwhite->roundClash[round] = whiteClash; pblack->roundClash[round] = blackClash; if (round > MaxRound) { MaxRound = round; } } pwhite->clashCount[blackIdx]++; pblack->clashCount[whiteIdx]++; if (pwhite->clashCount[blackIdx] > MaxClashes) { MaxClashes = pwhite->clashCount[blackIdx]; } pwhite->gameCount++; pblack->gameCount++; // Update averages of opponents ratings for performance stats: if (result && pblack->elo > 0) { pwhite->oppEloCount++; pwhite->oppEloTotal += OpponentElo(pwhite->elo, pblack->elo); } if (result && pwhite->elo > 0) { pblack->oppEloCount++; pblack->oppEloTotal += OpponentElo(pblack->elo, pwhite->elo); } if (FirstDate == ZERO_DATE) { FirstDate = date; } if (date != ZERO_DATE && date < FirstDate) { FirstDate = date; } switch (result) { case RESULT_White: pwhite->score += (ThreeWin ? 6 : 2); if (pblack->elo > 0) { pwhite->oppEloScore += 2; } break; case RESULT_Black: pblack->score += (ThreeWin ? 6 : 2); if (pwhite->elo > 0) { pblack->oppEloScore += 2; } break; case RESULT_Draw: pwhite->score += (ThreeWin ? 2 : 1); pblack->score += (ThreeWin ? 2 : 1); if (pblack->elo > 0) { pwhite->oppEloScore ++; } if (pwhite->elo > 0) { pblack->oppEloScore ++; } break; default: break; // Nothing. } ResultCount[result]++; GameCount++; return OK; }