0

I am struggling to convert a 2D array of points in a 1D array of ints. I wrote a wrapper class to do that for me (Array3D), which does the mapping for me with filling the underlying buffer, but it looks like the indexing is totally wrong, since when I print my 2D array and in comparison the buffer, it gives me different outputs.

The 2D point array has dimensions steps × number_of_robots. Therefore, the 1D buffer has a length of steps × number_of_robots × 2.

Idea is that

buffer[index(x,y,0)] corresponds to points[index(x,y)].x
buffer[index(x,y,1)] corresponds to points[index(x,y)].y

The output is wrong, since it should be identical when I print out the 2D point array and the 1D buffer. I read the row of points from a file, and therefore, they totally should be identical.

The points are derived from the input read by a file. How that is done seems unimportant. Fact is, that the output of main.cpp is:

(0, 4)  (0, 5)  (1, 5)  (2, 5)  (2, 4)  (3, 4)  (2, 4)  (2, 3)  (2, 2)  
(4, 0)  (4, -1) (4, 0)  (4, 1)  (3, 1)  (4, 1)  (4, 2)  (3, 2)  (2, 2)  

(0, 2)  (0, 3)  (1, 2)  (2, 2)  (2, 2)  (3, 3)  (2, 2)  (2, 2)  (2, 2)  
(1, 2)  (2, 2)  (2, 2)  (3, 3)  (2, 2)  (2, 2)  (2, 2)  (3, 3)  (2, 2)  

point.cpp

Point::Point(int a, int b) {
    x = a;
    y = b;
}

Array3D.cpp

template<class T>
int Array3D<T>::index(int x,int y,  int z) {
    return (x * ydim + y) * zdim + z;
}

template<class T>
T Array3D<T>::get( int x,  int y, int z) {
    return buffer[index(x,y,z)];
}

template<class T>
void Array3D<T>::set( int x,  int y, int z ,T n) {
    buffer[index(x,y,z)] = n;
}

Harvester.cpp

int Harvester::index(int t, int n) {
    return t*number_of_robots + n;
}

void Harvester::extract(Array3D<int> *array) {
    Point p;
    for(int t = 0; t < steps; t++ ) {
        for(int n = 0; n < number_of_robots; n++) {
            p = data[index(t,n)];
            array->set(t,n,0,p.x);
            array->set(t,n,1,p.x);
        }
    }
}

void Harvester::read_points(string filename) {
    string line;
    ifstream input;

    input.open(filename.c_str());

    input >> number_of_robots;

    int x, y;
    for(int n = 0; n < number_of_robots; n++) {
        if(input >> x >> y) {
            data[index(0,n)].x = x;
            data[index(0,n)].y = y;
            //cout << x << " " << y << endl;
        } else {
            cout << "Your file is bad, and you should feel bad!";
            return;
        }
    }
}

void Harvester::print_harvest() {
    for (int n = 0; n < number_of_robots; n++) {
        for (int t = 0; t < steps; t++) {
            data[index(t,n)].dump();
        }
        cout << endl;
    }
    cout << endl;
}

robots_002.txt

2
0 4
4 0

main.cpp

int main() {
    int mission_time;
    int number_of_robots;
    Point goal;
    string path;
    bool print = true;

    int choice = 2;    

    mission_time = 8;
    number_of_robots = 2;
    goal.x = 2;
    goal.y = 2;
    path = "robots_002.txt"; 

    int steps = mission_time + 1;

    Harvester h(mission_time, number_of_robots, goal);
    h.read_points("fixtures/" + path);
    h.run();


    int *buffer = new int[steps * number_of_robots * 2];
    Array3D<int> arr(steps, number_of_robots, 2, buffer);

    h.extract(&arr);

    h.print_harvest();
    for (int n = 0; n < number_of_robots; n++) {
        for (int t = 0; t < steps; t++) {
                printf("(%d, %d)\t", arr.get(t, n, 0), arr.get(t, n, 1));
        }
        cout << endl;
    }


    return 0;
}
jcklie
  • 4,054
  • 3
  • 24
  • 42
  • So the output is wrong, but you don't show the input, or even explain how the output is wrong. Good luck with that... – Scott Hunter Jan 04 '14 at 12:47
  • I thought that it was obvious that when I want to map something, that the output of the two should be identical. I added some more explanation to that. – jcklie Jan 04 '14 at 12:56

1 Answers1

1

still looking through but quick observation. In Harverster::extract, you are setting both to p.x

void Harvester::extract(Array3D<int> *array) {
    Point p;
    for(int t = 0; t < steps; t++ ) {
        for(int n = 0; n < number_of_robots; n++) {
            p = data[index(t,n)];
            array->set(t,n,0,p.x);
            array->set(t,n,1,p.x);  //<-- im thinking you want this to be p.y
        }
    }
}
KorreyD
  • 1,274
  • 8
  • 15
  • 1
    also are you sure that your Array3D index method is returning unique indexes into your 1D array (I can't evaluate it fully without knowing what ydim and zdim are). but it seems to me that with the error stated above (Harvester::extract() setting both values to p.x) that every point in your 1D array should have x and y equal to eachother, but they aren't according to your output. leading me to believe that the return value of Array3d::index() doesnt have a unique output for every unique input. – KorreyD Jan 04 '14 at 13:40
  • I googled on how to index a 1D array to a 3D one, and that looks wrong here. But thank you very much for spotting my stupid error. I used http://stackoverflow.com/questions/7367770/how-to-flatten-or-index-3d-array-in-1d-array – jcklie Jan 04 '14 at 14:09
  • http://stackoverflow.com/questions/3902648/c-representing-a-3d-array-in-a-1d-array + your hint of change give me the output I want. – jcklie Jan 04 '14 at 14:16