Conversion from array to vector

My issue today is working with this problem that I've been trying to pin down, and I've finally been able to find the issue.

Simply put: I am trying to convert my program to utilize a multidimensional vector instead of a multidimensional array.

I have accomplished majority of the conversion, but I am unsure on how I should execute the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
void Tile::InitializeBoard(vector< vector<int> > theBoard)
{
	// x is first counter, z is second counter.
	int enterno = 1; // enterno is declared as int initialized at 1.  // enterno means the number entered into the array
	for (int x = 0; x < NUM_ROWS; x++) // for x is declared as int initialized as 0, while x < NUM_ROWS, x goes up 1 when function loops
	{
		vector<int> row;
		for (int z = 0; z < NUM_COLS; z++) // for z is declared as int initialized as 0, while z < NUM_COLS, z goes up 1 when function loops
		{
			row.push_back(enterno); // array[x][z] will equal enterno.
			enterno++; //enterno counts up 1
		}
		theBoard.push_back(row);
	}
	setPivot(theBoard);
	// in the future, -1, or PIVOT, will equal PIVOT_SYMBOL
}
void Tile::PrintBoard(vector< vector<int> > theBoard)
{
	//print whatever
	// 1 2 3
	// 4 5 6
	// 7 8 * 
	HANDLE hConsole;
	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	vector< vector<int> > origBoard;
	InitializeBoard(origBoard);
	for (int x = 0; x < NUM_ROWS; x++) // for x is declare as int intitialized as 0, while x < NUM_ROWS, x goes up 1 when function loops
	{
		for (int z = 0; z < NUM_COLS; z++) // for z is declare as int intitialized as 0, while z < NUM_COLS, z goes up 1 when function loops
		{
			if (theBoard[x][z] == PIVOT) // if number is equal to PIVOT, then give color number as COLOR_DEFAULT
			{
				SetConsoleTextAttribute(hConsole, COLOR_DEFAULT); // sets to gray
				cout << "  " << PIVOT_SYMBOL; // outputs pivot
			}
			else if (theBoard[x][z] == origBoard[x][z]) // if a number is in correct position like above, then give color number as COLOR_GREEN
			{
				SetConsoleTextAttribute(hConsole, COLOR_GREEN); // sets to green
				cout << "  " << theBoard[x][z]; // outputs correct number
			}
			else if (theBoard[x][z] != origBoard[x][z]) // if a number is in an incorrect position, then give color number as COLOR_RED
			{
				SetConsoleTextAttribute(hConsole, COLOR_RED); // sets to red
				cout << "  " << theBoard[x][z]; // outputs wrong number
			}
		}
		cout << "\n";
	}
	SetConsoleTextAttribute(hConsole, COLOR_DEFAULT);
}


The following code is obviously incorrect and out of context, but I wish to convert the usage of theBoard[x][z] towards a better usage in vector form, as whenever I run the program in its current state, it stops on the first theBoard[x][z] and says the vector is out of bounds.

The whole basis of the question right now is asking how would I go pulling a vector value and applying it to an if statement and also to output a specific vector value in a cout<<.
Last edited on
The first thing you need to do is to learn to pass the vector by reference/const reference instead of by value into your function. That will probably solve several of your problems. Right now everything the Initialize() function does is lost when the function returns.



This, in my case, is utilizing OOP in a source file where the vector I thought was being shared with whatever case it is called in. Are you saying that I should return theBoard; in InitializeBoard() and allow origBoard = InitializeBoard(origBoard); inside PrintBoard()?
Last edited on
This, in my case, is utilizing OOP in a source file where the vector I thought was being shared with whatever case it is called in.

I don't see what OOP has to do with passing a vector by value or by reference. But since you're passing the vector by value any changes made to the vector inside that function are lost when that function returns. Remember when you pass any variable into a function by value a copy of that variable is made so that the original variable is unaffected.
void Tile::InitializeBoard(vector<vector<int>> theBoard) // This is passing the vector by value.

Are you saying that I should return theBoard; in InitializeBoard()

You could, but that may not solve the underlying problems. I suggest you pass the vector by reference:

void Tile::InitializeBoard(vector<vector<int>>& theBoard) // This is passing the vector by reference, note the ampersand.

and allow origBoard = InitializeBoard(origBoard); inside PrintBoard()?

Why would you want to do that? You already have a copy of origBoard inside PrintBoard() just use that. But what I'm really saying is that you should pass origBoard into PrintBoard() by const reference because PrintBoard should not need to alter the variable and using a const reference prevents the unnecessary copy that could be time consuming if that function is called often.

