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