Infinite while loop with a random number - c++

I have this code:
void generar() {
while (true) {
if (yPos == topOfTheWorld) {
scene[xPos][yPos] = 2;
} else if (yPos >= topOfTheWorld) {
scene[xPos][yPos] = 1;
} else if(yPos < topOfTheWorld) {
scene[xPos][yPos] = 0;
} else {
scene[xPos][yPos] = 0;
}
yPos++;
if(yPos>worldHeight) {
topOfTheWorld += 0;
yPos = 0;
xPos++;
}
if (xPos>worldWidth) {
break;
}
}
std::ofstream output("mapa.txt");
for(int y=0;y<worldHeight;y++) {
for(int x=0;x<worldWidth;x++) {
output<<scene[x][y];
if(x<(worldWidth-1)){output<<",";}
}
if(y<(worldHeight-1)){output<<std::endl;}
}
MessageBox(0, "World generation has finished!", "Finished!", MB_OK);
}
That generates a world based in an array. But when I add:
slope = random(5)-2;
To:
if(yPos == worldHeight) {
topOfTheWorld += 0; //There would be the slope var...
if(yPos == worldHeight) {
slope = random(5)-2;
topOfTheWorld += slope;
For some reason the while becomes an infinite loop, and I don't know why.
(Random Function)
#include <time.h>
#include <windows.h>
int random(int n = 0) {
srand(time(NULL));
if(n!=0){
return rand() % n;
} else {
return rand();
}
}
(Variables)
const int worldWidth = 50;
const int worldHeight = 26;
int topOfTheWorld = worldHeight/2;
int xPos = 0;
int yPos = 0;
int scene[worldWidth][worldHeight];
int slope;
What can I do?

You show that scene is defined as:
int scene[worldWidth][worldHeight];
However, your code has this:
if (xPos>worldWidth) {
break;
}
Which means you will actually write a value outside the array boundary when xPos == worldWidth, and this causes undefined behavior. Adding the slope variable may cause your variable organization to change in a way that the undefined behavior ends up affecting the values of and or all of your loop control variables.
To fix, you should change the erroneous check with:
if (xPos>=worldWidth) {
break;
}
You have since edited your question with code that makes your yPos check incorrect in a similar way.

There's a repeated calls to srand in your random function
Fixes : -
void generar() {
srand(time(NULL)); //Remove srand() from random(), add it here
bool finished = false;
while (!finished) {
if (yPos == topOfTheWorld) {
scene[xPos][yPos] = 2;
} else if (yPos >= topOfTheWorld) {
scene[xPos][yPos] = 1;
} else if(yPos < topOfTheWorld) {
scene[xPos][yPos] = 0;
} else {
scene[xPos][yPos] = 0;
}
yPos++;
if(yPos == worldHeight) {
// slope = random(5)-2; your random call
topOfTheWorld += 0;
yPos = 0;
xPos++;
}
if (xPos>worldWidth) {
finished = true;
//goto Guardar; not required,
//also use of goto is bad programming practice
}
}

Related

Visual Studio C++ trigger a breakpoint at the end of main function

Me and my group is making a game for our project and I keep running into this error, after some testing, it looks like it happens at the end of the main function. I have no idea how this happen as most of the code is from our teacher, we need to fix the intentional bugs placed by him and add additional functionalities.
This is the code:
#include <winuser.h>
#include <iostream>
#include <time.h>
#include <conio.h>
#include <thread>
using namespace std;
#define MAX_CAR 5
#define MAX_CAR_LENGTH 40
#define MAX_SPEED 3
POINT** X;
POINT Y;
int cnt = 0;
int MOVING;
int SPEED;
int HEIGHT_CONSOLE = 29, WIDTH_CONSOLE = 119;
bool STATE;
void FixConsoleWindow() {
HWND consoleWindow = GetConsoleWindow();
LONG_PTR style = GetWindowLongPtr(consoleWindow, GWL_STYLE);
style = style & ~(WS_MAXIMIZEBOX) & ~(WS_THICKFRAME);
SetWindowLongPtr(consoleWindow, GWL_STYLE, style);
}
void GotoXY(int x, int y) {
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void ResetData() {
MOVING = 'D';
SPEED = 1;
Y = { 18, 19 };
if (X == NULL) {
X = new POINT * [MAX_CAR];
for (int i = 0; i < MAX_CAR; i++) {
X[i] = new POINT[MAX_CAR_LENGTH];
}
for (int i = 0; i < MAX_CAR; i++) {
int temp = rand() % (WIDTH_CONSOLE - MAX_CAR_LENGTH) + 1;
for (int j = 0; j < MAX_CAR_LENGTH; j++) {
X[i][j].x = temp + j;
X[i][j].y = 2 + 5 * i;
}
}
}
}
void DrawBoard(int x, int y, int width, int height, int curPosX = 0, int curPosY = 0) {
GotoXY(x, y);
for (int i = 1; i < width; i++) {
cout << 'X';
}
cout << 'X';
GotoXY(x, height + y);
for (int i = 1; i < width; i++) {
cout << 'X';
}
cout << 'X';
for (int i = y + 1; i < height + y; i++) {
GotoXY(x, i);
cout << 'X';
GotoXY(x + width, i);
cout << 'X';
}
GotoXY(curPosX, curPosY);
}
void StartGame() {
system("cls");
ResetData();
DrawBoard(0, 0, WIDTH_CONSOLE, HEIGHT_CONSOLE);
STATE = true;
}
void GabageCollect() {
for (int i = 0; i < MAX_CAR; i++) {
delete[] X[i];
}
delete[] X;
}
void ExitGame(HANDLE t) {
GabageCollect();
system("cls");
TerminateThread(t, 0);
}
void PauseGame(HANDLE t) {
SuspendThread(t);
}
void ProcessDeath() {
STATE = false;
GotoXY(0, HEIGHT_CONSOLE + 2);
cout << "Dead, type y to continue or any key to exit";
}
void ProcessFinish(POINT& p) {
SPEED == MAX_SPEED ? SPEED = 1 : SPEED++;
p = { 18,19 };
MOVING = 'D';
}
void DrawCars() {
for (int i = 0; i < MAX_CAR; i++) {
for (int j = 0; j < MAX_CAR_LENGTH; j++) {
GotoXY(X[i][j].x, X[i][j].y);
std::cout << '.';
}
}
}
void DrawPlayer(const POINT& p, char s) {
GotoXY(p.x, p.y);
cout << s;
}
bool IsImpact(const POINT& p) //d=Y.y p = Y
{
if (p.y == 1 || p.y == 19) return false;
for (int i = 0; i < MAX_CAR; i++)
{
for (int j = 0; j < MAX_CAR_LENGTH; j++)
{
if (p.x == X[i][j].x && p.y == X[i][j].y) return true;
}
}
return false;
}
void MoveCars(int x1, int y1)
{
for (int i = 1; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
cnt++;
for (int j = 0; j < MAX_CAR_LENGTH - 1; j++)
{
X[i][j] = X[i][j + 1];
}
X[i][MAX_CAR_LENGTH - 1].x + 1 == WIDTH_CONSOLE + x1 ? X[i][MAX_CAR_LENGTH - 1].x = 1 : X[i][MAX_CAR_LENGTH - 1].x++;
} while (cnt < SPEED);
}
for (int i = 0; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
cnt++;
for (int j = MAX_CAR_LENGTH - 1; j > 0; j--)
{
X[i][j] = X[i][j - 1];
}
X[i][0].x - 1 == 0 + x1 ? X[i][0].x = WIDTH_CONSOLE + x1 - 1 : X[i][0].x--;
} while (cnt < SPEED);
}
}
void EraseCars()
{
for (int i = 0; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
GotoXY(X[i][MAX_CAR_LENGTH - 1 - cnt].x, X[i][MAX_CAR_LENGTH - 1 - cnt].y);
cout << " ";
cnt++;
} while (cnt < SPEED);
}
for (int i = 1; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
GotoXY(X[i][0 + cnt].x, X[i][0 + cnt].y);
cout << " ";
cnt++;
} while (cnt < SPEED);
}
}
void MoveRight()
{
if (Y.x < WIDTH_CONSOLE - 1)
{
DrawPlayer(Y, ' ');
Y.x++;
DrawPlayer(Y, 'Y');
}
}
void MoveLeft()
{
if (Y.x > 1)
{
DrawPlayer(Y, ' ');
Y.x--;
DrawPlayer(Y, 'Y');
}
}
void MoveDown()
{
if (Y.y < HEIGHT_CONSOLE - 1)
{
DrawPlayer(Y, ' ');
Y.y++;
DrawPlayer(Y, 'Y');
}
}
void MoveUp()
{
if (Y.y > 1)
{
DrawPlayer(Y, ' ');
Y.y--;
DrawPlayer(Y, 'Y');
}
}
void SubThread()
{
while (1)
{
if (STATE)
{
switch (MOVING)
{
case 'A':
MoveLeft();
break;
case 'D':
MoveRight();
break;
case'W':
MoveUp();
break;
case'S':
MoveDown();
break;
}
MOVING = ' ';
EraseCars();
MoveCars(0, 0);
DrawCars();
if (IsImpact(Y))
{
ProcessDeath();
}
if (Y.y == 1)
{
ProcessFinish(Y);
Sleep(50);
}
}
}
}
void main()
{
int temp;
FixConsoleWindow();
srand(time(NULL));
StartGame();
thread t1(SubThread);
while (1)
{
temp = toupper(_getch());
if (STATE == 1)
{
EraseCars();
if (temp == 27)
{
ExitGame(t1.native_handle());
break;
}
else if (temp == 'P')
{
PauseGame(t1.native_handle());
temp = toupper(_getch());
if (temp == 'B')
ResumeThread((HANDLE)t1.native_handle());
}
else
{
if (temp == 'D' || temp == 'A' || temp == 'W' || temp == 'S')
{
MOVING = temp;
}
}
}
else
{
if (temp == 'Y') StartGame();
else
{
ExitGame(t1.native_handle());
break;
}
}
}
}
And this is the image of the error: https://imgur.com/PGJJX2w
Basically, this is a crossing road game, every time you go to the top, it saves the location and you cannot go that location again (still working on this), game finish when you run into the cars (lines of dots as of the moment). Thanks in advance
You created a std::thread object here:
thread t1(SubThread);
but you didn't call join() nor detach() for that.
This causes that std::terminate() is called (the program aborts) when the object is destructed.
Call t1.join() if you want to wait until the thread ends or t1.detach() if you want to let the thread run freely before returning from the main() function.
Another option is using CreateThread() directly instead of std::thread to create threads. This may be better because you are using t1.native_handle() for operations on the thread.