void Tile::PrintBoard(const vector<vector<int>>& theBoard) // Note the const and the ampersand means pass by const reference.


You really really need to review your textbook and class notes on the different ways to pass variables to and from your functions.


"Source1.cpp"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <cstdlib>
#include <iostream>
#include <windows.h>			// for COLOR!
#include <vector>
#include "Header.h"
#define PIVOT -1			// used to mark the pivot spot (blank area) on the puzzle
#define PIVOT_SYMBOL	"*"		// used to show the pivot location when drawing the board
#define COLOR_DEFAULT	        7
#define COLOR_RED		12
#define COLOR_GREEN		10
bool Tile::setColumns(int myCols)
{
	bool accepted = false;
	if (myCols <= 0) {
		accepted = false;
		cout << "Invalid Column Count.\n";
	}
	else
	{
		accepted = true;
		NUM_COLS = myCols;
	}
	return accepted;
}
bool Tile::setRows(int myRows)
{

	bool accepted = false;
	if (myRows <= 0) {
		accepted = false;
		cout << "Invalid Column Count.\n";
	}
	else
	{
		accepted = true;
		NUM_ROWS = myRows;
	}
	return accepted;
}
bool Tile::setPivot(vector< vector<int> > theBoard)
{
	int accepted = false;
	int pivotnum = NUM_COLS * NUM_ROWS;
	for (int x = 0; x < NUM_ROWS; x++)
	{
		for (int z = 0; z < NUM_COLS; z++)
		{
			if (theBoard[x][z] == pivotnum)
			{
				accepted = true;
				theBoard[x][z] = PIVOT;
			}
		}
	}
	return accepted;
}
void Tile::InitializeBoard(vector< vector<int> > theBoard)
{
	// x is first counter, z is second counter.
	int enterno = 1; // enterno is declared as int initialized at 1.  // enterno means the number entered into the array
	for (int x = 0; x < NUM_ROWS; x++) // for x is declared as int initialized as 0, while x < NUM_ROWS, x goes up 1 when function loops
	{
		vector<int> row;
		for (int z = 0; z < NUM_COLS; z++) // for z is declared as int initialized as 0, while z < NUM_COLS, z goes up 1 when function loops
		{
			row.push_back(enterno); // array[x][z] will equal enterno.
			enterno++; //enterno counts up 1
			cout << "  " << theBoard[x][z];
		}
		theBoard.push_back(row);
	}
	setPivot(theBoard);
	// in the future, -1, or PIVOT, will equal PIVOT_SYMBOL
}
void Tile::PrintBoard(vector< vector<int> > theBoard)
{
	//print whatever
	// 1 2 3
	// 4 5 6
	// 7 8 * 
	HANDLE hConsole;
	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	vector< vector<int> > origBoard;
	InitializeBoard(origBoard);
	for (int x = 0; x < NUM_ROWS; x++) // for x is declare as int intitialized as 0, while x < NUM_ROWS, x goes up 1 when function loops
	{
		for (int z = 0; z < NUM_COLS; z++) // for z is declare as int intitialized as 0, while z < NUM_COLS, z goes up 1 when function loops
		{
			if (theBoard[x][z] == PIVOT) // if number is equal to PIVOT, then give color number as COLOR_DEFAULT
			{
				SetConsoleTextAttribute(hConsole, COLOR_DEFAULT); // sets to gray
				cout << "  " << PIVOT_SYMBOL; // outputs pivot
			}
			else if (theBoard[x][z] == origBoard[x][z]) // if a number is in correct position like above, then give color number as COLOR_GREEN
			{
				SetConsoleTextAttribute(hConsole, COLOR_GREEN); // sets to green
				cout << "  " << theBoard[x][z]; // outputs correct number
			}
			else if (theBoard[x][z] != origBoard[x][z]) // if a number is in an incorrect position, then give color number as COLOR_RED
			{
				SetConsoleTextAttribute(hConsole, COLOR_RED); // sets to red
				cout << "  " << theBoard[x][z]; // outputs wrong number
			}
		}
		cout << "\n";
	}
	SetConsoleTextAttribute(hConsole, COLOR_DEFAULT);
}


