C++ a function call is not called again after the loop iterates - c++

Hey so I am relatively a beginner at programming. I am trying to create a very simple minesweeper game over a 2D array, the issue I am running into is after the player steps on a mine (game over) they are given the option to play again. After this the set difficulty function is supposed to be called a second time (since it is within the loop) and a new minefield is to be generate. Unfortunately none of that is happening and the program skips that process.
Here is my code:
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int choose_difficulty(int x);
int generator();
int main()
{
//create initial variables
string Ans;
int Rounds;
int NewPosition_x = 0;
int NewPosition_y = 0;
//ask user if he wants to run the program and expect input
cout << "Would you like to play a game? Y/N" << endl;
cin >> Ans;
//based on user input the program will run or not
if (Ans == "Y" || "y") {
while (Ans == "Y" || "y")
{
//Create position variables to be checked
int Position_x;
int Position_y;
//ask user how many rounds in the game they want
cout << "How many chances do you want to give yourself?" << endl;
cin >> Rounds;
//Generate minefield could not be done as separate function since you cannot output an array
int a = choose_difficulty(a);
int mines;
int n,m;
srand (time (0));
if(a == 0) {
mines = 3;
n = 4;
m = n;
}
else if (a == 1){
mines = 5;
n = 4;
m = n;
}
else if (a == 2){
mines = 7;
n = 4;
m = n;
}
int minefield[n][m] = { };
int g, h;
for (int num = 0; num < mines; num++) {
g = rand()%n;
h = rand()%n;
minefield[g][h] = 1;
}
for (int x = 0; x < Rounds; x++)
{
//Begin Game
cout << "Where are you at to avoid the mines? (Enter a 2 numbers 0 through 3)" << endl;
cin >> NewPosition_x >> NewPosition_y;
//check if the player has entered a new position
while (NewPosition_x == Position_x && NewPosition_y == Position_y) {
cout << "You have to move somewhere, put a valid location" << endl;
cin >> NewPosition_x >> NewPosition_y;
}
//check to see if that position is valid
while ((NewPosition_x < 0 || NewPosition_x > 3) || (NewPosition_y < 0 || NewPosition_y > 3)) {
cout << "I'm sorry, but that place doesn't exist. Try somewhere else" << endl;
cin >> NewPosition_x >> NewPosition_y;
}
//Assign Player Position and check position vs mines
Position_x = NewPosition_x;
Position_y = NewPosition_y;
if (minefield[Position_y][Position_x] == 1) {
cout << "You stepped on a mine, Game Over" << endl;
cout << "You minefield was this:" << endl;
for (int i=0; i < n; i++){
for (int j=0; j < n; j++){
cout << minefield[i][j] << "\t";
}
cout << endl;
}
cout << "Would you like to play again? Y/N" << endl;
cin >> Ans;
if (Ans == "n" || Ans == "N"){
return 0;
}
}
else if ((minefield[Position_x + 1][Position_y] == 1) || (minefield[Position_x - 1][Position_y] == 1) || (minefield[Position_x][Position_y + 1] == 1) || (minefield[Position_x][Position_y - 1] == 1)) {
cout << "You're hot right now, you better watch your step. Continue to the next round" << endl;
}
else {
cout << "You're safe. Continue to the next round" << endl;
}
}
}
}
return 0;
}
int choose_difficulty(int a)
{
do{
string difficulty;
//Difficulty Selection
cout << "Choose the game difficulty: Easy, Medium, Hard" << endl;
cin >> difficulty;
if (difficulty == "easy" || difficulty == "Easy"){
a = 0;
}
else if (difficulty == "medium" || difficulty == "Medium"){
a = 1;
}
else if (difficulty == "hard" || difficulty == "Hard"){
a = 2;
}
else {
cout << "Invalid input";
a = 3;
}
}while (a == 3);
return a;
}

