Craps game doesnt return right values - c

wiHi everyone since last time i found extreme help on here, im gonna ask a question again
My code doesnt return right values :
something is wrong in the play_game function and i cant figure out what it is.I believe that all cases are covered but somehow they end up messed up.
also the code doesnt loop for everytime i want to play a game after the second game it stops.
this is not an assignment
any suggestion?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
static int sum, point, win = 0, roll = 0;
bool play_game(void);
int roll_dice(void);
int main(void){
srand(time(NULL));
play_game();
char input[10];
do{ point = 0;
play_game();
if(win == 1){ // I'm assuming that play returns whether you won or not
printf("You won!\n");
}else{
printf("You lost!\n");
}
printf("Would you like to continue? y/n\n");
gets(input);
}while(*input == 'y'); // gets() flushes the buffer for next time you need input
return 0;
}
bool play_game(void){
point=0;
roll_dice();
printf("Your point is %d\n", sum);
while(roll == 1) /* first round */
{
if(sum == 7 || sum == 11)
return win = 1;
else if(sum == 2 || sum == 3 || sum == 12)
return win = 0;
else if(sum == 1 || sum == 4 || sum == 5 || sum == 6 || sum == 8 || sum == 9 || sum == 10){
point=sum;
roll_dice();
}
}
while(roll > 1) /* all others rounds*/
{
if(sum == 7)
return win = 0;
else if(sum == point)
return win = 1;
else if(sum != point || sum != 7)
roll_dice();
}
}
int roll_dice(void){
int a,b;
a=1+rand() % (6);
b=1+rand() % (6);
sum=a+b;
roll++;
printf("You rolled %d\n", sum);
return sum;
}
OUTPUT

A couple of points:
You probably want 1 + rand() % 6
The return value of printf() is probably not what you want to return from roll_dice()

The loop needs to be more like:
main(){
char input[10];
do{
score = 0; //Always initialize the score
if(play_game()){ // I'm assuming that play returns whether you won or not
printf("You won!\n");
}else{
printf("You lost!\n");
}
printf("Would you like to continue? y/n\n");
gets_s(input, 9);
}while(*input == 'y'); // gets() flushes the buffer for next time you need input
}

Kyle's answer is just fine (as I see it), But I can spot a few problems, hope it'll help you in further cases.
You always win, and I know it's nice, but I bet it's not the expected behavior:
while(true) // This will always happen, because true is always evaluated as true
{
printf("Won\n\n");
printf("Play again? y/n: ");
break;
}
while(false) //This will never happen, since false is always evaluated as false
{
printf("Lost\n\n");
printf("Play again? y/n: ");
break;
}
I think you meant to check the result of play_game(). So add another variable and check against it:
bool win;
win = play_game();
while (win == true)
...
while (win == false)
...
Why using while loop there? you break it in the first iteration anyway
if(win == true)
{
printf("Won\n\n");
}
else
{
printf("Lost\n\n");
}
printf("Play again? y/n: ");
The game will run not more than twice, because you don't have a loop that depends on the answer, but only an if statement that is evaluated just one time:
if(v=getchar() == 'y') //This is the second time the code runs, after that? nada.
{
point =0; /* reset point var */
play_game();
}
else if(v=getchar() == 'n') // Why adding this check? you're going out anyway after the if-else
exit(1);
EDIT
When you use a while loop, what you do is saying:
While (some expression in the parenthesis) is true, execute the code in the block {..} and then check again the expression in parenthesis.
If you write while(true), you actually writing while true is true, execute the code in the block. And this will always happen.
If you write while(false) you actually write while false is true, execute the code in the block. and this false is never true, than it will never execute the code in the block.
If you want a real condition here, you can use while(play_game()). this is like writing, while the returned value from the function play_game is true, execute the code in the block and then the code will be executed only when the play_game function return true (which indicates a win in the game).
There are many good C tutorials out there, start here or here

It is hard to tell from your description (please say what you expected to happen, and what happened instead), but the first thing I notice is that you are rolling 5-sided dice for a and b.

