Infinite while loop with a std::ofstream C++ - c++

Well I have that code that saves an array map on a txt file:
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;}
}
I want to integrate it to a while loop:
std::ofstream output("mapa.txt");
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;
}
output<<scene[xPos][yPos] << ",";
//if(xPos<(worldWidth-1)){output<<",";}
//if(yPos<(worldHeight-1)){output<<std::endl;}
yPos++;
if(yPos>worldHeight) {
output<<std::endl;
slope = random(5)-2;
if(topOfTheWorld<(worldHeight/6)) {
slope = 1;
} else if(topOfTheWorld>(worldHeight-10)) {
slope = -1;
}
topOfTheWorld += slope;
yPos = 0;
xPos++;
}
if (xPos>=worldWidth) {
break;
}
}
But for some reason the 'while' loop becomes infinite... :/
What can I do?

The code looks good.
However I'm not sure if scene is correctly allocated.
You have yPos>worldHeight and below xPos>=worldWidth which suggests that you're not sure how to compare these. I suspect you got at least one of them wrong. This can easily write outside the scene variable and overwrite yPos or xPos.
Try changing to ypos>=worldHeight and see if that works.
If not check how much space you allocate for scene and if it looks OK try making it a bit bigger.

Related

Code only outputs std::vector one time instead of wanted multiple times

So my problem is the following: I want to program a basic game of life simulation. Therefore I am using std::vector to save the current state and calculate the next state. All put together in a while(). I am doing std::cout for every value, formated as a matrix. The problem is, that I only get one "matrix" as an output, instead of expected multiple.
I've also tried to output text after calculating the next state (so before and after the nextCells=currentCells), which didn't work, while outputting text within the calculating for() loop works.
I don't know what to do anymore. Appreciate any kind of help!
I've tried to output text after calculating the next state (so before and after the nextCells=currentCells), which didn't work, while outputting text within the calculating for() loop works.
#include <iostream>
#include <vector>
#include <unistd.h>
#define DIMX 10
#define DIMY 10
int countCells(std::vector<std::vector<int>> currentGrid, int x, int y);
int main() {
std::vector<std::vector<int>> currentCells(DIMX, std::vector<int>(DIMY));
std::vector<std::vector<int>> nextCells(DIMX, std::vector<int>(DIMY));
int count = 0;
nextCells = currentCells;
while(true) {
count++;
for(int i=0;i<=DIMX-1;i++) {
for(int j=0;j<=DIMY-1;j++) {
std::cout << currentCells[i][j];
std::cout.flush();
}
std::cout << "\n";
}
for(int i=0;i<=DIMX-1;i++) {
for(int j=0;j<=DIMY-1;j++) {
int aliveCells = countCells(currentCells, i, j);
if(currentCells[i][j]==0) {
if(aliveCells==3) {
nextCells[i][j]=1;
} else {
nextCells[i][j]=0;
}
} else {
if(aliveCells>3) {
nextCells[i][j]=0;
} else if(aliveCells<2) {
nextCells[i][j]=0;
} else {
nextCells[i][j]=1;
}
}
}
}
currentCells = nextCells;
if(count>=5) {
return 0;
}
}
}
int countCells(std::vector<std::vector<int>> currentGrid, int x, int y) {
int aliveCounter;
if(x==DIMX || x==0 || y==DIMY || y==0) {
return 0;
}
if(currentGrid[x-1][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x-1][y]==1) {
aliveCounter++;
} else if(currentGrid[x-1][y+1]==1) {
aliveCounter++;
} else if(currentGrid[x][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x][y+1]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y+1]==1) {
aliveCounter++;
}
return aliveCounter;
}
Your code produces an out of vector-range exception, For optimization reasons the exception may not throw in release mode.
When countCells gets called for y = 9 or x = 9
currentGrid[x+1][y+1]
is out of range.
Notice that
v = std::vector<int>(10,0) can be called from v[0] to v[9]; not v[10],
which would be out of range.

How to center a widget in QScrollArea?

