/* * This file keeps track of the user's bad guesses. * * Why is this in a separate file? 'cause I'm going to attempt to make * a clean OO API for this functionality. * * The PURPOSE of this API, is to attempt to make "try this again" * repeating, be more appropriately distributed, favouring much-missed ones. * * * The nasty part of this code is that currently it implements * a "priority queue", with a static array. * Maybe I should have made this a linked list. ug. * * Since this is finicky, I put in a -DDEBUG main() routine */ #include #define BADCACHESIZE 100 #include "defs.h" /* Here's the queue */ static TRANSLATION badcache[BADCACHESIZE]; static int maxbad=0; /* delete item at position 'delpos'. * move items from start+1, to end-1, to cover up * You'll probably want to call with * deletepos(position, maxbad) * * We do NOT adjust maxbad. Caller has to do that. */ static void deletepos(int delpos, int end){ int ndx; for(ndx=delpos; ndx0){ newpos=start-1; while(newpos>=0){ if(badcache[newpos]->incorrect < moveme->incorrect){ newpos-=1; } else break; } if(newpos < start-1){ insert(newpos+1, start, badcache[start]); maxbad--; return; } } /* no? check for decrease */ newpos=start+1; while(newposincorrect >= moveme->incorrect){ newpos++; } else break; } if(newpos>start+1){ deletepos(start, newpos); newpos-=1; badcache[newpos]=moveme; } } /* Subroutines are up here. Global routines are further down below */ /* pass in a TRANSLATIONS ptr, and a range of * the cache we should play with. * For pure insert, internal functions should use * insert(0, maxbad, whatever) * Except you should probably just want to use insertupdate() instead * * We allow the other syntax, for use with resort(). * * We dont have to optimize this right now, cause the * cache is relatively tiny. * * We assume that there is one "empty" space at * badcache[endndx] * * If tnum already exists, we will update existing slot, reguardless * of startndx and endndx * * We update maxbad here!! * */ static void insert(int startndx, int endndx, TRANSLATION trans) { /* find place it SHOULD go, between startndx and endndx*/ int idx,shuffleidx; if(endndx>=BADCACHESIZE){ /* cache full */ return; } idx=startndx; while(idxincorrect) < (trans->incorrect)){ break; } idx++; } /* Now make a "space" in middle of array, if needed */ if(idxidx){ badcache[shuffleidx]=badcache[shuffleidx-1]; shuffleidx--; } badcache[idx]=trans; maxbad++; } /* insert at right place, or update existing one and resort*/ static void insertupdate(TRANSLATION trans) { int idx; /* first search for pre-exist, in ENTIRE CACHE*/ for(idx=0;idxincorrect); } } #endif /**********************************************************************/ /* Here are the globally visible thingies */ /**********************************************/ /* If you like an explicit "remove" call, here it is. But normally, * this is not used directly by outsiders */ void RemoveBadCache(TRANSLATION trans){ deletebad(trans); } /* This tells us to insert or update or REMOVE a translation, from * our cache of missed translations. We assume the caller has * just changed the trans->incorrect value * */ void AdjustBadCache(TRANSLATION trans){ if(trans->incorrect==0){ RemoveBadCache(trans); return; } insertupdate(trans); } /* basically, just returns first missed one, or a random one */ TRANSLATION GetRepeat(){ if(maxbad==0){ return NULL; } return badcache[0]; } #ifdef DEBUGMAIN TRANSLATION translations[6]; main(){ int tc; for(tc=0;tc<6;tc++){ translations[tc]=(TRANSLATION)malloc(sizeof (struct translationstruct)); } translations[0]->incorrect=0; translations[1]->incorrect=1; translations[2]->incorrect=2; translations[3]->incorrect=3; translations[4]->incorrect=4; translations[5]->incorrect=5; AdjustBadCache(translations[3]); print(); AdjustBadCache(translations[5]); print(); AdjustBadCache(translations[2]); print(); AdjustBadCache(translations[3]); print(); AdjustBadCache(translations[4]); print(); AdjustBadCache(translations[1]); print(); printf("updating tnum5, %d\n", translations[5]); translations[5]->incorrect-=2; AdjustBadCache(translations[5]); print(); printf("updating tnum3, %d\n", translations[5]); translations[5]->incorrect+=2; AdjustBadCache(translations[5]); print(); printf("deleting tnum2, %d\n", translations[2]); RemoveBadCache(translations[2]); print(); } #endif /* DEBUG */