C program - Faulty scores output - c

C program. IDE used is Xcode v12.2.
The problem I am facing:
Faulty scores output. For each round, the program should output the highest and lowest scores and the average score if the player chooses to do so.
Scores output after playing for 1 round:
Enter 'S' to show results
Enter 'P' to play another round
Enter 'R' to return to the main menu
S
Round 0 score: 92/100
Highest score: 92/100
Lowest score: 92/100
Average score:inf
****** Player: MAX ******
Scores output after playing for 2 rounds:
Enter 'S' to show results
Enter 'P' to play another round
Enter 'R' to return to the main menu
S
Round 0 score: 95/100
Highest score: 95/100
Lowest score: 92/100
Average score:inf
****** Player: MAX ******
Questions:
Why is 'Round 1' shown as 'Round 0'? And what does the 'inf' mean in the average score section? How do I turn 'inf' into a numerical output? After 2 rounds, the output 'Round 2' is still shown as 'Round 0' and the 'Average score' did not change to a numerical output.
What I have tried:
void quiz(char name[])
{
// function created to enclose quiz functionality apart from instructions
int rounds = 0;
int highest = 0;
int lowest = INT_MAX;
float allScore = 0;
float avg = 0;
int i, j, g = 0;
//char x;
struct struc test[MAX_TESTS];
srand((unsigned) time(NULL));
for (;;)
{
rounds++;
for (i = 0; i < MAX_TESTS; i++) // generate all questions
{
ctm_i(&test[i]);
for (j = 0; j < i; j++)
if (test[i].a == test[j].a && test[i].b == test[j].b && test[i].c == test[j].c)
//if question is already present
ctm_i(&test[i]); //then re-generate
}
//int ig = getchar();
char x;
x = getchar();
printf("\n Are you ready? Press Enter key to continue. ");
fflush(stdin);
while (x != '\n') {}
while (getchar() != '\n') {}
//getchar();
for (i = 1; i <= 5; i++)
{
printf( " *******************************************************************"
"**"
"***********\n");
printf( " ..................................................................."
".."
"...........\n");
}
// Take quiz
for (i = 0; i < MAX_TESTS; i++)
tcm_i(&test[i], i);
printf(" End\n\n");
bool done = false;
bool unsure = true;
bool showS = true;
while (unsure)
{
unsure = false;
puts("\n");
if (showS)
{
puts(" Enter 'S' to show results");
}
puts(" Enter 'P' to play another round");
//puts(" Enter 'Q' to quit");
puts(" Enter 'R' to return to main menu");
char choice;
printf(" ");
myread("%c", &choice);
if (choice == 'r' || choice == 'R')
{
done = true;
}
else if (choice == 'S' || choice == 's')
{
showS = false;
// calculate total score for current round
g = 0;
for (i = 0; i < MAX_TESTS; i++)
{
g += test[i].grade; //add score of each question
}
allScore += g; //add current round's score to total
avg = allScore / rounds; //average of all rounds
if (g > highest)
{
highest = g;
}
if (g < lowest)
{
lowest = g;
}
if (rounds == 1)
{
printf(" Final score: %d/100\n", g); //display round score
printf(" ******Player: %s ******\n", name);
}
else
{
//puts("Whoops! Looks like highest/lowest have not been adjusted!");
printf(" Round %d score: %d/100\n", rounds, g); //display round score
printf(" Highest score: %d/100\n", highest);
printf(" Lowest score: %d/100\n", lowest);
printf(" Average score: %f\n", avg);
printf(" ******Player: %s ******\n", name);
}
unsure = true;
//getchar();
}
else if (choice == 'P' || choice == 'p')
{
g = 0;
for (i = 0; i < MAX_TESTS; i++)
{
g += test[i].grade; //add score of each question
}
allScore += g; //add current round's score to total
if (g > highest)
{
highest = g;
}
if (g < lowest)
{
lowest = g;
}
}
else
{
puts(" Invalid input!");
unsure = true;
}
}
if (done)
break;
}
}

