mardi 14 mars 2017

Random returns same value in for loop

I have reduced my code to be minimal and it compiles reproducing the same error. I know it puts out warnings, you don't need to mention them. I am pretty new to coding, so I appreciate the help. The problem I have is that the vectors Xpos and Ypos are returning the same value for each completion of the for loop in main(). Can you help me find what's wrong? Thank you so much. Code:

#include "stdafx.h"
#include <ctime>
#include <cmath>
#include <vector>
#include <random>
#include <iostream>

using namespace std;

//ignor this overload operator cout for vector

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
    out << "[";
    size_t last = v.size() - 1;
    for (size_t i = 0; i < v.size(); ++i) {
        out << v[i];
        if (i != last)
            out << ", ";
    }
    out << "]";
    return out;
}

//error is here?

int phaseTwoSimulate(double &Xpos, double &Ypos, int diameter, double stepSize) {


    while (pow(Xpos - 200, 2) + pow(Ypos - 200, 2) < pow(diameter, 2)) {

        int direction = rand() % 8;
        switch (direction) {
        case 0://north
            Ypos = Ypos - stepSize;
            break;
        case 1://east
            Xpos = Xpos + stepSize;
            break;
        case 2://south
            Ypos = Ypos + stepSize;
            break;
        case 3://west
            Xpos = Xpos - stepSize;
            break;
        case 4://north east
            Xpos = Xpos - sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos + sqrt(pow(stepSize, 2) / 2);
            break;
        case 5://south east
            Xpos = Xpos + sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos + sqrt(pow(stepSize, 2) / 2);
            break;
        case 6://south west
            Xpos = Xpos + sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos - sqrt(pow(stepSize, 2) / 2);
            break;
        case 7://north west
            Xpos = Xpos - sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos - sqrt(pow(stepSize, 2) / 2);
            break;
        default:
            cout << "Error in randomizer, press enter to exit." << endl;
            cin.ignore();
            cin.get();
            exit(5);
            break;
        }
    }
    return 0;
}

int main()
{
    vector <int> vectorX;
    vector <int> vectorY;
    double Xpos = 201;
    double Ypos = 201;
    srand(time(NULL));
    for (int x = 0; x < 50; x++) {
        phaseTwoSimulate(Xpos,Ypos,50,1);
        vectorX.push_back(Xpos);
        vectorY.push_back(Ypos);
        double Xpos = 201;
        double Ypos = 201;
    }
    cout << vectorX << endl << vectorY;
    cin.ignore();
    cin.get();
    return 0;
}

The code for the full program, in case you're interested:

#include "stdafx.h"
#include "iostream"
#include <vector>
#include <algorithm>
#include <cmath>
#include <numeric>
#include <ctime> 
#include <random>

using namespace std;

int loopCounter() {
    int loop_count;
    cout << "How many repetitions would you like?" << endl;
    cin >> loop_count;
    cout << endl;
    return loop_count;
}

