rt300@22: // rt300@22: // TrainingScoreManager.h rt300@22: // riftathon rt300@22: // rt300@22: // Created by Robert Tubb on 23/10/2014. rt300@22: // rt300@22: // rt300@22: rt300@22: #ifndef __riftathon__TrainingScoreManager__ rt300@22: #define __riftathon__TrainingScoreManager__ rt300@22: rt300@22: #include rt300@22: #include "ofMain.h" rt300@22: #include "algorithms.h" rt300@22: #include "globalVariables.h" rt300@32: #include "eventLogger.h" rt300@32: rt300@32: extern EventLogger eventLogger; rt300@22: //------------------------------------------------------------- rt300@22: rt300@22: struct TrainingTestResult{ rt300@22: float realDistanceToTarget; rt300@22: int targetBandHit; // eg bullseye = 0 edge = 7 rt300@22: float timeAllowed; rt300@22: int score; rt300@22: ofColor colorBand; rt300@22: string displayText; rt300@29: float bits; rt300@35: int difficultyLevel; rt300@22: }; rt300@22: rt300@22: class TrainingScoreManager{ rt300@22: rt300@22: // equiv of score bit of testController rt300@22: public: rt300@35: TrainingScoreManager(){ rt300@35: totalScored = 0; rt300@35: } rt300@22: rt300@35: TrainingTestResult getScoreForAnswer(vector targetParams, rt300@35: vector startPosition, rt300@35: vector answer, rt300@35: int timeAllowed, rt300@35: int difficulty, rt300@35: int whichInSequence, rt300@36: int presetIndex, rt300@36: int tempoLevel, rt300@36: int runNumber) { rt300@22: TrainingTestResult result; rt300@22: stringstream msg; rt300@22: int score = 0; rt300@22: // work out euc distance from actual point rt300@36: rt300@36: float initDist = euclideanDistance(targetParams, startPosition); rt300@22: float dist = euclideanDistance(targetParams, answer); rt300@36: if (initDist <= 0) { rt300@36: initDist = 0.001; rt300@36: } rt300@36: if (dist <= 0) dist = 0.001; rt300@29: float TP = calculateThroughput(TOTAL_NUM_PARAMS, dist, initDist, timeAllowed/1000.); rt300@36: cout << "Preset index " << presetIndex << endl; rt300@36: cout << "whichInSequence " << whichInSequence << endl; rt300@29: rt300@29: auto dimComp = sqrt(TOTAL_NUM_PARAMS); rt300@22: int band = -1; rt300@22: if (dist < TARGET_SCORE_CC_BAND*dimComp){ rt300@35: rt300@22: band = 1; rt300@22: rt300@22: msg << "DOUBLE BULLSEYE!" << endl; rt300@22: rt300@22: rt300@22: }else if (dist < TARGET_SCORE_CC_BAND*2*dimComp){ rt300@35: rt300@22: band = 2; rt300@22: rt300@22: msg << "SINGLE BULLSEYE!" << endl; rt300@22: rt300@22: }else if (dist < TARGET_SCORE_CC_BAND*3*dimComp){ rt300@35: rt300@22: band = 3; rt300@22: msg << "CLOSE..." << endl; rt300@22: rt300@22: }else if (dist < TARGET_SCORE_CC_BAND*4*dimComp){ rt300@35: rt300@22: band = 4; rt300@22: msg << "OK...ISH" << endl; rt300@22: rt300@22: }else if (dist < TARGET_SCORE_CC_BAND*6*dimComp){ // 30 rt300@35: rt300@22: band = 5; rt300@22: msg << "MEDIOCRE" << endl; rt300@22: rt300@22: }else if (dist < TARGET_SCORE_CC_BAND*9*dimComp){ // 45 rt300@35: rt300@22: band = 6; rt300@22: msg << "POOR..." << endl; rt300@22: rt300@22: }else{ rt300@35: rt300@22: band = 7; rt300@22: msg << "MISSED COMPLETELY!" << endl; rt300@22: rt300@22: rt300@22: } rt300@22: msg << "Distance from target: " << dist << endl; rt300@32: msg << "Score: " << round(TP*10) << endl; rt300@22: msg << "-----" << endl; rt300@22: msg << "Time allowed: " << timeAllowed/1000.0 << endl; rt300@22: rt300@22: msg << "-----" << endl; rt300@22: rt300@22: result.realDistanceToTarget = dist; rt300@22: result.targetBandHit = band; // eg bullseye = 0 edge = 7 rt300@22: result.timeAllowed = timeAllowed; rt300@37: result.score = int(round(TP*10.0)); rt300@22: result.displayText = msg.str(); rt300@35: result.difficultyLevel = difficulty; rt300@35: rt300@22: rt300@22: ofColor c; rt300@22: if(result.targetBandHit == 1){ rt300@35: rt300@35: c = ofColor(255,255,0,255); // yellow 1 rt300@22: }else if(result.targetBandHit == 2){ rt300@35: c = ofColor(255,0,0,255); // red 2 rt300@22: }else if(result.targetBandHit == 3){ rt300@35: c = ofColor(45,45,255,255); // blue 3 rt300@22: }else if(result.targetBandHit == 4){ rt300@35: c = ofColor(0,255,0,255); // green 4 rt300@22: }else{ rt300@37: c = ofColor(123,123,123,255); // grey worst rt300@22: } rt300@22: result.colorBand = c; rt300@22: rt300@37: if(result.score > 0) totalScored += result.score; rt300@36: rt300@32: rt300@32: vector details; rt300@35: rt300@35: details.push_back(result.realDistanceToTarget*1000); rt300@32: details.push_back(result.targetBandHit); rt300@32: details.push_back(result.timeAllowed); rt300@32: details.push_back(result.score); // 10 x throughput rt300@35: details.push_back(difficulty); rt300@35: details.push_back(whichInSequence); rt300@35: details.push_back(initDist*1000); rt300@35: details.push_back(presetIndex); rt300@36: details.push_back(tempoLevel); rt300@36: details.push_back(runNumber); rt300@32: eventLogger.logEvent(TRAINING_RESULT, details); rt300@34: details.clear(); rt300@34: details.insert(details.begin(), targetParams.begin(), targetParams.end()); rt300@34: details.insert(details.end(), answer.begin(), answer.end()); rt300@34: eventLogger.logEvent(TARGET_AND_MATCH, details); rt300@22: rt300@22: return result; rt300@22: } rt300@32: rt300@36: int getScore(){ rt300@36: cout << "RUNNING SCORE: " << totalScored << endl; rt300@36: return totalScored; rt300@36: }; rt300@32: rt300@22: private: rt300@32: rt300@32: rt300@29: float calculateThroughput(int numDims, float endDistance, float startDistance, float time) const{ rt300@36: rt300@29: float ISSR = numDims * log2( startDistance / endDistance); rt300@32: cout << "==========Result======= " << endl; rt300@29: cout << "start: " << startDistance << endl; rt300@29: cout << "end: " << endDistance << endl; rt300@29: cout << "ISSR: " << ISSR << endl; rt300@32: cout << "time: " << time << endl; rt300@29: float TP = ISSR / time; rt300@32: cout << "TP: " << TP << endl; rt300@29: return TP; rt300@29: } rt300@34: rt300@32: int totalScored; rt300@22: rt300@22: }; rt300@22: #endif /* defined(__riftathon__TrainingScoreManager__) */