Constructor:
ScrollArea::ScrollArea(...)
{
...
end = myItems.count();
for(int i=0; i<end; i++)
{
scrollItems.append(new ScrollItem(myItems.at(i), 0, width, i, this));
}
scrollArea->setWidget(this); //must be last for auto-scrolling to work
}
Member function:
void ScrollArea::updateSelection(int selection)
{
foreach(ScrollItem* item, scrollItems)
{
if(item->updateSelection(selection, 0))
{
scrollArea->ensureWidgetVisible(item);
}
}
}
After running ScrollArea::updateSelection, it looks like this:
I want it to look like this:
Google returns a mis-titled question (as far as I can tell: Place widget in center of QScrollArea) and a bunch of junk.
Still don't know why QScrollArea::ensureWidgetVisible doesn't work, even with explicit margins, but I found something that does:
void ScrollArea::updateSelection(int selection)
{
int item = -1;
int i = scrollItems.count();
while(i)
{
i--;
if(scrollItems.at(i)->updateSelection(selection, 0))
{
item = i;
}
}
if(item < 0)
{
return;
}
i = scrollItems.first()->height();
item *= i;
item += i / 2;
//item is now the position that should be centered
scrollArea->verticalScrollBar()->setValue(
item - (scrollArea->height() / 2)
);
}
So I'm basically brute-forcing what I want instead of having the library do it. (and fail)

