# Thread: High Low Game with High Scores

1. How did you manage to write this:
Code:
for(incr=MAX2 -1;incr >set_pt;incr--)  //this for loop will make room in the array for the new data insertion
{
local[incr] = local[incr-1];
local[incr].score=local[incr-1].score;
strcpy(local[incr].name,local[incr-1].name);
}
and yet you can't figure out how to copy a plain old struct into one spot in your array? Did you not see the amazing similarity between that bit of code and what you are trying to write? If you don't understand what you did there, I have to ask: did you even write this code?

2. The professor provides us with examples which we can incorporate into our projects. We're supposed to incorporate the code and then figure out how it works.

3. Originally Posted by Bradley Buck
The professor provides us with examples which we can incorporate into our projects. We're supposed to incorporate the code and then figure out how it works.
Your professor is providing Scoop and Poop code for you to use?

I hope the course isn't actually training programmers. By the time you hit the real world you're gonna be so screwed. The real programming challenge you take on, you're going to discover how little you actually learned about C programming.

To learn coding skills you have to actually WRITE code...

4. Well, I generally try to read his code first and then write my own based on it, but I was in a hurry this time so I though I could just copy it in and figure it out as I went along, but I don't think I properly understand what it's doing.

5. If someone knows a good tutorial on copying into arrays that might help.

6. Originally Posted by Bradley Buck
If someone knows a good tutorial on copying into arrays that might help.
I don't know what such a tutorial might contain other than "Use =". On the right side of the equal sign: the thing you want to store. On the left side of the equal sign: the place you want to store it (which is going to be one particular slot in your array -- or in your case, since each element of your array is a struct, a field of one particular slot in your array). The only thing to remember is that since a string is not a single thing, you have to use strcpy instead of =.

And remember the bit pointed out above: "local[incr].score". You have to pick an array slot first, then choose a field from that struct.

7. This is what I have now:

Code:
for(incr=MAX2 -1;incr >set_pt;incr--)  //this for loop will make room in the array for the new data insertion
{
player[incr] = player[incr-1];
player[incr].score=player[incr-1].score;
strcpy(player[incr].name,player[incr-1].name);
top_scores[incr] = top_scores[incr-1];
top_scores[incr].score = top_scores[incr-1].score;
strcpy(top_scores[incr].name,top_scores[incr-1].name);
}
When I run it it returns this:

Code:
Element #0 is:╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠♦         4
Element #1 is:                          init         0
Element #2 is:                          init         0
Element #3 is:                          init         0
Element #4 is:                          init         0
Element #5 is:                          init         0
Element #6 is:                          init         0
Element #7 is:                          init         0
Element #8 is:                          init         0
Element #9 is:                          init         0

Press any key
For some reason the name is showing up as gibberish.

9. Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>

#define MAX 5
#define MAX2 10

struct player
{
char name[30];
int score;
};
void init_array(struct player *top_scores);
char* new_player(void);
void print_array(struct player *top_scores);
int setpt(struct player *player,struct player *top_scores, int Gnd_it);
void save_array(struct player *player,int size);
char make_choice();
void count_change();
int guess_number(struct player *player, struct player *top_scores, char gn[30]);
void printsummary(int ct, int Gnt, int t);

int main(void)
{
int Gn_Total= 0;
int Gn_Tries=0;
int	CC_Total= 0;
int tries= 0;
char choice;
char Gnd_name[30];

struct player top_scores[MAX2];
struct player player[MAX2];
print_array(top_scores);
new_player();

do
{
choice = make_choice();
switch(choice)
{
case 'A':
count_change();
CC_Total++;
break;
case 'B':
Gn_Tries += guess_number(player, top_scores, Gnd_name);
Gn_Total++;

break;
case 'C':
printsummary(CC_Total, Gn_Total, Gn_Tries);
break;
case 'N':
new_player();
break;
case 'S':
print_array(top_scores);
break;
}
}while(choice != 'Q');

save_array(top_scores,sizeof(top_scores));
return 0;
}

void init_array(struct player *player)
{
int cur_row;
for(cur_row=0;cur_row<MAX2;cur_row++)
{
player[cur_row].score=0;
strcpy(player[cur_row].name,"init");
}
}

void print_array(struct player *player)
{
int cur_row;
printf("\n");
for(cur_row=0;cur_row<MAX2;cur_row++)
{
printf("Element #%d is:%30s    %6d\n"
,cur_row,player[cur_row].name,player[cur_row].score);
}
printf("\n\nPress any key");
getch();
}

char* new_player(void)
{
char Gnd_name[30];
printf("\nEnter a name\n");
flushall();
gets(Gnd_name);
return Gnd_name;
}

int setpt(struct player *player, struct player *top_scores, int Gnd_it)
{
int set_pt,incr;

for(set_pt=0;set_pt < MAX2 && Gnd_it > player[set_pt].score
&& player[set_pt].score!=0;set_pt++); //this for loop will locate the row that the new data is to be inserted

for(incr=MAX2 -1;incr >set_pt;incr--)  //this for loop will make room in the array for the new data insertion
{
player[incr] = player[incr-1];
player[incr].score=player[incr-1].score;
strcpy(player[incr].name,player[incr-1].name);
top_scores[incr] = top_scores[incr-1];
top_scores[incr].score = top_scores[incr-1].score;
strcpy(top_scores[incr].name,top_scores[incr-1].name);
}
return set_pt;

}

void save_array(struct player *player,int size)
{
FILE *fptr;

if ((fptr = fopen("topten.dat","wb"))==NULL)
{
system("CLS");
printf("File write error...Press any key to terminate");
getch();
exit(0);
}
else
{
fwrite(player,size,1,fptr);
fclose(fptr);
}
}

