Thread: Selecting 1 struct out of 2

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    6

    Question Selecting 1 struct out of 2

    Hi All,

    I have been working on a program well game in C. It is basically top trumps. I decided to build this as i thought it would help me understand different parts of programming in C. So far it has help me learn a lot.

    But now i have a small problem. I want to have the game give me the option of selecting a deck to use. The first deck was build using a struct in a header file.

    I am a little confused as i wanted to use the same set-up for a second deck but well
    i will post what i have and you can comment on it.

    I was thinking i should have a second header file for the second deck but that didnt seem to work out so though i would keep it all in a single header file. But then i could not figure out how to get it to choose a deck.

    this is the header file.

    Code:
    struct football_str
    {
    	char name[20];
    	int passing, teamwork, influence, skill, shooting;	//5 stats per player
    };
    
    struct tryanid_str
    	{
    	char name[30];
    	int Weapon_Skill, Balistic_Skill, Strenght, Thoughness, Woonds, Initative, Attacks, leadership, Save;
    	};
    This is the main program.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <conio.h>
    #include "footballhead.h"
    
    
    
    int new_game(struct football_str *card, int, int);
    void settings_menu(struct football_str *card);
    void online(void);
    void Main_Menu(struct football_str *card);
    void FF(void);
    void press_space(void);
    void shuffle_cards(struct football_str *card);
    void list_cards(struct football_str *card);
    
    char name[30];
    int target = 5; // needed to take in the new target score for each game default can be set here currenly set to 5
    
    int main (void)
    {
    	struct football_str card[52];
    	int temp;
    
    	FILE *infp;
    
    	char look[50];
    
    	infp = fopen("footystats.db", "rb+");
    	if (infp == NULL)
    	{
    		printf("Problem Opening File \n");
    		getchar();
    		return 10;
    	}
    	fread(&temp, sizeof(int), 1, infp);
    	//printf("You should have %d cards\n", temp);
    	fread(card, sizeof(struct football_str), 52, infp);
    	fclose(infp);
    
    	printf("\n\tWELCOME TO TOP TRUMPS\n");
    	printf("\n\tPlease Enter Your Name: ");
    	scanf("%s", &name);
    	//printf("\n\tEnter a Target score: ");
    	//scanf("%d", &target); // take the new target score and applies it to the new game
    	Main_Menu(card);
    	return (0);
    	}
    
    int new_game(struct football_str *card, int score, int target)
    	{
    	int c, i, result, scorea=0, scoreb=0; // scorea, scoreb, are for the 2 players so we can get to the target
    	char key, look[50];
    	
    	shuffle_cards(card);
    
    	do
    		{
    		for ( c = 0; c < 3; ++c)
    			{
    			system("cls");
    			printf("***********************************\n\n");
    			printf("	    %s \n\n", card[c].name); // removed player: to just show the player name also known as card:
    			printf("***********************************\n\n");
    			printf("1. Passing:\t		%d\n", card[c].passing);
    			printf("2. Teamwork:\t		%d\n", card[c].teamwork);
    			printf("3. Influence:\t		%d\n", card[c].influence);
    			printf("4. Skill:\t		%d\n", card[c].skill);
    			printf("5. Shooting:\t		%d\n\n", card[c].shooting);
    			printf("***********************************\n");
    
    			printf("Selects a statistic [1-5] or Q to Quit to Main Menu:\n\n\n");
    			printf("Your current score = %d,\n\n", scorea); //will always show you YOUR current score.
    			FF();
    			do
    				key = tolower(getchar());
    			while (key < '0' || key > '5');
    
    			switch (key)
    				{
    				//compare my card [c] with the other half of the deck [c+26]
    				case '1':
    				result = (card[c].passing > card[c+26].passing);
    				break;
    								
    				case '2':
    					result = (card[c].teamwork > card[c+26].teamwork);
    				break;
    				
    				case '3':
    					result = (card[c].influence > card[c+26].influence);
    				break;
    
    				case '4':
    					result = (card[c].skill > card[c+26].skill);
    				break;
    
    				case '5':
    					result = (card[c].shooting > card[c+26].shooting);
    				break;
    
    				case 'q':
    					Main_Menu(card);
    				break;
    
    				}
    
    			if (result)
    				{
    				system("cls");
    				printf("\n\n You win!\n\n");
    				++scorea, --scoreb; // counting the win losses for player and CPU 
    				}
    			else
    				{
    				system("cls");
    				printf("\n\n You Loose!\n\n");
    				--scorea, ++scoreb; // counting the win losses for player and CPU
    				}
    			// scorea = player scoreb = cpu IF ether gets the target number it will out put it as score
    			// The score will always be POSITIVE so if CPU reaches target (5) you loose if player 
    			//reaches target (5) you win.
    			if (scorea > scoreb)
    				{
    				score = scorea;
    				}
    			else
    				{
    				score = scoreb;
    				}
    			// the above was added to output the score for the target argument.
    				if (score >= target)				
    				break;
    				press_space();
    			}
    
    		}while (score < target);
    
    	system("cls");
    	printf("\n\n\n\n\n");
    	printf("\n\t\t\t%s vs CPU scored %d\n\n", name, score);
    	// This will return a win loose result if ether CPU or player reaches the target
    	if (scorea > scoreb)
    		{
    		printf("\t\t\t YOU WIN!\n\n");
    		}
    	else
    		{
    		printf("\t\t\t YOU Lost!\n\n");
    		}
    	printf("\t\t\t GAME OVER!\n");
    
    	FF();
    	getchar();
    	return score;
    	}
    void settings_menu(struct football_str *card)
    {
    	char key;
    do
    	{
    		system("cls");
    		printf("\tTOP TRUMPS - Settings\n");
    		printf("\n\n");
    		printf("\t1. (A)udio\n");
    		printf("\t2. (D)eck\n");
    		printf("\t3. Edit(P)layer Name\n");
    		printf("\t4. Set (T)arget Score\n");
    		printf("\n\tSelect 1-4 And Press Enter Or X Go Back To Main Menu. \n\n");
    
    		FF();
    		key = tolower(getchar());
    		FF();
    		printf(" \n");
    		
    		switch (key)
    		{
    		case '1': case 'a':
    			printf("Sound Adjustment");
    			getch();
    			break;
    
    		case '2': case 'd':
    			printf("Please Choose Deck");
    			break;
    
    		case '3': case 'p':
    			printf("\tEnter Your Name:");
    			scanf("%s", &name);
    			printf("\tSuccessfull Name Change");
    			press_space();
    			break;
    
    		case '4': case 't':
    			printf("\n\tEnter a Target Score: \n");
    			scanf("%d", &target);
    			printf("\tSuccessfull Changed Target Score\n");
    			printf("\tThe new target score is: %d \n", target);
    			press_space();
    			break;
    
    		case 'x': 
    			Main_Menu(card);
    			break;
    			
    		default:
    			printf(" %c Is Not A Recognised Option! \n", key);
    			press_space();			
    		}
    	} while (key != 'x');
    	return 0;
    }
    void online(struct football_str *card)
    {
    	char key;
    do
    	{
    		system("cls");
    		printf("\tTOP TRUMPS - Online\n");
    		printf("\n\n");
    		printf("\t1. (M)ultiplayer\n");
    		printf("\t2. (P)arty Mode\n");
    		printf("\t3. (S)earch Internet\n");
    		printf("\n\tSelect 1-3 And Press Enter Or X Go Back To Main Menu. \n\n");
    
    		FF();
    		key = tolower(getchar());
    		printf(" \n\n");
    		
    		switch (key)
    		{
    		case '1': case 'm': case 'M':
    			printf("Entering Multiplayer Mode");
    			getch();
    			break;
    
    		case '2': case 'p': case 'P':
    			printf("Online Party Mode");
    			getch();
    			break;
    
    		case '3': case 's': case 'S':
    			printf("You Are Now Connecting To The Internet");
    			getch();
    			break;
    
    		case 'x': 
    			Main_Menu(card);
    			break;
    			
    		default:
    			printf(" %c Is Not A Recognised Option! \n", key);
    			press_space();			
    		}
    	} while (key != 'x');
    	return 0;
    }
    void Main_Menu(struct football_str *card)
    {
    	char key;
    	int c, score = 0;
    	do
    	{
    		system("cls");
    		printf("\tTOP TRUMPS - Main Menu\n");
    		printf("\n\n");
    		printf("\t1. (N)ew Game\n");
    		printf("\t2. (S)ettings\n");
    		printf("\t3. (O)nline\n");
    		printf("\t4. (R)andom shuffle\n");
    		printf("\t5. (L)ist Cards\n");
    		printf("\n\tSelect 1-5 And Press Enter Or X To Exit Top Trumps. \n\n");
    
    		FF();
    		key = tolower(getchar());
    		FF();
    		printf(" \n\n");
    		
    		switch (key)
    		{
    		case '1': case 'n':
    			score = new_game(card, 0, target); // new target replaced a set number so each game can have a diffrent score set eact time the game is played
    			break;
    
    		case '2': case 's':
    			settings_menu(card);
    			break;
    
    		case '3': case 'o':
    			online(card);
    			break;
    
    		case '4': case 'r':
    			shuffle_cards(card);
    			break;
    
    		case '5': case 'l':
    			list_cards(card);
    			break;
    		case 'x': 
    			printf("Quitting program!\n");
    			exit(0);
    			break;
    			
    		default:
    			printf(" %c Is Not A Recognised Option! \n", key);
    			press_space();
    		}
    		
    	} while (key != 'x');
    	return 0;
    }
    void FF(void)
    {
    	fflush(stdin);	
    }
    void press_space(void)
    {
    	printf("\n\tPress SPACE to continue...\n\n");
    	while (getch() != ' ')
    		;
    }
    
    void shuffle_cards(struct football_str *card)
    {
    	int f1, f2, c;
    	struct football_str tmp;
    
    	for (c = 0; c < 50; ++c)
    	{
    	f1 = rand() %52;
    	f2 = rand() %52;
    
    	tmp = card[f1];
    	card[f1] = card[f2];
    	card[f2] = tmp;
    	}
    }
    
    void list_cards(struct football_str *card)
    {
    	int c;
    
    	for (c = 0; c < 52; c++)
    		printf("Card %d: name: %s shooting : %d\n", c, card[c].name, card[c].shooting);
    
    	press_space();
    }

  2. #2
    Registered User
    Join Date
    Feb 2011
    Posts
    6
    just a though i had.

    Am i going to need to make a new function that the program will have to call to in order to find out what struct to use and what file to use for the deck?


    if so then what would i need to change this to?

    int new_game(struct football_str *card, int, int);

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I'm not sure exactly what you are trying to do.
    Code:
    struct footballstats {
        int which;
        union {
            struct firststruct f;
            struct secondstruct s;
        } stats;
    };
    But you may want to consider using a union, if you are trying to do what I think you are trying to do.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    Feb 2011
    Posts
    6
    a union? we have not been shown this on our course as of yet.

    Basically i want to have 2 deck of playing cards
    but only one usable at any given time.

    so one would have deck a and deck b
    and get asked what deck they wish to play with.

    i am just unsure how to get the call to work for what deck to use.
    i think i would have to change a lot of the programming to remove the
    bit in bold but dont know how to call to the struct that it needs for the correct deck

    int new_game(struct football_str *card, int, int);

    the footballer stats struct is just for one deck the second deck is tyranid stats.
    2 very different setups
    Last edited by yrthilian; 04-28-2011 at 04:40 AM.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by yrthilian View Post
    Basically i want to have 2 deck of playing cards
    but only one usable at any given time.

    so one would have deck a and deck b
    and get asked what deck they wish to play with.
    That's the part I'm not clear about. What is a card? Just a regular playing card here? So what's the difference between deck1 and deck2? If it's just two instances of the same structure, then that's easy, you just pass whatever one you decide to use. If it's completely different structures - like say Uno cards vs Pinocle cards - then unless you feel like playing with void pointers, or having entirely different functions to deal with each one, then you are going to probably want a union to make this easy.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Feb 2011
    Posts
    6
    yes they are 2 very different cards.

    one deck has footballer and stats relating to them 5
    the other is from another game but the stats bar is 9 long

    Both decks are not compatible with each other.
    I don't know if you heard of the game called top trumps it is a game i used to play when i was a kid.
    i chose it as my project because i knew it would be difficult and would teach me a lot.

    I have it working almost 100% with the single deck. I just added the complexity of wanting to choose between one deck or the other.

    Code:
    struct footballstats {
        int which;
        union {
            struct firststruct f;
            struct secondstruct s;
        } stats;
    };
    in the case of the union code you provided would it then make sense for me to make a new function?
    whit the slight change to the struct name to keep from confusion
    Code:
    struct deckstats {
        int which;
        union {
            struct footballtruct f;
            struct tyranidtruct s;
        } stats;
    };

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I did not go thru your code much, but based on what you are saying, it seems to me that the structs have some common elements and some dissimilar elements. I don't think a union is the way to go here unless the structs have an identical layout, only with different identifiers, which seems sort of pointless.

    You can stick with the three structs, just instead of a union, you have two pointers:

    Code:
    struct deckstats {
        int which;
        struct football *f;
        struct tyranid *s;
    };
    I'm presuming the "which" is to indicate which deck is being used in a particular instance. You can do that, or you could just set the unused pointer NULL. Eg, to play tyranid:

    Code:
    struct deckstates eg;
    eg.football = NULL;
    eg.tyranid = malloc(sizeof(struct tryanid));
    [...populate, etc...]
    
    // say we pass this into a function:
    
    void somefunction (struct deckstats *deck) {
              if (deck->tyranid) {
                       // tyranid specific code
              else {
                      // football specific code
              }
    }
    Make sense? You can actually keep the same deck struct and switch games by free()ing one pointer, setting it NULL, and allocating the other.

    Code:
    void switchGame (struct deckstats *deck) {
        if (deck->tyranid) {
            free(deck->tryanid);
            deck->tryanid = NULL;
            deck->football = malloc(sizeof(struct football));
        } else {
            // same thing the other way around
        }
    }
    Last edited by MK27; 04-28-2011 at 05:45 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by MK27 View Post
    I don't think a union is the way to go here unless the structs have an identical layout, only with different identifiers, which seems sort of pointless.

    You can stick with the three structs, just instead of a union, you have two pointers:
    You don't need to have the same items in the same order to get a union working, because you don't need both decks at the same time, you only ever need one, which is why I didn't use pointers. That's the whole point of a union, to use the same block of memory for two different things. Not that there is anything wrong with using pointers, that could work too . But if all he needs is one deck at a time; never both at the same time, then a union is just fine, and the order of the items makes no difference.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. confused.. in selecting my line of deapth
    By jawwadalam in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 05-04-2003, 01:21 PM
  2. selecting input from a floppy
    By neilman88 in forum C++ Programming
    Replies: 1
    Last Post: 04-17-2003, 02:26 PM
  3. Question about list (struct {..struct *next}
    By jmzl666 in forum C Programming
    Replies: 1
    Last Post: 10-23-2002, 01:34 AM
  4. A simple question about selecting elements in an array
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 08-30-2001, 10:37 PM
  5. Selecting things on the canvas
    By Barjor in forum Windows Programming
    Replies: 0
    Last Post: 08-30-2001, 02:10 PM