Converting a 1D vector into 2D - c++

I have a problem, I am making a RPG game with C++, and here is my problem:
I have a 1D vector that contains "gid" elements of tiles in my game, like this picture:
This 1D vector contains 400 elements (my map is 20x20), and I want to convert it to a 2D vector, so I can then create a grid of tiles...
I have tried this:
map_floor2D.resize(map_floor.size(), map_floor);
for (int i = 0; i < map_floor2D.size(); i++)
{
for (int j = 0; j < map_floor2D[i].size(); i++)
{
cout << map_floor2D[i][j];
}
}
map_floor is the 1D vector.
map_floor2D is the 2D vector
How can I do that?

vector<int> map_floor1D;
vector<vector< int> > map_floor2D;
map_floor2D.resize(20);
for (int i = 0; i < 20; i++)
{
map_floor2D[i].resize(20);
}
for (int i = 0; i < map_floor1D.size(); i++)
{
int row = i / 20;
int col = i %20;
map_floor2D[row][col] = map_floor1D[i];
}

I wouldn't do any conversion at all. Just create a 2D view over the 1D data:
const int WIDTH = 16;
const int x = 5; // 5 across
const int y = 6; // 6 down
cout << map_floor[y*WIDTH + x];

Related

Writing a function to rotate a 2d vector 90 degrees clockwise

I am trying to rotate a 2d vector clockwise but I am unable to get it to work for vectors that are not square.
Here is what I tried
bool Pgm::Clockwise(){
int i, j, k;
vector <vector <int> > tempPixel;
for (i = 0; i < Pixels.size(); i++) {
tempPixel.push_back(Pixels.at(i));
}
for (j = 0; j < tempPixel.size(); j++) {
tempPixel.push_back(vector<int>());
for (k = 0; k < tempPixel.at(0).size(); k++) {
tempPixel.at(j).push_back(Pixels.at(j));
}
}
return true;
}
#include <vector>
std::vector<std::vector<int>> rotateClockwise(std::vector<std::vector<int>> v) {
int n = v.size();
int m = v[0].size();
// create new vector with swapped dimensions
std::vector<std::vector<int>> rotated(m, std::vector<int>(n));
// populate the new vector
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
rotated[j][n-i-1] = v[i][j];
}
}
return rotated;
}
This function takes a 2D vector as input and returns a new 2D vector that is rotated 90 degrees clockwise. It first creates a new vector rotated with dimensions swapped, then populates it by copying the elements from the input vector in the appropriate order.
i hope this will help you to get an idea..

Assign a value to a certain position in a vector of a vector (2D)

Ok, im starting c++ and i want to assign a value to a specific position in a vector of a vector. I have done it with an array of array (2D) but now would like to do it with vectors.
int main() {
int newLine = 10;
int newColumm = 10;
const string WALL = "\u2588";
cout << endl;
string grille[10][10];
for (int j = 0; j < newColumm + 1; j++) {
int i = 0;
grille[i][j] = WALL;
}
for (int j = 0; j < newColumm + 1; j++) {
int i = newLine + 1;
grille[i][j] = WALL;
}
I would like to do the same thing with vectors.
I Have :
int main() {
int newLine = 10;
int newColumm = 10;
const string WALL = "\u2588";
cout << endl;
// string grille[10][10];
vector<vector<string>> grille;
for (int j = 0; j < newColumm + 1; j++) {
int i = 0;
grille.at(i).at(j) = WALL;
}
for (int j = 0; j < newColumm + 1; j++) {
int i = newLine + 1;
grille.at(i).at(j) = WALL;
}
It's obviously not working for the moment.
(Sorry for my bad language, english is my second language...)
Your vector has no size. You are getting a std::range_error exception when you access the vector out-of-bounds. Since you are not handling exceptions, your program crashes.
The naive fix for this is to simply pre-allocate your vector to the dimensions you expect:
vector<vector<string>> grille(10, std::vector<string>(10));
Note that your for-loops will naturally overshoot anyway and you'll still get an exception, since they are actually looping to 10 inclusive. Remember that if you have 10 elements, then the valid indices are 0 to 9 inclusive.

Working with small 2D parts of big 2D array and moving around it

I have one big 2D array and I want change values in smaller 2D. I can't just get some results.
I have something like that (for 16x16 array f.e.)
int Down8 = 0;
int Right8 = 0;
for (int Down = 0; Down < 16; Down+8)
{
for (int Right = 0; Right < 16; Right+8)
{
Right8 = Right;
Down8 = Down;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
matrixZ[j][i] = TEST[Right8][Down8];
Right++;
}
Down++;
Right8 = Right;
}
dctTransform(matrixZ);
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
matrixZ[j][i] = matrixZ[j][i] / Quant50[j][i];
}
}
zigZagMatrix(matrixZ, 8, 8);
}
}
For 2D 16x16 my function zigZagMatrix should return 4 lines into file (because 16x16 array has 4 8x8 arrays) but only returns 2. 640x480 array should return 4800 lines ( 640/8*480/8 ), returns 60.
Where am I blind/wrong?
All functions I have works with 8x8 array so all of it is loops problem.

