view SequenceController.mm @ 42:2bd658b44c2d

buttons dont lite up back to menu shows in more appropriate times
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Mon, 08 Dec 2014 18:29:10 +0000
parents ba426cc4e6e1
children 4ad0d218f890
line wrap: on
line source
//
//  SequenceGenerator.mm
//  riftathon
//
//  Created by Robert Tubb on 21/10/2014.
//
//

#include "SequenceController.h"
AnimStep::AnimStep(){
    type = PREVIEW_NEUTRAL_COUNT;
    presetIndex = -1;
    seqNumber = -1;
    runNumber = -1;
    whichInSequence = -1;
    
    tempo = MIN_TEMPO;
    
    isLastOfSeq = false;
    isLastOfRun = false;
    isLastOfAll = false;
    
    showsGuides = false;
    showsIcons = true;
    showsResultsAtEnd = false;
    difficulty = 0;
    setTimeFromTempo();
}

void AnimStep::saveResult(TrainingTestResult aresult){
    result = aresult;
}

Step::Step(){
    type = COUNT_IN;
    
    showsTargetIcon = false;
    showsControlSettings = false;
    showsControlGuides = false;
    showsMatchResults = false;
    hidesSliders = true;
    isPreview = false;
    
    allowsCandidateControl = false;
    playsTarget = false;
    playsCandidate = false;
    
    showsCountDown = true;
    
    isLastOfSeq = false;
    isLastOfRun = false;
    isLastOfAll = false;
    presetIndex = -1;
    seqNumber = -1;
    runNumber = -1;
    
    tempo = MIN_TEMPO;
}
void Step::setAsBlankCounter(){
    type = COUNT_IN;
    showsTargetIcon = false;
    showsControlSettings = false;
    showsControlGuides = false;
    showsMatchResults = false;
    hidesSliders = true;
    isPreview = false;
    
    allowsCandidateControl = false;
    playsTarget = false;
    playsCandidate = false;
    showsCountDown = true;
    
}
void Step::setAsPreviewPreparer(){
    type = PREVIEW_PREPARER;
    showsTargetIcon = true;
    showsControlSettings = false;
    showsControlGuides = true;
    
    showsMatchResults = false;
    hidesSliders = true;
    isPreview = true;
    
    allowsCandidateControl = true;
    playsTarget = true;
    playsCandidate = false;
    showsCountDown = true;
}

void Step::setAsPreviewPlayer(){
    type = PREVIEW_DISPLAYER;
    showsTargetIcon = true;
    showsControlSettings = false;
    showsControlGuides = true;
    showsMatchResults = false;
    hidesSliders = false;
    
    isPreview = true;
    
    allowsCandidateControl = true;
    playsTarget = true;
    playsCandidate = false;
    
    showsCountDown = false;
}

void Step::setAsMatchingPreparer(){
    // just a count down
    type = MATCHING_PREPARER;
    showsTargetIcon = true;
    showsControlSettings = false;
    showsControlGuides = false;
    showsMatchResults = false;
    hidesSliders = true;
    
    isPreview = false;
    
    allowsCandidateControl = true;
    playsTarget = true;
    playsCandidate = false;
    
    showsCountDown = true;
}
void Step::setAsMatchingInteraction(){
    type = MATCHING_INTERACTION;
    showsTargetIcon = true;
    showsControlSettings = false;
    showsControlGuides = true;
    showsMatchResults = false;
    hidesSliders = false;
    isPreview = false;
    
    allowsCandidateControl = true;
    playsTarget = false;
    playsCandidate = false; // ??
    
    showsCountDown = false;
}
void Step::setAsMatchingFeedback(){
    type = MATCHING_INTERACTION;
    showsTargetIcon = false;
    showsControlSettings = false;
    showsControlGuides = false;
    showsMatchResults = true;
    hidesSliders = true;
    isPreview = false;
    
    allowsCandidateControl = false;
    playsTarget = false;
    playsCandidate = true; // ??
    
    showsCountDown = false;
}

