So I am trying to code a game using C++. I am using this online compiler so I can also work on it at school. This program was just a simple clicker game that I starting making. When I tested it to see if the code worked so far, nothing showed up, which is strange considering I have print statements in the code that give the directions for the player.
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int SCORE = 0;
int LEVEL = 1;
int COST = 50;
int ADDSCORE = 10;
char KEYINPUT;
bool GAMEON = true;
printf("Press space bar to gain points to your score.\n");
printf("Press z key to upgrade your score multiplyer.\n");
printf("Press the escape key (esc) to quit.\n");
printf("Upgrade score multiplyer = %d.\n", COST);
printf("Score multiplyer = LV%d.\n", LEVEL);
printf("Score = %d.\n", SCORE);
while (GAMEON == true) {
if (KEYINPUT == 32) {
SCORE += ADDSCORE;
}
if (KEYINPUT == 122) {
ADDSCORE += 10;
SCORE -= COST;
COST *= 2;
LEVEL += 1;
}
if (KEYINPUT == 27) {
GAMEON = false;
}
}
printf("Game has ended. You may now close out of the game");
return 0;
}
I am not sure if it is my code or if it is the online compiler, but I executed on a different compiler and got the same result. Nothing. Not exactly sure why this is happening, but if someone can spot what is wrong can you let me know.
I tried a bit around and on my system with a local compiler the text also does not print. Now in the first place if you want to code in C++ you need to use C++. printf is actually a C function. You are not using any C++ specific code in your example. If you want to use C in your C++ application though, use the C++ equivalents of the C libraries which wourld be <cstdio> in your case. Now to the problem itself: i am using MSYS shell on windows and i assume you use something similar. There seems to be a problem with the output buffer when you use printf. Normally the output buffer is flushed with the \n newline character at the end of the input. Apparently this does not seem to work in some cases. Adding an fflush(stdout) at the end of the output worked in my case and the text was printed from the buffer and also calling it directly from windows command line, without flushing the buffer, did the trick. So i think it is a problem how your shell handles the buffers. Now to the solutions. Either you flush the output buffer everytime you want to print or you start to use C++ IO. Also as mentioned you need to initialize and change the value from KEYINPUT while your program is running.
#include <iostream>
using namespace std;
int main()
{
int SCORE = 0;
int LEVEL = 1;
int COST = 50;
int ADDSCORE = 10;
char KEYINPUT;
bool GAMEON = true;
/* Use cout instead of printf for output operations */
cout << "Press space bar to gain points to your score." << endl
<< "Press z key to upgrade your score multiplyer." << endl
<< "Press the escape key (esc) to quit" << endl
<< "Upgrade score multiplyer = " << COST << endl
<< "Score multiplyer = LV" << LEVEL << endl
<< "Score = " << SCORE << endl;
while (GAMEON == true) {
KEYINPUT = cin.get(); /* You need to initialize the value before using and change it in the loop */
if (KEYINPUT == 32) {
SCORE += ADDSCORE;
}
if (KEYINPUT == 122) {
ADDSCORE += 10;
SCORE -= COST;
COST *= 2;
LEVEL += 1;
}
if (KEYINPUT == 27) {
GAMEON = false;
}
}
cout << "Game has ended. You may now close out of the game" << endl;
return 0;
}
A little note at the end: Since i tried to do similar little games as i started, you will need to use a platform dependent library to capture those keystrokes like ESC or other keys which not directly get put into the input buffer. i know conio for windows and otherwise the winapi is well documented and relatively easy to use. There are also many examples of how to use the winapi to capture keystrokes from the command line window which can easily be found on google.
Related
As I'm sure the question makes clear, I'm new and learning and I'm sure many will wonder why ask.....cause I get the rest of it, just not this. I am using C++ and am trying to make a self guessing program, that uses an algorithim given to me. I have played with this section of code multiple ways and so far the one thing I have narrowed down, is what its not doing, and I want to both understand why and how to fix it because nothing I have tried is working. The basic version of the code I have been playing with is this:
// test_room.cpp : This file contains the 'main' function. Program execution
//begins and ends there. This is where
//I am going to test some code to understand my mistakes and how to fix
//them.
//
#include "pch.h"
#include <iostream>
#include <cstdlib>
#include<ctime>
using namespace std;
int main()
{
char play = 'y';
while (play == 'y')
{
int bad = 27;
int a = 50;
int b = 1;
int good = ((a - b) / 2);
int s = 0;
cout << "\nBegin?";
cin >> play;
do
{
++s;
if (good > bad)
{
cout <<"\n" <<good;
cout <<"\n" << s;
--a;
}
else if (good < bad)
{
cout << "\n"<<good;
cout <<"\n" << s;
++b;
}
else
{
cout << "good job";
}
} while (s < 50);
}
cout << "\nOK\n";
return 0;
}
What my question is I have tried moving the variables, I have fixed brace issues, I have tried using cin>>good>>a or b(depending on >< ) and so far I can not manipulate variables a or b to get it to try to guess or figure out the number 27, all it does is repeat 24 50 times. What do I need to do to change the values of a and b based on the algorithim?
Good and bad are never changed in the loop, I don't really understand the purpose of you algorithm(it looks like a binary search, but not really), but if you aren't changing any values that the if conditions evaluate in the loop, then none of the other conditions will ever be evaluated.
This code prints the desired no(4 here) of perfect numbers. It's an old code of mine and checks up every number whether it's perfect or not. It runs normally and finishes in 6-ish seconds, but if I put a cls before checking every number it takes a big hit(about 100 secs). Please tell me the theory behind it(why multiple cls takes a hit on performance).
No normie answers like "Dude obviously it takes a hit, it's refreshing the screen every time."
PS- I know the better way is not to check perfect numbers but to generate them.(By Euclid-Euler theorem)
IDE- DevC++
#include <iostream>
#include <string>
using namespace std;
int choice, quan, i, a[50], number;
string schoice;
void startgame()
{
choice = 3;
quan = 4;
system("cls");
cout << "Hey guys, today we are gonna print different types of numbers\n";
cout << "\nFollowing are some of the special numbers found in the known observable little universe of ours:- \n";
cout << "\n1. Prime numbers\n2. Square numbers\n3. Perfect Numbers\n\n";
cout << "Which ones do you wanna see?\n";
//cin >> choice;
cout << "\nCool! How many of them do you wanna see?\n";
//cin >> quan;
}
void perfect()
{
if (choice == 3)
{
int j = 0, y = 0, f = 0, number = 2;
do
{
//This is the cls in question
//system("cls");
cout << "The number under inspection: " << number << "\n";
f = 0;
for (i = (number - 1); i >= 1; i--)
{
if (number % i == 0)
{
f = f + i;
}
}
if (f == number)
{
//cout<<number<<", ";
a[j] = number;
j = j + 1;
y = y + 1;
}
number++;
}
while (y < quan);
system("cls");
cout << "\nHere are your " << quan << " perfect numbers starting from 1:-\n";
j = 1;
for (i = 0; i < quan; i++)
{
cout << a[i];
if (j != quan)
{
cout << ", ";
}
j++;
}
}
}
int main()
{
do
{
startgame();
perfect();
cout << "\n\nReturn to Main menu?(Y/N)\n";
schoice = "N";
//cin >> schoice;
}
while (schoice == "Y");
return 0;
}
When you run system("cls"), you create a new process, and you do that every time you pick a new number for inspection.
Creating a process is an expensive operation, and more importantly you don't need it, if all you want is to update current number on screen.
It is sufficient to write
cout << "The number under inspection: " << number << "\r";
cout.flush();
The first line will output text and return cursor to the beginning of the same line.
The second line will make sure all the above does show up on the display.
Note: this is also slow operation, so you would probably want to rate limit it.
I suggest you output this for every 1 number in 1000 or so.
Windows CreateProcess() is quite expensive, much more expensive than Unix fork(). Moreover, system("cls") is an inefficient, non-portable hack. You can't use it in non-windows systems. You can use ncurses library that supports console manipulation.
For Windows, via Console API:
void clear() {
COORD topLeft = { 0, 0 };
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO screen;
DWORD written;
GetConsoleScreenBufferInfo(console, &screen);
FillConsoleOutputCharacterA(
console, ' ', screen.dwSize.X * screen.dwSize.Y, topLeft, &written
);
FillConsoleOutputAttribute(
console, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
screen.dwSize.X * screen.dwSize.Y, topLeft, &written
);
SetConsoleCursorPosition(console, topLeft);
}
I'm looking for a method to limit the visible user input using std::cin.
#include <iostream>
int main()
{
std::cout << "Enter your planet:\n";
string planet;
std::cin >> planet; // During the prompt, only "accept" x characters
}
What the user sees if they enter earth or any other word exceeding 4 characters before pressing enter:
Enter your planet:
eart
This is assuming the character limit is 4, note that the 'h' is missing. The console does not display any other character once it has exceeded the character limit. and this is before you press the enter key.
Kinda like typing in an input box like password fields, but it only allows 5 characters, so typing any other character goes unnoticed
A better analogy would be the maxlength attribute for text input in HTML.
That can't be achieved portably, because OS consoles aren't part of C++ standard. In windows, you could use <windows.h> header - it provides console handles etc., but since you didn't specify OS you are using, the is no point in posting windows-only code here (since it might not meet your needs).
EDIT:
Here is (not perfect) code that will limit visible input of the user:
#include <iostream>
#include <windows.h>
#include <conio.h>
int main()
{
COORD last_pos;
CONSOLE_SCREEN_BUFFER_INFO info;
std::string input;
int keystroke;
int max_input = 10;
int input_len = 0;
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
std::cout << "Input (max 10) characters, press ENTER to prompt:" << std::endl;
GetConsoleScreenBufferInfo(handle, &info);
last_pos = info.dwCursorPosition;
while(true)
{
if(kbhit())
{
keystroke = _getch();
//declare what characters you allow in input (here: a-z, A-Z, 0-9, space)
if(std::isalnum(keystroke) || keystroke == ' ')
{
if(input_len + 1 > max_input)
continue;
++input_len;
std::cout << char(keystroke);
input += char(keystroke);
GetConsoleScreenBufferInfo(handle, &info);
last_pos = info.dwCursorPosition;
}
else if(keystroke == 8) //backspace
{
if(input_len - 1 >= 0)
{
--input_len;
input.pop_back();
COORD back_pos {short(last_pos.X-1), last_pos.Y};
SetConsoleCursorPosition(handle, back_pos);
std::cout << ' ';
SetConsoleCursorPosition(handle, back_pos);
GetConsoleScreenBufferInfo(handle, &info);
last_pos = info.dwCursorPosition;
}
}
else if(keystroke == 13) //enter
{
std::cout << std::endl;
break;
}
}
}
std::cout << "You entered: " << std::endl
<< input << std::endl;
}
After a few days of experimenting, I found another solution that seems to be quite easy to grasp as it is somewhat beginner level and without requiring any knowledge of windows programming.
NOTE:
The conio.h library function _getch() could easily be replaced with the getchar() function;
I'm not saying the previous answer was not okay, but this solution is sort of aimed towards beginners with only basic knowledge of c++
char ch;
string temp;
ch = _getch();
while(ch != 13)// Character representing enter
{
if(ch == '\b'){ //check for backspace character
if(temp.size() > 0) // check if string can still be reduced with pop_back() to avoid errors
{
cout << "\b \b"; //
temp.pop_back(); // remove last character
}
}
else if((temp.size() > 0) || !isalpha(ch))// checks for limit, in this case limit is one
{ //character and also optional checks if it is an alphabet
cout << '\a'; // for a really annoying sound that tells you know this is wrong
}else {
temp.push_back(ch); // pushing ch into temp
cout << ch; // display entered character on screen
}
ch = _getch();
}
This could probably use some tweaks, because it's definitely not perfect, but I think it is easy enough to understand, at least I hope so
I want to have an array output a certain piece of the array depending on what a randomly generated variable is.
I want to have a karate-based simulator that reads what the opponent's kick is (1, 2, 3, or 4,) and connects that with certain kicks. (Round Kick, Hook Kick, Front Kick, Side Kick) and then prints that to the screen.
Skip to int main() if you need to, the rest of the code is for reference.
My code:
#include <iostream>
#include <random>
#include <ctime>
#include <string>
#include <Windows.h>
using namespace std;
mt19937 ranGen(time(0));
uniform_real_distribution<float> attack(0.00f, 1.00f);
uniform_real_distribution<float> defense(0.00f, 1.00f);
uniform_int_distribution<int> okick(1, 4);
string belt = "White Belt";
float landed = attack(ranGen);
float blocked = defense(ranGen);
float ekick = okick(ranGen);
int kick;
string kicks [4] = ("Round Kick","Hook Kick","Front Kick","Side Kick");
void roundKick() {
if (belt == "White Belt") {
if (landed < 0.70) {
cout << "Round kick to head | Blocked\n";
} else {
cout << "Round kick to head | Direct Hit\n";
}
}
}
int main()
{
string yn;
syn:
cout << "Spar? y/n\n";
cin >> yn;
if (yn == "y") {
cout << "\nFighting Stance!\n";
Sleep(3000);
cout << "C'ject!\n\n";
cout << "1 - Round Kick\n2 - Hook Kick\n3 - Front Kick\n4 - Side Kick\n";
cin >> kick;
if (kick == 1) {
roundKick();
}
cout << "Opponent used kick " << ekick;
if (blocked < 0.50) {
//
//
//I want to replace the 1 with the random Gen kick (ekick) to have the user know which kick it is
cout << kicks[1] << " to the body | Blocked\n";
} else
} else if (yn == "n") {
cout << "This is a sparring simulator, kid. Hit yes.\n\n";
goto syn;
}
return 0;
}
If you don't understand just tell me what you don't and I will try to make sense of it.
I'd suggest something like:
if(blocked < 0.50) {
ekick = okick(ranGen); // you had this in the code, but at a wrong place
cout << "Replied with " << kicks[ekick] << endl;
}
The problem is that you have the parts of the statements you need in the wrong place. You have defined and initialised these global variables at the beginning of your game, so they keep the same value throughout the game.
float landed = attack(ranGen);
float blocked = defense(ranGen);
float ekick; // we have now assigned ekick within the game. So here, just declare it
But I suppose you start learning. So we've solved the issue with ekick, but you've still a similar issue with landed and blocked. Up to you to solve it. Senpai ni rei !
P.S: immediately after you've done this, you should replace the horrible goto with a while loop. And later, one nice thing to improve would be to get rid of global variables
I have been trying to fix this program for the past two days and it is proving to be quite troublesome. It is an assignment for my intro to C++ course and has given me nothing but trouble. I have searched this board, posted on Cplusplus.com and spent hours on Google, looking for some assistance.
Here is my problem. I have been given a program and need to add a few features to it:
I have to save the users entries.
I have to display an error message if the user enters the same entry twice.
Seems simple? Not for a beginner such as myself. Here is the code, with what I have attempted to add to it in order to meet the problem's requirements.
int main()
{
//declare variables
string origWord = "";
string letter = "";
char dashReplaced = 'N';
char gameOver = 'N';
int numIncorrect = 0;
string displayWord = "-----";
string letterGuess[26];
//get original word
do //begin loop
{
cout << "Enter a 5-letter word in uppercase: ";
getline(cin, origWord);
} while (origWord.length() != 5);
//clear the screen
system("cls");
//start guessing
cout << "Guess this word: " <<
displayWord << endl;
while (gameOver == 'N')
{
cout << "Enter an uppercase letter: ";
cin >> letter;
//Entry Storage and Error Message. This is my problem.
for (int x = 0; x < 26; x++)
{
letterGuess[x] = letter;
for (int i = x; i < 26; i++)
{
if (i != x)
{
if (letterGuess[x] == letterGuess[i])
{
cout << "Letter already entered. Choose another letter."
<< endl;
}
}
}
}
//search for the letter in the original word
for (int x = 0; x < 5; x += 1)
{
//if the current character matches
//the letter, replace the corresponding
//dash in the displayWord variable and then
//set the dashReplaced variable to 'Y'
if (origWord.substr(x, 1) == letter)
{
displayWord.replace(x, 1, letter);
dashReplaced = 'Y';
} //end if
} //end for
//if a dash was replaced, check whether the
//displayWord variable contains any dashes
if (dashReplaced == 'Y')
{
//if the displayWord variable does not
//contain any dashes, the game is over
if (displayWord.find("-", 0) == -1)
{
gameOver = 'Y';
cout << endl << "Yes, the word is "
<< origWord << endl;
cout << "Great guessing!" << endl;
}
else //otherwise, continue guessing
{
cout << endl << "Guess this word: "
<< displayWord << endl;
dashReplaced = 'N';
} //end if
}
else //processed when dashReplaced contains 'N'
{
//add 1 to the number of incorrect guesses
numIncorrect += 1;
//if the number of incorrect guesses is 10,
//the game is over
if (numIncorrect == 10)
{
gameOver = 'Y';
cout << endl << "Sorry, the word is "
<< origWord << endl;
} //end if
} //end if
} //end while
system("pause");
return 0;
} //end of main function
My only edit to the program is directly under the header of Entry Storage and Error Message. I have tried a single for loop, but that simply displayed the error message for every letter entered. Not only that but it displayed it 26 times. Adding a Break command fixed that and it only displayed once. However, it still displayed on every entry.
A member of Cplusplus, pointed out that I was incorrectly testing the same variable against the array in the same location. That is why it displayed the error on every entry. Now with this loop, the error only displays when an entry is entered twice. However, the error message displays all 26 times once more. On top of that, it will only error if the letters are entered one after another.
For example, if I enter A then X then A again, no error is shown. If I enter, A then A again, the error is displayed 26 times. Something is clearly wrong with how the letter variable is being entered into the array on top of the whatever is causing the error message to display multiple times.
Any amount of assistance would be greatly appreciated.
Edit: My professor has gotten back to me and suggested using the following instead of what I have been tinkering with:
for (int x=0; x<5; x++)
if (origWord[x] == letterEntered)
origWord[x] = '-';
Is it just me, or does this miss the mark completely? I haven't tried converting it into my program as a simple copy and paste job produces compile errors. However, I don't see how that does anything with what I'm trying to do.
This set's all entries of your letterGuess array to the most recently guessed letter.
letterGuess[x] = letter;
This isn't what you want.
You need to think about the actual algorithm you need to implement:
The user enters a guess
Check to see if they've already guessed that letter
If they have, display an error message, return to 1.
If they have not, save that guess, continue with the game logic.
If you have already learned about standard containers, this can be trivially done with a std::set, or a std::vector that has been sorted.
You need to compare each element in the array to the guessed word. Best use a for loop for this. No more needs to be said if this is an assignment.
Also don't use system("cls") in your program, it is a massive security flaw and may lose you marks.