2D array changes multiple values while only one changed - c++

My question is much like this one Setting a value in a 2d array causes others in array to change, however it does not solve what I have here.
I am also trying to make a game field with a 2D array, currently full of '#'. I am trying to get the top left corner to become '.' (but leaving a border or '#' around the field, so its 1, not [0][0]).
However, whatever I tried so far always turns two spots into '.':
################.###
#.##################
####################
#####D##############
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
This doesn't make any sense, since (as far as I can see) I am not overflowing anywhere into a RAM slot, and even when I set map[1][1].symbol = '.'; it still gives those two spots as '.', though there is only one location being changed.
Code (partial):
#include <ctime>
#include "stdlib.h"
// Create structure for map tiles
struct mapTile{
char symbol;
bool walkable;
};
//Set map Width and Height and create empty array
//I did it like this so I can change the width and height later via ingame menu
int const mapWidth = 20;
int const mapHeight = 15;
mapTile map[mapWidth][mapHeight];
char x = 1;
char y = 1;
void generateField(){
srand(time(NULL)); //not used yet
//Set whole field to '#'
for(int y = 0; y < mapHeight; y++){
for(int x=0; x < mapWidth; x++){
map[y][x].symbol = '#';
map[y][x].walkable = false;
}
}
//Open up route to walk
map[3][5].symbol = 'D';
map[y][x].symbol = '.';
map[y][x].walkable = true;
};
void printField(){
//print each symbol of the field
for(int y = 0; y < mapHeight; y++){
for(int x=0; x < mapWidth; x++){
cout << map[y][x].symbol;
}
cout << endl;
}
}

In both your for-loops you access the map as [height][width], however you define it as [width][height].
Changing it solves the problem (on my machine).

first of all you are going out of the bounds of the array. The limit of your array is [mapWidth][mapHeight]. But in the initialization loop you are iterating the [y][x] - y till mapHeight and x till mapWidth.
And the second reason is, the value of x and y has already changed when you are initializing it to '.' and false. Please see the array size and work accordingly.

Related

Laggy Output to Console

I have been trying to make asteroids in the console, I know that the console isn't an ideal way to do this, but I wanted to challenge myself.
The problem I am having is with printing to the screen. At first, my screen was flickering because I wasn't updating certain screen parts and instead redrawing every frame by appending the whole array to a string and outputting that string.
So I changed my code to do that, but my current problem now is that the fps of my game is really low because I can't batch call it to one cout function.
To print my code to the screen I have a 2d array of characters with width and height as its size. Then I copy the array, change the output, and compare it to the previous output to see if the pixel needs to be changed, then change it.
Here is my draw function
void draw() {
char prevOutput[ArrayBorder][ArrayBorder];
copyOutput(outputBuffer, prevOutput);
innitOutput();
plotPolygons();
for (int y = 0; y < GameBorder; y++) {
for (int x = 0; x < GameBorder; x++) {
if (outputBuffer[x][y] == prevOutput[x][y]) {continue;}
setCursorPosition(x, y);
cout << outputBuffer[x][y];
}
}
cout.flush();
}
Here is my previous draw function
void draw() {
innitOutput();
plotPolygons();
system("CLS");
string output = "";
for (int y = 0; y < GameBorder; y++) {
for (int x = 0; x < GameBorder; x++) {
output += outputBuffer[x][y];
}
output += "\n";
}
cout << output;
}

Conway's game of life algoritm is not working

I'm trying to simulate conway's game of life. The algorithm I made is not working, but I can't figure out how.
If I have a situation like this:
|.........|
|....x....|
|....x....|
|....x....|
|.........|
a . is a dead cell, an x is an alive cell
It is expected that the vertical bar flips into a horizontal bar, but this doesn't happen.
Instead it only removes the bottom one, running it again again only removes the bottom so theres 1 left.
Clearly theres something wrong with the algorithm, but I can't figure out what.
I've been looking online but all problems other people have had, the solutions didn't work for me.
So what is the error in this algorithm?
This is my code:
void new_generation() {
// Create one new generation
// double for loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
// find the amount of living neighbours, stored in count
// dubbele for loop -> iterates every neighbour of the current cell
count = 0;
for (int y=0; y<2; y++) {
for (int x=0; x<2; x++){
if (i != 0 and j!= 0) { // the cell itself doesnt count
if (world[i+y][j+x]) count++;
}
}
}
if (world[i][j]) { // current cell is alive
if (count<2 or count>3) new_world[i][j] = false;
else new_world[i][j] = true;
}
else { // current cell is dead
if (count==3) new_world[i][j] = true;
else new_world[i][j] = false;
}
}
}
// copy every value from the newly generated world to the current
// double foor loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
world[i][j] = new_world[i][j];
}
}
worldHeight and worldWidth are ints denoting how big the world is.
world and new_world are 2-dimensional arrays containing booleans where true is a living cell and false is a dead cell
You count the neighbor cells wrong
Both x and y are runing from 0 to 2 not from -1 to 2. in
for (int y=0; y<2; y++) {//should be int y=-1; y<2; y++
for (int x=0; x<2; x++){//should be int x=-1; x<2; x++
if (i != 0 and j!= 0) { // shold be x!=0 or y!=0
if (world[i+y][j+x]) count++;
}
}
}
Also you have to check if world[i+y][j+x] is valid (coordinates are in teh 0,size range)
And the third problem is that when you want not to count in word[i][j] you check if (i!=0 and j!=0) not x!=0 or y!=0 i and j are the coordinates of the examined cell, x and y are the difference of the coordinates.