//=================================================================
//=================================================================
//=================================================================

SequenceController::SequenceController(){

};
//-------------------------------------------------------------------
void SequenceController::init(bool asoundOnlyMode){
    soundOnlyMode = asoundOnlyMode;
    tempoInc = float(MAX_TEMPO - MIN_TEMPO) / float(NUM_TEMPO_STEPS);
    timeInc = (MAX_TIME - MIN_TIME) / NUM_TEMPO_STEPS;
    generateSteps();
    setToStart();
};
//-------------------------------------------------------------------
AnimStep SequenceController::getNextStep(){
    
    currentStep++;
    if ((*currentStep).isLastOfRun){
        // uh
    }
    if ((*currentStep).isLastOfSeq){
        
    }
    return (*currentStep);
    
};
//-------------------------------------------------------------------
void SequenceController::setToStart(){
    currentStep = steps.begin();
}
//-------------------------------------------------------------------
void SequenceController::stepForward(){
    currentStep++;
};
//-------------------------------------------------------------------
float SequenceController::getStartTickTime(){
    return 1000. * (60.0/MIN_TEMPO);
}
//-------------------------------------------------------------------
void SequenceController::generateSteps(){
    srand (time(NULL));
    
    int run = 0;
    
    
    
    for(int numInSequence = MIN_TARGETS_IN_SEQUENCE; numInSequence <= MAX_TARGETS_IN_SEQUENCE; numInSequence++){
        
        for(int rep = 0; rep < NUM_REPETITIONS_AT_LEVEL; rep++){
        
        generateCountIn(1);
        
        if (soundOnlyMode){
            generateASoundOnlyRun(run, numInSequence);
        }else {
            generateRun(run, numInSequence);
        }
        steps.back().isLastOfRun = true;
        run++;
        cout << "-generate run finished-" << endl;
        }
    }
    totNumRuns = run;
    steps.back().isLastOfAll = true;
};

//-------------------------------------------------------------------


void SequenceController::generateCountIn(int countInLength){
    AnimStep countStep;
    for (int i = 0; i < countInLength; i++){
        countStep.whichInSequence = countInLength - i + 1;
        countStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
        countStep.showsResultsAtEnd = false;
        steps.push_back(countStep);
        
    }
};

//-------------------------------------------------------------------


vector<int> SequenceController::randomSequence(int numInSequence){
    vector<int> stepPresetIndices;
    // get some random ints
    for(int n=0; n < numInSequence; n++){
        int nextPreset = getRandomButNot(NUM_PRESETS,stepPresetIndices);
        stepPresetIndices.push_back(nextPreset);
        cout << nextPreset << ",";
    }
    
    return stepPresetIndices;
}

vector<int> SequenceController::nonRandomSequence(int numInSequence){
    vector<int> stepPresetIndices;
    // get some random ints
    for(int n=0; n < numInSequence; n++){
        int nextPreset = n;
        stepPresetIndices.push_back(nextPreset);
        cout << nextPreset << ",";
    }
    
    return stepPresetIndices;
}
//-------------------------------------------------------------------