Rolling of the dice is happening at at incorrect points during your game sequence.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
// add defines to make states easier to read
#define WIN 1
#define LOSE 0
static int sum, point, win = 0, roll = 0;
//bool play_game(void);
int play_game(void); // changed return type to be int
int roll_dice(void);
int main(void){
srand(time(NULL));
// play_game(); // unncessary
char input[10];
do
{
point = 0;
//play_game();
// if(win == 1){
if(play_game()){ // use return value from play_game()
printf("You won!\n");
}else{
printf("You lost!\n");
}
printf("Would you like to continue? y/n\n");
// gets(input);
fgets(input, sizeof(input), stdin); // a safer input read
} while(*input == 'y'); // gets() flushes the buffer for next time you need input
return 0;
}
// bool play_game(void)
int play_game(void) // changed return type to be int
{
point=0;
// remove as this messes up the roll sequence.
// roll_dice();
// incorrect place to display this message
//printf("Your point is %d\n", sum);
// the while loop here is unnecessary
//while(roll == 1) /* first round */
//{
roll_dice(); // add for initial come out roll.
if(sum == 7 || sum == 11) { // I use braces to remove ambiguity
// return win = 1;
return WIN;
} else if(sum == 2 || sum == 3 || sum == 12) {
//return win = 0;
return LOSE;
}
// sum will never be 1
// on that note if it control reaches here it will be one of the other numbers.
//} else if(sum == 1 || sum == 4 || sum == 5 || sum == 6 || sum == 8 || sum == 9 || sum == 10){
// point=sum;
// roll_dice(); // remove as this messes up the roll sequence.
// }
point=sum;
printf("Your point is %d\n", sum);
//}
// while(roll > 1) /* all others rounds*/
while (1) // might as well loop forever
{
roll_dice(); // add for subsequent dice rolls
if(sum == 7) {
//return win = 0;
return LOSE;
} else if(sum == point) {
// return win = 1;
return WIN;
}
// remove as this is unnecessary
// else if(sum != point || sum != 7)
// remove as this messes up the roll sequence.
//roll_dice();
}
}
int roll_dice(void){
int a,b;
a=1+rand() % (6);
b=1+rand() % (6);
sum=a+b;
// roll++; // unncessary
printf("You rolled %d\n", sum);
return sum;
}

Related

How to identify the digit 7 between the given number

I want my code to print "YES" if there is digit 7 in the entered number, and otherwise print "NO".
When I use while(T != 0) for test cases, my code prints "YES" for all the numbers - even for number 45. Without while(T != 0) my code runs perfectly.
Where is my mistake?
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
while (T != 0) {
int X;
scanf("%d", &X);
int flag, result;
while (X != 0) {
result = X % 10;
if (result == 7) {
flag = 1;
}
X = X / 10;
}
if (flag == 1) {
puts("YES");
} else {
puts("NO");
}
T--;
}
return 0;
}
After trying out your code, the main issue was not with the "while" test. Rather, in the code your test flag was not being reset so once the a value was found to have the digit "7" in it, all subsequent tests were noted as being "YES". With that, following is a refactored version of your code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int T;
printf("How many numbers to test: "); /* Clarifies what the user is being asked for */
scanf("%d", &T);
while (T != 0)
{
int X;
printf("Enter a number to be tested: "); /* Again, lets the user know what to enter */
scanf("%d", &X);
int flag = 0, result;
while (X != 0)
{
result = X % 10;
if (result == 7)
{
flag = 1;
}
X = X / 10;
}
if (flag == 1)
{
puts("YES");
}
else
{
puts("NO");
}
flag = 0; /* Needs to be reset after being set and before next check */
T--;
}
return 0;
}
Some things to note.
Although not really needed, verbiage was added as prompts to clarify to the user what needed to be entered for values.
Most importantly, the flag variable gets initialized to zero and then subsequently gets reset to zero after each test has been completed.
With those bits addressed, following is some sample terminal output.
#Vera:~/C_Programs/Console/Seven/bin/Release$ ./Seven
How many numbers to test: 4
Enter a number to be tested: 3987
YES
Enter a number to be tested: 893445
NO
Enter a number to be tested: 8445
NO
Enter a number to be tested: 58047
YES
Give that a try and see if it meets the spirit of your project.

