rt300@8: // rt300@8: // SequenceController.h rt300@8: // riftathon rt300@8: // rt300@8: // Created by Robert Tubb on 17/10/2014. rt300@8: // rt300@8: // rt300@8: rt300@8: #ifndef __riftathon__SequenceController__ rt300@8: #define __riftathon__SequenceController__ rt300@8: rt300@8: #include rt300@8: #include "presetManager.h" rt300@8: rt300@13: #define MAX_TARGETS_IN_SEQUENCE 2 rt300@10: #define MIN_TEMPO 80 rt300@10: #define MAX_TEMPO 200 rt300@13: #define NUM_TEMPO_STEPS 3 rt300@10: #define NUM_PRESETS 16 rt300@10: rt300@13: //=============================================================================== rt300@13: rt300@10: rt300@8: class Sequence{ rt300@13: public: rt300@13: Sequence(vector si, int t, bool pv){ rt300@13: tempo = t; rt300@13: presetSequence = si; rt300@13: isSequencePreview = pv; rt300@13: curStep = 0; rt300@13: }; rt300@13: bool moveToNextStep(){ rt300@13: curStep++; rt300@13: rt300@13: if (curStep >= presetSequence.size()){ rt300@13: return false; rt300@13: }else{ rt300@13: return true; rt300@13: } rt300@13: }; rt300@13: int getCurrentPresetIndex(){ rt300@13: cout << "step : " << curStep << endl; rt300@13: if (curStep >= presetSequence.size()){ rt300@13: cout << "ERROR: off end of seq" << endl; rt300@13: return 0; rt300@13: } rt300@13: int i = presetSequence[curStep]; rt300@13: if(i < 0){ rt300@13: cout << "ERROR: negative index" << endl; rt300@13: } rt300@13: return i; rt300@13: rt300@13: }; rt300@13: int getStepNo(){ rt300@13: return curStep; rt300@13: } rt300@13: float tempo; rt300@8: rt300@13: bool isSequencePreview; // true if demoing the seq to the user, false if user is matching a seq rt300@13: vector presetSequence; rt300@13: int curStep; rt300@8: rt300@8: }; rt300@8: rt300@13: //=============================================================================== rt300@13: rt300@13: class Run{ rt300@13: public: rt300@13: Run(vector vs, int sl){ rt300@13: theSequences = vs; rt300@13: sequenceLength = sl; rt300@13: curSeq = 0; rt300@13: }; rt300@13: bool moveToNextStep(){ rt300@13: if (curSeq >= theSequences.size()){ rt300@13: return false; rt300@13: } rt300@13: rt300@13: bool stepFound = theSequences[curSeq].moveToNextStep(); rt300@13: if (stepFound){ rt300@13: return true; rt300@13: }else{ rt300@13: curSeq++; rt300@13: if (curSeq >= theSequences.size()){ rt300@13: return false; rt300@13: rt300@13: }else{ rt300@13: return true; rt300@13: } rt300@13: } rt300@13: rt300@13: return false; rt300@13: }; rt300@13: int getCurrentPresetIndex(){ rt300@13: cout << "seq : " << curSeq << endl; rt300@13: if (curSeq >= theSequences.size()){ rt300@13: cout << "ERROR: get preset" << endl; rt300@13: return 0; rt300@13: } rt300@13: return theSequences[curSeq].getCurrentPresetIndex(); rt300@13: rt300@13: }; rt300@13: int getSequenceNo(){ rt300@13: return curSeq; rt300@13: } rt300@13: rt300@13: vector theSequences; rt300@13: int curSeq; rt300@13: int sequenceLength; rt300@13: rt300@13: }; rt300@13: //=============================================================================== rt300@13: rt300@10: class SequenceController{ rt300@10: public: rt300@13: rt300@10: SequenceController(){ rt300@10: makeSequences(); rt300@13: tempoInc = float(MAX_TEMPO - MIN_TEMPO) / float(NUM_TEMPO_STEPS); rt300@13: curRun = 0; rt300@10: }; rt300@13: rt300@13: int stepForward(){ rt300@13: cout << "run : " << curRun << endl; rt300@13: if (curRun >= theRuns.size()){ rt300@13: return -1; rt300@13: } rt300@13: rt300@13: bool stepFound = theRuns[curRun].moveToNextStep(); rt300@13: if (stepFound){ rt300@13: return curRun; rt300@13: }else{ rt300@13: curRun++; rt300@13: if (curRun >= theRuns.size()){ rt300@13: cout << " END OF RUNS " << endl; rt300@13: return -1; rt300@13: rt300@13: }else{ rt300@13: return -2; // in order to stop the metro, next tick will just start thjings agaaain rt300@13: } rt300@13: } rt300@10: rt300@13: return false; rt300@13: rt300@13: } rt300@13: rt300@13: int getCurrentPresetIndex(){ rt300@10: rt300@10: // if end of sequence return something else so we can do something rt300@10: // if end of tempo ramp return something else rt300@13: if (curRun >= theRuns.size()){ rt300@13: cout << "DAAAAHHH" << endl; rt300@13: return -1; rt300@13: } rt300@13: int nextIndex = theRuns[curRun].getCurrentPresetIndex(); rt300@13: rt300@13: return nextIndex; rt300@13: }; rt300@13: vector getCurrentRunSeqAndStep(){ rt300@13: vector rss; rt300@13: // int r = curRun - theRuns.begin(); rt300@13: // int sq = (*curRun).getSequenceNo(); rt300@13: // int s = 4534534; rt300@13: // rss.push_back(r); rt300@13: // rss.push_back(sq); rt300@13: // rss.push_back(s); rt300@13: return rss; rt300@10: rt300@13: } rt300@10: protected: rt300@10: void makeSequences(){ rt300@13: srand (time(NULL)); rt300@10: rt300@13: rt300@13: for(int numInSequence = 1; numInSequence <= MAX_TARGETS_IN_SEQUENCE; numInSequence++){ rt300@13: float curTempo = MIN_TEMPO; rt300@13: vector seqsForRun; rt300@13: rt300@10: for(int tempoLevel = 0; tempoLevel < NUM_TEMPO_STEPS; tempoLevel++){ rt300@10: rt300@13: vector stepsForSequence; rt300@10: rt300@10: // repeat the same tests for xtra practice? rt300@10: for(int n=0; n < numInSequence; n++){ rt300@13: int next = getRandomButNot(NUM_PRESETS,stepsForSequence); rt300@13: stepsForSequence.push_back(next); rt300@10: rt300@10: cout << next << ","; rt300@10: } rt300@13: seqsForRun.push_back(Sequence(stepsForSequence, curTempo, true)); rt300@13: seqsForRun.push_back(Sequence(stepsForSequence, curTempo, false)); rt300@13: curTempo += tempoInc; rt300@10: cout << endl; rt300@13: rt300@10: } rt300@13: rt300@13: theRuns.push_back( Run(seqsForRun,numInSequence) ); rt300@13: rt300@10: cout << "---" << endl; rt300@10: } rt300@10: }; rt300@8: rt300@10: int getRandomButNot(int max, vector notThese){ rt300@10: rt300@10: bool there = true; rt300@13: int randomInt = rand() % max; rt300@10: rt300@10: if (notThese.size()){ rt300@10: while(there){ rt300@10: randomInt = rand() % max; rt300@10: vector::iterator result = std::find(notThese.begin(), notThese.end(), randomInt); rt300@10: there = (result != notThese.end()); rt300@10: } rt300@10: } rt300@10: return randomInt; rt300@10: rt300@10: }; rt300@13: rt300@8: rt300@8: private: rt300@13: rt300@13: vector theRuns; rt300@13: int curRun; rt300@13: rt300@13: float tempoInc; rt300@8: }; rt300@13: //=============================================================================== rt300@8: rt300@8: #endif /* defined(__riftathon__SequenceController__) */