rt300@0
|
1 //
|
rt300@0
|
2 // TestController.h
|
rt300@0
|
3 // tweakathlon
|
rt300@0
|
4 //
|
rt300@0
|
5 // Created by Robert Tubb on 16/01/2014.
|
rt300@0
|
6 //
|
rt300@0
|
7 //
|
rt300@0
|
8
|
rt300@0
|
9 #ifndef __tweakathlon__TestController__
|
rt300@0
|
10 #define __tweakathlon__TestController__
|
rt300@0
|
11
|
rt300@0
|
12 #include <iostream>
|
rt300@0
|
13 #include "ofMain.h"
|
rt300@0
|
14 #include "globalVariables.h"
|
rt300@0
|
15 #include "boost/foreach.hpp"
|
rt300@0
|
16 #include "boost/bind.hpp"
|
rt300@0
|
17 #include "boost/function.hpp"
|
rt300@0
|
18 #include "timeController.h"
|
rt300@0
|
19 #include <functional>
|
rt300@0
|
20 #include <algorithm> // std::transform
|
rt300@0
|
21
|
rt300@0
|
22 //-------------------------------------------------------------
|
rt300@0
|
23 //-------------------------------------------------------------
|
rt300@0
|
24 template <class T>
|
rt300@0
|
25 class randomiseCCVal : public unary_function<T, T>{
|
rt300@0
|
26 public:
|
rt300@0
|
27 T operator()(T a){
|
rt300@0
|
28 return ofRandom(0,127);
|
rt300@0
|
29
|
rt300@0
|
30 };
|
rt300@0
|
31 };
|
rt300@0
|
32 template <class T>
|
rt300@0
|
33 class randomiseCCValIf : public binary_function<T, bool, T>{
|
rt300@0
|
34 public:
|
rt300@0
|
35 T operator()(T a, bool doit ){
|
rt300@0
|
36 if (doit)
|
rt300@0
|
37 return ofRandom(0,127);
|
rt300@0
|
38 return a;
|
rt300@0
|
39
|
rt300@0
|
40 };
|
rt300@0
|
41 };
|
rt300@0
|
42 template <class T>
|
rt300@0
|
43 class printThing : public unary_function<T, void>{
|
rt300@0
|
44 public:
|
rt300@0
|
45 void operator()(T a){
|
rt300@0
|
46 cout << a << endl;
|
rt300@0
|
47
|
rt300@0
|
48 };
|
rt300@0
|
49 };
|
rt300@0
|
50
|
rt300@0
|
51 template <class T>
|
rt300@0
|
52 class difference : public binary_function<T, T, T>{
|
rt300@0
|
53 public:
|
rt300@0
|
54 T operator()(T a, T b ){
|
rt300@0
|
55 return abs(a - b);
|
rt300@0
|
56 };
|
rt300@0
|
57 };
|
rt300@0
|
58 template <class T>
|
rt300@0
|
59 class squared : public unary_function<T, T>{
|
rt300@0
|
60 public:
|
rt300@0
|
61 T operator()(T a ){
|
rt300@0
|
62 return a*a;
|
rt300@0
|
63 };
|
rt300@0
|
64 };
|
rt300@0
|
65
|
rt300@0
|
66 //-------------------------------------------------------------
|
rt300@0
|
67
|
rt300@0
|
68 struct TestResult{
|
rt300@0
|
69 float realDistanceToTarget;
|
rt300@0
|
70 int targetBandHit; // eg bullseye = 0 edge = 7
|
rt300@0
|
71 TimerMillisec timeTaken;
|
rt300@0
|
72 int timeWindowHit; // eg < 5s = 0
|
rt300@0
|
73 int dimensionMult;
|
rt300@0
|
74 int score;
|
rt300@0
|
75 string displayText;
|
rt300@0
|
76 };
|
rt300@0
|
77
|
rt300@0
|
78 //-------------------------------------------------------------
|
rt300@0
|
79 // tests, once genrated by the testcontroller get passed around and used to set synths and so on
|
rt300@0
|
80 //-------------------------------------------------------------
|
rt300@0
|
81 class Test {
|
rt300@0
|
82 public:
|
rt300@0
|
83 Test(){
|
rt300@0
|
84 //?
|
rt300@0
|
85 identifyingLetter = '?';
|
rt300@0
|
86 timeGiven = 0;
|
rt300@0
|
87 panelType= SEQUENTIAL;
|
rt300@0
|
88 numDimensions = 0;
|
rt300@0
|
89
|
rt300@0
|
90 generateListOfControls();
|
rt300@0
|
91 makeRandomTarget();
|
rt300@0
|
92 setCandidateToTarget();
|
rt300@0
|
93 randomParamSelection(numDimensions);
|
rt300@0
|
94 randomiseCandidate();
|
rt300@0
|
95 scored = true;
|
rt300@0
|
96 withHint = false;
|
rt300@0
|
97 memoryTest = false;
|
rt300@0
|
98 targetPlaysLeft = 2; // only decr if memory test
|
rt300@0
|
99 };
|
rt300@0
|
100 // test with random params
|
rt300@0
|
101 Test(char letter, int atimeGiven, controlPanelType apanelType, int anumDimensions){
|
rt300@0
|
102 // init the stuff
|
rt300@0
|
103 //cout << "Making test " << letter << endl;
|
rt300@0
|
104
|
rt300@0
|
105 identifyingLetter = letter;
|
rt300@0
|
106 timeGiven = atimeGiven;
|
rt300@0
|
107 panelType= apanelType;
|
rt300@0
|
108 numDimensions = anumDimensions;
|
rt300@0
|
109
|
rt300@0
|
110 generateListOfControls();
|
rt300@0
|
111 makeRandomTarget();
|
rt300@0
|
112 setCandidateToTarget();
|
rt300@0
|
113 randomParamSelection(numDimensions);
|
rt300@0
|
114 randomiseCandidate();
|
rt300@0
|
115 scored = true;
|
rt300@0
|
116 };
|
rt300@0
|
117 // constructor that copies params from other test, pass em in
|
rt300@0
|
118 // also serves as a constructor that passes in specific settings
|
rt300@0
|
119 Test(char letter, int atimeGiven, controlPanelType apanelType, int anumDimensions, vector<int> aTargetValues, vector<int> aCandidateValues, vector<bool> adjustables){
|
rt300@0
|
120 identifyingLetter = letter;
|
rt300@0
|
121 timeGiven = atimeGiven;
|
rt300@0
|
122 panelType= apanelType;
|
rt300@0
|
123 numDimensions = anumDimensions;
|
rt300@0
|
124
|
rt300@0
|
125 whichCandidateParamAdjustable = adjustables;
|
rt300@0
|
126 generateListOfControls();
|
rt300@0
|
127 targetParams = aTargetValues;
|
rt300@0
|
128 candidateParams = aCandidateValues;
|
rt300@0
|
129 scored = true;
|
rt300@0
|
130
|
rt300@0
|
131 }
|
rt300@0
|
132 // constructot that enables you to set the space the test is carried out in but not start
|
rt300@0
|
133 Test(char letter, int aTimeGiven, controlPanelType pType, int aNumDimensions, vector<bool> adjustables){
|
rt300@0
|
134 identifyingLetter = letter;
|
rt300@0
|
135 timeGiven = aTimeGiven;
|
rt300@0
|
136 panelType= pType;
|
rt300@0
|
137 numDimensions = aNumDimensions;
|
rt300@0
|
138
|
rt300@0
|
139 generateListOfControls();
|
rt300@0
|
140 makeRandomTarget();
|
rt300@0
|
141 setCandidateToTarget();
|
rt300@0
|
142 whichCandidateParamAdjustable = adjustables;
|
rt300@0
|
143 randomiseCandidate();
|
rt300@0
|
144 scored = true;
|
rt300@0
|
145 }
|
rt300@0
|
146
|
rt300@0
|
147
|
rt300@0
|
148
|
rt300@0
|
149 // constructor that takes target values, but leaves those not adjustable
|
rt300@0
|
150 Test(char letter, int aTimeGiven, controlPanelType pType, int aNumDimensions, vector<bool> adjustables, vector<int> aTargetValues){
|
rt300@0
|
151 identifyingLetter = letter;
|
rt300@0
|
152 timeGiven = aTimeGiven;
|
rt300@0
|
153 panelType= pType;
|
rt300@0
|
154 numDimensions = aNumDimensions;
|
rt300@0
|
155
|
rt300@0
|
156 generateListOfControls();
|
rt300@0
|
157 targetParams = aTargetValues;
|
rt300@0
|
158 whichCandidateParamAdjustable = adjustables;
|
rt300@0
|
159 randomiseTargetAdjustable();
|
rt300@0
|
160 setCandidateToTarget();
|
rt300@0
|
161
|
rt300@0
|
162 randomiseCandidate();
|
rt300@0
|
163 scored = true;
|
rt300@0
|
164 }
|
rt300@0
|
165
|
rt300@0
|
166 // the one that is called from generate some tests!!
|
rt300@0
|
167 Test(char letter, int aTimeGiven, controlPanelType pType, int aNumDimensions, vector<bool> adjustables, vector<int> aTargetValues, bool ascored = true, bool ahint = false, bool aMemoryTest = false){
|
rt300@0
|
168 identifyingLetter = letter;
|
rt300@0
|
169 timeGiven = aTimeGiven;
|
rt300@0
|
170 panelType= pType;
|
rt300@0
|
171 numDimensions = aNumDimensions;
|
rt300@0
|
172
|
rt300@0
|
173 generateListOfControls();
|
rt300@0
|
174 targetParams = aTargetValues;
|
rt300@0
|
175 whichCandidateParamAdjustable = adjustables;
|
rt300@0
|
176 randomiseTargetAdjustable();
|
rt300@0
|
177 setCandidateToTarget();
|
rt300@0
|
178
|
rt300@0
|
179 randomiseCandidate();
|
rt300@0
|
180 scored = ascored;
|
rt300@0
|
181 withHint = ahint;
|
rt300@0
|
182 memoryTest = aMemoryTest;
|
rt300@0
|
183 targetPlaysLeft = 1; // only decr if memory test
|
rt300@0
|
184 };
|
rt300@0
|
185 bool isWithHint(){
|
rt300@0
|
186 return withHint;
|
rt300@0
|
187 };
|
rt300@0
|
188 bool isMemoryTest(){
|
rt300@0
|
189 return memoryTest;
|
rt300@0
|
190 };
|
rt300@0
|
191 bool isPractice(){
|
rt300@0
|
192 return !scored;
|
rt300@0
|
193 };
|
rt300@0
|
194 float euclideanDistance(vector<int> v1, vector<int> v2) const{
|
rt300@0
|
195 if (v1.size() != v2.size()){
|
rt300@0
|
196 cout << "ERROR ERROR: vectors must be same length for Mr Euclid";
|
rt300@0
|
197 return 0.;
|
rt300@0
|
198 }
|
rt300@0
|
199 vector<float> diff;
|
rt300@0
|
200
|
rt300@0
|
201 std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), difference<float>());
|
rt300@0
|
202 // sqr diff
|
rt300@0
|
203
|
rt300@0
|
204 std::transform(v1.begin(), v1.end(), v1.begin(),squared<float>());
|
rt300@0
|
205 float ans = std::accumulate(v1.begin(),v1.end(),0.0);
|
rt300@0
|
206
|
rt300@0
|
207 return sqrt(ans);
|
rt300@0
|
208
|
rt300@0
|
209 };
|
rt300@0
|
210
|
rt300@0
|
211 TestResult getScoreForAnswer(vector<int> answer, TimerMillisec timeTaken) const {
|
rt300@0
|
212 TestResult result;
|
rt300@0
|
213 stringstream msg;
|
rt300@0
|
214 int score = 0;
|
rt300@0
|
215 // work out euc distance from actual point
|
rt300@0
|
216 //for_each(answer.begin(),answer.end(),printThing<int>());
|
rt300@0
|
217 //for_each(targetParams.begin(),targetParams.end(),printThing<int>());
|
rt300@0
|
218 float dist = euclideanDistance(targetParams, answer);
|
rt300@0
|
219 auto dimComp = sqrt(numDimensions);
|
rt300@0
|
220 int band = -1;
|
rt300@0
|
221 if (dist < TARGET_SCORE_CC_BAND*dimComp){
|
rt300@0
|
222 score = 50;
|
rt300@0
|
223 band = 1;
|
rt300@0
|
224
|
rt300@0
|
225 msg << "DOUBLE BULLSEYE!" << endl;
|
rt300@0
|
226
|
rt300@0
|
227
|
rt300@0
|
228 }else if (dist < TARGET_SCORE_CC_BAND*2*dimComp){
|
rt300@0
|
229
|
rt300@0
|
230 score = 25;
|
rt300@0
|
231 band = 2;
|
rt300@0
|
232
|
rt300@0
|
233 msg << "SINGLE BULLSEYE!" << endl;
|
rt300@0
|
234
|
rt300@0
|
235 }else if (dist < TARGET_SCORE_CC_BAND*3*dimComp){
|
rt300@0
|
236
|
rt300@0
|
237 score = 15;
|
rt300@0
|
238 band = 3;
|
rt300@0
|
239 msg << "CLOSE..." << endl;
|
rt300@0
|
240
|
rt300@0
|
241 }else if (dist < TARGET_SCORE_CC_BAND*4*dimComp){
|
rt300@0
|
242 score = 5;
|
rt300@0
|
243 band = 4;
|
rt300@0
|
244 msg << "OK...ISH" << endl;
|
rt300@0
|
245
|
rt300@0
|
246 }else if (dist < TARGET_SCORE_CC_BAND*6*dimComp){ // 30
|
rt300@0
|
247 score = 2;
|
rt300@0
|
248 band = 5;
|
rt300@0
|
249 msg << "MEDIOCRE" << endl;
|
rt300@0
|
250
|
rt300@0
|
251 }else if (dist < TARGET_SCORE_CC_BAND*9*dimComp){ // 45
|
rt300@0
|
252 score = 1;
|
rt300@0
|
253 band = 6;
|
rt300@0
|
254 msg << "POOR..." << endl;
|
rt300@0
|
255
|
rt300@0
|
256 }else{
|
rt300@0
|
257 score = 0;
|
rt300@0
|
258 band = 7;
|
rt300@0
|
259 msg << "MISSED COMPLETELY!" << endl;
|
rt300@0
|
260
|
rt300@0
|
261
|
rt300@0
|
262 }
|
rt300@0
|
263 msg << "Distance from target: " << dist << endl;
|
rt300@0
|
264 msg << "Basic Score: " << score << endl;
|
rt300@0
|
265 msg << "-----" << endl;
|
rt300@0
|
266 msg << "Time taken: " << timeTaken/1000.0 << endl;
|
rt300@0
|
267 int window = -1;
|
rt300@0
|
268 if (timeTaken < 5000){
|
rt300@0
|
269 msg << "Under 5 seconds: 10x bonus" << endl;
|
rt300@0
|
270 score *= 10;
|
rt300@0
|
271 window = 1;
|
rt300@0
|
272 }else if (timeTaken < 10000){
|
rt300@0
|
273 msg << "Under 10 seconds: 5x bonus" << endl;
|
rt300@0
|
274 score *= 5;
|
rt300@0
|
275 window = 2;
|
rt300@0
|
276 }else if (timeTaken < 15000){
|
rt300@0
|
277 msg << "Under 15 seconds: 3x bonus" << endl;
|
rt300@0
|
278 score *=3;
|
rt300@0
|
279 window = 3;
|
rt300@0
|
280 }else if (timeTaken < 20000){
|
rt300@0
|
281 msg << "Under 20 seconds: 2x bonus" << endl;
|
rt300@0
|
282 score *=2;
|
rt300@0
|
283 window = 4;
|
rt300@0
|
284 }else if (timeTaken < 20000){
|
rt300@0
|
285 msg << "Under 25 seconds: no bonus" << endl;
|
rt300@0
|
286 score *=2;
|
rt300@0
|
287 window = 4;
|
rt300@0
|
288 }else if (timeTaken > 30000){
|
rt300@0
|
289 msg << "Over 30 seconds: TOO LATE!" << endl;
|
rt300@0
|
290 score *=0;
|
rt300@0
|
291 window = 4;
|
rt300@0
|
292 }
|
rt300@0
|
293 score *= numDimensions; // dimension bonus
|
rt300@0
|
294 msg << numDimensions*numDimensions << "X Dimension bonus" << endl;
|
rt300@0
|
295 msg << "-----" << endl;
|
rt300@0
|
296 if (!scored){
|
rt300@0
|
297
|
rt300@0
|
298 msg << "PRACTICE RUN, scored: " << score << endl;
|
rt300@0
|
299 score = 0;
|
rt300@0
|
300 }else{
|
rt300@0
|
301 msg << "Total: " << score << endl;
|
rt300@0
|
302 }
|
rt300@0
|
303 result.realDistanceToTarget = dist;
|
rt300@0
|
304 result.targetBandHit = band; // eg bullseye = 0 edge = 7
|
rt300@0
|
305 result.timeTaken = timeTaken;
|
rt300@0
|
306 result.timeWindowHit = window; // eg < 5s = 0
|
rt300@0
|
307 result.dimensionMult = numDimensions*numDimensions;
|
rt300@0
|
308 result.score = score;
|
rt300@0
|
309 result.displayText = msg.str();
|
rt300@0
|
310
|
rt300@0
|
311
|
rt300@0
|
312 return result;
|
rt300@0
|
313 }
|
rt300@0
|
314
|
rt300@0
|
315 vector<int> getChangeableIndices() {
|
rt300@0
|
316 vector<int> ids;
|
rt300@0
|
317 for(int i=0; i< whichCandidateParamAdjustable.size();i++){
|
rt300@0
|
318 if (whichCandidateParamAdjustable[i]){
|
rt300@0
|
319 ids.push_back(i);
|
rt300@0
|
320 }
|
rt300@0
|
321 }
|
rt300@0
|
322 return ids;
|
rt300@0
|
323 };
|
rt300@0
|
324 vector<int> getTargetValues() const{
|
rt300@0
|
325 return targetParams;
|
rt300@0
|
326
|
rt300@0
|
327 };
|
rt300@0
|
328 vector<int> getStartingCandidateValues() const{
|
rt300@0
|
329 return candidateParams;
|
rt300@0
|
330
|
rt300@0
|
331 };
|
rt300@0
|
332
|
rt300@0
|
333 int getNumDimensions() const{
|
rt300@0
|
334 return numDimensions;
|
rt300@0
|
335 }
|
rt300@0
|
336 char getTestLetter() const{
|
rt300@0
|
337 return identifyingLetter;
|
rt300@0
|
338 }
|
rt300@0
|
339 vector<bool> getAdjustableMask() const{
|
rt300@0
|
340 return whichCandidateParamAdjustable;
|
rt300@0
|
341 }
|
rt300@0
|
342 vector<controllerType> getListOfControlTypes() const{
|
rt300@0
|
343 return listOfControls;
|
rt300@0
|
344 }
|
rt300@0
|
345 controlPanelType getControlPanelType() const{
|
rt300@0
|
346 return panelType;
|
rt300@0
|
347 };
|
rt300@0
|
348 string getTestTypeAdvanceWarning(){
|
rt300@2
|
349
|
rt300@0
|
350 stringstream msg;
|
rt300@0
|
351
|
rt300@0
|
352 msg << "Next test: " << endl << endl;
|
rt300@0
|
353 if (panelType == REVISITABLE){
|
rt300@0
|
354 msg << "Sliders " << " x " << numDimensions << endl;
|
rt300@0
|
355 }
|
rt300@0
|
356 if (panelType == SIMULTANEOUS && numDimensions == 2){
|
rt300@0
|
357 msg << "XY pad " << endl;
|
rt300@0
|
358 }
|
rt300@0
|
359 if (panelType == SIMULTANEOUS && numDimensions == 3){
|
rt300@0
|
360 msg << "LEAP MOTION 3D -> -> -> -> ->" << endl;
|
rt300@0
|
361 }
|
rt300@2
|
362 if (panelType == REVISITABLE && numDimensions > 3){
|
rt300@2
|
363 msg << numDimensions << " DOF. The new frontier." << endl;
|
rt300@2
|
364 }
|
rt300@0
|
365 if (isMemoryTest()){
|
rt300@0
|
366 msg << endl << "MEMORY TEST - ONE TARGET LISTEN ONLY!!" << endl;
|
rt300@0
|
367 }
|
rt300@0
|
368 if (!scored){
|
rt300@0
|
369 msg << "PRACTICE RUN" << endl;
|
rt300@0
|
370 }
|
rt300@0
|
371
|
rt300@0
|
372 return msg.str();
|
rt300@0
|
373 };
|
rt300@0
|
374 bool checkTargetPlaysRemaining(){
|
rt300@0
|
375 if (isMemoryTest()){
|
rt300@0
|
376 targetPlaysLeft--;
|
rt300@0
|
377 if (targetPlaysLeft <= 0){
|
rt300@0
|
378 return false;
|
rt300@0
|
379 }
|
rt300@0
|
380
|
rt300@0
|
381 }
|
rt300@0
|
382 return true;
|
rt300@0
|
383 }
|
rt300@0
|
384 int getTargetPlaysLeft(){
|
rt300@0
|
385 return targetPlaysLeft;
|
rt300@0
|
386 }
|
rt300@0
|
387
|
rt300@0
|
388 private:
|
rt300@0
|
389 char identifyingLetter;
|
rt300@0
|
390 int timeGiven;
|
rt300@0
|
391 int timeElapsed;
|
rt300@0
|
392 controlPanelType panelType;
|
rt300@0
|
393 vector<controllerType> listOfControls;
|
rt300@0
|
394 int numDimensions;
|
rt300@0
|
395 vector<int> targetParams;
|
rt300@0
|
396 vector<int> candidateParams;
|
rt300@0
|
397 vector<bool> whichCandidateParamAdjustable;
|
rt300@0
|
398 int targetPlaysLeft;
|
rt300@0
|
399 bool scored, withHint, memoryTest;
|
rt300@0
|
400
|
rt300@0
|
401
|
rt300@0
|
402 void setCandidateToTarget(){
|
rt300@0
|
403
|
rt300@0
|
404 for(vector<int>::iterator ii = targetParams.begin(); ii < targetParams.end(); ii++){
|
rt300@0
|
405 candidateParams.push_back(*ii);
|
rt300@0
|
406 }
|
rt300@0
|
407 };
|
rt300@0
|
408
|
rt300@0
|
409 void generateListOfControls(){
|
rt300@0
|
410 // need ?
|
rt300@0
|
411 if(panelType == SEQUENTIAL || panelType == REVISITABLE){
|
rt300@0
|
412 for(int i=0;i<numDimensions;i++){
|
rt300@0
|
413 listOfControls.push_back(SLIDER);
|
rt300@0
|
414 }
|
rt300@0
|
415 }else{ // panelType == SIMULTANEOUS
|
rt300@0
|
416 if(numDimensions == 2){
|
rt300@0
|
417 listOfControls.push_back(XYPAD);
|
rt300@0
|
418 }
|
rt300@0
|
419 if(numDimensions == 3){
|
rt300@0
|
420 listOfControls.push_back(LEAP3D);
|
rt300@0
|
421
|
rt300@0
|
422 }
|
rt300@0
|
423 if(numDimensions == 4){
|
rt300@0
|
424 listOfControls.push_back(XYPAD);
|
rt300@0
|
425 listOfControls.push_back(XYPAD);
|
rt300@0
|
426 }
|
rt300@0
|
427
|
rt300@0
|
428 }
|
rt300@0
|
429 };
|
rt300@0
|
430
|
rt300@0
|
431 void makeRandomTarget(){
|
rt300@0
|
432 targetParams.clear();
|
rt300@0
|
433 for(int i=0;i<TOTAL_NUM_PARAMS; i++){
|
rt300@0
|
434 int n = ofRandom(0,127); // why does this consistently come out the same??
|
rt300@0
|
435 targetParams.push_back(n);
|
rt300@0
|
436
|
rt300@0
|
437 }
|
rt300@0
|
438
|
rt300@0
|
439 };
|
rt300@0
|
440
|
rt300@0
|
441
|
rt300@0
|
442 void randomiseCandidate(){
|
rt300@0
|
443 // randomises only those who are adjustable
|
rt300@0
|
444 // needs to be more than a certain distance (1/3 of total = 40?)
|
rt300@0
|
445 float reasonableDistance = 40.0*sqrt(numDimensions);
|
rt300@0
|
446 bool notFarEnough = true;
|
rt300@0
|
447 while (notFarEnough){
|
rt300@0
|
448 transform(candidateParams.begin(),
|
rt300@0
|
449 candidateParams.end(),
|
rt300@0
|
450 whichCandidateParamAdjustable.begin(),
|
rt300@0
|
451 candidateParams.begin(),
|
rt300@0
|
452 randomiseCCValIf<int>());
|
rt300@0
|
453 notFarEnough = ( euclideanDistance(candidateParams,targetParams) < reasonableDistance );
|
rt300@0
|
454 }
|
rt300@0
|
455 cout << "Test distance = " << euclideanDistance(candidateParams,targetParams) << endl;
|
rt300@0
|
456
|
rt300@0
|
457 };
|
rt300@0
|
458
|
rt300@0
|
459 void randomiseTargetAdjustable(){
|
rt300@0
|
460 // randomises only those who are adjustable, in the case where we want exactly the same space
|
rt300@0
|
461 // i.e. original target was fed in
|
rt300@0
|
462 transform(targetParams.begin(),
|
rt300@0
|
463 targetParams.end(),
|
rt300@0
|
464 whichCandidateParamAdjustable.begin(),
|
rt300@0
|
465 targetParams.begin(),
|
rt300@0
|
466 randomiseCCValIf<int>());
|
rt300@0
|
467
|
rt300@0
|
468
|
rt300@0
|
469 };
|
rt300@0
|
470
|
rt300@0
|
471 // select a few params that will be the ones to chng
|
rt300@0
|
472 void randomParamSelection(int numToChange){
|
rt300@0
|
473
|
rt300@0
|
474 for(int i= 0; i<numToChange; i++){
|
rt300@0
|
475 whichCandidateParamAdjustable.push_back(true);
|
rt300@0
|
476 }
|
rt300@0
|
477 for(int i= 0; i<(TOTAL_NUM_PARAMS - numToChange); i++){
|
rt300@0
|
478 whichCandidateParamAdjustable.push_back(false);
|
rt300@0
|
479 }
|
rt300@0
|
480 random_shuffle(whichCandidateParamAdjustable.begin(), whichCandidateParamAdjustable.end());
|
rt300@0
|
481 //for_each(whichCandidateParamAdjustable.begin(), whichCandidateParamAdjustable.end(), printThing<int>());
|
rt300@0
|
482
|
rt300@0
|
483 };
|
rt300@0
|
484
|
rt300@0
|
485
|
rt300@0
|
486 };
|
rt300@0
|
487 //-------------------------------------------------------------
|
rt300@0
|
488 //-------------------------------------------------------------
|
rt300@0
|
489
|
rt300@0
|
490
|
rt300@0
|
491 class TestController {
|
rt300@0
|
492 public:
|
rt300@0
|
493 static const int numDifferentTests;
|
rt300@0
|
494 static const int totalNumTests;
|
rt300@0
|
495 vector<Test>::iterator currentTest;
|
rt300@0
|
496 TestController(){
|
rt300@0
|
497
|
rt300@2
|
498 // int howManyTests,
|
rt300@2
|
499 // int numDimensions,
|
rt300@2
|
500 // controlPanelType panelType,
|
rt300@2
|
501 // int whichSpace,
|
rt300@2
|
502 // bool scored,
|
rt300@2
|
503 // bool aHint,
|
rt300@2
|
504 // bool aMemoryTest){
|
rt300@0
|
505
|
rt300@2
|
506 generateSomeTests(8, 8, REVISITABLE,1, false, false, false);
|
rt300@0
|
507
|
rt300@0
|
508 currentTest = testList.begin()-1; // dont do this
|
rt300@0
|
509 scoreRunningTotal = 0;
|
rt300@0
|
510 };
|
rt300@0
|
511
|
rt300@0
|
512
|
rt300@0
|
513 bool isLastTest(){
|
rt300@0
|
514 if (currentTest == testList.end()-1){
|
rt300@0
|
515 return true;
|
rt300@0
|
516 }
|
rt300@0
|
517 return false;
|
rt300@0
|
518 }
|
rt300@0
|
519 Test goToNextTest(){
|
rt300@0
|
520
|
rt300@0
|
521 if (currentTest < testList.end()-1){
|
rt300@0
|
522 currentTest++;
|
rt300@0
|
523 cout << "***************** NEXT TEST : " << (*currentTest).getTestLetter() << endl;
|
rt300@0
|
524 // return a copy
|
rt300@0
|
525 // (*currentTest).logThisTestSetup();
|
rt300@0
|
526
|
rt300@0
|
527 return *currentTest;
|
rt300@0
|
528
|
rt300@0
|
529 }else{
|
rt300@0
|
530 cout << "Sequence finished!!!!!!" << endl;
|
rt300@0
|
531 Test dummyTest;
|
rt300@0
|
532 return dummyTest;
|
rt300@0
|
533 }
|
rt300@0
|
534 };
|
rt300@0
|
535
|
rt300@0
|
536 Test getCurrentTest(){
|
rt300@0
|
537 // check for valid current test?
|
rt300@0
|
538 return *currentTest;
|
rt300@0
|
539 }
|
rt300@0
|
540
|
rt300@0
|
541 Test* getCurrentTestPtr(){
|
rt300@0
|
542 // check for valid current test?
|
rt300@0
|
543 if (currentTest < testList.end() && currentTest >= testList.begin()){
|
rt300@0
|
544 return &(*currentTest);
|
rt300@0
|
545 }else{
|
rt300@0
|
546 return NULL;
|
rt300@0
|
547 }
|
rt300@0
|
548 }
|
rt300@0
|
549 //
|
rt300@0
|
550 TestResult submitAnswer(vector<int> answer, TimerMillisec timeTaken){
|
rt300@0
|
551 TestResult result;
|
rt300@0
|
552 result = (*currentTest).getScoreForAnswer(answer, timeTaken);
|
rt300@0
|
553 scoreRunningTotal += result.score;
|
rt300@0
|
554 return result;
|
rt300@0
|
555 }
|
rt300@0
|
556 vector<controllerType> getCurrentListOfControls(){
|
rt300@0
|
557 return (*currentTest).getListOfControlTypes();
|
rt300@0
|
558 }
|
rt300@0
|
559 int getScoreRunningTotal(){
|
rt300@0
|
560 return scoreRunningTotal;
|
rt300@0
|
561 };
|
rt300@0
|
562 char getCurrentTestLetter(){
|
rt300@0
|
563 return (*currentTest).getTestLetter();
|
rt300@0
|
564 };
|
rt300@0
|
565 controlPanelType getCurrentPanelType(){
|
rt300@0
|
566 return (*currentTest).getControlPanelType();
|
rt300@0
|
567 };
|
rt300@0
|
568 vector<int> getCurrentChangeableParams(){
|
rt300@0
|
569 return (*currentTest).getChangeableIndices();
|
rt300@0
|
570 }
|
rt300@0
|
571 private:
|
rt300@0
|
572 void generate2DRandomTests();
|
rt300@0
|
573 void generate1DSpecificTests();
|
rt300@0
|
574 void generate2DSpecificTests();
|
rt300@0
|
575 void generate3DSpecificTests();
|
rt300@0
|
576 void generate4DTests();
|
rt300@0
|
577 void generateSomeTests(int howManyTests, int dimensions, controlPanelType panelType, int whichSpace, bool scored = true,bool aHint = false, bool aMemoryTest = false);
|
rt300@0
|
578
|
rt300@0
|
579 void generateTestSequence(){
|
rt300@0
|
580
|
rt300@0
|
581 };
|
rt300@0
|
582 //aregaergeargera
|
rt300@0
|
583 vector<Test> testList;
|
rt300@0
|
584
|
rt300@0
|
585 long scoreRunningTotal;
|
rt300@0
|
586
|
rt300@0
|
587
|
rt300@0
|
588 };
|
rt300@0
|
589
|
rt300@0
|
590
|
rt300@0
|
591
|
rt300@0
|
592
|
rt300@0
|
593 #endif /* defined(__tweakathlon__TestController__) */
|