getting row/column of dynamic 2d array element

I am currently using the following code to get the current row and column of an element in a 2D int array:
const int num_rows = 5;
const int num_columns = 7;
int a[num_rows][num_columns];
int *p = &a[2][4];
int row = (p - &a[0][0]) / num_columns;
int col = (p - &a[row][0]);
This works fine but now I need to change the code to take the number of rows and columns as a parameter. As far as I know, this means I need to create the 2D array dynamically:
int** ary = new int*[sizeX];
for(int i = 0; i < sizeX; ++i)
ary[i] = new int[sizeY];
If I create the 2D array this way, the above code to find the row/column breaks. What can I do?
int *ary = new int [sizeX * sizeY]; // allocate memory for the 2d array
for(int i = 0; i < sizeX; ++I)
for(j = 0; j < sizeY; ++j)
ary[i * sizeY + j] = 0;
// to get the value of collumn c and row r: use ary[c * sizeY + r];
int row = (p - &a[0][0]) / num_columns;
int col = (p - &a[row][0]);
It's a very good idea to stay way from pointer arithmetic. Don't do this! You are essentially subtracting the pointer and divide that number by num_columns, and that number will be random.
If you want to get the row/column of an element, search the array one element at a time.
for(int row=0; row<num_rows; ++row) {
for(int column=0; column<num_columns; ++column) {
if (a[row][column] == element) {
// we got it!
}
}
}

Iterating over 2D vector of "char" in C++, blank characters are not printing out

I am currently working on a battleship text based game and I am switching my container that I am using to store the board from a 2D array of char to a 2D vector. In the code snipped below I am initializing the entire board and setting all the characters in it to be blank spaces to begin with. What follows this is all of my code to create the board etc.
const int width = 100;
const int height = 35;
vector< vector<char> > buffer(width, vector<char>(height,0));
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
buffer[x][y] = ' ';
When I am going to output the board to the screen I am trying to use the iterators that are provided for vectors. Only problem I am having is that when using the iterator it seems to ignore blank spaces in my vector so my game board does not look as it should. Just using a double for loop to iterate through the vector then the output is fine.
vector<vector<char> >::const_iterator row;
vector<char>::const_iterator col;
for (row = buffer.begin(); row != buffer.end(); row++) {
for (col = row->begin(); col != row->end(); col++) {
cout << *col;
}
cout << endl;
}
This is the first time im attempting to use vectors so im stumped. Anyone know why it would be ignoring the blank characters?
My first question is: "why are you using vectors for a simple 2-D array?" I would simply use a two-dimensional array and be done with it. An efficient way to allocate a 2-D array of objects with a single malloc() call (so it can be freed with a single free() call) is:
/* set up the memory for a 2D matrix with entries of size "size" */
void** matrix2D(long rows, long columns, long size)
{
long i;
unsigned long long row_size = (unsigned long long)columns * (unsigned long long)size;
unsigned long long data_size = ((unsigned long long)rows * (unsigned long long)columns + 1) * (unsigned long long)size;
unsigned long long pointer_size = (unsigned long long)rows * sizeof(void*);
void** result;
if ( (result = (void**)malloc((size_t)(data_size + pointer_size))) == NULL ) {
return NULL;
}
// take the first bit for a vector pointing to the m_pData for each row
char* pdata = (char*)result + pointer_size;
if ((unsigned long)pdata % size) {
pdata += size - (unsigned long)pdata % size;
}
// for each row, set up the pointer to its m_pData
for (i = 0; i < rows; i++) {
result[i] = (void*)pdata;
pdata += row_size;
}
return result;
}
I would then setup your matrix using:
char** buffer = (char**)matrix2D(height, width, sizeof(char));
I would initialize the array using:
for (int i = 0; i < height; ++i)
for (int j = 0; j < width; ++j)
buffer[i][j] = ' ';
and I would print the array using:
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j)
cout << buffer[i][j];
cout << endl;
}
You don't need to use the vector<vector<char> >::iterator. The vector class has overloaded for you the subscript operator[]. So you can write:
for(size_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j++)
{
cout << buffer[i][j]; // buffer is a vector<vector<char> >
}
cout << "\n";
}