First try on string array not working. Is there something I don't know?

I just tried to use string array for the first time, and I experienced consistent crashes. It's supposed to draw a shrinking circle. Did I forget to add some important line, or is there an error in the existing code? I'm a beginner, so please don't be too mean..
#include <iostream>
#include <string>
#include <cmath>
#include <windows.h>
using namespace std;
int main() {
for (int h = -10; h < 10; h ++)
{
int r = abs(h);
string gps[20];
for (int i = -10; i < 10; i ++)
{
for (int j = -10; j < 10; j ++)
{
if (i*i + j*j <= r*r && i*i + j*j >= (r-1)*(r-1))
gps [j+10][i+10] = char (219);
else
gps [j+10][i+10] = ' ';
}
}
for (int i = 0; i < 20; i ++)
{
for (int j = 0; j < 20; j ++)
cout << gps[i][j];
cout << '\n';
}
//system("CLS"); // I know this isn't the best method, but it's the only one i know that works
// By proffesional analysis (cout), i diagnosed the problem to occur right about here
}
return 0;
}
One major issue with your code is that you are writing to the string at an out-of-bounds index here:
//...
gps [j+10][i+10] = char (219);
//...
gps [j+10][i+10] = ' ';
This declaration:
string gps[20];
declares an array of 20 empty strings. Since the strings are empty, you cannot simply write to any position in these string. These strings must already be sized appropriately before writing to a particular location.
What you may need to do is the following:
string gps[20];
for (auto& s : gps)
s.resize(20);
This will resize each string in the array to 20 elements, thus making your loop access valid entries in any of those strings. Writing to an out-of-bounds string position is undefined behavior, where in your case, the program crashes.
Now, will this draw the circle correctly, I am not sure. But this answer focuses on the crash you are getting when running the program.

Can int values reset if too much is loaded at once?