For loop isn't running C++

I am writing a piece of code to make two LED lights blink in a specific sequential order.
my code
int main()
{
int blue = 3;
int green = 4;
int time = 1;
int i = 1;
int j = 1;
greenLED = 1;
blueLED = 1;
wait(1);
for(time; time<green*blue; time++)
{
if (time == green*i)
{
blueLED = 1;
i=i+1;
}
if(time == blue*j)
{
greenLED = 1;
j=j+1;
}
wait(1);
}
}
My problem is that it says my for loop has no effect. I am assuming that it means my for loop is not running because the expression for my for loop doesn't make sense or isn't picking up any of the variables I have? Can someone please help me out and tell me why?
cheers
i think this is what you wanted
int main()
{
int blue = 3;
int green = 4;
int time = 1;
int i = 1;
int j = 1;
int greenLED = 1;
int blueLED = 1;
for(time; time<green*blue; time++)
{
blueLED=0;
greenLED=0;
printf("for loop start\n");
if (time == green*i)
{
printf("if1\n");
blueLED = 1;
i=i+1;
}
if(time == blue*j)
{
printf("if2\n");
greenLED = 1;
j=j+1;
}
printf("endforloop\n");
printf("%d\n",greenLED);
printf("%d\n",blueLED);
}
}
as you see the for loop is running

