How would I overwrite a printed 2D array to simulate 'updates' - c++

So given a 2D array called 'world' and the code below to output the array to the console. I want to constantly update the outputted array using a while loop to simulate movement and other actions via changes in the array values without it messily reprinting the entire thing for every update.
I would imagine the best way to do this would be to try and reset the output stream to the first line and overwrite the previous printed array each update but I am unsure on how to do this.
char world[20][20];
for (unsigned int row = 0; row < std::size(world); row++)
{
for (unsigned int col = 0; col < std::size(world); col++)
{
std::cout << world[row][col];
}
std::cout << std::endl;
}

There is a simple way to do this on one line, using \r with printf, as discussed here. However, I'm not certain this is easy if one wishes to reprint multiple lines, as you do.
A better suggestion would be to make use of something like ncurses, which seems to be designed for your purposes, and was probably used to make other programs you've seen operate this way.

Related

Strange characters appearing in 2D Char Array

I'm coding a game that utilizes a 'grid', which I have created using a 2 dimensional array of structs, which contain a char value and a boolean value. In my program's .h file, I declare the struct and create the grid.
struct Tile
{
char letter;
bool active;
};
Tile grid [6][5];
In my .cpp file, I initialize the grid so that all values are blank.
for (int i = 0; i < 7; ++i)
{
for (int j = 0; j < 6; ++j)
{
grid[i][j].active == false;
//grid[i][j].letter = '.';
//it always crashes when i try doing the above line
}
}
The function that prints the grid, printGrid, is below
for (int i = 0; i < 7; ++i)
{
for (int j = 0; j < 6; ++j)
{
cout << i;
//the above statement is for debugging purposes so that I can see
//which column easier
std::cout << grid[i][j].letter;
}
std::cout << std::endl;
}
cout << "1 2 3 4 5 6" << endl;
Now, the original goal was to have the default .letter value be '.'. But for some reason, when I tried to do this, there are disastrous results; the screen fills up with characters moving so fast I can't entirely see what they are (I recall some hearts and smiley faces), along with an obnoxious, rapid beeping. So I decided to leave that commented line out.
When I run the program without that line, for some reason, the "grid" always displays characters in certain spots, without any input from the user, or without me having expressly declared any values to that spot. For instance, the spot of the 1st column from the left and the bottom row, always has a character in it (grid[6][5].letter). It changes every time I run the program, and I've seen it range from a heart, to the letter A, to the spanish 'n' (the one with a ~ over it).
I thought to myself, "Hey, since grid[6][5] is the spots that are always buggy, I'll just declare those individual spot's .letter values to be blank (' ')!". That didn't work.
I've got no idea why this one spot is giving me trouble. There were other areas that would have an abnormal character, but I was able to neutralize them by setting their .letter values to blank. If anyone has any idea on how to fix this, pleas
EDIT: The other abnormal characters, which appear at grid[6][0], grid[6][1], grid[6][5], and grid[6][4], all make my program crash at later stages if I set them to blank (' '); however, blanking grid[6][5] is the one that makes it crash at the get go. I tried using a debugger, but it wasn't able to tell me anything helpful.
you're running over the end of your arrays
Tile grid [6][5]; needs to be Tile grid [7][6];
or you need to loop only to i < 6 and j < 5.

make permutations of an array of numbers, then turn them into a single int

Basic idea: Given an array, find all the permutations of that array. Then, take each of those arrays and put it all together. Eg the array {6,5,3,4,1,2} gives you 653412. The permutations work, but I cannot get the integers.
int main ()
{
int myints[] = {2,3,4,5,6,7,8,9};
int k;
int dmartin=0;
int powof10=1;
std::cout << "The 8! possible permutations with 8 elements:\n";
do {
for(k=0; k<8; k++){
std::cout << myints[k] << ' ';
dmartin=myints[8-k-1]*powof10+dmartin;
powof10=powof10*10;
}
cout << "\n" << dmartin << "\n";
} while ( std::next_permutation(myints,myints+8) );
dmartin=0;
return 0;
}
I also have some code that works when you just have one array, but in this case there are thousands. I though I needed to reset dmartin=0 at the end of each while loop so that it didn't keep adding to the previous answer, however when I tried that I got "0" for each of my answers. Without trying to reset, I get answers that seem random (and are negative).
The problem is that you're not resetting your two variables inside your loop, so they'll continue from the values they had during the previous iteration, which will just be wrong, and will quickly overflow, giving seemingly rubbish output. Try putting this at the beginning or the end of the do-while loop:
dmartin = 0;
powof10 = 1;
But you're really overcomplicating it a lot. It would be way simpler to just build the number from the most significant digit instead of the least significant one instead. This would eliminate the need for a powof10 variable. This new for-loop would look like this:
for(k = 0; k < 8; k++){
std::cout << myints[k] << ' ';
dmartin = 10*dmartin + myints[k];
}
That won't work for long, since your integer will soon overflow.
That's probably what you are experiencing when you get negative numbers.
Using an integer to store the result does not seem the most appropriate choice to me. Why not use a string, for instance? That would save you the hassle of reinventing base10 conversion in 2014, and you could easily derive a number from the string when needed.
That won't solve the overflow problem, though.
First point: the code to take a vector of digits and turn them into a single number should almost certainly be written as a function, not just code inside the loop.
Second point: you can use std::string like a container of char, and apply normal algorithms to it.
Seem to me, the lazy way would look like this:
std::string input="23456789";
do {
std::cout<<std::stoi(input)<<"\n";
} while (std::next_permutation(input.begin(), input.end()));