void SequenceController::generateRun(int run, int numInSequence){
    float curTempo = MIN_TEMPO;
    int seqNo = 0;
    AnimStep nextStep;
    for(int tempoLevel = 0; tempoLevel < NUM_TEMPO_STEPS; tempoLevel++){
        
        
        
        // first we have a preparation count in
        nextStep.presetIndex = -1; // minus one means "blank"
        nextStep.runNumber = run;
        nextStep.seqNumber = seqNo;
        nextStep.whichInSequence = 0;
        nextStep.tempo = curTempo;
        nextStep.tempoLevel = tempoLevel;
        nextStep.setTimeFromTempo();
        nextStep.showsGuides = true;
        nextStep.difficulty = 0;
        nextStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
        nextStep.showsResultsAtEnd = false;
        
        //nextStep = makeFirstCountIn();
        steps.push_back(nextStep);
        if(numInSequence > 1){
            // xtra count for tricky one
            steps.push_back(nextStep);
        }
        
        
        // generate a sequence of random preset indices
        vector<int> stepPresetIndices = randomSequence(numInSequence);
        nextStep.thisSequence = stepPresetIndices;
        
        makePreview(stepPresetIndices, run, nextStep);
        
        // make GUIDED sequence (1 and 2)
        makeGuidedSequence(stepPresetIndices, run, nextStep);
        makeGuidedSequence(stepPresetIndices, run, nextStep);
        
        // make matching sequence without icon seq help
        makeMatchingSequence(stepPresetIndices, run, nextStep);
        makeMatchingSequence(stepPresetIndices, run, nextStep);
        
        steps.back().isLastOfSeq = true;
        if(numInSequence == 1){
            curTempo += tempoInc*0.8; // easier!!!??? will mess up time points
        }else{
            curTempo += tempoInc;
        }
        seqNo++;
        cout << endl;
        
    }
    // ANIM nextStep.setAsBlankCounter();
    nextStep.type = AnimStep::MATCHING_NEUTRAL_COUNT;
    steps.push_back(nextStep);
    
}
void SequenceController::makePreview(vector<int> stepPresetIndices, int run, AnimStep& nextStep){
    
    // MAKE PREVIEW
    int n = 1;
    for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
        // put loader
        
        nextStep.presetIndex = *si;
        nextStep.runNumber = run;
        nextStep.whichInSequence = n;
        if (soundOnlyMode){
            nextStep.showsGuides = false;
            nextStep.showsIcons = false ;
        }else{
            nextStep.showsGuides = true;
            nextStep.showsIcons = true;
        }
        nextStep.showsResultsAtEnd = false;
        nextStep.type = AnimStep::PREVIEW_MOVE;
        steps.push_back(nextStep);
        
        n++;
    }
    
    // move back to neutral
    nextStep.presetIndex = -1;
    nextStep.type = AnimStep::PREVIEW_LAST;
    nextStep.whichInSequence = 0;
    nextStep.difficulty = 0;
    nextStep.showsResultsAtEnd = true;
    steps.push_back(nextStep);
}
void SequenceController::makeGuidedSequence(vector<int> stepPresetIndices, int run, AnimStep& nextStep){
    int n = 1;
    for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
        // put loader
        nextStep.difficulty = 1;
        nextStep.presetIndex = *si;
        nextStep.runNumber = run;
        nextStep.whichInSequence = n;
        nextStep.setTimeFromTempo();
        nextStep.showsGuides = true;
        nextStep.showsIcons = true;
        nextStep.showsResultsAtEnd = true;
        nextStep.type = AnimStep::MATCHING_MOVE;
        steps.push_back(nextStep);
        
        if (SPACER_BARS){
            nextStep.type = AnimStep::MATCHING_LAST;
            steps.push_back(nextStep);
        }
        n++;
    }
    // move back to neutral
    nextStep.presetIndex = -1;
    nextStep.type = AnimStep::MATCHING_LAST;
    nextStep.showsGuides = true;
    nextStep.showsIcons = true;
    nextStep.whichInSequence = END_NEUTRAL_MATCH;
    nextStep.difficulty = 0;
    nextStep.showsResultsAtEnd = true;
    steps.push_back(nextStep);
}
void SequenceController::makeMatchingSequence(vector<int> stepPresetIndices, int run, AnimStep& nextStep){
    int n = 1;
    for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
        // put loader
        if(soundOnlyMode){
            nextStep.difficulty = 3;
        }else{
            nextStep.difficulty = 2;
        }
        nextStep.presetIndex = *si;
        nextStep.runNumber = run;
        nextStep.whichInSequence = n;
        nextStep.setTimeFromTempo();
        nextStep.showsGuides = false;
        nextStep.showsIcons = false;
        nextStep.showsResultsAtEnd = true;
        nextStep.type = AnimStep::MATCHING_MOVE;
        steps.push_back(nextStep);
        
        if (SPACER_BARS){
            nextStep.type = AnimStep::MATCHING_LAST;
            steps.push_back(nextStep);
        }
        n++;
    }
    // move back to neutral
    nextStep.presetIndex = -1;
    nextStep.type = AnimStep::MATCHING_LAST;
    nextStep.whichInSequence = END_NEUTRAL_MATCH;
    nextStep.difficulty = 0;
    nextStep.showsGuides = false; // fact that preset is -1 indicates end of each seq
    nextStep.showsIcons = false;
    nextStep.showsResultsAtEnd = true; // to record neutral hit
    steps.push_back(nextStep);
}
//-------------------------------------------------------------------
void SequenceController::generateASoundOnlyRun(int run, int numInSequence){
    
    // here the preview is sound only
    float curTempo = MIN_TEMPO;
    int seqNo = 0;
    AnimStep nextStep;
    for(int tempoLevel = 0; tempoLevel < NUM_TEMPO_STEPS; tempoLevel++){
        // first we have a preparation count in
        nextStep.presetIndex = -1; // minus one means "blank"
        nextStep.runNumber = run;
        nextStep.seqNumber = seqNo;
        nextStep.whichInSequence = 0;
        nextStep.difficulty = 0;
        nextStep.tempo = curTempo;
        nextStep.showsGuides = true; // guide shown for neutral point
        nextStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
        nextStep.showsResultsAtEnd = false;
        steps.push_back(nextStep);
        
        // generate a sequence of random preset indices
        vector<int> stepPresetIndices = randomSequence(numInSequence);
        nextStep.thisSequence = stepPresetIndices;
        
        makePreview(stepPresetIndices, run, nextStep);
        
        // make matching sequence without icon seq help
        makeMatchingSequence(stepPresetIndices, run, nextStep);
        makeMatchingSequence(stepPresetIndices, run, nextStep);
        
        
        steps.back().isLastOfSeq = true;
        curTempo += tempoInc;
        seqNo++;
    }
    // shows last result ?
    nextStep.type = AnimStep::MATCHING_NEUTRAL_COUNT;
    steps.push_back(nextStep);
}
//-------------------------------------------------------------------