"Header.h"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#ifndef __HEADER__
#define __HEADER__
using namespace std;
class Tile
{
private:
	int NUM_COLS;
	int NUM_ROWS;
public:
	Tile()
	{
		NUM_COLS = 0;
		NUM_ROWS = 0;
	}
	bool setColumns(int);
	bool setRows(int);
	bool setPivot(vector< vector<int> >);
	void InitializeBoard(vector< vector<int> >);
        void PrintBoard(vector< vector<int> >);
};
#endif 


"Source.cpp"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>				// for general IO
#include <windows.h>			// for COLOR!
#include <vector>               // for vector<>
#include "Header.h"
using namespace std;
int main() {
	bool valid = false; //
	bool colvalid = false;
	bool rowvalid = false;
		int rows = 0, cols = 0;
		Tile tiles;
		while (colvalid == false)
		{
			cout << "Enter Columns\n";
			cin >> cols;
			colvalid = tiles.setColumns(cols);
		}
		while (rowvalid == false)
		{
			cout << "Enter Rows\n";
			cin >> rows;
			rowvalid = tiles.setRows(rows);
		}
		vector< vector<int> > slidingBoard;	// the board that holds the sliding tiles
		tiles.InitializeBoard(slidingBoard);
		tiles.PrintBoard(slidingBoard);
return 0;
}


This is a portion of the code I am dealing with that i want to focus on. Simply put, should InitializeBoard be constructed in order to return its vector value? Or in this case does InitializeBoard return its value directly toward the vector inputted and modify it for use in the other few functions?

Edit: I see, utilize reference. adressing is difficult for me to figure out where to place it.
Double Edit: It does not output a syntax, but rather the breakpoint, then towards an out of bounds vector, i assume that is what you mean when you say that the vector does not come through from the initialize to the print.
Last edited on
Arrays as parameters are probably part of the confusion.
1
2
3
4
5
6
7
8
9
void foo( int[] X );
void gaz( std::vector<int> Y );

int main() {
  int bar[42];
  foo( bar );
  std::vector<int> snafu(42);
  gaz( snafu );
}

The foo() takes its parameter by value, just like the gaz():
The X is copy constructed from bar.
The Y is copy constructed from snafu.

The tough part is that X is not an array. X is a pointer.
The Y is a copy of the entire snafu. The X is a copy of the address of an integer.

Since X is a pointer, X[7] = 13; does not modify X, it modifies bar[7] (on this call of foo).
Y[7] = 13; does modify Y and only Y. Nothing to do with snafu.

If you have learned that "array parameters" modify caller's data, then you could assume that
vector is a kind of array => vector is used like an array
applies to function parameters too.

The devil is in the details.
Simply put, should InitializeBoard be constructed in order to return its vector value?

Again you could but it probably won't solve your underlying misunderstandings.

Or in this case does InitializeBoard return its value directly toward the vector inputted and modify it for use in the other few functions?

What are you talking about here? Please rephrase the question.

Why is InitializeBoard() part of the Tiles class? Perhaps you should have a "Board" class that contains a vector of Tiles, that has an "initialize" function to initialize each individual element of the vector.

By the way what is a "Tile"? IMO, your Tile class doesn't make much sense.



I think @keskiverto explains it perfectly: I was using a vector as if the vector was a pointer. So in my case I should not use this format but instead find a correct way to return the vector manually.

InitializeBoard() is part of the Tiles class because the bounds of it are undetermined until someone enters in a value, therefore I wait for the function to be called in order for its past case of when it was a pointer to be returned. Once InitializeBoard() with pointers came through, it would stay modified from the function. Since it is no longer a pointer, the vector does not modify itself and now it becomes the same as it was when it was first called.

Perhaps I did not name it appropriately, but the class of Tile itself means the actions of the Board, while the constructor Tile initializes the columns and rows.
The by reference is the way to "stay close to array behaviour":
1
2
void foo( int[] X );
void gaz( std::vector<int>& Y );



Overall, your design is quite "anti-OOP". Why do you have a class (Tile) at all, when it (almost) is just a collection of functions?

Vector knows its current size. Use that. You should not have the additional NUM_COLS, NUM_ROWS for they merely add complexity, i.e. bugs to your code.
IMO, in this game a "Tile" should probably describe each actual tile. For example with a member variable that contains the "number" of the Tile or if that Tile is the "Blank" tile.
1
2
3
4
5
6
7
8
class Tile
{
    private:
        int value; 
    public:
       Tile(int Value) : value(Value) {}
       int showValue() { return value;}
};


And then maybe you should have a "Board" class that has a vector of the tiles?

Topic archived. No new replies allowed.