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 "SequenceController.h" rt300@22: #include "algorithms.h" rt300@22: #include "globalVariables.h" 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@22: }; rt300@22: rt300@22: class TrainingScoreManager{ rt300@22: rt300@22: // equiv of score bit of testController rt300@22: public: rt300@22: rt300@29: TrainingTestResult getScoreForAnswer(vector targetParams, vector startPosition, vector answer, int timeAllowed) const { rt300@22: TrainingTestResult result; rt300@22: stringstream msg; rt300@22: int score = 0; rt300@22: // work out euc distance from actual point rt300@22: //for_each(answer.begin(),answer.end(),printThing()); rt300@22: //for_each(targetParams.begin(),targetParams.end(),printThing()); rt300@29: float initDist = euclideanDistance(startPosition, answer); rt300@22: float dist = euclideanDistance(targetParams, answer); rt300@29: rt300@29: float TP = calculateThroughput(TOTAL_NUM_PARAMS, dist, initDist, timeAllowed/1000.); rt300@29: rt300@29: cout << TP << 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@22: score = 50; 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@22: rt300@22: score = 25; 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@22: rt300@22: score = 15; rt300@22: band = 3; rt300@22: msg << "CLOSE..." << endl; rt300@22: rt300@22: }else if (dist < TARGET_SCORE_CC_BAND*4*dimComp){ rt300@22: score = 5; 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@22: score = 2; rt300@22: band = 5; rt300@22: msg << "MEDIOCRE" << endl; rt300@22: rt300@22: }else if (dist < TARGET_SCORE_CC_BAND*9*dimComp){ // 45 rt300@22: score = 1; rt300@22: band = 6; rt300@22: msg << "POOR..." << endl; rt300@22: rt300@22: }else{ rt300@22: score = 0; 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@22: msg << "Basic Score: " << score << 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@22: result.score = score; rt300@22: result.displayText = msg.str(); rt300@22: rt300@22: ofColor c; rt300@22: if(result.targetBandHit == 1){ rt300@22: // yellow red blue rt300@22: c = ofColor(255,255,0,255); rt300@22: }else if(result.targetBandHit == 2){ rt300@22: c = ofColor(255,0,0,255); rt300@22: }else if(result.targetBandHit == 3){ rt300@22: c = ofColor(45,45,255,255); rt300@22: }else if(result.targetBandHit == 4){ rt300@22: c = ofColor(0,255,0,255); rt300@22: }else{ rt300@22: c = ofColor(150,235,200,255); rt300@22: } rt300@22: result.colorBand = c; rt300@22: rt300@22: rt300@22: return result; rt300@22: } rt300@22: private: rt300@29: float calculateThroughput(int numDims, float endDistance, float startDistance, float time) const{ rt300@29: rt300@29: float ISSR = numDims * log2( startDistance / endDistance); rt300@29: cout << "start: " << startDistance << endl; rt300@29: cout << "end: " << endDistance << endl; rt300@29: cout << "ISSR: " << ISSR << endl; rt300@29: float TP = ISSR / time; rt300@29: return TP; rt300@29: } rt300@22: float euclideanDistance(vector v1, vector v2) const{ rt300@22: if (v1.size() != v2.size()){ rt300@22: cout << "ERROR ERROR: vectors must be same length for Mr Euclid"; rt300@22: return 0.; rt300@22: } rt300@22: vector diff; rt300@22: rt300@22: std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), difference()); rt300@22: // sqr diff rt300@22: rt300@22: std::transform(v1.begin(), v1.end(), v1.begin(),squared()); rt300@22: float ans = std::accumulate(v1.begin(),v1.end(),0.0); rt300@22: rt300@22: return sqrt(ans); rt300@22: rt300@22: }; rt300@22: rt300@22: }; rt300@22: #endif /* defined(__riftathon__TrainingScoreManager__) */