Why is 'Round 1' shown as 'Round 0'?
The value of variable rounds is printed as the round number. If the round number always prints as 0 then it follows that rounds always has value zero at the point where that printf() call is made. And indeed, a look at all the appearances of that variable in your code shows that it is initialized to zero in its declaration, and then never modified.
And what does the 'inf' mean in
the average score section?
It means "infinity", and before even looking at your code, I would take it as a sign that you have somewhere used the result of dividing a non-zero floating-point number by zero.
In particular, the problem seems to be the same one as the previous: you use rounds as the divisor in your average score computation, and it is always zero.
How do I turn 'inf' into a numerical
output?
Change the faulty computation into a correct one. Properly maintaining the value of the rounds variable may be enough.
After 2 rounds, the output 'Round 2' is still shown as 'Round
0' and the 'Average score' did not change to a numerical output.
That's consistent with my observations above.

Related

C - Comparing a float to an array to see if the value is in the array

I have a program where I need to take a value and compare it to 12 values in an array. If this value lies within the array, I need to return a true value to the main function so that it prints something if this true value is returned. I can post some of my code, but I am confused on how to return this true value.
void resistor (void) // Function to input resistor and capacitor values
{
float ra, rb, c; // Float variables for two resistor values and capacitor
while(1) // While loop to gather resistor A value
{
printf("Enter a value for Resistor Ra (kOhms): "); // First Resistor Value
scanf("%f", &ra);
if(ra < 1 || ra > 100) // Will repeat loop until value between 1 and 100
is entered
printf("Invalid selection, choose again.\n");
else
{
break; // breaks loop when valid data is entered
}
}
while(1) // while loop to gather Resistor B value
{
printf("Enter a value for Resistor Rb (kOhms): "); // Second Resistor Value
scanf("%f", &rb);
if(rb < 1 || rb > 100) // Will repeat loop until value between 1 and 100
is entered
printf("Invalid selection, choose again.\n");
else
{
break; // breaks loop when valid data is entered
}
}
while(1)
{
printf("\nCapacitor (uF) : "); // Capacitor Value
scanf("%f", &c);
if(c <= 0) // Repeats loop until a value greater than 0 is entered
{
printf("Invalid selection, choose again.\n");
}
else
{
float freq = calc_freq(ra, rb, c); // call function to calculate frequency
float duty_cycle = calc_duty_cycle(ra, rb, c); // call function to calculate duty cycle
printf("\nFrequency is: %.2f kHz\n", freq); // print frequency
printf("Duty cycle is: %.2f percent\n\n", duty_cycle * 100); // print duty cycle
checkstdval(ra, rb);
if{
raa = 1;
printf("Resistor A is not")
}
break;
}
}
main(); // Returns to beginning of program following calculations
}
bool checkstdval (float ra, float rb)
{
int i; // variable used to initilize array
bool raa, rbb;
// Array of standard values for resistors
int stdv[12] = {10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82};
while(1)
{
while (ra <10)
ra *= 10;
while (ra >= 100)
ra /= 10;
i = 0;
for(i<12; i++ ;)
if ((ra - stdv[i]) < 0.01)
return raa = 1;
else
{
return raa = 0;
break;
}
}
while(1)
{
while (rb <10)
rb *= 10;
while (rb >= 100)
rb /= 10;
i = 0;
for(i<12; i++ ;)
if ((rb - stdv[i]) < 0.01)
return rbb = 1;
else
{
return rbb = 0;
break;
}
}
}
Comparing floats is a topic in itself. A solution is in https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/ where the Qt function qFuzzyCompare is used and comparing of floats is analyzed deeper

I want a counter to add each time matrix[yVal][xVal] == 5

I have the following code:
do{
int health = 3;
int xVal;
int yVal;
printf("Enter an x value from 0 to 9\n");
scanf("%d", &xVal);
printf("You entered '%d'\n",xVal);
printf("Enter a y value from 0 to 9\n");
scanf("%d", &yVal );
printf("You entered '%d'\n",yVal);
printf("Value at '%d', '%d' is '%d'\n", yVal , xVal, matrix[yVal][xVal]);
if ( matrix[yVal][xVal] == 5 )
{
health = health - 1;
printf("Ouch... You have found a 5 and lost a point\n If you lose %d more, you will lose.\n", health);
}
if (health == 0)
{
isGameOver = true;
printf("You have lost.\n");
}
if ( matrix[yVal][xVal] == 9 )
{
isGameOver = true;
printf("You have won.\n");
}
} while(isGameOver != true);
The problem comes each time I find a five in the array, it only subtracts from the health counter once.
If I find 2 fives, it will stay as a 2 rather than counting down to one, the whole point of my game is that if you find 3 "5"s, you lose.
The problem is you are declaring health = 3 inside the loop, so each time it loops it resets it to 3. Move it to before the loop (ie before the "do" statement)