Array String null

Why does my IntForItem1 go over the max lenght of arrayStrings???
int TotalItems = 0, IntForItem1 = 0;
struct Item
{
int Index;
std::string* stringArray = new std::string[555]; //random value coz it will change in GetItems right?
};
Item item[120];
int AddNewItem(int i, int Index, std::string stringarray[])
{
item[i].Index = Index;
item[i].stringArray = stringarray;
return (i + 1);
}
void GetItems()
{
int i = 0;
std::string * test = new std::string[4]{ "1", "2", "3", "4"};
i = AddNewItem(i, IntForItem1, test);
TotalItems = i;
}
int main()
{
GetItems();
while (true)
{
system("CLS");
for (int i = 0; i < TotalItems; i++)
std::cout << item[i].stringArray[item[i].Index].c_str();
while (true)
{
if (GetAsyncKeyState(VK_LEFT) & 1)
{
if (item[0].Index <= 0)
item[0].Index = 0;
else
item[0].Index -= 1;
break;
}
else if (GetAsyncKeyState(VK_RIGHT) & 1)
{
if (item[0].Index >= sizeof(item[0].stringArray))
item[0].Index = sizeof(item[0].stringArray);
else
item[0].Index += 1;
break;
}
}
}
Sleep(1);
return 0;
}
sizeof(item[0].stringArray) in your code is the size of the string pointer, not the size of the space you set.
You can try this.
In additon, you should pay attention to the size of your array, otherwise you will always right-click the size of the array, can cause array crossing bounds, causing program errors.

