> Should the interface to the program (menu, options, input, and what is printed > out) be *exactly* like it is in the example in the specification and on the > website? YES!! The specification tells you exactly what the interface should be. This is extremely important in any software development effort. If you get a job in software, you will be required to create systems that follow the exact specification that the design dictates. Also, few software systems outside of the academic environment will be small and contained enough for you to program by yourself. You will find that even working with one other person is sometimes difficult due to module interfacing problems. So, you need to follow interface guidelines (often designated by function prototypes) to the letter. Fortunately, you are afforded that opportunity in this project. If you're concerned about stifled creativity, excercise your ingenuity in the design and implementation of the underlying code. Create useful and efficient algorithms so that others will ooh and aah at your code. Of course, this practice should not be taken so far as to make your code esoteric or "clever" to the point of absurdity. -------------------------------------------------------------------------- > I'm a bit confused about the assignment, and how to get started. I think it's > the .h files that are throwing me off. > > I defined CARD_T and DECK_T in cards.h, and defined STATS_T in blackjack.c. > > So now, I need to list the function prototypes (play, init_stats, etc) in > blackjack.c....right? And since some of those functions take DECK_T or CARD_T > types as arguments, I need to #include cards.h in blackjack.c....right? Yes, everything is right up to here. > If that is right, where exactly do blackjack.h and cards.c come in? Functions in blackjack.c will call functions that are in cards.c. You will need to include cards.h in blackjack.c to get the function prototypes. blackjack.h needs to be included in cards.h to get the number of cards in a blackjack hand. -------------------------------------------------------------------------- > I guess I'm confused about the set_seed and shuffle > methods. The shuffle method uses a random number to swap > cards...so is that where we would use init_rand? If so, I > don't really understand how, since init_rand doesn't return > any value and neither does set_seed. > > Why can't we just say random_number= rand()%52 inside > shuffle to get an index number? The init_rand() function initializes the random number generator; therefore, you only need to call it once at the beginning of the program. If you didn't initialize the random number generator with a different value each time you started you program, you would probably start with the same cards each time and, if you made the same decisions, you'd play exactly the same set of hands. This behavior is not consistent across all systems, but you wouldn't want it to ever occur. So, you need to seed the random number generator with another semi-random value (the number of seconds after the hour in the code I made available) to make the game more interesting across program executions. To make the program easier to grade, the specifications call for an additional option to allow the user to enter a value to act as the seed. This will guarantee that the program will work in a predictable fashion for a given system. -------------------------------------------------------------------------- > So if I understand right, I just need to call init_rand(0) > in the beginning, then if the user wants to set the seed, > they can call set_seed and put in some value. And that > will "over ride" the original call to init_rand? Yes, that's right. -------------------------------------------------------------------------- > Is it ok to add a print_deck function into our program? > Can we leave it in there even when turning it in or will points > be counted off? I think it's a good idea to add a print_deck function -- it will help with debugging your program. You'll be able to leave the function in the program without a point deduction. -------------------------------------------------------------------------- > Can we use global variables in the program? No. Point deductions will be assessed for global variables. -------------------------------------------------------------------------- > Do we need to use fflush (stdin) for this program? No, you won't need to do this kind of I/O processing for this assignment. You can use all scanf()'s. As a matter of fact, the TA and I have decided that calling fflush(stdin) is not a good idea in general, so you should no longer use it in *any* of your programs. -------------------------------------------------------------------------- > What kind of style guidelines (commenting, code formatting, etc.) > should we use? There are style guidelines available off the lab homepage. Your program will be graded according to those standards. -------------------------------------------------------------------------- > I was trying to set the topdeck to point at the beginning of the array and > this was the logic that first came to mind but as you know is incorrect: > > deck->top->cards[0]; Almost, but keep in mind that you want to assign the top of the deck to the first card in the deck. That is, deck -> top = something The "something" is the address of the card in the first position of the deck. > Also, my shuffle works & used rand()%52 but I get the same random #'s all of > the time. Should I use the init_rand(seed) to obtain a random # in shuffle? Only now can you understand why the random number generator needs to be seeded. So, yes, call init_rand() with 0 and you'll get a different shuffle. Later, when you're testing other parts of the program, you won't want the shuffle to be so randomized. -------------------------------------------------------------------------- > Should we set the cards in the deck to 0 after we deal them? No, you should *not* set card values to 0 once they're used. That's what top is for -- it's a pointer to the current top card in the deck. Plus, things are going to go horribly wrong if you try to use this deck after shuffling for the next hand (which you are required to do). -------------------------------------------------------------------------- > Should I initialize the deck before each play session? No, you should only call init_cards only once at the very beginning of the program before any menu option is selected. -------------------------------------------------------------------------- > just want to make sure I'm doing the set_seed( ) right.... > so, we can copy your init_rand() function and call it in set_seed(), and > also at the beginning of main. is that right? Yes -- call init_rand() with the user-specified seed in set_seed(). Also, call init_rand() with 0 at the very beginning of main. -------------------------------------------------------------------------- > why can we not define STATS_T in blackjack.h? it would be nice to define > STATS_T in blackjack.h instead of in blackjack.c since I would like to list > function prototypes in blackjack.h. It's better to keep prototypes in .c files unless they need to be accessed by other .c files -- then they go in a .h file. Since neither STATS_T, nor the functions that use STATS_T in their parameter definitions, are called outside blackjack.c, it's better to keep them in blackjack.c. -------------------------------------------------------------------------- > What should happen when the top of the deck (pointer) reaches the end? > Should it be shuffled again or should the pointer just rest to the top of > the original deck? The top card pointer should never reach the end of the deck. It is reset to the first card in the deck every time a new hand is played. -------------------------------------------------------------------------- > How do you print a %? I've tried: > printf("Winning \%: %f", float_variable); > and I get the warning: dubious escape: \% Use double percent ("%%") inside the string to print out "%". -------------------------------------------------------------------------- > Do we need to initialize the cards in any specific order? Yes, initialize the cards in the following manner: 2 C 3 C ... 12 C 13 C 14 C 2 D 3 D ... 12 D 13 D 14 D 2 H 3 H ... 12 H 13 H 14 H 2 S 3 S ... 12 S 13 S 14 S That is, initialize each set of 13 cards by suit, where the four suits are in alphabetical order. -------------------------------------------------------------------------- > Do we need to sort cards in the the hand that have the same value by suit? Yes. If you have the hand: 3 H 3 D 3 C J H it should be sorted as 3 C 3 D 3 H J H Note the difference in the order of the 3's. -------------------------------------------------------------------------- > This may be dumb to ask, but am I right in assuming that only the part of > the deck that has not been used should be shuffled ie from the top of the > deck and so on? Otherwise, although the probability is small, it is still > possible to deal cards that have already been played. On each new play, the entire deck should be shuffled and the top card pointer reset to the first card in the deck. -------------------------------------------------------------------------- > How do you want us to turn this in? handin command with > blackjack.c, blackjack.h, cards.c, cards.h? Yes, please turn in all four files with those exact names. -------------------------------------------------------------------------- > The webpage makes it very clear about init_rand and set_seed, but I'm > hearing conflicting reports about whether or not we are supposed to > shuffle the deck after we initialize it or not. Are we supposed to > shuffle at the beginning of execution before the first game is played? You should not automatically shuffle the cards before the first hand is played. If you want to play the game for fun, you need to select option 3 before the first hand is dealt so that you'll get random cards. -------------------------------------------------------------------------- ****************** > Here is my problem: > > printf("Would you like to play again? (y/n) "); > /* fflush(stdin); */ > scanf("%c", &again); > > You said not to use fflush, but if i omit it, the program skips the question. > I left it in for that reason, but now when I test it with input from a file, > it screws up because I used the fflush. I'm afraid that you might use an > input file to test my program when I turn it in, so how can I take out > fflush without it skipping the scanf when it runs? This is a good question. This situation unfortunately occurs often. One solution is to read the input as a string ("%s") into a character array, and then copy the first character of that string into the variable again. -------------------------------------------------------------------------- > I'm having trouble w/ my shuffle. > > I declare two pointers of type CARD_T, as in > > void shuffle_cards (DECK_T *deck){ > > CARD_T *x1; > CARD_T *x2; > > then set them > > x1 = &deck.cards[i]; > x2 = deck.cards[rand_indx]; > > but when I try to define x1 and x2 I get the following errors. > "blackjack.c", line 168: left operand of "." must be struct/union object > "blackjack.c", line 169: left operand of "." must be struct/union object > > I have tried removing the ampersand and using (*deck).cards[i] and > x1->deck.cards[i] etc etc... Keep in mind that you're passing deck in as a pointer. So, whenever you access any of its fields, you need to use the pointer ("->") notation. So your assignment would look more like x1 = &(deck -> cards [i]); and similarly for x2. -------------------------------------------------------------------------- > I am trying to set the top of the deck to the first card in the deck, but I am > getting an assignment error because top_of_deck is a pointer to DECK_T and the > address of the card is a pointer to CARD_T. What am I missing here???? The field in DECK_T representing the top of the deck should be a pointer to CARD_T, not a pointer to DECK_T. -------------------------------------------------------------------------- > I thought you were asking us to shuffle after a card is dealt. > It did not make sense to me that you would want us to shuffle in the middle > of a play ... You should only shuffle after each hand has been completely finished and a winner has been determined. -------------------------------------------------------------------------- > You told us to put the cards in order of SUIT (C , D, H, S) and THEN > in order of value. For initializing the *deck*, you order the cards by suit first, then by value. For sorting cards in the *hand*, you sort by value first, then by suit. See the examples above and in the sample test run. -------------------------------------------------------------------------- > What is the late penalty for assignments? Is the same as the last > assignment? Yes, same as last assignment: 3^(num of days late). -------------------------------------------------------------------------- > So, what hand total does the dealer stand on? The dealer no longer draws cards once his hand is >= 17. -------------------------------------------------------------------------- > What changes were made to the revised specifications? p. 2 (middle paragraph): old: If the player or dealer draws a hand totaling 21 on the first draw, BLACKJACK!! should be printed at the end of the Player: line... new: If the player draws a hand totaling 21 on the first draw, BLACKJACK!! should be printed at the end of the Player: line... (see below for related line added later) p. 3 (first paragraph): old: The dealer continues to draw until the total value of the dealer's hand is greater than the player's or greater than 16. new: The dealer continues to draw until the total value of the dealer's hand is greater than the player's or >= 17. (note that the two statements above have the same meaning) old: ... the dealer stands with his original hand and wins. For this case, DEALER STANDS must be printed on the screen. new: ... the dealer stands with his original hand and wins. If the player's hand is 21, then the dealer does not draw any additional cards. For these cases, DEALER STANDS must be printed on the screen. If the dealer draws a hand totaling 21 on the first draw, BLACKJACK!! should be printed at the end of the Dealer: line, and the program should not allow the dealer to draw any additional cards. old: Note that the dealer must stop drawing cards if his hand is greater than 16... new: Note that the dealer must stop drawing cards if his hand is >= 17... (note that the two statements above have the same meaning) -------------------------------------------------------------------------- > I was just in the middle of working on project three when I came > to the point where I needed to write the function for deal_card. The > function prototype as given in the project guidelines is: > void deal_card (CARD_T *hand, DECK_T *deck) > > My question is, shouldnt the first argument be a HAND_T, I was thinking it > needed to be whoevers hand was getting the card, but now I am not sure. > And it makes sense following the pattern you have going with naming the > parameters being passed to the functions. Think of it this way: deal_card is going to deal a single card to a certain location in the hand. That is, you should pass the location in the hand to which you want to deal the card. But you're right -- the parameter may have been more understandable if it had been named 'card' instead of 'hand'. -------------------------------------------------------------------------- > The function prototype for sort_hand is > > void sort_hand (HAND_T hand) > > Shouldn't hand be a pointer to HAND_T? Yes, this is a mistake in the specification. You need to make hand a pointer so that you can change its value -- that is, after sorting, the cards will be in different locations. -------------------------------------------------------------------------- > Can we assume: > > 1. You will play no more games than the 52 cards will allow, or do > we need to check for a *top = NULL and then re-shuffle and set > *top back to deck->top = deck->cards[0]? Keep in mind that *top (as written above) will NEVER equal NULL since *top is a structure (not a pointer to a structure). On the other hand, top (with no *) CAN equal NULL, but WILL NOT after reaching the end of the deck -- it will just equal the first address after the array. But you don't have to worry about top running out of the array bounds. The maximum number of cards you will ever use for a single game is less than 22 (11 for the player and < 11 for the dealer -- since all the low cards are in the player's hand). After a winner is determined, the cards are shuffled and the top pointer is set to point at the top of the deck. So, it's not possible to use all the cards in the deck. > 2. 'Y', 'y', 'N', 'n' will be given when asked to deal again or > should we do error checking for that? You can assume the user will enter a valid response. > Also, I am having trouble with deal cards. I just want to incriment > top by one pointing to that position in the cards[]. I have tried > several different ways and looked on the FAQ but could find anything > pertaining to it. I saw how to initialize top to cards[0]. You've already answered the question. The text above contains the phrase "increment top by one." How do you perform an increment? For int i, it's just i++. It works the same for top, but the number of bytes to add to top will be automatically computed to skip over the rest of the current struct and point to the next one. -------------------------------------------------------------------------- > I have a doubt in testing the project.Please correct > me if i am wrong.We are supposed to load the deck that u have given as it > is and run the sample input.then we check the output.we don't use any of > the random number functions while testing it this way.please answer my > question. Your program should behave exactly as the sample output specifies. Since you don't shuffle cards until *after* each hand is played for this sample run, the random numbers, though generated for this program, do not come into play. Here's what happens: - you read in a sample deck - play the hand - shuffle the cards with random values - read in another sample deck (overwriting the previous shuffled cards) - play the hand - shuffle the cards with random values - quit For the other sample run, the random numbers *will* affect play. -------------------------------------------------------------------------- > In early hours i was checking my output generated with the output provided > on web, and they matched exact.To match my output even in terms of > identation, i added few \n 's here and there.When i compiled the whole > program again, it gives me a error saying > > Line:417 : Unterminated charancter constant at line 417 in blackjack.c > > I see that there is nothing wrong at that line.It is just a > printf(); statement, with proper closing of double quotes. Here's the problem: printf() must take at least one parameter, even if it's just the empty string. So, what you really want is probably printf ("\n"); You could have printf (""); but it wouldn't print anything out, not even a newline. --------------------------------------------------------------------------