Can't Print " * " in C

for some reason I am unable to print out "* " in my program. I want to print out * if the condition is met. the condition is if the rainfall that day is greater than the average.
under the mean column, i am getting weird symbols. i tried debugging to decimals and get -112 for ascii. i dont understand but i tried researching!
I am new to C so please be understanding. Just learned like 2 days ago!!.
Here is my code :
//Assignment one 9/20/2018
//Anthony Lomaistro and David Luong
//luongd5#student.lasalle.edu
//lomaistroa1#student.lasalle.edu
#include <stdio.h>
main() {
int n = 0; //counters for the loops
int x = 0; // counter for the loops
int counter = 0; // counter whenever i need to keep track of increments
int days_input = 0; // how many days we are keeping track of
int number_of_days = 0;
double rainfall_input = 0;
double rainfall_amount = 0; // how much rainfall per day
double rainfall_average = 0; // average of rainfall
double rainfall_total = 0;
double rainfall_counter = 0; // count how many days it rained above the average
int correct = 0;
double rainfall_array[50];//array that contains the user input
char rainfall_condition[50]; // array that contains the *
double sum = 0;
double average = 0;
double percent_days = 0; //rainfall % above average
double valid = 0;
double valid2 = 0;
printf("Welcome to Lomaistro and Luong's Rainfall Program \n");
printf("How many days would you like to keep track of? Please enter a value between 1 and 50: #%d:", n + 1);
//printf(number_of_days);
while (valid == 0) {
scanf_s("%d", &number_of_days);
if ((number_of_days > 50) || (number_of_days <= 0)) { // come back to this, this doesnt do anytihng
printf("Invalid value, please enter in a day that is between 1 and 50 \n");
}
else {
valid = 1;
}
}
//getting the user to enter in the rainfall
for (x = 0; x < number_of_days; x = x + 1) {
valid2 = 0;
while (valid2 == 0) {
printf("Enter rainfall (in inches): ");
scanf_s("%lf", &rainfall_amount);
if ((rainfall_amount >= 0) && (rainfall_amount <= 10)) {
valid2 = 1;
rainfall_array[x] = rainfall_amount;
}
else
printf("Please enter in a valid rainfall amount between 1 and 10");
}
}
//computing average
for (n = 0; n < number_of_days; n = n + 1) {
sum += rainfall_array[n];
average = sum / number_of_days;
}
printf("Mean daily rainfall(in inches): %lf", average);
//seeing if the * should be the array or not
for (n = 0; n < number_of_days; n = n + 1) {
if (rainfall_array[n] > average) {
rainfall_condition[n] = "*";
rainfall_counter = rainfall_counter + 1;
}
else
rainfall_condition[n] = "empty";
}
// print out the thing
printf("\n Days \t Amount \t >Mean \n");
printf("==============================\n");
for (n = 0; n < number_of_days; n = n + 1) {
printf("%d \t %f \t %c \n", n + 1, rainfall_array[n], rainfall_condition[n]);
}
percent_days = rainfall_counter / number_of_days;
percent_days = percent_days * 100;
printf("Number of days that rained above average : %f \n", rainfall_counter);
printf("Percentage of days that rained above average: %f%% \n", percent_days);
system("pause");
}
rainfall_condition is an array of char, but you're putting a pointer to a string literal in there when you use "*". Use '*' for a character literal instead. To be more specific, this line:
rainfall_condition[n] = "*";
Should be:
rainfall_condition[n] = '*';
Turn some warnings on in your compiler; the first line (what you have now) isn't valid C code and you should be seeing a diagnostic message to that effect.
Edit: now that I've read more of the code, it appears you want either a * or an empty in that column? In that case you want to change the variable declaration to:
char *rainfall_condition[50]; // array that contains the *
And then change the print statement to:
printf("%d \t %f \t %s \n", n + 1, rainfall_array[n], rainfall_condition[n]);