C++ Access Violation with atoi() function

#include "stdafx.h"
#include <list>
#include <iostream>
#include <string>
using namespace std;
class Canvas
{
public:
void CleanCanvas(Canvas * Canvas);
int canvas[10][10];
void setCoords(int X,int Y,bool run);
bool Win(Canvas * Canvas,string * WinningPlayer);
}CANVAS;
int _tmain(int argc, _TCHAR* argv[])
{
string coords;
string temp;
int X,Y;
bool flag = true;
bool run = false;
string WinningPlayer = "";
system("color 02");
printf("------------------------------//TIC-TAC-TOE//------------------------\n\n\n\n\n");
printf(" *********************************************** \n\n\n");
printf("Example: player1- 3,3 to put a mark on 3 line of the 3 column\n\n\n\n\n\n");
CANVAS.CleanCanvas((Canvas*)&CANVAS.canvas);
cin.get();
while(flag)
{
printf("player1 make the mov: ");
cin >> coords;
X = atoi((char *)coords.at(0));
Y = atoi((char *)coords.at(2));
if(CANVAS.canvas[X][Y] != 0)
{
printf("Coords alrady taken...set new");
cin >> coords;
X = coords.at(1);
Y = coords.at(3);
}
run = false;
CANVAS.setCoords(X,Y,run);
if(CANVAS.Win((Canvas*)&CANVAS.canvas,&WinningPlayer) == true)
{
printf("%s Win",WinningPlayer);
flag = false;
}
printf("player2 make the mov: ");
cin >> coords;
X = coords.at(1);
Y = coords.at(3);
if(CANVAS.canvas[X][Y] != 0)
{
printf("Coords alrady taken...set new");
X = coords.at(1);
Y = coords.at(3);
}
}
cin.get();
return 0;
}
void Canvas::setCoords(int X,int Y,bool run)
{
if(run == false)
{
CANVAS.canvas[X][Y] = 1;
}else
{
CANVAS.canvas[X][Y] = 2;
}
}
void Canvas::CleanCanvas(Canvas * Canvas)
{
for (int i = 0; i <= 3; i++)
{
for(int a = 0; a <= 3; a++)
{
Canvas->canvas[i][a] = 0;
}
}
}
bool Canvas::Win(Canvas * Canvas,string * WinningPlayer)
{
int count = 0;
for(int i = 0; i <= 3; i++)
{
for(int a = 0; a <= 3; a++)
{
switch(Canvas->canvas[i][a])
{
case 1: count +=1;
break;
case 2: count *=2 + 1;
break;
}
if(count == 9)
{
WinningPlayer = (string *)"player2";
return true;
}else if (count == 3)
{
WinningPlayer = (string *)"player1";
return true;
}
}
}
}
The code above give me an access violation that i saw come from the
X = atoi((char *)coords.at(0));
Y = atoi((char *)coords.at(2));
I've tried to cast coords.at in a temporany variables but it didn't work
Don't look at the code because it's just a shot so it's not suppose to handle exception...
i need help to figure out what the real prblem is...thanks!
coords.at(0) returns a char, not a char*. Try to parse your std::string first, transform each number at a char*, and so, you use atoi.

