This is PerformanceEvaluator.m in view mode; [Download] [Up]
// (C) Copyright 1992 Jim Patterson #import <appkit/appkit.h> #import <objc/objc.h> #import "PerformanceEvaluator.h" #import "GameView.h" @implementation PerformanceEvaluator + new { int i; self = [super new]; for (i=0; i<128; i++) keyInfo[i] = (keyStatType *) malloc(sizeof(keyStatType)); [self reset]; return self; } - setKeyColumn:anObject { keyColumn = anObject; return self; } - setRelColumn:anObject {relColumn = anObject; return self; } - setAbsColumn:anObject {absColumn = anObject; return self;} - setSuggText:anObject { suggText = anObject; return self; } - setPerformanceEvaluatorWindow:anObject {performanceEvaluatorWindow = anObject; return self; } - tellGameCompleted:(BOOL) wasCompleted {gameCompleted = (int) wasCompleted; return self; } - logOccurrence: (char) aChar // tell evaluator that one more aChar is in game { keyInfo[(int) aChar]->numInGame++; return self; } - logKeyMiss: (char) aChar // tell evaluator that one more aChar was missed { keyInfo[(int) aChar]->numMissed++; return self; } - reset // erase all existing statistics { int i; missedCount = 0; for (i=0; i<128; i++) { keyInfo[i]->key = (char) i; keyInfo[i]->numMissed = 0; keyInfo[i]->numInGame = 0; keyInfo[i]->relFreq = 0.0; keyInfo[i]->absFreq = 0.0; *(keyInfo[i]->relFreqBuff) = '\0'; *(keyInfo[i]->absFreqBuff) = '\0'; } for (i=0; i<6; i++) largest[i] = keyInfo[i]; missedCount = 0; gameCompleted = NO; [performanceEvaluatorWindow setDocEdited:YES]; return self; } - flush { int i,j; char ch[2]; ch[1] = '\0'; for (i=0; i<6; i++) if (largest[i]->numMissed>0) { ch[0] = largest[i]->key; [[keyColumn cellAt:i:0] setStringValue:ch]; [[relColumn cellAt:i:0] setStringValue:largest[i]->relFreqBuff]; [[absColumn cellAt:i:0] setStringValue:largest[i]->absFreqBuff]; } else { [[keyColumn cellAt:i:0] setStringValue:""]; [[relColumn cellAt:i:0] setStringValue:""]; [[absColumn cellAt:i:0] setStringValue:""]; } return self; } - summarize { int i,totalMistakes; // compute total number of mistakes totalMistakes = 0; for (i=33; i<128; i++) totalMistakes += keyInfo[i]->numMissed; for (i=33; i<128; i++) if (keyInfo[i]->numMissed >0) { keyInfo[i]->relFreq = ((float) keyInfo[i]->numMissed) / ((float) totalMistakes); keyInfo[i]->absFreq = ((float) keyInfo[i]->numMissed)/ ((float) keyInfo[i]->numInGame); if (keyInfo[i]->numMissed>=keyInfo[i]->numInGame) sprintf(keyInfo[i]->relFreqBuff,"%4.1f%%",0.0); else sprintf(keyInfo[i]->relFreqBuff,"%4.1f%%",(1-keyInfo[i]->absFreq) * 100.0); sprintf(keyInfo[i]->absFreqBuff,"%d of %d",keyInfo[i]->numMissed, keyInfo[i]->numInGame); } if ((gameCompleted) && (totalMistakes < 5)) [suggText setStringValue: "You did very well! You should move on to the next lesson or play this lesson again, but faster."]; else if (gameCompleted) [suggText setStringValue: "You were fast but not accurate. Customize a lesson to practice your weak keys."]; else [suggText setStringValue: "\nYou did not finish. You should play again at a slower speed."]; return self; } - debugDump { int i,dummy; printf("======== SUMMARY ========\n"); for (i=33; i<128; i++) { if (keyInfo[i]->numMissed >0) printf("%c:: missed: %d of %d relFreq:|%s|(%4.1f) absFreq:|%s|(%4.1f)\n", keyInfo[i]->key, keyInfo[i]->numMissed, keyInfo[i]->numInGame, keyInfo[i]->relFreqBuff,keyInfo[i]->relFreq, keyInfo[i]->absFreqBuff,keyInfo[i]->absFreq); } printf("===========================\n"); return self; } - sortKeyInfo // partial (6 largest only) selection sort of keyInfo[] by absFreq { int i,j,max; keyStatType *temp,*copy[128]; for (i=0; i<128; i++) copy[i] = keyInfo[i]; for (i=0; i<6; i++) { max = i; for (j=i+1; j<128; j++) if (copy[j]->absFreq > copy[max]->absFreq) max = j; largest[i] = copy[max]; temp = copy[max]; copy[max] = copy[i]; copy[i] = temp; } return self; } - free { int i; for (i=0; i<128; i++) free(keyInfo[i]); [super free]; return self; } - readInfo:(NXTypedStream *) tstream { int i; for (i=0; i<6; i++) { NXReadTypes(tstream,"{ciiff}", &(largest[i]->key), &(largest[i]->numMissed),&(largest[i]->numInGame), &(largest[i]->relFreq),&(largest[i]->absFreq)); NXReadArray(tstream, "c", 20,largest[i]->relFreqBuff); NXReadArray(tstream, "c", 20, largest[i]->absFreqBuff); } NXReadTypes(tstream,"ii",&missedCount,&gameCompleted); [performanceEvaluatorWindow setDocEdited:NO]; [self flush]; return self; } - writeInfo:(NXTypedStream *) tstream { int i; for (i=0; i<6; i++) { NXWriteTypes(tstream,"{ciiff}", &(largest[i]->key), &(largest[i]->numMissed),&(largest[i]->numInGame), &(largest[i]->relFreq),&(largest[i]->absFreq)); NXWriteArray(tstream, "c", 20, largest[i]->relFreqBuff); NXWriteArray(tstream, "c", 20, largest[i]->absFreqBuff); } NXWriteTypes(tstream,"ii",&missedCount,&gameCompleted); [performanceEvaluatorWindow setDocEdited:NO]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.