int randomStep() {
    int oneOrZero = rand() % 2;
    if (oneOrZero == 0) {
        oneOrZero = -1;
    }
    return oneOrZero;
}
string wetnessOutput(int position, string &previousWetness) {
    for (int x=0; x < position; x++) {
        cout << " ";
    }
    if (previousWetness == "D" && position > 9 && position < 21) {
        cout << 'D' << endl;
        previousWetness = "D";
        return "D";
    }
    else {
        if (position > 9 && position < 21) {
            cout << "WD" << endl;
            previousWetness = "WD";
            return "WD";
        }
        else {
            cout << "W" << endl;
            previousWetness = "W";
            return "W";
        }
    }
}
int phaseOneStep() {
    int prevXpos = 15;
    string wetness = "D";
    const int WORFLENGTH = 50;
    for (int steps=0; steps < WORFLENGTH; steps++) {
        int Xpos = prevXpos + randomStep();
        wetnessOutput(Xpos, wetness);
        prevXpos = Xpos;
    }
    return prevXpos;
}
int phaseOneWalk(int &loopCount, vector <int> &data) {
    int totalEndPos = 0;
    loopCount = loopCounter();
    data.clear();
    for (int repititions = 1; repititions <= loopCount; repititions++) {
        int endPos = phaseOneStep();
        totalEndPos = endPos + totalEndPos;
        data.push_back(endPos);
        cout << endl << "Repititions completed: " << repititions << endl;
        cout << "Press enter for next step." << endl;
        cin.ignore();
        cin.get();
    }
    return totalEndPos;
}
int whichPhase(int &phase) {
    int phaseChoice;
    cout << "Which phase would you like? Type 1 or 2." << endl;
    cin >> phaseChoice;
    if (1 == phaseChoice || 2 == phaseChoice) {
        if (1 == phaseChoice) {
            return 1;
        }
        if (2 == phaseChoice) {
            return 2;
        }
    }
    else {
        cout << "Invalid input. Use 1 or 2." << endl;
        int phase = whichPhase(phase);
        return 0;
    }
    return 0;
}
int findMode(vector<int>data) {
    int mode;
    int size = data.size();
    vector<int>modeGetter(500);
    for (int x = 0; x < size; x++) {
        int value = data[x];
        modeGetter[value] = modeGetter[value]+1; 
        mode = distance(modeGetter.begin(), max_element(modeGetter.begin(), modeGetter.end()));
    }

    return mode;
}
void phaseOneCalculations(int totalXpos, vector<int>data) {
    double dataSize = data.size();
    int mode = 0;
    double max = *max_element(data.begin(), data.end());
    double min = *min_element(data.begin(), data.end());
    double middle = dataSize / 2;
    sort(data.begin(), data.end());
    mode = findMode(data);
    cout << "The mean variance from starting position is: " << fabs((totalXpos / dataSize) - 15) << endl;
    cout << "The mean of ending x positions, starting at 15, is: " << totalXpos / dataSize << endl;
    cout << "The minimum ending x positions is: " << min << endl;
    cout << "The maximum ending x positions is: " << max << endl;
    cout << "The median  ending x positions is: " << data[middle] << endl;
    cout << "The mode of ending x positions is: " << mode << endl;
    cout << "Press enter to exit." << endl;
    cin.ignore();
    cin.get();
    exit(1);
}
int getDiameter(double &stepSize) {
    int diameter = 0;
    cout << "Enter the diameter of the circle. Max 200 Min 20." << endl;
    cin >> diameter;
    cout << "Enter the size of each step. Max 5 Min 0.1" << endl;
    cin >> stepSize;
    if (diameter > 19 && diameter < 201 && stepSize >= 0.1 && stepSize <= 5) {
        return diameter;
    }
    else {
        cout << endl << "Invalid input, restart program." << endl;
        exit(5);
        return 0;
    }
}
int phaseTwoSimulate(double &Xpos, double &Ypos, int diameter, double stepSize) {
    int repeateTimes = 0;
    while (pow(Xpos - 200, 2) + pow(Ypos - 200, 2) < pow(diameter, 2)) {

        int direction = rand() % 8;
        repeateTimes = repeateTimes + 1;
        switch (direction) {
        case 0://north
            Ypos = Ypos - stepSize;
            break;
        case 1://east
            Xpos = Xpos + stepSize;
            break;
        case 2://south
            Ypos = Ypos + stepSize;
            break;
        case 3://west
            Xpos = Xpos - stepSize;
            break;
        case 4://north east
            Xpos = Xpos - sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos + sqrt(pow(stepSize, 2) / 2);
            break;
        case 5://south east
            Xpos = Xpos + sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos + sqrt(pow(stepSize, 2) / 2);
            break;
        case 6://south west
            Xpos = Xpos + sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos - sqrt(pow(stepSize, 2) / 2);
            break;
        case 7://north west
            Xpos = Xpos - sqrt(pow(stepSize, 2) / 2);
            Ypos = Ypos - sqrt(pow(stepSize, 2) / 2);
            break;
        default:
            cout << "Error in randomizer, press enter to exit." << endl;
            cin.ignore();
            cin.get();
            exit(5);
            break;
        }
    }
    return repeateTimes;
}
int phaseTwoWalk(int &loopCount, vector<int>&dataX, vector<int>&dataY) {
    int totalXpos = 0;
    int totalYpos = 0;
    int endXpos = 0;
    int endYpos = 0;
    int totalSteps;
    double Xpos = 201;
    double Ypos = 201;
    double stepSize = 0;
    int diameterCircle = getDiameter(stepSize);
    dataX.clear();
    dataY.clear();
    loopCount = loopCounter();

    for (int repititions = 0; repititions < loopCount; repititions++) {
        int randomHelp = 0;
        totalSteps = phaseTwoSimulate(Xpos,Ypos,diameterCircle,stepSize);
        dataX.push_back(Xpos);
        dataY.push_back(Ypos);
        int Xpos = 201;
        int Ypos = 201;
    }
    return totalSteps;
}
void phaseTwoCalculations(vector<int>dataX, vector<int>dataY) {
    double dataSizeX = dataX.size();
    double dataSizeY = dataY.size();
    int modeX = 0;
    int modeY = 0;
    double maxX = *max_element(dataX.begin(), dataX.end());
    double minX = *min_element(dataX.begin(), dataX.end());
    double maxY = *max_element(dataY.begin(), dataY.end());
    double minY = *min_element(dataY.begin(), dataY.end());
    double middleX = dataSizeX / 2;
    double middleY = dataSizeY / 2;
    double sumX = accumulate(dataX.begin(), dataX.end(), 0);
    double sumY = accumulate(dataY.begin(), dataY.end(), 0);
    sort(dataX.begin(), dataX.end());
    sort(dataY.begin(), dataY.end());
    modeX = findMode(dataX);
    modeY = findMode(dataY);
    cout << "The center of the circle is 201,201" << endl;
    cout << "The mean variances from starting position are (x,y): " << (fabs((sumX / dataSizeX)) - 201) <<
        "," << (fabs((sumY / dataSizeY) - 201)) << endl;
    cout << "The mean of ending x,y positions are: " << sumX / dataSizeX << "," <<
        sumY / dataSizeY << endl;
    cout << "The minimum ending x,y positions are: " << minX << "," << minY << endl;
    cout << "The maximum ending x,y positions are: " << maxX << "," << maxY << endl;
    cout << "The medians ending x,y positions are: " << dataX[middleX] << "," << dataY[middleY] << endl;
    cout << "The mode of ending x,y positions are: " << modeX << "," << modeY << endl;

//add the number of steps average, repititions.
    cout << "Press enter to exit." << endl;
    cin.ignore();
    cin.get();
    exit(1);
}
int main()
{
    int repititions;
    vector<int>phaseOneData;
    vector<int>phaseTwoDataX;
    vector<int>phaseTwoDataY;
    srand(time(NULL));
    int phase = whichPhase(phase);
    if (phase == 1) {
        int totalPos = phaseOneWalk(repititions, phaseOneData);
        phaseOneCalculations(totalPos, phaseOneData);
    }
    if (phase == 2) {
        phaseTwoWalk(repititions, phaseTwoDataX, phaseTwoDataY);
        phaseTwoCalculations(phaseTwoDataX, phaseTwoDataY);
    }
    if (phase == 0) {
        cout << endl << "Phase error, restart program." << endl;
        cin.ignore();
        cin.get();
        exit(4);
    }
    return 0;
}




Aucun commentaire:

Enregistrer un commentaire