void SequenceController::generateARun(int run, int numInSequence){
    float curTempo = MIN_TEMPO;
    int seqNo = 0;
    AnimStep nextStep;
    for(int tempoLevel = 0; tempoLevel < NUM_TEMPO_STEPS; tempoLevel++){
        
        
        
        // first we have a preparation count in
        nextStep.presetIndex = -1; // minus one means "blank"
        nextStep.runNumber = run;
        nextStep.seqNumber = seqNo;
        nextStep.whichInSequence = 0;
        nextStep.tempo = curTempo;
        nextStep.tempoLevel = tempoLevel;
        nextStep.setTimeFromTempo();
        nextStep.showsGuides = false;
        nextStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
        nextStep.showsResultsAtEnd = false;
        // two neutrals between the new sequences
        steps.push_back(nextStep);
        nextStep.showsGuides = true;
        steps.push_back(nextStep);
        
        // generate a sequence of random preset indices
        vector<int> stepPresetIndices = randomSequence(numInSequence);
        nextStep.thisSequence = stepPresetIndices;

        // make preview sequence
        int n = 1;
        for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
            // put loader
            
            nextStep.presetIndex = *si;
            nextStep.runNumber = run;
            nextStep.seqNumber = seqNo;
            nextStep.whichInSequence = n;

            nextStep.showsGuides = true;
            nextStep.showsIcons = true;
            nextStep.showsResultsAtEnd = false;
            nextStep.type = AnimStep::PREVIEW_MOVE;
            steps.push_back(nextStep);
            
            if (SPACER_BARS){
                nextStep.type = AnimStep::PREVIEW_LAST;
                steps.push_back(nextStep);
            }
            n++;
        }
        
        // move back to neutral
        nextStep.presetIndex = -1;
        nextStep.type = AnimStep::PREVIEW_MOVE;
        nextStep.difficulty = 0;
        nextStep.whichInSequence = 0;
        nextStep.showsResultsAtEnd = true;
        steps.push_back(nextStep);
        
        // make GUIDED sequence
        n = 1;
        for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
            // put loader
            nextStep.difficulty = 1;
            nextStep.presetIndex = *si;
            nextStep.seqNumber = seqNo;
            nextStep.whichInSequence = n;

            nextStep.showsGuides = true;
            nextStep.showsIcons = true;
            nextStep.showsResultsAtEnd = true;
            nextStep.type = AnimStep::MATCHING_MOVE;
            steps.push_back(nextStep);

            if (SPACER_BARS){
                nextStep.type = AnimStep::MATCHING_LAST;
                steps.push_back(nextStep);
            }
            n++;
        }
        // move back to neutral
        nextStep.presetIndex = -1;
        nextStep.whichInSequence = 0;
        nextStep.type = AnimStep::MATCHING_LAST;
        nextStep.showsResultsAtEnd = false;
        steps.push_back(nextStep);
        
        
        // make matching sequence with icon seq help
        n = 1;
        for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
            // put loader
            nextStep.difficulty = 2;
            nextStep.presetIndex = *si;
            nextStep.whichInSequence = n;

            nextStep.showsGuides = false;
            nextStep.showsIcons = true;
            nextStep.type = AnimStep::MATCHING_MOVE;
            nextStep.showsResultsAtEnd = true;
            steps.push_back(nextStep);
            
            if (SPACER_BARS){
                nextStep.type = AnimStep::MATCHING_LAST;
                steps.push_back(nextStep);
            
            }
            n++;

        }
        
        // move back to neutral
        nextStep.presetIndex = -1;
        nextStep.whichInSequence = 0;
        nextStep.type = AnimStep::MATCHING_LAST;
        nextStep.showsResultsAtEnd = false;
        steps.push_back(nextStep);
        
        // make matching sequence WITHOUT icon seq help
        n = 1;
        for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
            // put loader
            nextStep.difficulty = 3;
            nextStep.presetIndex = *si;
            nextStep.whichInSequence = n;
            
            nextStep.showsGuides = false;
            nextStep.showsIcons = false;
            
            nextStep.type = AnimStep::MATCHING_MOVE;
            nextStep.showsResultsAtEnd = true;
            
            steps.push_back(nextStep);
            
            if (SPACER_BARS){
                nextStep.type = AnimStep::MATCHING_LAST;
                steps.push_back(nextStep);
                
            }
            n++;
            
        }
        
        nextStep.type = AnimStep::MATCHING_LAST;
        nextStep.presetIndex = -1;
        nextStep.whichInSequence = 0;
        nextStep.showsGuides = false; // so you know when to go to neutral
        nextStep.showsResultsAtEnd = false;
        steps.push_back(nextStep);
        
        steps.back().isLastOfSeq = true;
        curTempo += tempoInc;
        seqNo++;
        cout << endl;
        
    }
    // ANIM nextStep.setAsBlankCounter();
    nextStep.type = AnimStep::MATCHING_NEUTRAL_COUNT;
    steps.push_back(nextStep);
    
}
//-----------------------------------------------------------------------
void SequenceController::saveResultForCurrentStep(TrainingTestResult result){
    (*currentStep).saveResult(result);
    
}
//-----------------------------------------------------------------------
TrainingTestResult SequenceController::getResultForPreviousStep(){
    if (currentStep == steps.begin()){

        cout << "ERROR - " << endl;

    }
    return (*currentStep--).result;
    

}
//-----------------------------------------------------------------------


int SequenceController::getRandomButNot(int max, vector<int> notThese){
    
    bool there = true;
    int randomInt = rand() % max;
    
    if (notThese.size()){
        while(there){
            randomInt = rand() % max;
            vector<int>::iterator result = std::find(notThese.begin(), notThese.end(), randomInt);
            there =  (result != notThese.end());
        }
    }
    return randomInt;
    
};