{
FILE *fptr;

if ((fptr = fopen("topten.dat","rb"))==NULL)
{
system("CLS");
printf("File does not exists...initializing new array...Press any key to continue");
getch();
init_array(player);
}
else
{
fclose(fptr);
}
}

char make_choice()
{
char ch;
do{
ch = toupper(_getch());
}while (!strchr("ABCNSQ",ch));
return ch;
}

{
system("cls");

printf( "Please select one of these options. \n");
printf( "A. Change Count \n");
printf( "B. Play High / Low Game \n");
printf( "C. Print Summary \n");
printf( "N. Change Name \n");
printf( "S. High Scores \n");
printf( "Q. Quit Program \n");
}

void count_change()
{
int hd,
q,
d,
n,
p;
system("cls");
printf("You have chosen Change Count \n\nEnter number of half dollars: ");
scanf_s("%i", &hd);
printf("Enter number of quarters: ");
scanf_s("%i", &q);
printf("Enter number of dimes: ");
scanf_s("%i", &d);
printf("Enter number of nickles: ");
scanf_s("%i", &n);
printf("Enter number of pennies: ");
scanf_s("%i", &p);
int tc= hd+q+d+n+p;
double hd_v= hd*0.5,
q_v= q*0.25,
d_v= d*0.10,
n_v= n*0.05,
p_v= p*0.01;
printf("\nYou have entered %i half dollars: \$", hd);
printf("%.2f",hd * 0.5);
printf("\nYou have entered %i quarters: \$", q);
printf("%.2f", q * .25);
printf("\nYou have entered %i dimes: \$", d);
printf("%.2f", d * .10);
printf("\nYou have entered %i nickles: \$", n);
printf("%.2f", n * .05);
printf("\nYou have entered %i pennies: \$", p);
printf("%.2f", p * .01);
double tm= hd_v+q_v+d_v+n_v+p_v;
printf("\n\nYou have entered %i coins worth a total of %.2f", tc, tm);
_getch();
}

int guess_number(struct player *player, struct player *top_scores, char gn[30])
{
int magic,
guess,
Gnd_row=0,
cur_row,
tries=0;
char Gnd_name[30];
srand((unsigned)time(NULL));
magic = rand()%MAX;
system("cls");

printf("\n\nGuess the random number from 0 to %d\n\n",MAX);

do
{
printf("guess: ");
scanf_s("%d",&guess);
if(guess == magic)
{
printf("** Right **");
printf(" %d is the magic number\n", magic);
}
else
if (guess > magic)
printf(".. Wrong .. Too High\n");
else
printf(".. Wrong .. Too Low\n");
tries++;
}while (guess != magic);
Gnd_row=setpt(player, top_scores, tries);
player[Gnd_row].score=tries;
strcpy(player[Gnd_row].name, Gnd_name);
printf("%s", Gnd_name);
getch();
printf("You took %d tries.\n", tries);

getch();
return tries;
}

void printsummary(int ct, int Gnt, int t)
{
char* n = new_player();
system("cls");
printf("Hello %10s\n\n", n);
printf("You have counted change %d times\n", ct);
printf("You have played High / Low %d times\n", Gnt);
printf("Your average tries for High / Low are %.2f\n", (float) t/Gnt);
getch();
}

10. Wow. No offense, but your code is massively broken. You have a lot of fundamental issues to resolve, and I get the impression that you really don't understand C that well. You really need to back up, crack your textbook and pull out your class notes. Go through the tutorials we have here and Google for some more. Read everything carefully and do all the examples until you understand it. Functions, pointers, arrays and structs are probably the most relevant topics where you could use the most work.

The first problem I see: you're still using gets! Don't! It's a horrible function. Go back to my first post and click the red text for an explanation and alternative method.

In new_player, you try to return the address of a local stack variable, but once the function returns, that memory is no long valid. You have undefined behavior there, meaning it may work, or it may not, it may crash your program. Also, you never actually use the value you return, so it's totally pointless. Try something like:
Code:
void new_player(struct *player player)
{
print "Enter a name"
fgets player->name from stdin
trim the newline at the end of the name
}
Also, why is player an array? There's only one person playing at a time, so there's no need to make it an array. Just make a single variable and pass it into functions by address:
Code:
int main(void)
{
...
struct player player;
new_player(&player);  // & passes the struct by address, so when you read into it in new_player, the changes show up in main
...
guess_number(&player, top_scores);  // no need for a 3rd param here, you never use it anyhow
}

int guess_number(struct player *player, struct player top_scores)
{
...
player->score = tries;
setpt(player, top_scores);  // no &, we already have pointers; and no need for tries, it's part of the player struct
...
}
Your setpt function is not right, primarily because you try to tread player as an array. You have one player, and you copy that into the spot you freed up in your loop:
Code:
void setpt(struct player *player, struct player *top_scores)  // only need 2 params
{
// player is not an array, you need to compare the player against scores in the top_scores list
for(set_pt=0;set_pt < MAX2 && player->score > top_scores[set_pt].score && top_scores[set_pt].score!=0;set_pt++);

for(incr=MAX2 -1;incr >set_pt;incr--)  //this for loop will make room in the array for the new data insertion
{
// dropped the erroneous player array code
// dropped top_scores[incr] = top_scores[incr-1], since you aren't copying the individual parts
top_scores[incr].score = top_scores[incr-1].score;
strcpy(top_scores[incr].name,top_scores[incr-1].name);
}

copy score and name fields from player into top_scores[set_pt]  // this should look similar to the two lines in the above loop
// no need to return anything
}
Chew on that for a while, it should get you moving in the right direction.