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@0
|
349 stringstream msg;
|
rt300@0
|
350
|
rt300@0
|
351 msg << "Next test: " << endl << endl;
|
rt300@0
|
352 if (panelType == REVISITABLE){
|
rt300@0
|
353 msg << "Sliders " << " x " << numDimensions << endl;
|
rt300@0
|
354 }
|
rt300@0
|
355 if (panelType == SIMULTANEOUS && numDimensions == 2){
|
rt300@0
|
356 msg << "XY pad " << endl;
|
rt300@0
|
357 }
|
rt300@0
|
358 if (panelType == SIMULTANEOUS && numDimensions == 3){
|
rt300@0
|
359 msg << "LEAP MOTION 3D -> -> -> -> ->" << endl;
|
rt300@0
|
360 }
|
rt300@0
|
361 if (isMemoryTest()){
|
rt300@0
|
362 msg << endl << "MEMORY TEST - ONE TARGET LISTEN ONLY!!" << endl;
|
rt300@0
|
363 }
|
rt300@0
|
364 if (!scored){
|
rt300@0
|
365 msg << "PRACTICE RUN" << endl;
|
rt300@0
|
366 }
|
rt300@0
|
367
|
rt300@0
|
368 return msg.str();
|
rt300@0
|
369 };
|
rt300@0
|
370 bool checkTargetPlaysRemaining(){
|
rt300@0
|
371 if (isMemoryTest()){
|
rt300@0
|
372 targetPlaysLeft--;
|
rt300@0
|
373 if (targetPlaysLeft <= 0){
|
rt300@0
|
374 return false;
|
rt300@0
|
375 }
|
rt300@0
|
376
|
rt300@0
|
377 }
|
rt300@0
|
378 return true;
|
rt300@0
|
379 }
|
rt300@0
|
380 int getTargetPlaysLeft(){
|
rt300@0
|
381 return targetPlaysLeft;
|
rt300@0
|
382 }
|
rt300@0
|
383
|
rt300@0
|
384 private:
|
rt300@0
|
385 char identifyingLetter;
|
rt300@0
|
386 int timeGiven;
|
rt300@0
|
387 int timeElapsed;
|
rt300@0
|
388 controlPanelType panelType;
|
rt300@0
|
389 vector<controllerType> listOfControls;
|
rt300@0
|
390 int numDimensions;
|
rt300@0
|
391 vector<int> targetParams;
|
rt300@0
|
392 vector<int> candidateParams;
|
rt300@0
|
393 vector<bool> whichCandidateParamAdjustable;
|
rt300@0
|
394 int targetPlaysLeft;
|
rt300@0
|
395 bool scored, withHint, memoryTest;
|
rt300@0
|
396
|
rt300@0
|
397
|
rt300@0
|
398 void setCandidateToTarget(){
|
rt300@0
|
399
|
rt300@0
|
400 for(vector<int>::iterator ii = targetParams.begin(); ii < targetParams.end(); ii++){
|
rt300@0
|
401 candidateParams.push_back(*ii);
|
rt300@0
|
402 }
|
rt300@0
|
403 };
|
rt300@0
|
404
|
rt300@0
|
405 void generateListOfControls(){
|
rt300@0
|
406 // need ?
|
rt300@0
|
407 if(panelType == SEQUENTIAL || panelType == REVISITABLE){
|
rt300@0
|
408 for(int i=0;i<numDimensions;i++){
|
rt300@0
|
409 listOfControls.push_back(SLIDER);
|
rt300@0
|
410 }
|
rt300@0
|
411 }else{ // panelType == SIMULTANEOUS
|
rt300@0
|
412 if(numDimensions == 2){
|
rt300@0
|
413 listOfControls.push_back(XYPAD);
|
rt300@0
|
414 }
|
rt300@0
|
415 if(numDimensions == 3){
|
rt300@0
|
416 listOfControls.push_back(LEAP3D);
|
rt300@0
|
417
|
rt300@0
|
418 }
|
rt300@0
|
419 if(numDimensions == 4){
|
rt300@0
|
420 listOfControls.push_back(XYPAD);
|
rt300@0
|
421 listOfControls.push_back(XYPAD);
|
rt300@0
|
422 }
|
rt300@0
|
423
|
rt300@0
|
424 }
|
rt300@0
|
425 };
|
rt300@0
|
426
|
rt300@0
|
427 void makeRandomTarget(){
|
rt300@0
|
428 targetParams.clear();
|
rt300@0
|
429 for(int i=0;i<TOTAL_NUM_PARAMS; i++){
|
rt300@0
|
430 int n = ofRandom(0,127); // why does this consistently come out the same??
|
rt300@0
|
431 targetParams.push_back(n);
|
rt300@0
|
432
|
rt300@0
|
433 }
|
rt300@0
|
434
|
rt300@0
|
435 };
|
rt300@0
|
436
|
rt300@0
|
437
|
rt300@0
|
438 void randomiseCandidate(){
|
rt300@0
|
439 // randomises only those who are adjustable
|
rt300@0
|
440 // needs to be more than a certain distance (1/3 of total = 40?)
|
rt300@0
|
441 float reasonableDistance = 40.0*sqrt(numDimensions);
|
rt300@0
|
442 bool notFarEnough = true;
|
rt300@0
|
443 while (notFarEnough){
|
rt300@0
|
444 transform(candidateParams.begin(),
|
rt300@0
|
445 candidateParams.end(),
|
rt300@0
|
446 whichCandidateParamAdjustable.begin(),
|
rt300@0
|
447 candidateParams.begin(),
|
rt300@0
|
448 randomiseCCValIf<int>());
|
rt300@0
|
449 notFarEnough = ( euclideanDistance(candidateParams,targetParams) < reasonableDistance );
|
rt300@0
|
450 }
|
rt300@0
|
451 cout << "Test distance = " << euclideanDistance(candidateParams,targetParams) << endl;
|
rt300@0
|
452
|
rt300@0
|
453 };
|
rt300@0
|
454
|
rt300@0
|
455 void randomiseTargetAdjustable(){
|
rt300@0
|
456 // randomises only those who are adjustable, in the case where we want exactly the same space
|
rt300@0
|
457 // i.e. original target was fed in
|
rt300@0
|
458 transform(targetParams.begin(),
|
rt300@0
|
459 targetParams.end(),
|
rt300@0
|
460 whichCandidateParamAdjustable.begin(),
|
rt300@0
|
461 targetParams.begin(),
|
rt300@0
|
462 randomiseCCValIf<int>());
|
rt300@0
|
463
|
rt300@0
|
464
|
rt300@0
|
465 };
|
rt300@0
|
466
|
rt300@0
|
467 // select a few params that will be the ones to chng
|
rt300@0
|
468 void randomParamSelection(int numToChange){
|
rt300@0
|
469
|
rt300@0
|
470 for(int i= 0; i<numToChange; i++){
|
rt300@0
|
471 whichCandidateParamAdjustable.push_back(true);
|
rt300@0
|
472 }
|
rt300@0
|
473 for(int i= 0; i<(TOTAL_NUM_PARAMS - numToChange); i++){
|
rt300@0
|
474 whichCandidateParamAdjustable.push_back(false);
|
rt300@0
|
475 }
|
rt300@0
|
476 random_shuffle(whichCandidateParamAdjustable.begin(), whichCandidateParamAdjustable.end());
|
rt300@0
|
477 //for_each(whichCandidateParamAdjustable.begin(), whichCandidateParamAdjustable.end(), printThing<int>());
|
rt300@0
|
478
|
rt300@0
|
479 };
|
rt300@0
|
480
|
rt300@0
|
481
|
rt300@0
|
482 };
|
rt300@0
|
483 //-------------------------------------------------------------
|
rt300@0
|
484 //-------------------------------------------------------------
|
rt300@0
|
485
|
rt300@0
|
486
|
rt300@0
|
487 class TestController {
|
rt300@0
|
488 public:
|
rt300@0
|
489 static const int numDifferentTests;
|
rt300@0
|
490 static const int totalNumTests;
|
rt300@0
|
491 vector<Test>::iterator currentTest;
|
rt300@0
|
492 TestController(){
|
rt300@0
|
493
|
rt300@0
|
494 generateSomeTests(1, 3, SIMULTANEOUS,1, false, true, true);
|
rt300@0
|
495
|
rt300@0
|
496 generateSomeTests(4, 2, SIMULTANEOUS, 1, true);
|
rt300@0
|
497
|
rt300@0
|
498 // 3 demo runs
|
rt300@0
|
499 generateSomeTests(1, 1, REVISITABLE, 1, false, false, false);
|
rt300@0
|
500 generateSomeTests(1, 2, SIMULTANEOUS, 1, false, false, true);
|
rt300@0
|
501 generateSomeTests(1, 3, SIMULTANEOUS,1, false, true, false);
|
rt300@0
|
502 // 3 practice runs
|
rt300@0
|
503
|
rt300@0
|
504 //----------------------
|
rt300@0
|
505 // 1D set 1
|
rt300@0
|
506 // 7 to 12
|
rt300@0
|
507 generateSomeTests(2, 1, REVISITABLE, 1, true);
|
rt300@0
|
508 generateSomeTests(2, 1, REVISITABLE, 2, true);
|
rt300@0
|
509 generateSomeTests(2, 1, REVISITABLE, 4, true);
|
rt300@0
|
510
|
rt300@0
|
511
|
rt300@0
|
512 // 2D tests 1
|
rt300@0
|
513 // 13 to 28
|
rt300@0
|
514 generateSomeTests(4, 2, REVISITABLE, 1, true);
|
rt300@0
|
515 generateSomeTests(4, 2, SIMULTANEOUS, 1, true);
|
rt300@0
|
516 generateSomeTests(4, 2, SIMULTANEOUS, 2, true);
|
rt300@0
|
517 generateSomeTests(4, 2, REVISITABLE, 2, true);
|
rt300@0
|
518
|
rt300@0
|
519 // 3D Tests 1
|
rt300@0
|
520 // 29 to 44
|
rt300@0
|
521 generateSomeTests(8,3,SIMULTANEOUS,1, true);
|
rt300@0
|
522 generateSomeTests(8,3,REVISITABLE,1, true);
|
rt300@0
|
523
|
rt300@0
|
524 //----------------------
|
rt300@0
|
525
|
rt300@0
|
526 // 1D set 2 (WITH HINTS)
|
rt300@0
|
527 // 45 to 47
|
rt300@0
|
528 generateSomeTests(1, 1, REVISITABLE, 1, true, true);
|
rt300@0
|
529 generateSomeTests(1, 1, REVISITABLE, 2, true, true);
|
rt300@0
|
530 generateSomeTests(1, 1, REVISITABLE, 4, true, true);
|
rt300@0
|
531
|
rt300@0
|
532 // 2D set 2 (WITH HINTS)
|
rt300@0
|
533 // 48 to 51
|
rt300@0
|
534 generateSomeTests(2, 2, SIMULTANEOUS, 1, true, true);
|
rt300@0
|
535 generateSomeTests(2, 2, REVISITABLE, 1, true, true);
|
rt300@0
|
536
|
rt300@0
|
537 // 3D set 2 (WITH HINTS)
|
rt300@0
|
538 // 52 to 59
|
rt300@0
|
539 generateSomeTests(4,3,REVISITABLE ,1, true, true);
|
rt300@0
|
540 generateSomeTests(4,3,SIMULTANEOUS,1, true, true);
|
rt300@0
|
541
|
rt300@0
|
542 //----------------------
|
rt300@0
|
543
|
rt300@0
|
544 // NOW MEMORY TESTS!
|
rt300@0
|
545 // 1D memory test
|
rt300@0
|
546 generateSomeTests(2, 1, REVISITABLE, 1, true,false, true);
|
rt300@0
|
547 generateSomeTests(2, 1, REVISITABLE, 2, true,false, true);
|
rt300@0
|
548 generateSomeTests(2, 1, REVISITABLE, 4, true,false, true);
|
rt300@0
|
549
|
rt300@0
|
550 // 2D set 3
|
rt300@0
|
551 generateSomeTests(4, 2, SIMULTANEOUS, 1, true,false, true);
|
rt300@0
|
552 generateSomeTests(4, 2, REVISITABLE, 1, true,false, true);
|
rt300@0
|
553 generateSomeTests(4, 2, REVISITABLE, 2, true,false, true);
|
rt300@0
|
554 generateSomeTests(4, 2, SIMULTANEOUS, 2, true,false, true);
|
rt300@0
|
555
|
rt300@0
|
556
|
rt300@0
|
557 // 3D set 3
|
rt300@0
|
558 // MEMORY
|
rt300@0
|
559 generateSomeTests(8,3,REVISITABLE ,1, true,false, true);
|
rt300@0
|
560 generateSomeTests(8,3,SIMULTANEOUS,1, true,false, true);
|
rt300@0
|
561 // 72
|
rt300@0
|
562 //----------------------
|
rt300@0
|
563
|
rt300@0
|
564
|
rt300@0
|
565
|
rt300@0
|
566 //generate1DSpecificTests();
|
rt300@0
|
567
|
rt300@0
|
568 //generate2DSpecificTests();
|
rt300@0
|
569 //generate3DSpecificTests();
|
rt300@0
|
570 //generate2DRandomTests();
|
rt300@0
|
571 //generate4DTests();
|
rt300@0
|
572 currentTest = testList.begin()-1; // dont do this
|
rt300@0
|
573 scoreRunningTotal = 0;
|
rt300@0
|
574 };
|
rt300@0
|
575
|
rt300@0
|
576
|
rt300@0
|
577 bool isLastTest(){
|
rt300@0
|
578 if (currentTest == testList.end()-1){
|
rt300@0
|
579 return true;
|
rt300@0
|
580 }
|
rt300@0
|
581 return false;
|
rt300@0
|
582 }
|
rt300@0
|
583 Test goToNextTest(){
|
rt300@0
|
584
|
rt300@0
|
585 if (currentTest < testList.end()-1){
|
rt300@0
|
586 currentTest++;
|
rt300@0
|
587 cout << "***************** NEXT TEST : " << (*currentTest).getTestLetter() << endl;
|
rt300@0
|
588 // return a copy
|
rt300@0
|
589 // (*currentTest).logThisTestSetup();
|
rt300@0
|
590
|
rt300@0
|
591 return *currentTest;
|
rt300@0
|
592
|
rt300@0
|
593 }else{
|
rt300@0
|
594 cout << "Sequence finished!!!!!!" << endl;
|
rt300@0
|
595 Test dummyTest;
|
rt300@0
|
596 return dummyTest;
|
rt300@0
|
597 }
|
rt300@0
|
598 };
|
rt300@0
|
599
|
rt300@0
|
600 Test getCurrentTest(){
|
rt300@0
|
601 // check for valid current test?
|
rt300@0
|
602 return *currentTest;
|
rt300@0
|
603 }
|
rt300@0
|
604
|
rt300@0
|
605 Test* getCurrentTestPtr(){
|
rt300@0
|
606 // check for valid current test?
|
rt300@0
|
607 if (currentTest < testList.end() && currentTest >= testList.begin()){
|
rt300@0
|
608 return &(*currentTest);
|
rt300@0
|
609 }else{
|
rt300@0
|
610 return NULL;
|
rt300@0
|
611 }
|
rt300@0
|
612 }
|
rt300@0
|
613 //
|
rt300@0
|
614 TestResult submitAnswer(vector<int> answer, TimerMillisec timeTaken){
|
rt300@0
|
615 TestResult result;
|
rt300@0
|
616 result = (*currentTest).getScoreForAnswer(answer, timeTaken);
|
rt300@0
|
617 scoreRunningTotal += result.score;
|
rt300@0
|
618 return result;
|
rt300@0
|
619 }
|
rt300@0
|
620 vector<controllerType> getCurrentListOfControls(){
|
rt300@0
|
621 return (*currentTest).getListOfControlTypes();
|
rt300@0
|
622 }
|
rt300@0
|
623 int getScoreRunningTotal(){
|
rt300@0
|
624 return scoreRunningTotal;
|
rt300@0
|
625 };
|
rt300@0
|
626 char getCurrentTestLetter(){
|
rt300@0
|
627 return (*currentTest).getTestLetter();
|
rt300@0
|
628 };
|
rt300@0
|
629 controlPanelType getCurrentPanelType(){
|
rt300@0
|
630 return (*currentTest).getControlPanelType();
|
rt300@0
|
631 };
|
rt300@0
|
632 vector<int> getCurrentChangeableParams(){
|
rt300@0
|
633 return (*currentTest).getChangeableIndices();
|
rt300@0
|
634 }
|
rt300@0
|
635 private:
|
rt300@0
|
636 void generate2DRandomTests();
|
rt300@0
|
637 void generate1DSpecificTests();
|
rt300@0
|
638 void generate2DSpecificTests();
|
rt300@0
|
639 void generate3DSpecificTests();
|
rt300@0
|
640 void generate4DTests();
|
rt300@0
|
641 void generateSomeTests(int howManyTests, int dimensions, controlPanelType panelType, int whichSpace, bool scored = true,bool aHint = false, bool aMemoryTest = false);
|
rt300@0
|
642
|
rt300@0
|
643 void generateTestSequence(){
|
rt300@0
|
644
|
rt300@0
|
645 };
|
rt300@0
|
646 //aregaergeargera
|
rt300@0
|
647 vector<Test> testList;
|
rt300@0
|
648
|
rt300@0
|
649 long scoreRunningTotal;
|
rt300@0
|
650
|
rt300@0
|
651
|
rt300@0
|
652 };
|
rt300@0
|
653
|
rt300@0
|
654
|
rt300@0
|
655
|
rt300@0
|
656
|
rt300@0
|
657 #endif /* defined(__tweakathlon__TestController__) */
|