Function Help on Dice Game

I have a new problem. I got most of the things fixed. I need my (turnAgain) function fixed. I specifically need to fix my if else statement. I need it to let the player continue rolling if they type in 'r'. else if they type 'h' the other player gets to roll. And I need it to say try again type 'r' or 'h' if they type in something that is is not 'r' or 'h'. I just dont know how to do that. New to coding thanks!! I REALLY NEEEEEEEEEEEEEEEEEEEEEEED HELP.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#define SIDES 6
typedef enum {doublesPoints, onesPoints, noPoints, singlesPoints} status;
void prnRules(void)
// function: prnRules
// pre: none
// post: prints the rules
{
printf("%s\n",
"The goal is to be the first player to reach 50 points.\n\n"
"On a turn, a player rolls the two dice repeatedly until either a 1 is rolled \n"
"or the player chooses to hold and stop rolling.\n\n"
"If a 1 is rolled, that player's turn ends and no points are earned for the round.\n"
"If the player chooses to hold, all of the points rolled during that round are added to their score.\n\n"
"If a player rolls double 1s, that counts as 25 points.\n"
"Other doubles are worth 2x double points, so that a 2-2 is worth 8 points; 3-3 is worth 12; \n"
"4-4 is worth 16; 5-5 is worth 20; and 6-6 is worth 24.\n\n"
"When a player reaches a total of 50 or more points, the game ends and that player is the winner.\n");
}
int rollDie ()
// function: rollDie
// pre: none
// post: generates a random number for the die
{
int d;
d = rand() % SIDES + 1;
return d;
}
status turnPoints(int die1, int die2)
// function: turnStatus
// pre: dice have been rolled
// post: returns the status of the roll (doublesPoints, onesPoints, no Points, singlesPoints)
{
if (die1 == die2 && !(die1 == 1 && die2 == 1))
return doublesPoints;
else if (die1 == 1 && die2 == 1)
return onesPoints;
else if ((die1 == 1 || die2 == 1) && !(die1 == 1 && die2 == 1))
return noPoints;
else
return singlesPoints;
}
void turnAgain(int status)
{
char rollDie;
do
{
printf("Would you like to roll again or hold(r/h)?");
scanf("%c",&rollDie);
} while(rollDie!='r'&&rollDie!='h');
if(rollDie=='r')
{
}
else
{
}
//to switch the current player when the turn is over
int switchPlayer(int currentPlayer)
{
if (currentPlayer == 1)
return 2;
else
return 1;
}
char gameAgain()
// function: gameAgain
// pre: none
// post: returns a valid (y or n) answer
{
char ans;
do
{
printf("Play another game (y or n)? ");
ans = getchar();
getchar();
}while (ans != 'y' && ans != 'n');
return ans;
}
int gameOver (int p1Total, int p2Total)
// function: gameOver
// pre: none
// post: returns a '1' if either total exceeds 50
{
if (p1Total || p2Total >= 50)
{
return 1;
}
else
{
return 0;
}
}
//The final print statement with all the totals
void finalOutput(int p1Total, int p2Total)
// function: finalOutput
// pre: gameOver returns a '1'
// post: returns the final scores of the game
{
printf("\n");
printf("WE HAVE A WINNER!!!\n");
printf("Player 1 your final score was %d\n", p1Total);
printf("Player 2 your final score was %d\n", p2Total);
}
int updatePlayerTotal(int currentPlayer, int turnTotal, int playerTotal)
// function: pudatePlayerTotal
// pre: none
// post: returns the player total
{
printf("Player %d, your total at the start of this turn was %d .\n",
currentPlayer, playerTotal);
playerTotal = playerTotal + turnTotal;
printf("Your total at the end of this turn is %d.\n\n", playerTotal);
return playerTotal;
}
int main (void)
{//begin main
// variable declarations
int sum; // for sum of two dice
char answer; // for yes/no questions
int tempTotal = 0; // temporary player total for the round
int p1Total = 0; // running total for player 1
int p2Total = 0; // running total for player 2
int total = 0; // player total after each round
int die1 = 0; // the roll value of die1
int die2 = 0; // the roll value of die2
int currentPlayer = 1; // start with Player 1
int status = 0; // status for choice to continue
srand(time(NULL)); // seed random # generator
do // play at least one game
{//Begin game loop
//give option to view the rules
printf("Welcome to the game of Fifty. Would you like to view the rules? (y or n)?\n");
answer = getchar();
getchar();
if (answer == 'y')
prnRules();
do // until game is won
{//Begin roll loop1
{ //Begin roll loop2
die1 = rollDie();
die2 = rollDie();
sum = (die1 + die2);
printf("Player %d:\n", currentPlayer);
printf("Die 1 is a %d.\n", die1);
printf("Die 2 is a %d.\n", die2);
//award points (rolled a double but not double 1's)
if (turnPoints(die1, die2) == doublesPoints)
{
printf(" Player %d, you rolled a double %d!\n ", currentPlayer, die1);
printf(" That's worth %d points.\n", (sum * 2));
tempTotal = (tempTotal + total + (sum * 2));
status = 1;
}
//award points (rolled double 1's)
else if (turnPoints(die1, die2) == onesPoints)
{
printf(" Player %d, You rolled a double 1!\n ", currentPlayer);
printf(" That's worth 25 points.\n");
tempTotal = (tempTotal + total + 25);
status = 1;
}
//award no points (one of the two dice = 1)
else if (turnPoints(die1, die2) == noPoints)
{
printf("Sorry Player %d, you rolled a single 1. You do not earn any points this round\n", currentPlayer);
printf("Your current total is %d\n", total);
tempTotal = 0;
total = total + tempTotal;
status = 0;
}
//award points (rolled singles)
else if (turnPoints(die1, die2) == singlesPoints)
{
printf("Player %d, your roll totals %d points.\n", currentPlayer, sum);
tempTotal = tempTotal + (total + sum);
status = 1;
}
}while (status == 1 && (turnAgain(status) == 'y'));//end roll loop2 - while player continues roll
if (turnAgain(status) == 'n')//(answer == 'n')
{
total = (tempTotal + total);
if (currentPlayer == 1)
{
p1Total = updatePlayerTotal(currentPlayer, tempTotal, p1Total);
}
else
{
p2Total = updatePlayerTotal(currentPlayer, tempTotal, p2Total);
}
//switch players
currentPlayer = switchPlayer(currentPlayer);
}
}while (gameOver(p1Total, p2Total) != 1); //end loop1 - continue while game is not over
answer = gameAgain();
}while (answer != 'n'); //end game loop - loop while wanting to play again
return 0;
}//end main
int rollDie ()
// function: rollDie
// pre: none
// post: generates a random number for the die
{
int d;
d = rand() % SIDES + 1;
return d;
}
...
int turnAgain(int status)
---> you forget the left brace {
char rollDie; // Conflict, rollDie redeclared
Compile with warnings:
die1 = rollDie();
^
demo.c:60:10: note: declared here
char rollDie;

Using local variables out of loop scope

I've got a function to calculate the total value of any given cards, it stores the sum of all current cards into score.
It also counts the number of aces in the deck.
I'm having trouble linking the value of ace and score after the loop.
I've implemented print statements in my actual file, it calculates correctly, but score and ace are obviously filled with random numbers after the for loop.
I don't know how to use those values outside of the for loop.
void calculateScore(Player * current_player)
{
int i, ace;
unsigned score;
ace = 0;
score = 0;
for (i=0; i<current_player->curnumcards; i++){
if (current_player->hand[i].c_face == 0){
ace++;
} else if (current_player->hand[i].c_face == 10){
score += 10;
} else if (current_player->hand[i].c_face == 11){
score += 10;
} else if (current_player->hand[i].c_face == 12){
score += 10;
} else {
score += ++current_player->hand[i].c_face;
}//end if to check ace/jack/queen/king
}//end for loop
if (ace>0){
for (;ace!=1;ace--){
if (score>11){
score += 1;
} else {
score += 11;
}//end if > 10 ace
}//end for loop to calculate ace's
}// end if ace loop
printf("Current score: %d\n", &score);
}
you should printf("Current score %u\n", score); You are printing the memory address &score, where you just want score. And it's unsigned so %u not %i.
ace, score = 0;
Takes the value of ace, does nothing with it, and assigns 0 to score. You probably want to assign 0 to both:
ace = score = 0;

Resources