I am making a game in Visual studious 2017 (visual c++), where you have to repeatedly press the space bar to earn money. But I have run into a problem, the compiler can't keep up when you press the spacebar really fast and so It miscounts. I tried doing some research, but all I got was this and as I said earlier it cant keep up.
this is so far what i got:
int click_systm()
{
char spacebar;
while (1)
{
if (GetAsyncKeyState(VK_SPACE) != 0)
{
if (GetKeyState(VK_SPACE) == 0)
{
spacebar = _getch();
int value = spacebar;
if (value == 32)
{
money++;
cout << money << endl;
}
}
}
}
}
If you made it here, thanks for taking your time to read this :)
The compiler is what compiles your C++ code into some binary. The CPU as well as the OS should be able to keep up with a human speed spacebar smashing. The problem can be from the fact that you run your soft inside a console(please see the comment left by user253751).
std::cout slows down a program by a lot because of the time it takes to print. As also mentioned it the comment, split your printing in a different thread. You can also add std::ios_base::sync_with_stdio(false); to gain some speed if you really need to.
I have found an answer to my own question, for those that have the same problem. This code here will do the same thing but is more responsive and will keep up to the button mashing.
int click_systm()
{
char spacebar;
while (1)
{
spacebar = _getch();
if (spacebar == 32)
{
money++;
cout << money << "\n";
}
}
}
Thanks to everyone trying to help me, espically MrScriptX and Antonio.
Related
The famous text scrolling effect has been used in many games, and I mean many console-based-RPG games.
I'm somewhat trying to make my own as a novice project to sharpen my C++ skills, however, I got stuck somewhere.
You see, while a stream of text is scrolling, the player eventually gets bored and wants to skip those texts.
What happens is, that when the player presses a certain key, the text stops scrolling(and by scrolling I mean spitting out characters of a string with increasing index i with a slight delay) and it spits out everything at once.
This is quite the effect which I am trying to replicate.
This is the I currently use (without the skip-through effect):
for(int i = 0; i<text.length();i++)
{
std::cout << text[i];
Sleep(200);//WINAPI function for timeout. DWORD Milliseconds as argument
}
And the one that I want:
for(int i = 0; i<text.length();i++)
{
std::cout << text[i];
if(GetAsyncState(VK_RETURN)
{
continue;
}
else{
Sleep(200);//WINAPI function for timeout. DWORD Milliseconds as argument
}
}
This is very novice code, so please don't criticize me.
So I end this shtick with my question:
How to stop text from streaming with a delay, and to make it output it all at once.
Have a nice day!
Update
Ok, I removed the 3 couts and replaced it with *buffer = 'a', and there was a big performance difference. Removing that line made the program 2x as fast. If you go on godbolt and compile it using msvc, that single line of code changes most of the program. (It adds a whole lot more complexity)
The following might seem extremely weird, but it's true on my computer:
Alright, so I was doing some benchmarking of some code, and I noticed extremely weird performance anomalies that were 100% consistent. I'm running windows-10 and visual-studio-2019. Basically, deleting a line of code that is never called completely changes the performance of the program.
Here is exactly what to do:
Create new VS-2019 Console C++ App project
Set the configuration to Release & x64
Paste the code below:
#include <iostream>
#include <chrono>
class Test {
public:
size_t length;
size_t doublingVal;
char* buffer;
Test() : length(0), doublingVal(2) {
buffer = static_cast<char*>(malloc(1));
}
~Test() {
std::cout << "called" << "\n";
std::cout << "called" << "\n";
std::cout << "called" << "\n"; // Remove this line and the time decreases DRASTICALLY (ie remove line 14)
}
void append() {
if (doublingVal == length) {
doublingVal <<= 1;
}
*buffer = 'a';
++length;
}
};
int main()
{
Test test;
auto start = std::chrono::high_resolution_clock::now();
for (size_t i = 0; i < static_cast<size_t>(1024) * 1024 * 1024 * 4; ++i) {
test.append();
}
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count() << "\n";
}
Run the program using CTRL+F5, not in debug. Now remember how long it takes to run. (a few seconds)
Then, in the destructor of Test, remove the third line which has the comment.
Run the program again, and you should see that the performance increases drastically. I tested this exact same code with 4 different projects all brand new, and 3 different computers.
The destructor is called at the very end, when the entire program is finished measuring time. The extra cout shouldn't affect anything.
Edit:
You can also see a similar thing go on if you remove the 3 cout's and replace it with a single *buffer = 'a'. Then CTRL+F5 once again, record the time, and then remove that line we just added. Then run it again and the time magically decreases by half.
WTF is going on, and how do you solve the weird performance difference?
I have a weird problem with the value returned by my class called Timer (that uses std::chrono).
If I keep the std::cout commented, I have the feeling that delta returned by timer.restart() gets a very low value (it takes 3 or 4 times longer to reach 10.f). I tried to display it, but as I said above, uncommenting the std::cout solves the problem.
My timer does its job well in others parts of the application, so I don't think the problem is in there.
void Party::gameOver(float delta)
{
_delta += delta;
// std::cout << _delta << std::endl; // if I uncomment this the problem is solved
if (_delta > 10.0000f) {
// ...
_state = GameStatusType::Waiting;
_delta = 0;
}
}
This method is called here:
void Party::loop(void)
{
Timer timer;
while (!isFinished())
{
float delta = timer.restart(); // return in second
switch (_state)
{
// ...
case GameStatusType::GameOver:
gameOver(delta);
break;
}
}
}
The method "loop" is called in a thread like below:
void Party::run(void)
{
_party = std::thread(&Party::loop, shared_from_this());
}
I don't know if this can help, but I execute this code on Visual Studio 2015 on Windows 10. If you need further information, just ask.
One possibility is the windows console is really slow, there was many topic about this. You may try use overlapped io to write to console to see if it's improved.
The problem was just the loop was going too fast. Just added a Sleep.
I am writing a simple program (my 1st program) to display the laptop battery, however, I would like to keep it active to monitor the battery %.:
using namespace std;
int main(int argc, char *argv[]) {
id:
SYSTEM_POWER_STATUS spsPwr;
if (GetSystemPowerStatus(&spsPwr)) {
cout << "\nAC Status : " << static_cast<double>(spsPwr.ACLineStatus)
<< "\nBattery Status : " << static_cast<double>(spsPwr.BatteryFlag)
<< "\nBattery Life % : " << static_cast<double>(spsPwr.BatteryLifePercent)
<< endl;
system("CLS");
goto id;
return 0;
}
else return 1;
}
using goto seems to be a bad idea as the CPU utilization jump to 99% ! :(, I am sure this is not the right way to do it.
Any suggestion?
Thanks
while (true) {
// do the stuff
::Sleep(2000); // suspend thread to 2 sec
}
(you are on Windows according to the API function)
see: Sleep
First of all, the issue you are asking about: of course you get 100% CPU usage, since you're asking the computer to try and get and print the power status of the computer as fast it possibly can. And since computers will happily do what you tell them to, well... you know what happens next.
As others have said, the solution is to use an API that will instruct your application to go to sleep. In Windows, which appears to be your platform of choice, that API is Sleep:
// Sleep for around 1000 milliseconds - it may be slightly more since Windows
// is not a hard real-time operating system.
Sleep(1000);
Second, please do not use goto. There are looping constructs in C and you should use them. I'm not fundamentally opposed to goto (in fact, in my kernel-driver programming days I used it quite frequently) but I am opposed to seeing it used when better alternatives are available. In this case the better alternative is a while loop.
Before I show you that let me point out another issue: DO NOT USE THE system function.
Why? The system function executes the command passed to it; on Windows it happens to execute inside the context of the command interpreter (cmd.exe) which supports and internal command called cls which happens to clear the screen. At least on your system. But yours isn't the only system in the world. On some other system, there might be a program called cls.exe which would get executed instead, and who knows what that would do? It could clear the screen, or it could format the hard drive. So please, don't use the system function. It's almost always the wrong thing to do. If you find yourself looking for that command stop and think about what you're doing and whether you need to do it.
So, you may ask, how do I clear the screen if I can't use system("cls")? There's a way to do it which should be portable across various operating systems:
int main(int, char **)
{
SYSTEM_POWER_STATUS spsPwr;
while (GetSystemPowerStatus(&spsPwr))
{
std::string status = "unknown";
if (spsPwr.ACLineStatus == 0)
status = "offline";
else if (spsPwr.ACLineStatus == 1)
status = "online";
// The percent of battery life left is returned as a value
// between 0 and 255 so we normalize it by multiplying it
// by 100.0 and dividing by 255.0 which is ~0.39.
std::cout << "Current Status: " << status << " ("
<< static_cast<int>(spsPwr.BatteryFlag) << "): "
<< 0.39 * static_cast<int>(spsPwr.BatteryLifePercent)
<< "% of battery remaining.\r" << std::flush;
// Sleep for around 1000 milliseconds - it may be slightly more
// since Windows is not a hard real-time operating system.
Sleep(1000);
}
// Print a new line before exiting.
std::cout << std::endl;
return 0;
}
What this does is print the information in a single line, then move back to the beginning of that line, sleep for around one second and then write the next line, overwriting what was previously there.
If the new line you write is shorter than the previous line, you may see some visual artifacts. Removing them should not be difficult but I'll leave it for you as an exercise. Here's a hint: what happens if you output a space where a letter used to be?
In order to do this across lines, you will need to use more advanced techniques to manipulate the console, and this exercise becomes a lot trickier.
You are having 100% CPU usage because your program is always running.
I don't want to get into details, and given that this is your first program, I'll recommend to put a call to usleep before the goto.
And, of course, avoid goto, use a proper loop instead.
int milliseconds2wait = 3000;
while (!flag_exit) {
// code
usleep( 1000 * milliseconds2wait )
}
Update: This is windows, use Sleep instead of usleep:
Sleep( milliseconds2wait );
My application keeps closing when debugging. I'm not able to view what the "results" are since it goes too fast.
I've been looking at many different forums and topics and all the solutions given just wont apply. I've tried different commands before returns 0; etc and also changing an option in the project.
I'm just starting and trying to learn from the c++ primer but this is frustrating me already :).
Following is my code, please help!
#include <iostream>
int main ()
{
int sum = 0, val = 1;
while (val <= 10) {
sum +=val;
++ val;
}
std::cout << "Sum of 1 to 10 inclusive is "
<< sum << std::endl;
Console.Read();
return 0;
}
Don't do Console.Read();, do std::cin.get();.
Try this:
#include <iostream>
int main ()
{
int sum = 0, val = 1;
while (val <= 10) {
sum +=val;
++ val;
}
std::cout << "Sum of 1 to 10 inclusive is "
<< sum << std::endl;
std::cin.get(); // hackish but better than system("PAUSE");
return 0;
}
Assuming that you are using Visual Studio:
Debug builds will run until they hit a breakpoint or until the program finishes (which ever comes first). If the program finishes, the console closes. Place a break point on the line containing return 0; and your console will stay open until you click Continue.
Release builds will run until the program finishes. If the program finishes, you will be prompted to Press any key to continue. . . and the console will stay open.
If you are not setting breakpoints in such a small program, you are wasting your resources -- debug mode will impact the performance of the program.
Thus, you should build in Release mode and forget about using std::cin.get().