Can't figure out how to loop playerturns and moves Tic Tac Toe (C++) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
EDIT: Solved now thank you triple_r and AJNeufield for your help on this problem I was having.
I've looked around multiple websites and YouTube about this and I can't seem to find anything on what I am specifically looking for this as my format for the program is a good bit different than others. Therefore, it's hard to decipher where I need to put the things I do need that I know of.
Please note that I'm relatively new to C++ so I'd appreciate all the feedback or criticism you might provide me.
Also, note my code does compile and run it just does not allow me to put in more than one input and more than likely does not allow for a switch of player turns.
Quick Edit: Switched the code with the new setup suggested by triple_r but I seemed to have messed it up somewhere along the line and it does compile(with the exception of x and y not being utilized and one other error) but it always starts off with player 2 going first and as soon as it receives input it ends automatically with a segmentation fault.
#include <iostream>
#include <cstdlib>
using namespace std;
//////////////////////////////////////////////////////////
void initboard(char board[3][3])
{
int x,y;
for (x=0;x<3;x++)
for (y=0;y<3;y++)
board[x][y]=' ';
return;
}
//////////////////////////////////////////////////////////
void printboard(char board[3][3])
{
int x,y;
for (x=0;x<3;x++)
{
cout<<"\n";
for (y=0;y<3;y++)
{
cout<<" "<<board[x][y]<<" ";
if (y<2) cout<<"|";
}
if (x<2) cout<<"\n===========";
}
return;
}
//////////////////////////////////////////////////////////
void getmove(char board[3][3], int player)
{
return;
}
//////////////////////////////////////////////////////////
int main()
{
bool done=false;
char board[3][3];
int x,y,player=1,turn,playerchoice,playermark;
initboard(board);
turn=0;
do
{
if (player==1)
playermark='X';
else
playermark='O';
if (turn%2)
player=1;
else
player=2;
cout<<"Player "<<player<<" where do you want to move?: ";
cin>>playerchoice;
if (playerchoice==1)
{
board[0][0]=playermark;
}
else if (playerchoice==2)
{
board[0][1]=playermark;
}
else if (playerchoice==3)
{
board[0][2]=playermark;
}
else if (playerchoice==4)
{
board[1][0]=playermark;
}
else if (playerchoice==5)
{
board[1][1]=playermark;
}
else if (playerchoice==6)
{
board[1][2]=playermark;
}
else if (playerchoice==7)
{
board[2][0]=playermark;
}
else if (playerchoice==8)
{
board[2][1]=playermark;
}
else if (playerchoice==9)
{
board[2][2]=playermark;
}
else
{
cout<<"Invalid move ";
}
if (board[x][y]!=' ')
cout<<"Move is already taken.";
board[x][y]=playermark;
if(board[x][y]==' ')
turn++;
}while (!done);
void printboard(char board[3][3]);
return 0;
}
EDIT: based on the updated code
So, the first thing I can see is that you are using x and y in your program but you don't initialize them or assign any values to them. Also, try to use functions/classes/... yo make your code more readable. You already have a function for player move but you are not using it. You can move the large if statement inside that function and that will make your main code shorter and more readable.
Here are my comments on the main part of your program:
int main()
{
// add a new variable to see if the move was valid or not:
bool done=false, validmove = true;
char board[3][3];
int x, y, player = 1, turn = 0, playerchoice, playermark;
initboard(board);
do
{
// swap the two `if`s so you decide who`s turn it is then assign the player mark,
// also, reverse the condition to make sure turn '0' is player 1's turn.
if (!(turn % 2))
player = 1;
else
player = 2;
if (player == 1)
playermark = 'X';
else
playermark = 'O';
cout << "Player " << player << " where do you want to move?: ";
cin >> playerchoice;
// Assign `x` and `y` here instead of updating the board, because you want to make
// sure that the move is valid before putting the mark:
validmove = true;
if (playerchoice == 1)
{
x = 0; y = 0;
}
else if (playerchoice == 2)
{
x = 0; y = 1;
}
else if (playerchoice == 3)
{
x = 0; y = 2;
}
else if (playerchoice == 4)
{
x = 1; y = 0;
}
else if (playerchoice == 5)
{
x = 1; y = 1;
}
else if (playerchoice == 6)
{
x = 1; y = 2;
}
else if (playerchoice == 7)
{
x = 2; y = 0;
}
else if (playerchoice == 8)
{
x = 2; y = 1;
}
else if (playerchoice == 9)
{
x = 2; y = 2;
}
else
{
cout << "Invalid move, try again!";
// Make sure to mark the move as invalid so they get a chance to
// change their move:
validmove = false;
}
// check to see if the turn was valid:
if(validmove)
{
if (board[x][y] != ' ')
{
cout << "Move is already taken, try again";
}
else
{
board[x][y] = playermark;
turn++;
}
}
// have to make sure you have a condition for end of game. A simple
// one is to check if turn is less than `9`, otherwise the board is
// full:
if(turn == 9)
done = true;
// you probably want to add a few more checks to see who won the game.
}while (!done);
// when calling a function, no need to put the return type or parameter type:
printboard(board);
return 0;
}
========================================================================
There are two do-while loops in your program and both seem to be meant as a game loop. What I would do is:
initboard(...);
turn = 0;
do{
//this is the game loop
...;
if( validturn )
turn++;
}while(!done);
release_resources(...);
return 0;
so, you fold everything into one loop. In that loop, you want to:
find who's turn it is:
if (turn % 2)
player = 1;
else
player = 2;
get users input:
std::cin >> playerchoice;
...
convert player choice to grid location:
switch ( move )
{
case 0:
x = 0;
y = 0;
break;
case 1:
...;
...
default:
//invalid move
}
see if the move is valid:
if( board[x][y] != ' ' )
//already taken, invalid move
then apply the move:
board[x][y] = playermark;
I hope this helps.
Your cin >> playerchoice is outside your do { ... } while ( moves != 9); loop. Move it inside.

OpenGL/Glut: glutTimerFunc seems not to start

