I don't understand why the following code always prints 'draw!'. Can you help me figure that out?
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
void main()
{
clrscr();
int choice1;
char choice2[50];
int compare(const char*, const char*); //prototype
char s[100];
cout << "\n\n WELCOME TO STONE PAPER SCISSORS " << endl
<< endl;
cout << " enter your choice" << endl;
cout << "\n 1:SCISSORS \n";
cout << "\n 2:ROCK \n";
cout << "\n 3:PAPER \n";
cout << "enter choice number";
cin >> choice1;
if (choice1 == 2) {
cout << "you have entered Stone!";
strcpy(s, "ROCK");
}
if (choice1 == 1) {
cout << "you have entered scissors";
strcpy(s, "SCISSORS");
}
if (choice1 == 3) {
strcpy(s, "PAPER");
cout << "you have entered paper";
}
randomize();
float point = 2;
float compchoice;
compchoice = random(point);
if (compchoice < 0.37) {
strcpy(choice2, "ROCK");
}
else if (compchoice < 0.64) {
strcpy(choice2, "PAPER");
}
else {
strcpy(choice2, "SCISSORS");
}
cout << endl;
cout << "User Choice=" << s << endl;
cout << "Computer Choice=" << choice2 << endl;
cout << s << "\t"
<< "VS"
<< "\t" << choice2 << "="
<< " ";
int p = compare(s, choice2);
if (p == 1) {
cout << "computer wins";
if (p == 0)
cout << "user wins";
if (p == -1)
cout << "draw!";
getch();
}
int compare(const char* s, const char* choice2)
{
if (s == "SCISSORS") {
if (choice2 == "ROCK")
return 1;
else
return 0;
}
else if (s == "ROCK") {
if (choice2 == "SCISSORS")
return 0;
else
return 1;
}
else if (s == "PAPER") {
if (choice2 == "SCISSORS")
return 1;
else
return 0;
}
else
return -1;
}
The problem in this code lies within code like if (choice2 == "SCISSORS")
as this is a pointer comparison. For details, see this stack overflow post.
I would suggest modernizing this code and use std::string instead of char [50] as you have to worry less about memory for these strings, nor the fact that strings are stored as arrays.
Related
I have written a code that displays a rock-paper-scissors game against the computer. I would like to add a feature where I can create a text file in order to store the person's score and the computer score and keep track of the score but I don't know how to do it. Thank you in advance!
Here is my code.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
void rock_paper_scissors()
{
static int userscore = 0;
static int computerscore = 0;
string playername;
int userchoice;
int computerchoice;
cout << "Hello to rock-paper-scissors!\n";
cout << "rock beats scissors, scissors beats paper and paper beats rock." << endl;
cout << "choose 1 for rock, 2 for paper, 3 for scissors.\n";
cout << "please enter your name." << endl;
cin >> playername;
cout << endl;
cout << "Please enter your choice\n";
cin >> userchoice;
cout << endl;
while (!(userchoice > 0 && userchoice <= 3))
{
cout << "invalid choice. please enter a number between 1 and 3\n";
cin >> userchoice;
}
if (userchoice == 1)
{
cout << playername << " picked rock." << endl;
}
else if (userchoice == 2)
{
cout << playername << " picked paper." << endl;
}
else if (userchoice == 3)
{
cout << playername << " picked scissors." << endl;
}
computerchoice = (rand() % 3) + 1;
if (userchoice == 1 && computerchoice == 3)
{
cout << playername << " wins!" << endl;
}
else if (userchoice == 2 && computerchoice == 1)
{
cout << playername << " wins!" << endl;
}
else if (userchoice == 3 && computerchoice == 2)
{
cout << playername << " wins!" << endl;
}
else if (userchoice == computerchoice)
{
cout << " draw!" << endl;
}
else
{
cout << "computer wins!" << endl;
}
cout << "thank you for playing!\n";
string restart;
cout << "Would you like to play again?" << endl << "(y)es / (n)o" << endl;
cin >> restart;
if (restart == "y")
{
rock_paper_scissors();
}
}
int main()
{
cout << "MAIN\n";
rock_paper_scissors();
return 0;
}
Why do you need to write the data into in file? Updating a simple txt file after each round could be cumbersome, as you always result in a single score at the end of the program. I would suggest changing the type of the rock_paper_scissors into int indicating the score achieved by the player in a single lot. The intermediate results are irrelevant. Just place the game loop into your main function and do not use a recursive function call and static function variables here. Otherwise, the player is forced to enter his name for every single lot.
Moreover, I tested your code and you have to change your error handling. I typed in "rock" and the program stuck in an infinity loop "invalid choice. please enter a number between 1 and 3\n" Whereby it is not possible to make another entry. As I entered a string instead of an integer, you have to reset the console. Beware of the dumbest possible user.
Moreover, you should seed your program to avoid identical computer choices in each game. This could be done with srand(time(NULL)).
Eventually, I write the tracked score into a score file at the end of the main function using the fstream standard library.
#include <iostream>
#include <string>
#include <algorithm> // min max
#include <fstream> // read/write from/to files
#include <time.h> // time
using namespace std;
int rock_paper_scissors(const std::string& playername);
int main()
{
srand(time(NULL));
cout << "MAIN\n";
cout << "Hello to rock-paper-scissors!\n";
cout << "rock beats scissors, scissors beats paper and paper beats rock." << endl;
cout << "choose 1 for rock, 2 for paper, 3 for scissors.\n";
int userscore = 0;
int computerscore = 0;
std::string playername;
std::string restart;
cout << "please enter your name." << endl;
cin >> playername;
cout << endl;
do
{
int result = rock_paper_scissors(playername);
cout << "thank you for playing!\n";
userscore += result;
computerscore += std::max(0, 3 - 2 * result);
cout << playername << "'s score: " << userscore;
cout << "\ncomputer's score: " << computerscore;
cout << "\nWould you like to play again?" << endl << "(y)es / (n)o" << endl;
cin >> restart;
} while (restart == "y");
std::ofstream ofile;
ofile.open("scorefile.txt");
ofile << "Scores:\n" << playername << ": " << userscore;
ofile << "\nComputer: " << computerscore;
ofile.close();
return 0;
}
int rock_paper_scissors(const std::string& playername)
{
int userchoice;
int computerchoice;
cout << endl << endl;
do {
cout << "Please enter your choice\n";
if (std::cin >> userchoice)
{
if (userchoice > 0 && userchoice <= 3)
{
break;
}
else
{
cout << "invalid choice. please enter a number between 1 and 3\n";
continue;
}
}
else if (!cin.bad() && !cin.eof())
{
// a non integer value entered
cerr << "invalid choice. please enter a number between 1 and 3\n";
// Reset error state
cin.clear();
// remove error input
cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
}
} while (true);
if (userchoice == 1)
{
cout << playername << " picked rock." << endl;
}
else if (userchoice == 2)
{
cout << playername << " picked paper." << endl;
}
else if (userchoice == 3)
{
cout << playername << " picked scissors." << endl;
}
computerchoice = (rand() % 3) + 1;
if (userchoice == 1 && computerchoice == 3)
{
cout << playername << " wins!" << endl;
return 3;
}
else if (userchoice == 2 && computerchoice == 1)
{
cout << playername << " wins!" << endl;
return 3;
}
else if (userchoice == 3 && computerchoice == 2)
{
cout << playername << " wins!" << endl;
return 3;
}
else if (userchoice == computerchoice)
{
cout << " draw!" << endl;
return 1;
}
else
{
cout << "computer wins!" << endl;
return 0;
}
}
So I have an issue with my code where I cannot get either of my functions (int human_turn, or int computer_turn) to return the correct value of their turn totals. What I am trying to do is have the two int functions return their respective turn totals after they are done with their turn, then have a separate function that will cout these values and will act as the scoreboard and also show if the win conditions are met. Currently at the end of the while loop for each ones turn, I have turnTotal_1 = roll_1 + turnTotal_1; which updates the total and then the loop checks to see if the while is still true. I then put a return turnTotal_1; statement after the loop so it would return this value, and it will always return 1. No matter what the value of the turn total is, the return statement will always return 1. any help or advice would be appreciated.
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <unistd.h>
#include <stdio.h>
using namespace std;
/**
* rollDie
* returns a random integer between 1 and 6, works as rolling a dice.
* return value, int number (1-6)
*/
int rollDie()
{
return random() % 6 + 1;
}
int human_turn(int turnTotal_1)
{
cout << "It is now human's turn" << endl;
cout << "Do you want to roll a dice(Y/N)?:" << endl;
char user_choice;
cin >> user_choice;
while ((user_choice == 'y') || (user_choice == 'Y'))
{
int roll_1 = rollDie();
if ((roll_1 == 2) || (roll_1 == 5))
{
cout << "You rolled a " << roll_1 << endl;
roll_1 = 0;
}
else if ((roll_1 == 1) || (roll_1== 3) ||(roll_1 == 6))
{
cout << "You rolled a " << roll_1 << endl;
}
else if (roll_1 == 4)
{
cout << "You rolled a " << roll_1 << endl;
roll_1 = 15;
}
turnTotal_1 = roll_1 + turnTotal_1;
cout << "Your turn total is " << turnTotal_1 << endl;
cout << "Do you want to roll a dice(Y/N)?:" << endl;
cin >> user_choice;
}
if ((user_choice == 'n') || (user_choice == 'N'))
{
return turnTotal_1;
}
}
int computer_turn()
{
int turnTotal_2 = 0;
cout << "It is now computer's turn" << endl;
int roll_1 = rollDie();
while (turnTotal_2 <= 10)
{
int roll_1 = rollDie();
if ((roll_1 == 2) || (roll_1 == 5))
{
cout << "Computer rolled a " << roll_1 << endl;
roll_1 = 0;
}
else if ((roll_1 == 1) || (roll_1== 3) ||(roll_1 == 6))
{
cout << "Computer rolled a " << roll_1 << endl;
}
else if (roll_1 == 4)
{
cout << "Computer rolled a " << roll_1 << endl;
roll_1 = 15;
}
turnTotal_2 = roll_1 + turnTotal_2;
cout << "Computer turn total is " << turnTotal_2 << endl;
}
}
void scoreboard()
{
cout << human_turn << endl;
cout << computer_turn << endl;
}
void game()
{
cout << "Welcome to Jeopardy Dice!" << endl;
human_turn(0);
cout << human_turn << endl;;
computer_turn();
scoreboard();
}
int main()
{
// start the game!
game();
return 0;
}
Here is an example of how it runs.
Welcome to Jeopardy Dice!
It is now human's turn
Do you want to roll a dice(Y/N)?:
n
1
It is now computer's turn
Computer rolled a 5
Computer turn total is 0
Computer rolled a 4
Computer turn total is 15
i am using turbo c++. when i run the following code from compiler i get different answer at marked point in function result(int) then what i get from running .exe file created.
#include<fstream.h>
#include<conio.h>
#include<process.h>
#include<iomanip.h>
#include<string.h>
#include<stdio.h>
#include<dos.h>
ifstream fil;
int pos[50];
char date[11];
void exitt(int times = 0)
{
cout << endl << endl << " Enter 0 to exit." << endl;
if (times == 0)
cout << " Enter L to return to last screen." << endl;
}
void options();
void companychoose();
void companyscreen(int);
void write(int ch, int pos = 0) //add a check for duplicacy
{
ofstream fout;
clrscr();
if (ch == 1)
{
fout.open("database.dat", ios::binary | ios::app | ios::ate);
char companyname[20], temp;
exitt();
cout << " Enter Company name: ";
gets(companyname);
if (strcmp(companyname, "0") == 0)
exit(0);
else if (strcmp(companyname, "l") == 0)
options();
for (int i = 19; i>0; i--)
companyname[i] = companyname[i - 1];
companyname[0] = '%';
fout << endl;
fout << companyname;
fout.close();
cout << " Add data now?(y/n)" << endl;
askagain:
cin >> temp;
switch (temp)
{
case 'y':
fil.close();
write(2);
break;
case 'n':
options();
break;
default:
cout << " Invalid input" << endl;
goto askagain;
break;
}
}
}
void result(int ch)
{
int high[4], low[4], end, i = 0, enough = 0, temp = 0;
char check[20];
fil.open("database.dat", ios::binary);
fil.seekg(pos[ch], ios::beg);
fil >> check;
cout << endl;
if (check[0] == '%')
{
cout << " Not Enough Data!!!" << endl;
fil.close();
return;
}
while (!fil.eof())
{
if (i == 3)
{
i = 0;
enough = 1;
}
fil >> high[i] >> low[i] >> end >> check;
if (check[0] == '%')
break;
i++;
}
low[i] = 0;
temp = low[0];
if (enough == 0)
cout << " Not Enough Data!!!" << endl;
else
{
for (i = 0; i<3; i++)
{
if (low[i]<low[i + 1])
temp = low[i + 1];
}
if (temp>end)
cout << " Stock Running Low!!";
else if (temp = end)
cout << " Stock Is Stable";
else
cout << " Stock is HIGH!!";
cout << " " << end - temp << endl << endl << endl;
}
fil.close();
}
int read(int ch, int find = 0)
{
clrscr();
result(ch);
fil.open("database.dat", ios::binary);
fil.seekg(pos[ch], ios::beg);
char entry[20];
fil >> entry;
cout << setw(20) << "Date" << setw(10) << "High" << setw(10) << "Low" << setw(10) << "Close" << endl;
while (entry[0] != '%')
{
if (find == 1)
{
if (strcmp(entry, date))
return(fil.tellg() - 11);
else
continue;
}
cout << setw(20) << entry;
fil >> entry;
cout << setw(10) << entry;
fil >> entry;
cout << setw(10) << entry;
fil >> entry;
cout << setw(10) << entry << endl;
fil >> entry;
delay(500);
}
fil.close();
getch();
clrscr();
companyscreen(ch);
}
void edit(int ch)
{
cout << "Enter date of data to be edited";
gets(date);
write(2, read(ch, 1));
}
void companyscreen(int ch)
{
int ch1;
askagain:
result(ch);
cout << " 1. Add Data" << endl;
cout << " 2. Show history" << endl;
cout << " 3. Edit Data" << endl;
exitt();
ch1 = getch() - 48;
if (ch1 == 1)
write(2);
else if (ch1 == 2)
read(ch);
else if (ch1 == 3)
{
read(ch);
edit(ch);
}
else if (ch1 == 0)
{
cout << " exiting!!" << endl;
exit(500);
}
else if (ch1 == 60)
companychoose();
else
{
cout << " Invalid option chosen" << endl;
getch();
clrscr();
goto askagain;
}
}
void companychoose()
{
char name[20];
int i, ch;
clrscr();
fil.open("database.dat", ios::binary);
askagain:
fil.seekg(0, ios::beg);
cout << " Choose Company:";
cout << endl;
i = 1;
while (!fil.eof())
{
fil >> name;
if (name[0] == '%')
{
name[0] = ' ';
pos[i] = fil.tellg();
cout << setw(10) << i << "." << name << endl;
i++;
}
}
fil.close();
exitt();
ch = getch() - 48;
if (ch == 0)
exit(0);
else if (ch == 60)
options();
else if (ch>i)
{
cout << "Invalid choice" << endl;
getch();
clrscr();
goto askagain;
}
clrscr();
companyscreen(ch);
}
void options()
{
int ch;
clrscr();
askagain:
cout << endl << endl;
cout << " 1. Add company" << endl;
cout << " 2. Choose company" << endl;
exitt(1);
ch = getch() - 48;
if (ch == 1)
write(1);
else if (ch == 2)
companychoose();
else if (ch == 0)
{
cout << setw(10) << " Exiting!!";
exit(500);
}
else
{
cout << setw(10) << " Invalid choice chosen" << endl;
getch();
clrscr();
goto askagain;
}
}
void main()
{
clrscr();
textbackground(MAGENTA);
textcolor(WHITE);
clrscr();
options();
getch();
}
pls note that program is yet not fully complete so some features dont work.
i don't know how to include dat file data nor screenshot here.
i don't use visual c++ cause my pc is slow.
i don't use codeblocks cause i dont know how to use it. above code give hundreds of error even after adding "using namespace std;"
pls help me solve it. if you need anything else then ask me. thanks
I get different answer (…) in function result(int) then what I get from running .exe file created.
When you execute your program from the IDE a different working directory is used so different files are seemingly present/missing. Usually the working directory is configurable.
By the way, the goto is not needed. Really, it is not.
my code compiles but it doesn't allow the user to guess the word correctly and when it displays the correct word, it is just a string of nonsense.
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
int instructions();
void manual();
void file(char*);
int letterFill(char, char*, char*);
void Unknown(char*, char*);
const int MAX_LENGTH = 10;
void main()
{
bool done = false;
char word[MAX_LENGTH];
char unknown[MAX_LENGTH];
char letter;
char name[MAX_LENGTH];
int wrong_guesses = 0;
int MAX_TRIES;
char ans;
while (!done)
{
switch (instructions())
{
case 1:
{
manual();
break;
}
case 2:
{
file(word);
break;
}
}
cout << "WHAT IS THE NUMBER OF GUESSES ALLOWED?: " << endl;
cin >> MAX_TRIES;
Unknown(word, unknown);
cout << endl << endl << "HANGMAN";
cout << endl << endl << "Each letter is represented by a star." << endl;
cout << "You have " << MAX_TRIES << " tries left.";
cout << "ENTER GUESS WHEN READY: ";
cin >> letter;
while (letter != 'N' && letter != 'n')
{
while (wrong_guesses < MAX_TRIES)
{
cout << unknown << endl;
cout << "Guess a letter: " << flush;
cin >> letter;
if (letterFill(letter, word, unknown) == 0)
{
cout << endl << "You got it wrong! You lose a guess" << endl;
wrong_guesses++;
}
else
{
cout << endl << "Pfft, you got lucky" << endl;
}
cout << "Guesses Left: " << MAX_TRIES - wrong_guesses << endl;
if (strcmp(word, unknown) == 0)
{
cout << word << endl;
cout << "You got it!" << endl;
exit(0);
}
cout << "You've been hanged." << endl;
cout << "The word was : " << word << endl;
}
}
cout << "Try again? (y/n): " << flush;
cin >> ans;
if (ans == 'y' || ans == 'Y')
done = true;
else
done = false;
}
system("pause");
}
int instructions()
{
int select = 0;
cout << endl << "HANGMAN" << endl << endl;
cout << " PROGRAM MENU" << endl;
cout << " Select option 1 or 2" << endl << endl;
cout << " 1. INPUT WORD MANUALLY" << endl;
cout << " 2. PLAY AGAINST THE COMPUTER" << endl;
cout << " 3. EXIT PROGRAM BY INPUTING: N or n" << endl << endl;
cin >> select;
return select;
}
void manual()
{
string word;
cout << endl << "INPUT WORD: " << endl;
cin >> word;
return;
}
void file(char *roc)
{
ifstream fin("word.txt");
int x;
int count = 1;
int word;
int i = 0;
srand(time(0));
word = rand() % 20;
while (count < word)
{
fin >> x;
if (x == 0)
{
count++;
}
}
do
{
fin >> x;
roc[i++] = char(x);
} while (x);
return;
}
int letterFill(char guess, char *secretword, char *guessword)
{
int i;
int matches = 0;
for (i = 0; i<MAX_LENGTH; i++)
{
if (secretword[i] == 0)
{
break;
}
if (guess == guessword[i])
{
return 0;
}
if (guess == secretword[i])
{
guessword[i] = guess;
matches++;
}
}
return matches;
}
void Unknown(char *word, char *unknown)
{
int i;
int length = strlen(word);
for (i = 0; i<length; i++)
{
unknown[i] = '*';
}
unknown[i] = 0;
}
Again
my code compiles but it doesn't allow the user to guess the word correctly and when it displays the correct word, it is just a string of nonsense.
After finding a text-based rock paper scissors app I wrote, I decided to improve the code. Now, I want to write in for the console to clear the screen before returning to the main menu, and before executing a requested app operation. Here is the code:
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
#include <algorithm>
using namespace std;
void scoreCounter(int playerWins, int playerTies, int playerLosses, int compWins, int compTies, int compLosses)
{
cout << "PLAYER SCORE:\n\n";
cout << "Wins: " << playerWins << "\n";
cout << "Losses: " << playerLosses << "\n";
cout << "Ties: " << playerTies << "\n\n\n";
cout << "COMPUTER SCORE:\n\n";
cout << "Wins: " << compWins << "\n";
cout << "Losses: " << compLosses << "\n";
cout << "Ties: " << compTies << "\n\n\n";
}
void mainMenu()
{
cout << "Main Menu\n\n";
cout << "1) Play Rock Paper Scissors\n";
cout << "2) Display scoreboard\n";
cout << "3) Exit app\n";
cout << "\n";
}
void rockPaperScissorsShoot(int playerWins, int playerTies, int playerLosses, int compWins, int compTies, int compLosses) {
cout << "Rock Paper Scissors Shoot!\n";
string playerChoice;
cin >> playerChoice;
transform(playerChoice.begin(), playerChoice.end(), playerChoice.begin(), ::tolower);
int n1;
int n2;
int n3;
srand(time(NULL));
if (playerChoice == "Rock" || playerChoice == "rock") {
n1 = rand() %3;
if (n1 == 0) {
cout << "You win!\n";
playerWins++;
compLosses++;
}
else if (n1 == 1) {
cout << "You lose!\n";
playerLosses++;
compWins++;
}
else if (n1 == 2) {
cout << "You tied!\n";
playerTies++;
compTies++;
}
}
else if (playerChoice == "Paper" || playerChoice == "paper") {
n2 = rand() %3;
if (n2 == 0) {
cout << "You win!\n";
playerWins++;
compLosses++;
}
else if (n2 == 1) {
cout << "You lose!\n";
playerLosses++;
compWins++;
}
else if (n2 == 2) {
cout << "You tied!\n";
playerTies++;
compTies++;
}
}
else if (playerChoice == "Scissors" || playerChoice == "scissors") {
n3 = rand() %3;
if (n3 == 0) {
cout << "You win!\n";
playerWins++;
compLosses++;
}
else if (n3 == 1) {
cout << "You lose!\n";
playerLosses++;
compWins++;
}
else if (n3 == 2) {
cout << "You tied!\n";
playerTies++;
compTies++;
}
}
else {
cout << "You made an invalid choice. Ending game...\n";
}
}
int main()
{
bool gameOver = 0;
bool exitProg = 0;
int playerWins = 0;
int playerTies = 0;
int playerLosses = 0;
int compWins = 0;
int compTies = 0;
int compLosses = 0;
int menuChoice;
while (exitProg != 1)
{
mainMenu();
cin >> menuChoice;
switch (menuChoice)
{
case 1:
{
while (gameOver == 0) {
rockPaperScissorsShoot(playerWins, playerTies, playerLosses, compWins, compTies, compLosses);
cout << "Would you like to play again? Press Y or N:\n";
char yOrN;
cin >> yOrN;
switch (yOrN) {
case 'Y': {
cout << "Ok then!\n";
break;
}
case 'y': {
cout << "Ok then!\n";
break;
}
case 'N': {
cout << "Game over.\n";
gameOver = 1;
break;
}
case 'n': {
cout << "Game over.\n";
gameOver = 1;
break;
}
}
}
cout << "\n";
break;
}
case 2:
{
scoreCounter(playerWins, playerTies, playerLosses, compWins, compTies, compLosses);
break;
}
case 3:
{
exitProg = 1;
system("PAUSE");
break;
}
}
}
return 0;
}
I considered using cin.clear(), but I don't think that will help me if I want to open a different function. What can I do?
For anyone who finds this question, I use system("CLS"); to clear the console before loading a different operation.