Certain values give incorrect results for prime number checking function

I recently wrote a program in C for a calculator. To produce a function that checks if the user input is a prime number or not (amongst other functions).
I essentially used this code (excluding all other functions):
#include <stdio.h>
#include <math.h>
int testForPrime(int);
int main(void) {
int ioperand1 = 0;
printf("\nEnter the value to check if prime (positive integer): ");
scanf("%d", &ioperand1);
if (testForPrime(ioperand1) != 0)
printf("\nThis number is prime.\n");
else
printf("\nThis number is not prime.\n");
return 0;
}
int testForPrime(int operand1) {
int i = 0;
for (i = 2; i <= sqrt(operand1); i++) {
if (operand1 == 0 || operand1 == 1)
return 0;
else if (operand1 % i == 0)
return 0;
else
return 1;
}
}
^
This code above produces the errors
I am not sure why the code produces an error for the value 9 (I fixed that above by adding the condition: if (operand1 == 9), but I don't understand why 9 is seemingly the only value that results in an incorrect solution (It would say 9 was prime, but not any other number give an incorrect result).
One other bug that I remidied with an extra condition statement was the value of 2.
Before adding the extra conditional statement in the main function: if (ioperand1 == 2), the value 2 would always come up as a non prime number.
I originally found this solution to check for prime numbers online, and I still don't understand why the for loop starts from 2.
#include <stdio.h>
#include <math.h>
int testForPrime(int);
int main(void) {
int ioperand1 = 0;
printf("\nEnter the value to check if prime (positive integer): ");
scanf("%d", &ioperand1);
if (testForPrime(ioperand1) != 0 || ioperand1 == 2)
printf("\nThis number is prime.\n");
else
printf("\nThis number is not prime.\n");
return 0;
}
int testForPrime(int operand1) {
int i = 0;
for (i = 2; i <= sqrt(operand1); i++) {
if (operand1 == 0 || operand1 == 1 || operand1 == 9)
return 0;
else if (operand1 % i == 0)
return 0;
else
return 1;
}
}
^This code above fixed the problem, though I don't undesttand why the problem existed in the first place.
TL;DR:
I don't know why this code doesn't work without the extra conditional statements:
if (operand1 == 9) in function definition,
and
if (ioperand1 == 2) in main function.
If anyone could help clear this up, I'd appreciate it.
It is because your prime checking loop does not iterate. It always returns on the first iteration. It must run to completion, and then the number will be prime. So
int testForPrime(int operand1) {
if(operand1 < 2) {
return 0;
}
int sr = (int)round(sqrt(operand1));
for(int i = 2; i <= sr; i++) {
if (operand1 % i == 0) {
return 0;
}
}
return 1;
}

How to limit an integer's input to 2-12 only?

I want to strictly limit a user's input on an integer in this program to 2-12 only. How do I do that?
#include <stdio.h>
int main(){
int i;
scanf("%d", &i);
int diceThrown, diceResult;
int sum = 0;
for(diceThrown = 1; diceThrown <= i; diceThrown++){
scanf("%d", &diceResult); //limit this input to 2-12 only, how?
sum += diceResult;
}
if(sum >= 40){
sum = sum % 40;
if(sum == 12){
printf ("28\n");
} else if(sum == 35){
printf ("7\n");
} else{
printf ("%d\n", sum);
}
} else if(sum < 40){
if(sum == 12){
printf ("28\n");
} else if(sum == 35){
printf ("7\n");
} else{
printf ("%d\n", sum);
}
}
return 0;
}
Also just to clarify, that I'm still a beginner in programming (like only 2 months into C.SCi course), so if you could explain it to me like I'm not a expert that would be great.
scanf has no functionality to do what you want. You can just use an if to validate input.
if(scanf("%d", &diceResult) != 1 || diceResult < 2 || diceResult > 12) {
//handle invalid input here
}
If the input is invalid it is up to you what you want to do. You could ignore the input and ask the user to enter a valid number, you can quit the whole program or just ignore the error, or something else entirely.
You can also check the input repeatedly with an while:
while(scanf("%d", &diceResult) != 1 || diceResult < 2 || diceResult > 12) {
//prompt user to enter valid input here
}
As mentioned by chux, part of handling invalid input would be to cosume the invalid input and check for EOF.
The scanf("%d", &diceResult) != 1 will assure, that scanf actually read exactly one number and no parsing errors occurred.
Consider this:
#include <stdio.h>
int main(){
int x;
do
{
printf("give a number between [2-12]\n");
scanf ("%d",&x);
}
while(x<2 || x>12);
return 0;
}
You can use a do-while loop so that you only take the values that are between the 2-12 range. That way you can force the user to give an integer as an input that is in the range that you ask for, in that case from [2,12]. Otherwise the program will turn back and request a valid input again.

Issue with not entering a loop in c

The code compiles however where my while loop should run until an odd number is inputted it only runs through once no matter whatever is added in there. From what I understand I should be able to use it like this however I cannot seem to figure it out what-so-ever
#include <stdio.h>
#include <stdbool.h>
//variables
bool flag = false;
int input = 0;
//function protoypes
void get_input(void);
bool is_valid(int);
int main(){
get_input();
return 0;
}
void get_input(){
while(flag == false){
printf("please enter an odd number betwen 1 and 9\n");
scanf("%d", &input);
if(is_valid){
flag = true;
}else{
flag = false;
}
}
}
bool is_valid(int number){
if(number == 1 || number == 3 || number == 5 || number == 7 || number == 9){
return true;
}else{
return false;
}
}
You calling is_valid function in wrong way.
Try :
if(is_valid(input)) {
//code
} ....
It's because you are not calling your function. (line is_valid should be is_valid(number)
#include <stdio.h>
#include <stdbool.h>
//variables
bool flag = false;
int input = 0;
//function protoypes
void get_input(void);
bool is_valid(int);
int main(){
get_input();
return 0;
}
void get_input(){
while(flag == false){
printf("please enter an odd number betwen 1 and 9\n");
scanf("%d", &input);
if(is_valid(input)){
flag = true;
}else{
flag = false;
}
}
}
bool is_valid(int number){
if(number == 1 || number == 3 || number == 5 || number == 7 || number == 9){
return true;
}else{
return false;
}
}
also, you can remove the function entirely by doing a modulo operation, so your is_valid will be:
if(input <= 9 && input >= 1 && input % 2 != 0){
flag = true;
}else{
flag = false;
}
It can even be further simplified to:
flag = (input <= 9 && input >= 1 && input % 2 != 0);
So your whole code can be:
#include <stdio.h>
#include <stdbool.h>
//variables
bool flag = false;
int input = 0;
//function protoypes
void get_input(void);
int main(){
get_input();
return 0;
}
void get_input(){
while(flag == false){
printf("please enter an odd number betwen 1 and 9\n");
scanf("%d", &input);
flag = (input <= 9 && input >= 1 && input % 2 != 0);
}
}
The problem is here
if(is_valid)
it should be
if(is_valid(input))
You did not pass input to the function is_valid(). That is what had been causing the problem.
Hope this solves your problem :)
This line is the problem:
if(is_valid){
Since is_valid is a function, the expression is_valid, without parentheses, evaluates as the address of the function rather than the result of calling said function.
Since the address of the function will never be NULL or 0, it will always be treated as a truth value, hence flag will be set to true always.
The correct way to do this is:
if (is_valid()) {
And, as an aside, it's not considered good form to compare boolean values such as with:
while (flag == false)
It's better to use something like:
while (! flag)
especially if you choose your variable names carefully:
int input_is_okay = 1;
void get_input (void) {
while (input_is_okay) {
printf ("please enter an odd number between 1 and 9\n");
input_is_okay = (scanf ("%d", &input) == 1);
input_is_okay = input_is_okay && is_valid (input);
}
}
You'll notice I'm setting input_is_okay to false if the scanf() fails as well since that means you didn't enter a valid integer.

C if statements skipped over

I'm currently learning C and am attempting to do the reverse of what some courses are asking for. miniMasterMind is an assignment I found where the user guesses numbers randomly generated by the computer. I'm attempting to make a simple flip on it, where the user tells the computer whether or not its guesses are correct for a user generated 3 digit number.
I have what I think is a fully working program, except my 3 if statements asking for user input sometimes do not work. I can't see any reason for it, but after compiling I often find one or two of the if statements to just skip over the user input. I put in system("pause")'s after each step to make it easier to see.
Each turn in the game, a different set of if statements seems to break. Why is this happening?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
// Initialize variables
int UCMain = 0;
int CG1 = -1, CG2 = -1, CG3 = -1;
int win1 = -2, win2 = -3, win3 = -4;
char check1 = 'A', check2 = 'B', check3 = 'C';
int turnCount = 0;
// Print out start screen
printf("Welcome to masterMind reversed! Let's see how this works out!\n\n");
// Accept user input
printf("Type in a three digit number for the computer to guess.\n");
scanf_s("%d", &UCMain, 3);
const int UC1 = (UCMain / 100) % 10;
const int UC2 = (UCMain / 10) % 10;
const int UC3 = UCMain % 10;
printf("\nTest print, UC1: %d UC2: %d UC3: %d\n", UC1, UC2, UC3);
system("Pause");
// Start game loop
while (turnCount < 10)
{
// Random number gen
srand((int)time(0));
// 1st number
if (win1 == UC1)
{
CG1 = win1;
}
else if (win1 != UC1)
{
CG1 = rand() % 10;
}
// 2nd number
if (win2 == UC2)
{
CG2 = win2;
}
else if (win2 != UC2)
{
CG2 = rand() % 10;
if (CG2 == CG1)
{
CG2 = rand() % 10;
} // End unique check
}
//3rd number
if (win3 == UC3)
{
CG3 = win3;
}
else if (win3 != UC3)
{
CG3 = rand() % 10;
if (CG3 == CG2 || CG3 == CG1)
{
CG3 = rand() % 10;
} // End unique check
}
// End random number generation
printf("The computer guesses: %d%d%d\n", CG1, CG2, CG3);
system("Pause");
// Check if numbers are correct
if (win1 != UC1)
{
printf("Is the first number correct? Y/N\n");
scanf_s("%c", &check1, 1);
if (check1 == 'Y')
{
win1 = UC1;
} //
}// End 1st check
system("pause");
if (win2 != UC2)
{
printf("Is the second number correct? Y/N\n");
scanf_s("%c", &check2, 1);
if (check2 == 'Y')
{
win2 = UC2;
} //
}// End second check
system("pause");
if (win3 != UC3)
{
printf("Is the third number correct? Y/N\n");
scanf_s("%c", &check3, 1);
if (check3 == 'Y')
{
win3 = UC3;
} //
}// End third check
system("pause");
// Check if game is over
if (win1 == UC1 && win2 == UC2 && win3 == UC3)
{
printf("The computer wins!");
}
turnCount++;
} // End while
// Win/lose state
if (turnCount == 10)
{
printf("The computer loses!");
}
}
it is not really skipped:
it is taking a character the newline character: '\n'
Using a scanf with a space before it:
scanf(" %c", &b); // this one will work instead
Will tell the scanf that any white space characters (including the newline '\n') left on stdin should be ignored.
please read more about scanf here
scanf() is reading all user input, including line feed and carriage return characters. If the user types "1" and presses enter, you'll actually get 2 (or 3, depending on the platform) input characters, one for the digit and one or two for the newline character(s). This will stimulate 2 or 3 iterations of your loop when you only intended one.

Resources