You should be careful on this kind of error:
//based on user input the program will run or not
if (Ans == "Y" || "y") {
while (Ans == "Y" || "y")
{
This, above, will always be true being "y" different from 0 (false).
Instead you need to check that Ans is either equal to "Y" or "y" in this way:
//based on user input the program will run or not
if (Ans == "Y" || Ans == "y") {
while (Ans == "Y" || Ans == "y")
{
Or use, as suggested in the comments, std::toupper()
UPDATE
It seems you have a problem on your buffer you should use cin.ignore() in order to clean it;

Related

Program Fails to output greatest integer

I am writing a program that takes multiple user inputs, and counts how many prime numbers there are, and which number is the greatest and smallest of the inputs. However, I am stuck. when I run the code, it thinks every new input is the greatest number. for example, if I enter 1, 2, 3, 2... It says the greatest number is 2. It takes the last integer inputted and thinks that is the greatest number. I have no started on the lease common number yet, but if I am able to understand how to get the greatest number, I bet I can get the least. Thanks guys!
#include <iostream>
using namespace std;
int main() {
int startstop = 1;
cout << "start program?" << endl;
int begin = 0;
int primecounter = 0;
cin >> begin;
if (begin >= 0) {
while (startstop != 0) {
cout << "enter any number, or press Q to process." << endl;
int oldnum = 0;
int userinput=0;
int newnum = userinput;
int greatestnum = 0;
int greatestcounter = 0;
cin >> userinput;
int x;
bool is_prime = true;
if (userinput == 0 || userinput == 1) {
is_prime = false;
}
// loop to check if n is prime
for (x = 2; x <= userinput / 2; ++x) {
if (userinput % x == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
primecounter++;
}
//check if input is greater than previous input
if (greatestnum > userinput) {
greatestnum = userinput;
}
cout << "prime count: " << primecounter << endl;
cout << "greatest num: " << greatestnum << endl;
userinput = 0;
}
return 0;
}
}
greatestnum is only assined if it's greater than the user input. Since it's initialized to 0, the if statement,
if (greatestnum > userinput) {
greatestnum = userinput;
}
will be false unless the user input is less than zero. If you want to make it the greatest from all user inputs, flip it to < and move the int greatestnum = 0; to right above the if (begin >= 0) {.
if (greatestnum < userinput) {
greatestnum = userinput;
}
#include <iostream>
using namespace std;
int main() {
int startstop = 1;
cout << "start program?" << endl;
int begin = 0;
int primecounter = 0,greatestnum = 0,oldnum = 0,userinput = 0;
cin >> begin;
if (begin >= 0) {
while (startstop != 0) {
cout << "enter any number, or press Q to process." << endl;
cin >> userinput;
int x;
bool is_prime = true;
if (userinput == 0 || userinput == 1) {
is_prime = false;
}
// loop to check if n is prime
for (x = 2; x <= userinput / 2; ++x) {
if (userinput % x == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
primecounter++;
}
//check if input is greater than previous input
if (userinput > oldnum) {
greatestnum = userinput;
oldnum = userinput;
}
cout << "prime count: " << primecounter << endl;
cout << "greatest num: " << greatestnum << endl;
userinput = 0;
}
return 0;
}
}
Initialize 'oldnum=0' , 'userinput=0' and 'greatestnum=0' outside the loop. And there were some error in logic. If userinput is greater the old num the update greatest num=userinput and oldnum=userinput.

Skipping of For loop while using goto

This is my code for finding a palindrome of a string.
The initial execution works perfectly.
But when it comes to executing the program again, it goes to the label, and skips the cin statement and directly executes everything and finally reaches the end.
This didn't happen when I used it in c++ 6.0, but happens in visual studio 2015
Thanks in advance for your help.
#include "stdafx.h"
#include<iostream>
using namespace std;
void main()
{
char string[100], ch;
int x, i, j, flag = 0;
label:
cout << "Enter a string. Max Length 99 : ";
cin.getline(string, 100);
x = strlen(string);
cout << "Checking For Palindrome...........";
for (long i = 0; i < 5000000; ++i)
{
cout << "";
}
cout << endl;
for (i = 0, j = x - 1; i < x / 2; ++i, --j)
{
if (string[i] == string[j])
continue;
else
{
flag = 1;
break;
}
}
if (flag == 1)
cout << "The String You Entered Is Not A Palindrome";
else
cout << "The String You Entered Is A Palindrome";
cout << "\nDo you want to execute again? (Y/N)";
cin >> ch;
if (ch == 'y' || ch == 'Y')
goto label;
else
cout << "See You Later :)";
}

Segmentation fault: 11 c++ Error

this is my first time asking a question on this forum so here it goes. I am creating a tic-tac-toe game for practice and am using enumerators and recursion because I have never really done enumeration and could always get some recursion practice in. Well anyway I just finished coding for the player2 to take a random move and after about 3 turns it gives a segmentation fault and I cannot figure out why... I hope you guys can figure it out and thank you!
#include <iostream>
#include <string>
#include <cstdlib>
const int size = 3;
enum play {none,X,O};
void NPC(play (&board)[size][size],play player2) {
srand(time(NULL));
int tempx = rand() % 3;
int tempy = rand() % 3;
if(board[tempx][tempy] == none)
board[tempx][tempy] = player2;
else
NPC(board,player2);
}
void getBoardState(play (&board)[size][size],int y,int x) {
if(board[x][y] == none) std::cout << " ";
else if(board[x][y] == X) std::cout << "X";
else std::cout << "O";
}
void printboard(play (&board)[size][size]){
int length = 4 * size - 1;
for(int i = 1; i <= length; i++) {
for(int j = 1; j <= length; j++) {
if(i % 4 == 0 && j % 4 == 0) std::cout << "+";
else if(i % 4 == 0) std::cout << "-";
else if(j % 4 == 0) std::cout << "|";
else if(i % 2 == 0 && j % 2 == 0) getBoardState(board,(i - 2)/4,(j - 2)/4);
else std::cout << " ";
}
std::cout << std::endl;
}
}
int main() {
play player = O, player2 = X;
bool over = false;
play board[size][size];
for(int i = 0; i < size; i++) {
for(int j = 0; j < size; j++) {
board[i][j] = none;
}
}
std::string player1 = "";
std::cout << "What would You like to be? An X or an O?" << std::endl;
while(((player1 != "X") + (player1 != "O")) == 2) {
std::cin >> player1;
if(((player1 != "X") + (player1 != "O")) == 2)
std::cout << "Invalid entry! Please enter X or an 0!" << std::endl;
}
if(player1 == "X") {
player2 = O;
player = X;}
int tempx,tempy;
while(!over) {
std::cout << "Please enter an x and then a y (1 to " << size << ")" << std::endl;
std::cin >> tempx;
std::cin >> tempy;
while(tempx > size || tempy > size || board[tempx-1][tempy-1] != none) {
std::cout << "Invalid entry! Try again!" << std::endl;
std::cin >> tempx;
std::cin >> tempy;
}
board[tempx-1][tempy-1] = player;
NPC(board,player2);
printboard(board);
}
return 0;
}
You're running out of stack space in your recursion because you call srand(time(NULL)) every time. The random number generator should only be seeded once, in main, and not in NPC. time(NULL) returns a number of seconds, so it changes infrequently (compared to how fast your recursive function calls will occur) which will consume all available stack space.

Can anyone tell me why these functions are not giving me a result in a reasonable spectrum?

The full code I am using is listed below, it is supposed to simulate a game of craps and print details to the user and allow for betting if the user desires it. Everything functions except for the actual craps game. Instead of looping only while there is not a truth value associated to crapsResult, it finds one real value and an incomprehensible string of a single negative number. Any help would be appreciated.
int main()
{
//Declare the user input variables
int gamesPlayed = 0;
char inputPrint = ' ';
char isBetting = ' ';
int startingBet = 0;
//Declare the variables used by the program
int endingBet = 0;
int currentGame = 0;
bool crapsResult;
int gamesWon = 0;
int gamesLost = 0;
double percentWon = 0;
bool detailPrint = false;
//Prompt the user to input their variables
cout << "Enter the number of games to be played: ";
cin >> gamesPlayed;
while(gamesPlayed < 1)
{
cout << " Error: must be greater than 0" << endl;
cout << "Enter the number of games to be played: ";
cin >> gamesPlayed;
cin.clear();
cin.ignore();
}
cout << "Do you wish to print details (Y/N): ";
cin >> inputPrint;
if(inputPrint == 'y' || inputPrint == 'Y')
{
detailPrint = true;
}
cout << "Do you wish to bet (Y/N): ";
cin >> isBetting;
if(isBetting == 'y' || isBetting == 'Y')
{
cout << "Enter money to start betting with: ";
cin >> startingBet;
while(startingBet < 1)
{
cout << " Error: must be greater than 0" << endl;
cout << "Enter the number of games to be played: ";
cin >> gamesPlayed;
cin.clear();
cin.ignore();
}
}
//Seed the random number generator
srand(time(NULL));
//Set a value for ending bet
if(startingBet == 0)
{
endingBet = 1;
}
else
{
endingBet = startingBet;
}
//Call playcraps to simulate the game for as many games as the user input
for(currentGame = 1; currentGame <= gamesPlayed && endingBet > 0; currentGame += 1)
{
crapsResult = NULL;
crapsResult = playCraps(currentGame, detailPrint, isBetting, startingBet);
if(crapsResult == true)
{
gamesWon += 1;
endingBet = betting(endingBet, crapsResult);
}
if(crapsResult == false)
{
gamesLost += 1;
endingBet = betting(endingBet, crapsResult);
}
if((isBetting == 'Y' || isBetting == 'y') && (detailPrint == true))
{
cout << "Money left is $" << endingBet << endl;
}
}
//Calculate the percentage of games won
percentWon = (double(gamesWon) / double(currentGame-1)) * 100.0;
//Print the results to the user
if(isBetting == 'Y' || isBetting == 'y')
{
cout << "Money at end of games is $" << endingBet << endl;
}
cout << "The number of games played is " << currentGame - 1 << endl;
cout << "The number of games won is " << gamesWon << endl;
cout << "The number of games lost is " << gamesLost << endl;
cout << "The percent of games won is " << fixed << showpoint << setprecision(3) << percentWon << endl;
}
//Simulates the roll of a single die and returns the result
int roll()
{
int rollResult = 0;
rollResult = rand() % 6 + 1;
return rollResult;
}
//Calls roll twice and returns the sum of the two results
int roll2Dice()
{
//Declare variables for this function
int rollOne = 0;
int rollTwo = 0;
int rollSum = 0;
//Find rollOne and rollTwo
rollOne = roll();
rollTwo = roll();
//Find rollSum
rollSum = rollOne + rollTwo;
return rollSum;
}
bool playCraps(int currentGame, bool detailPrint, char isBetting, int startingBet)
{
bool crapsResult = NULL;
int currentGameStorage[100];
int currentRoll = 1;
int point = roll2Dice();
int printingNumber = 0;
currentGameStorage[0] = point;
if(point == 7 || point == 11)
{
crapsResult = true;
}
else if(point == 2 || point == 3 || point == 12)
{
crapsResult = false;
}
else
{
crapsResult = NULL;
}
while(crapsResult != true && crapsResult != false)
{
currentGameStorage[currentRoll] = roll2Dice();
if(currentGameStorage[currentRoll] == point)
{
crapsResult = true;
}
else if(currentGameStorage[currentRoll] == 7)
{
crapsResult = false;
}
currentRoll += 1;
}
if(detailPrint == true)
{
cout << "Game " << currentGame << ": ";
for(printingNumber = 0; printingNumber <= currentRoll; printingNumber += 1)
{
cout << currentGameStorage[printingNumber] << " ";
}
if(crapsResult == true)
{
cout << "win";
}
else if(crapsResult == false)
{
cout << "lose";
}
cout << endl;
}
return crapsResult;
}
int betting(int endingBet, bool crapsResult)
{
if(crapsResult == true)
{
endingBet += 1;
}
else if(crapsResult == false)
{
endingBet -= 1;
}
return endingBet;
}
Just skimmed and didn't read all of your code (so there may be other things wrong too), but this line is definitely problematic:
while(crapsResult != true && crapsResult != false)
It is logically impossible for crapsResult to simultaneously be both true and false, so that loop will never be entered.
Turix got the right bug I believe, but I would put the emphasis on a different spot:
bool crapsResult = NULL;
You are trying to use crapsResult for three different values (true, false and NULL). However, NULL usually has a integer value of 0, which translates to a boolean value of false, so your loop will never be entered.
Then a second bug comes into play: currentRoll is 1 at this time, so you try to print the contents of currentGameStorage from index 0 to 1 (inclusive), currentGameStorage[1] hasn't been assigned yet. This is why you get the cryptic numer in your output. This is a general mistake: Your code always tries to print one item too much. Use < instead of <= in the loop head to fix that:
for(printingNumber = 0; printingNumber < currentRoll; printingNumber += 1)

Replay tic tac toe game

So I am trying to program a way to replay a tic tac toe game after someone wins, loses, or ties.
So basically my attempt to get replay to work, doesnt work. If player 1 won and I type 1 to replay, it would ask player 2 for their input.
Pseudocode outline:
do {
set entire 2d array to '*'
do {
player 1 input
does game tie?
does player 1 win
player 2 input
does game tie?
does player 2 win
} while no one wins
} while replay = 1
My actual code:
//tie check, replay, use pointer notation
#include <iostream>
using namespace std;
void initialize(char [][3]);
void player1(char [][3]);
void player2(char [][3]);
void display(char [][3]);
char check(char [3][3]);
int checkWin(int);
int tie(int);
int askReplay();
int main()
{
char board[3][3];
char end = '*';
int row1, column1, row2,column2;
int replay = 0;
int turns = 0;
//replay loop
do {
//set board to *
initialize(board);
display(board);
do {
//player 1 turn
player1(board);
turns++;
display(board);
//if turns = 9 then tie
replay = tie(turns);
//check if player 1 won
end = check(board);
replay = checkWin(end);
//player 2 turn
player2(board);
turns++;
display(board);
//if turns = 9 then tie
replay = tie(turns);
//check if player 2 won
end = check(board);
replay = checkWin(end);
} while (end == '*');
} while (replay == 1);
return 0;
}
void initialize(char (*array)[3])
{
for (int i = 0;i < 3;i++)
for (int j = 0;j < 3;j++)
array[i][j] = '*';
cout << "New Game\n";
}
void player1(char (*array)[3])
{
int row1, column1;
cout << "Player 1\nRow: ";
cin >> row1;
while (row1 < 0 || row1 > 2) {
cout << "Enter a number between 0 and 2 for Row:: ";
cin >> row1;
}
cout << "Column: ";
cin >> column1;
while (column1 < 0 || column1 > 2) {
cout << "Enter a number between 0 and 2 for Column: ";
cin >> column1;
}
if (array[row1][column1] == '*')
array[row1][column1] = 'X';
else {
cout << "Space Occupied\n";
player1(array);
}
}
void player2(char (*array)[3])
{
int row2,column2;
cout << "Player 2\nRow: ";
cin >> row2;
while (row2 < 0 || row2 > 2) {
cout << "Enter a number between 0 and 2 for Row: ";
cin >> row2;
}
cout << "Column: ";
cin >> column2;
while (column2 < 0 || column2 > 2) {
cout << "Enter a number between 0 and 2 for Column: ";
cin >> column2;
}
if (array[row2][column2] == '*')
array[row2][column2] = 'O';
else {
cout << "Space Occupied\n";
player2(array);
}
}
void display(char (*array)[3])
{
for (int x = 0;x < 3;x++) {
for (int y = 0;y < 3;y++)
cout << *(*(array + x) + y) << " ";
cout << endl;
}
}
char check(char (*array)[3])
{
int i;
/* check rows */
for(i = 0; i < 3; i++)
if(array[i][0] == array[i][1] && array[i][0] == array[i][2])
return array[i][0];
/* check columns */
for(i = 0; i < 3; i++)
if(array[0][i] == array[1][i] && array[0][i] == array[2][i])
return array[0][i];
/* test diagonals */
if(array[0][0] == array[1][1] && array[1][1] == array[2][2])
return array[0][0];
if(array[0][2] == array[1][1] && array[1][1] == array[2][0])
return array[0][2];
return '*';
}
int checkWin(int over)
{
if (over == '*')
return 0;
if (over == 'X')
cout << "Player 1 Won!\n";
else if (over == 'O')
cout << "Player 2 Won!\n";
//ask if they want to play again
int answer;
answer = askReplay();
switch (answer) {
case 1:
return 1;
case 2:
cout << "Thank you for playing.\n";
exit(0);
}
}
int tie(int count)
{
if (count == 9) {
int answer;
cout << "Tie game";
answer = askReplay();
switch (answer) {
case 1:
return 1;
case 2:
cout << "Thank you for playing.\n";
exit(0);
}
}
}
int askReplay()
{
int input;
do {
cout << "Play Again?\n1.Yes\n2.No\nEnter 1 or 2: ";
cin >> input;
if (input > 2 || input < 1)
cout << "Invalid Option\n";
} while(input > 2 || input < 1);
return input;
}
It sounds like you're having troubles with your main loop.
I'd suggest making a variable that controls which player is running and just toggle that.
do
{
set entire 2d array to '*'
current player = 0
do
{
(current player + 1) input
does game tie?
does (current player + 1) win
current player = (current player + 1) % 2
}while no one wins
}while replay = 1
See if that gets you further along.
You may want to look up the Memento Design Pattern.