Optimize my code? C++ Compare arrays & calculate prize

I'm doing this slot machine game where a 3x3 2D-array is being generated with random letters.
I have successfully made the game work as I want but I wonder if you have any tips on how I can optimize or improve my code.
What I've gotten my code to do:
Generate an 2D-array (3x3) and randomly assign chars out of 3
letters.
An "if" that will compare and see what elements in the array belong
to each other (same char next to eachother for getting
columns/rows/diagonals).
An "if else" that will take total amount of columns/rows/diagonals
and make a prize out of it, depending on total amounts of row in the
slot machine and the bet.
So I'm now wondering if you have any suggestions on how I can improve the "if" code where the program checks if there are any rows/columns/diagonals? The game works as it should but I just wonder if there's any way of optimizing it - Perhaps with a "for-loop"?
I also wonder if you have any tips on the "prize" code where the code calculates total amout of rows/columns/diagonals and multiplies that with the bet.
I mean, there must be a way to optimize this. If I was to do a 100x100 array, the code where the elements are compared would be awfully long :)
I'm new to C++ (this is a course) so I'm looking forward to optimize this.
PS! I'm not asking for a solution but rather suggestions/tips of methods I can use to optimize it.
This is a homework so no solutions please, only suggestions/tips!
My code for the array comparison and prize calculation:
To optimize, running a profiler would give you a lot of information. If you're talking about general guidelines to optimizing your application, here are some:
1 - use threads to process in parallel
2 - reduce cache miss by keeping the data properly aligned depending on the processing done on it. For instance, if you need to use the speed to process the position, keeping them both near each other in memory will reduce cache-misses.
ie:
struct Particle
{
float position;
float speed;
};
Particle particles[NUM_PARTICLES];
vs
float positions[NUM_PARTICLES];
float speeds[NUM_PARTICLES];
3- Don't process what you don't need to process or user can't see. For instance, some stuff may not affect the current states - no need to process it (in graphics, we use scene management like octtrees but the same applies to all - if you don't need it, don't process it).
4- Reduce the amount of floating point operations.
See this post as well - it provices with some good C++ references for optimizations: C++ Optimization Techniques.
About optimizing:
Don't optimize prematurely - it won't help anything. I'm too lazy to write about that, but search internet, read "Code Complete" and "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices" books.
Don't waste - if optimization won't take more time and is at same readability level, than you can use it.
Optimize AFTER a speed problem arise.
About your problem:
You are absolutely right that there should be better ways to write a code. What you wrote is what workers do, but you need to be smart programmer to make it more easy.
But what you need is more knowledge about language.
Yes, there is a looping possibility for C++. For example following code checks whether a line contains same values:
const int rowCount = 3; // Number of rows
const int colCount = 3; // Number of columns
// Variable for counting same rows
int sameRowsCount = 0;
// Following line is loop: first it sets variable row to 0
// and for each pass it increments it until rowCount is reached
for(int row = 0; row < rowCount; ++row)
{
// This variable stores whether the row contains same values.
// At beginning we assume that it does.
bool isSame = true;
// Now we will check each column in current row. Note that
// we begin with 1 and not 0 - at 0 position is value which
// we check against all others.
for(int col = 1; (col < colCount) && isSame; ++col)
{
if(matrix[0] != matrix[col])
{
// We found different values
isSame = false;
}
}
// If row contains same values, isSame remained true and
// we increment same-rows counter.
if(isSame)
{
++sameRowsCount;
}
}
cout << "Number of same rows: " << sameRowsCount << "." << endl;
Depends on the array size(s) as you mentioned. With small arrays the if statements may be more efficient than using a loop (or two nested) to iterate over all the elements (this is also called 'loop unrolling' and is considered a performance improvement).
To 'optimize' (I'd better say generalize) your code for any array sizes you should use for loops of course to iterate over the x/y indices.
Completed code:
//Check all horiztonal and vertical locations
for(int i = 0; i <= 2; i++)
{
if(matris[i][0] == matris[i][1] && matris[i][1] == matris[i][2])
rows++;
if(matris[0][i] == matris[1][i] && matris[1][i] == matris[2][i])
rows++;
}
//Now check diagonals
if(matris[0][0] == matris[1][1] && matris[1][1] == matris[2][2])
if(matris[0][2] == matris[1][1] && matris[1][1] == matris[2][0])
//Calculate prize
prize = g_satsning*(1 << rows);
In terms of speed, what you have is not going to be inefficient. If you are looking to generalize the code and make it scalable (e.g. if you wanted to add 2 more rows/columns), there are several things you could do (e.g. looping and a more mathematical form of prize calculation).
The looping has already been discussed, but the prize calculation could be simplified a bit using something like the following:
if (rows > 0 && rows < SOMEMAXIMUMVALUE)
{
prize = g_satsning * (1 << rows);
}
else
{
prize = 0;
}
Since your multiplier is an exponent of 2, the math is fairly straight forward. SOMEMAXIMUMVALUE should be declared to be the maximum number of matching rows you expect. For a 3x3 setup, there would be 8 potential matches (3 rows, 3 columns, 2 diagonals), so SOMEMAXIMUMVALUE should be set to 8.

fire simulation program dont know how to initialize it

The program is supposed to output a matrix of 12x24 which is bordered by 0s, has 1s in the middle, and a 2 at the location of (1,1) i do not know in which part to initialize M[row][col]=2; because anywhere i put it, it does not output the 2 to the first spot, any suggestions?
int main()
{
int M[N/2][N];
int ROWS, COLS, row, col;
int r, c;
ROWS = sizeof(M) / sizeof(M[0]);
COLS = sizeof(M[0]) / sizeof(M[0][0]);
fill(M, ROWS, COLS, 1, 1);
row=1;
col=1;
for(r=0; r< ROWS; r++)
{
for(c=0; c < COLS; c++)
{
if (r==0||r ==ROWS-1)
{
M[ROWS][COLS]=0;
}
else if(c==0||c==COLS-1)
{
M[ROWS][COLS]=0;
}
else {
M[ROWS][COLS]=1;
}
cout<< M[ROWS][COLS];
}
cout << endl;
}
print(M, ROWS, COLS);
return 0;
}
I notice you're using ROWS and COLS as array indices inside the for loops...you
probably meant to use the loop variables r and c.
Also, it's considered bad form to use upper case names for regular variables...the
convention in C is to use upper case identifiers only for macros.
I bet if you write M[1][1]=2; just before the line cout<<M[ROWS][COLS] then you will see the output you want. It is silly to do it that way, because then you will assign that single location (M[1][1]) to the same value repeatedly--to be exact, 288 times--but you cannot print the wrong value for M[1][1] if you set it to the correct value each time you print anything. There are better ways to do it, of course.
You would be much better off to cleanly separate the actions the program performs. There are really two things it must do:
Initialize the array.
Print the contents of the array.
Each of these actions should be performed by a different function. That is, call one function one time to initialize the entire array, and then call another function one time to print the entire array. This way every cell in the array is set to the correct value before any cell is printed.
If you do this, you should very easily be able to find a good place in your code to set M[1][1]=2 so that you see the correct printout.
I am assuming this is an exercise that will later be extended to do something more with the array, so that it makes sense to use an array in the first place. If so, there is a very good chance you'll have to print the array again at some point, and then you'll be very glad that you wrote a function that prints the array and does nothing else.

Why am I getting this output?

Alright so I writing Conways Game of Life in C++, and so far I have only created the rule that allows users to create cells if it has 3 neighbors.
Here is the current code: http://tinypaste.com/f59b4463
When I launched the program I entered in the coordinates so that I would have the gameboard depicted in the photo below, and the output wasn't what I expected, it should have made it so that the cell 2,1 would be alive, but in the output it remained dead. I am not sure why it is not working. Any help?
Input & Output: http://i.imgur.com/1Mvhi.png
Several things to address, and while this is not an answer, it's too big for a comment. Please fix these then I will get back to you...
In gameboard() please arrange the code so that it consists of two for loops instead of all the couts. Example:
int i, j;
for (i = j = 0; i < 10; i++) {
for (; j < 10; j++) {
cout << world[i][j];
}
}
it's much more concise.
Second, in cells(), in the second for loop, you can use another nested for loop.
Third, I would avoid naming normal variables in ALL CAPS since that is generally reserved for preprocessor #defines.
K, enjoy cleaning up :)
Alright. It's an algorithmic issue. When you call calculate, it creates extra cells because it's not exactly one generation. It's a mix of two and three - it acts on cells you just created. Get what I'm saying? I explained this on GMail.