Aidan Aidan - 28 days ago 9
C++ Question

How to stop incrementing variable after bool becomes true?

So I'm working on a game that tasks the player with pressing either A, B, or C to make one of three boxes disappear. If a box disappears to reveal a smaller box, the user wins. I'm having difficulty trying to make it so that when the user wins, the counters for the amount of total guesses made and wrong guesses are no longer incremented, because at the moment, one can just keep pressing a button to continually increment those two variables (aptly named totalGuesses and wrongGuesses respectively). Does anyone have any idea how I could accomplish this task? I'm sure it's relatively simple, but it's driving me up the wall. Thank you so much.

Here's my main.cpp:

#include "Box.h"
#include "Font.h"
#include "Camera.h"
#include "Time.h"
#include <vector>
#include <sstream>
using namespace std;

#include "vgl.h"
using namespace glm;
#define SPACEBAR_KEY 32
#define ESCAPE_KEY 033

vector<Box * > boxes;
Camera* camera;
Font* font;
int numGenerator, guesses, totalGuesses, rounds, wrongGuesses, wrongGuessesRound, oldGuess, oldWrongGuess;
bool win;

void closeApp()
{
delete camera;
delete font;



for (auto it = boxes.begin(); it != boxes.end(); ++it)
delete (*it);


}

void startNewGame()
{
rounds++;
win = false;
guesses = 0;
wrongGuesses = 0;
wrongGuessesRound = 0;
numGenerator = rand() % 3;

boxes[1]->Visible = true;
boxes[2]->Visible = true;
boxes[3]->Visible = true;

if (numGenerator == 0)
{
boxes[0]->Position = vec3(0.0f, -3.0f, 0.0f);
}
else if (numGenerator == 1)
{
boxes[0]->Position = vec3(0.0f, 0.0f, 0.0f);
}
else
{
boxes[0]->Position = vec3(0.0f, 3.0f, 0.0f);
}

}

void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case ESCAPE_KEY: // ASCII Escape Key Code
closeApp();
exit(EXIT_SUCCESS);
break;
case 'a':
boxes[1]->Visible = false;
if (boxes[0]->Position != vec3(0.0f, -3.0f, 0.0f))
{
guesses++;
wrongGuesses++;
wrongGuessesRound++;
totalGuesses++;
}
else
{
win = true;
//totalGuesses++;
//guesses++;
}
glutPostRedisplay();
break;
case 'b':
boxes[2]->Visible = false;
if (boxes[0]->Position != vec3(0.0f, 0.0f, 0.0f))
{
guesses++;
wrongGuesses++;
totalGuesses++;
wrongGuessesRound++;
}
else
{
win = true;
//totalGuesses++;
//guesses++;
}
glutPostRedisplay();
break;
case 'c':
boxes[3]->Visible = false;
if (boxes[0]->Position != vec3(0.0f, 3.0f, 0.0f))
{
guesses++;
wrongGuesses++;
wrongGuessesRound++;
totalGuesses++;
}
else
{
win = true;
//totalGuesses++;
//guesses++;
}
glutPostRedisplay();
break;
case 'r':
if (win)
{
startNewGame();
}
glutPostRedisplay();
break;
}
}



void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
font->printText("Guessing Game!", 260, 560, 20);
font->printText("Press A, B, or C to make one of the boxes disappear!", 10, 540, 15);
font->printText("Try to find the small cube! Press 'r' to restart!", 30, 520, 15);
if (win)
{
font->printText("You win!", 275, 480, 30);
guesses = oldGuess;
wrongGuesses += 0;
}
if (guesses >= 3)
{
guesses = 3;
}
/*if (wrongGuessesRound >= 3)
{
wrongGuessesRound = 3;
}*/

std::stringstream ss1;
ss1 << "Guesses: " << guesses;
font->printText(ss1.str().c_str(), 20, 350, 15);
std::stringstream ss2;
ss2 << "Rounds played: " << rounds;
font->printText(ss2.str().c_str(), 20, 330, 15);
std::stringstream ss3;
ss3 << "Wrong guesses: " << wrongGuesses;
font->printText(ss3.str().c_str(), 20, 290, 15);
std::stringstream ss4;
ss4 << "Total guesses: " << totalGuesses;
font->printText(ss4.str().c_str(), 20, 310, 15);
//std::stringstream ss5;
//ss5 << "Round wrong guesses: " << wrongGuessesRound;
//font->printText(ss5.str().c_str(), 20, 270, 15);



boxes[0]->Draw(camera->ProjectionMatrix, camera->ViewMatrix);
boxes[1]->Draw(camera->ProjectionMatrix, camera->ViewMatrix);
boxes[2]->Draw(camera->ProjectionMatrix, camera->ViewMatrix);
boxes[3]->Draw(camera->ProjectionMatrix, camera->ViewMatrix);


glutSwapBuffers();
}

void init()
{
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);

srand(time(NULL));

font = new Font();

camera = new Camera();
camera->ViewMatrix = glm::lookAt(glm::vec3(0, 0, 20), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));


VertexBufferData vertexBufferData = VertexBufferData("Data\\Models\\Objects.xml");

boxes.push_back(new Box(vertexBufferData, glm::vec3(0.0f, 0.0f, 0.0f), "data/images/wood.bmp", "Data\\Shaders\\Vertex.shader", "Data\\Shaders\\Fragment.shader", vec3(0.4f, 0.4f, 0.4f), true));
boxes.push_back(new Box(vertexBufferData, glm::vec3(0.0f, -3.0f, 0.0f), "data/images/ground.tga", "Data\\Shaders\\Vertex.shader", "Data\\Shaders\\Fragment.shader", vec3(1.0f, 1.0f, 1.0f), true));
boxes.push_back(new Box(vertexBufferData,glm::vec3(0.0f, 0.0f, 0.0f), "data/images/metal.bmp", "Data\\Shaders\\Vertex.shader", "Data\\Shaders\\Fragment.shader", vec3(1.0f, 1.0f, 1.0f), true));
boxes.push_back(new Box(vertexBufferData, glm::vec3(0.0f, 3.0f, 0.0f), "data/images/brick.bmp", "Data\\Shaders\\Vertex.shader", "Data\\Shaders\\Fragment.shader", vec3(1.0f, 1.0f, 1.0f), true));

startNewGame();
}



int main(int argc, char** argv)
{
glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(1024, 768);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("Satterwhite_Project_5");


if (glewInit())
{
cerr << "Unable to init glew" << endl;
exit(EXIT_FAILURE);
}

init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}

Answer

Why wouldn't you do this to start:

void keyboard(unsigned char key, int x, int y)
{
    if (win)
    {
        if ((key == 'a') || (key == 'b') || (key == 'c'))
        {
            // ignore a,b,c if there is already a winner
            return;
        }
    }

    switch (key) 
    {
       ...