For loop just... not starting?

This is a bizarre problem. I've got a void function that performs a for loop and nothing else, but the for loop doesn't ever start, even though the function is being called. Here is the function:
void Cell::Consolidate()
{
cout << "Consolidating (outside)...\n";
for(int i = 0; i < m_Tiles.size(); ++i)
{
cout << "Consolidating (inside)...\n";
int row = m_Tiles[i]->GetRow();
int col = m_Tiles[i]->GetCol();
//Check below.
if((*m_pTileMap)[row + 1][col].pParentCell != this)
{
m_EdgeTiles.push_back(m_Tiles[i]);
m_Tiles[i]->SetColor(sf::Color(100, 100, 100));
bool newNeighbor = true;
for(int j = 0; j < m_Neighbors.size(); ++j)
{
if(m_Neighbors[j] == (*m_pTileMap)[row + 1][col].pParentCell)
{
newNeighbor = false;
break;
}
}
if(newNeighbor)
{
m_Neighbors.push_back((*m_pTileMap)[row + 1][col].pParentCell);
}
}
//Check above.
else if((*m_pTileMap)[row - 1][col].pParentCell != this)
{
m_EdgeTiles.push_back(m_Tiles[i]);
m_Tiles[i]->SetColor(sf::Color(100, 100, 100));
bool newNeighbor = true;
for(int j = 0; j < m_Neighbors.size(); ++j)
{
if(m_Neighbors[j] == (*m_pTileMap)[row - 1][col].pParentCell)
{
newNeighbor = false;
break;
}
}
if(newNeighbor)
{
m_Neighbors.push_back((*m_pTileMap)[row - 1][col].pParentCell);
}
}
//Check the right.
else if((*m_pTileMap)[row][col + 1].pParentCell != this)
{
m_EdgeTiles.push_back(m_Tiles[i]);
m_Tiles[i]->SetColor(sf::Color(100, 100, 100));
bool newNeighbor = true;
for(int j = 0; j < m_Neighbors.size(); ++j)
{
if(m_Neighbors[j] == (*m_pTileMap)[row][col + 1].pParentCell)
{
newNeighbor = false;
break;
}
}
if(newNeighbor)
{
m_Neighbors.push_back((*m_pTileMap)[row][col + 1].pParentCell);
}
}
//Check the left.
else if((*m_pTileMap)[row][col - 1].pParentCell != this)
{
m_EdgeTiles.push_back(m_Tiles[i]);
m_Tiles[i]->SetColor(sf::Color(100, 100, 100));
bool newNeighbor = true;
for(int j = 0; j < m_Neighbors.size(); ++j)
{
if(m_Neighbors[j] == (*m_pTileMap)[row][col - 1].pParentCell)
{
newNeighbor = false;
break;
}
}
if(newNeighbor)
{
m_Neighbors.push_back((*m_pTileMap)[row][col - 1].pParentCell);
}
}
}
}
When I run the program, "Consolidating (outside)...\n" gets send to cout, but "Consolidating (inside)...\n" does not. Nothing that is supposed to happen in the loop actually happens, either (for example the SetColor() calls don't do anything, nor does anything happen if I send things to cout anywhere else in the loop), so I can only assume the loop is not starting at all. Why not? What could cause this?
i < m_Tiles.size()
This loop condition gets checked on entrance to the loop, not only after each iteration. If your m_Tiles vector is empty, well, no loop for you.
Most likely, m_Tiles.size() returns a negative value or zero value.