I would like to use glutTimerFunc to move the camera around the scene which is composed of some mesh models. The camera path is build with a Bezier curve like the following:
if(sel == MODE_CAMERA_MOTION) {
mode = MODE_CAMERA_MOTION;
stepsCounter = 0;
// Building camera track
int i, j, k;
for(j=0; j<MAX_CV; j++) {
tmpCV[j][0] = CV[j][0];
tmpCV[j][1] = CV[j][1];
tmpCV[j][2] = CV[j][2];
}
for(i=0; i<STEPS; i++) {
for(j=1; j<MAX_CV; j++) {
for(k=0; k<MAX_CV-j; k++) {
lerp(i/(float)(STEPS*10), tmpCV[k], tmpCV[k+1], tmpCV[k]);
}
}
cameraPosition[i][0] = tmpCV[0][0];
cameraPosition[i][1] = tmpCV[0][1];
cameraPosition[i][2] = tmpCV[0][2];
}
glutTimerFunc(250, moveCamera, STEPS);
}
where the moveCamera function is:
void moveCamera() {
if (mode == MODE_CAMERA_MOTION) {
camE[0] = cameraPosition[stepsCounter][0];
camE[1] = cameraPosition[stepsCounter][1];
camE[2] = cameraPosition[stepsCounter][2];
if(stepsCounter < STEPS) {
stepsCounter++;
}
else {
/* come back to the first point */
camE[0] = 8.8;
camE[1] = 4.9;
camE[2] = 9.0;
stepsCounter = 0;
}
glutPostRedisplay();
}
}
But nothing moves. Maybe I have misunderstood the behaviour of that function.
Where am I wrong?
The prototype to the function passed to glutTimerFunc should be
void (*func)(int value)
Where the last parameter of glutTimerFunc is the passed value. So your moveCamera should be:
void moveCamera( int STEPS )
Also, even so, the moveCamera function will be called once. You need to reregister at end of execution. This might be a possible solution:
// instead of global STEPS and stepsCounter, we decrement at reexecution
void moveCamera( int STEPS ) {
... do stuff
glutTimerFunc(250, moveCamera, STEPS-1 );
}

How do I made shooting multiple bullets function correctly using a for loop?

I'm working on a prototype for a shmup game in C++ using SDL...Right now I'm just trying to get the basics working without using classes. Now, I have it so it shoots multiple bullets, but it behaves strangely which I believe is because of the way the counter is reset...The bullets will appear and disappear, and some will keep blinking in the original spot they were shot at, and there will sometimes be a delay before any can be shot again even if the limit isn't on the screen...And sometimes the player character will suddenly jump way to the right and only be able to move up and down. How do I fix this so it smoothly shoots? I've included all relevent code...
[edit] Please note that I intend on cleaning it up and moving it all to a class once I get this figured out...This is just a simple prototype so I can have the basics of the game programmed in.
[edit2] ePos is the enemy position, and pPos is the player position.
//global
SDL_Surface *bullet[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
bool shot[10];
int shotCount = 0;
SDL_Rect bPos[10];
//event handler
case SDLK_z: printf("SHOT!"); shot[shotCount] = true; ++shotCount; break;
//main function
for(int i = 0; i <= 9; i++)
{
shot[i] = false;
bullet[i] = IMG_Load("bullet.png");
}
//game loop
for(int i = 0; i <= shotCount; i++)
{
if(shot[i] == false)
{
bPos[i].x = pPos.x;
bPos[i].y = pPos.y;
}
if(shot[i] == true)
{
bPos[i].y -= 8;
SDL_BlitSurface(bullet[i], NULL, screen, &bPos[i]);
if( (bPos[i].y + 16 == ePos.y + 16) || (bPos[i].x + 16 == ePos.x + 16) )
{
shot[i] = false;
}
else if(bPos[i].y == 0)
{
shot[i] = false;
}
}
}
if(shotCount >= 9) { shotCount = 0; }
Here is something like I was suggesting in the comment. It was just written off the top of my head but it gives you a general idea of what I'm talking about..
class GameObject
{
public:
int x;
int y;
int width;
int height;
int direction;
int speed;
GameObject()
{
x = 0;
y = 0;
width = 0;
height = 0;
direction = 0;
speed = 0;
}
void update()
{
// Change the location of the object.
}
bool collidesWidth(GameObject *o)
{
// Test if the bullet collides with Enemy.
// If it does, make it invisible and return true
}
}
GameObject bullet[10];
GameObject enemy[5];
while(true)
{
for(int x=0; x<=10;x++)
{
bullet[x].update();
for(int y=0;y<=5;y++)
{
if(bullet[x].collidesWith(&enemy[y])
{
// Make explosion, etc, etc.
}
}
}
}