In my C++ project, I have some int values (I am following two of them specifically). These values are input when the user loads a file. Their values (should) never change throughout the entire program.
Later on in my program, I load about 30 MB of data into around 3000 QString variables (4 arrays). It seems that around a certain number of strings loaded, my int values reset to zero. I only use them at the beginning and end of my program.
I didn't put any source code simply because my program is huge and I don't feel comfortable putting all the source code on the web.
So my question is, is it possible for some variables to be "reset" because new variables are being filled? I get no errors or freezing like I would expect from bad allocation. This has got me completely puzzled.
Thanks for your time :)
EDIT:
Here is the exact spot I notice my int values get reset. Btw, All this code worked when editing a smaller amount of files.
//These loops input 2916 files each around 10kb. They are loaded into 4 QString arrays.
if(OregionBR != "Null")
{
for(int z=0; z <=26; z++)
{
for(int x=0; x <=26; x++)
{
temp_hex = OregionBR.mid((z*256)+(x*8), 6);
if(temp_hex != "000000")
{
temp_hex.append("000");
HexToInt(temp_hex, temp_int);
//Here, the files are input.
Input("stuff\\regions\\xbox_chunks\\br\\" + QString::number(temp_int) + ".dat", temp_chunk);
//... minor file changes
//The file is then loaded into the array
OBRChunks[(zPos*27) + xPos] = temp_chunk;
//... minor file changes
}
}
}
}
//level_ptr is my int value. This number is around 150,000
QMessageBox::information(this, "test", QString::number(level_ptr));
if(OregionBL != "Null")
{
for(int z=0; z <=26; z++)
{
for(int x=0; x <=26; x++)
{
temp_hex = OregionBL.mid((z*256)+(x*8)+40, 6);
if(temp_hex != "000000")
{
temp_hex.append("000");
HexToInt(temp_hex, temp_int);
Input("stuff\\regions\\xbox_chunks\\bl\\" + QString::number(temp_int) + ".dat", temp_chunk);
//... minor file changes
OBLChunks[(zPos*27) + xPos] = temp_chunk;
//... minor file changes
}
}
}
}
//level_ptr is my int value. This number is around 150,000
QMessageBox::information(this, "test", QString::number(level_ptr));
if(OregionTR != "Null")
{
for(int z=0; z <=26; z++)
{
for(int x=0; x <=26; x++)
{
temp_hex = OregionTR.mid((z*256)+(x*8)+1280, 6);
if(temp_hex != "000000")
{
temp_hex.append("000");
HexToInt(temp_hex, temp_int);
Input("stuff\\regions\\xbox_chunks\\tr\\" + QString::number(temp_int) + ".dat", temp_chunk);
//... minor file changes
OTRChunks[(zPos*27) + xPos] = temp_chunk;
//... minor file changes
}
}
}
}
//index_ptr is my int value. NOW IT SAYS LEVEL_PTR IS 0!
QMessageBox::information(this, "test", QString::number(level_ptr));
if(OregionTL != "Null")
{
for(int z=0; z <=26; z++)
{
for(int x=0; x <=26; x++)
{
temp_hex = OregionTL.mid((z*256)+(x*8)+1320, 6);
if(temp_hex != "000000")
{
temp_hex.append("000");
HexToInt(temp_hex, temp_int);
Input("stuff\\regions\\xbox_chunks\\tl\\" + QString::number(temp_int) + ".dat", temp_chunk);
//... minor file changes
OTLChunks[(zPos*27) + xPos] = temp_chunk;
//... minor file changes
}
}
}
}
It's possible for variables to be reset if you have a bug in your program. This is called memory corruption and has many many causes.
If you want help with the bug in your program you are going to have to show us the code. Try and produce a smaller version of your program that still has the same or similar problem.
is it possible that you are going out of range? something like
int temp = value_larger_than_MAX_INT;
In this case, the value will be truncated so you might see 0, or small numbers instead of very large numbers.
It sounds plausible to me after reading through your code, so consider using unsigned int instead of int, or even long.
hope this helps!

C++ 2d array doesn't display

I have a 2d array filled with global variables.
#define GRID_WIDTH 19
#define GRID_HEIGHT 10
char grid[GRID_WIDTH][GRID_HEIGHT];
Later in the code i use this 2d array
void Grid::ResetGrid()
{
// Empty the console screen
system("cls");
// Fills the grid with '#' walls
for (int i=0; i<GRID_WIDTH; i++)
{
for(int j = 0; j <GRID_HEIGHT; j++)
grid[i][j] = '#';
}
ir = 2;
}
While I'm running the program, i use watches and breakpoints. In the beginning the watch on grid said:
Name: grid
Value: [0] "###################"
[0] '#'
[1] '#'
[2] '#'
//and so on, i could expand it and look at every part of the array
type: char
but now it's broken and it only shows this:
Name: grid
Value: {...}
type: Grid
The strange thing is I didn't change the array code, only wrote code lines of compare to what's inside the array.
The code of printing it to the console:
void Grid::PrintGrid(int currentX, int currentY )
{
// Empty the console screen
system("cls");
// Displays the finished maze to the screen.
for (int y=0; y < GRID_HEIGHT; y++)
{
for (int x=0; x < GRID_WIDTH; x++)
{
cout << grid[x][y];
}
cout << endl;
}
// Just for testing, which direction and on what position the solver is
cout << ir << " " << currentX << "," << currentY;
}
The question is:
Why I can't see the information in the 2d array anymore in the watch or when I hoofer over?
I hope you can help me.
I don't think the problem happens to your codes posted out, because I just tested them in my visual stuido 2008, they runs well by your printGrid function, except varable ir I defined it gloably, and your printGrid function double defined x, and y, you defined it in function head, but in the loop, using for (int x...), which means no sense..
the result just come from the printGird is like this:
###################
###################
###################
###################
###################
###################
###################
###################
###################
###################
2 3,4请按任意键继续. . .
3, 4 is the value of x, y which passed in printGrid when using it.
It looks like your print code is going out of the bounds of the array. Much like when you're filling the array, you should use
for (int y=0; y < GRID_HEIGHT; ++y)
{
for (int x=0; x < GRID_WIDTH; ++x)
{
That may be the cause of your faulty print.
The question was why I couldn't see my 2d array anymore in the watch.
It's working again. Don't know what was wrong. But the image below shows the correct use of the watch. I use this to check the information inside the 2d array. But it didn't show information for a while just grid {...} instead of grid 0x00 char (* grid)[25] and then the information about the rows and columns.