GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 06-Oct-2005, 03:38
krisopotamus krisopotamus is offline
New Member
 
Join Date: Sep 2005
Posts: 21
krisopotamus is on a distinguished road

Need Help with my Cards Program (C++)


Okay I have been working on this for the past 5 hours tonight and like 3 hours yesturday, but I was at school for 13 hours today as I had 3 classes, 2 labs, and a night class. Anyways, I am going to bed to get like 5 hours of sleep then working on this tomorrow again. I was wondering if anyone could maybe debug it? I really don't know what to change...and im not getting anywhere fast.

Anyways here it is.... It is made up of a few different files


This is the header file for the random function the teacher made (So it works, skip checking over this)
CPP / C++ / C Code:
//
// random.h
//
// This module encapsulates a pseudo-random number generator.
//

#ifndef __RANDOM_H__
#define __RANDOM_H__

//
// initializeWithSeed
//
// Purpose: Initialize the encapsulated state of the random
//          number generator by specifying a seed.  The
//          random number generator produces the same numeric
//          sequence when it is initialized with the same seed.
// Argument(s):
//   seed: the seed of the pseudo-random number sequence.
// Precondition: The random number generator has not been
//               initialized yet.
// Return: N/A
// Side Effect: Initialize the encapsulated state of the random
//              number generator by the seed argument.
//

void initializeWithSeed(unsigned int seed);

//
// initializeWithoutSeed
//
// Purpose: Initialize the encapsulated state of the random
//          number generator.  The process ID of the currently
//          executing process is used as the seed of the
//          random number generator.  Therefore, the generator
//          is guaranteed to be seeded differently every time
//          the program is executed.
// Argument(s): N/A
// Precondition: The random number generator has not been
//               initialized yet.
// Return: N/A
// Side Effect: Initialize the encapsulated state of the random
//              number generator using the process ID as seed.
//

void initializeWithDefaultSeed();

//
// nextRandom
//
// Purpose: Compute the next number in the random number sequence.
// Argument(s): N/A
// Precondition: The random number generator must have been properly
//               initialized by a call to intializeWithSeed or
//               initializeWithoutSeed.
// Return: the next number in the random number sequence.
// Side Effect: Update the encapsulated state of the random number
//              generator, so that the next time this function is
//              called, a new random number will be returned.
//

unsigned int nextRandom();

//
// nextRandomInRange
//
// Purpose: Computer the next number in the random number sequence,
//          and convert it into a random number in a user-specified
//          range.
// Argument(s):
//   upper: the upper bound of the requested random number
// Precondition: 1/ The random number generator must have been properly
//                  initialized by a call to initializeWithSeed or
//                  initializeWithoutSeed.
//               2/ upper >= 2
// Return: a random number between 0 and upper-1 (inclusive), obtained
//         by a call to nextRandom().
// Side Effect: Same as that of invoking nextRandom().
//

unsigned int nextRandomInRange(unsigned int upper);

#endif


Here is the random.cpp, the teacher also made this so it is in working order.
CPP / C++ / C Code:
//
// random.cpp
//

#include "random.h"

#include <cassert>
#include <sys/types.h>
#include <unistd.h>

static const unsigned int max_unsigned_int = 0 - (unsigned int) 1;
static const double unsigned_int_upper = max_unsigned_int + 1.0;

static const unsigned int a = 1664525;
static const unsigned int c = 1013904223;

unsigned int X;

void initializeWithSeed(unsigned int seed) {
  static X = seed;
  initialized = true;
}

void initializeWithDefaultSeed() {
  initializeWithSeed(getpid());
}

unsigned int nextRandom() {
  static X = a * X + c;
  return X;
}

double nextRandomAsDoubleFloat() {
  return nextRandom() / unsigned_int_upper;
}

unsigned int nextRandomInRange(unsigned int upper) {
  return (unsigned int) (upper * nextRandomAsDoubleFloat());
}


This is my cards.h (header file) it contains my data types that I created and my function prototypes. Something is wrong with my prototypes they aren't compiling right
CPP / C++ / C Code:
//
// cards.h
//
//
//

#ifndef __CARDS_H__
#define __CARDS_H__

enum Suit {spades, hearts, diamonds, clubs };
enum Rank {two=2, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace};

struct Card             //struct of a single Card, contains rank & suit
{
  Rank rank;            //rank variable of data type Rank
  Suit suit;            //suit variable of data type Suit
};

typedef Card Deck[52];  //data type for a deck of cards

Deck deck;              //global variable for deck of cards



//
// initializeDeck
//
// Purpose: Initialize the deck so that it has 2-Ace for each suit
// Argument(s):
//   deck: the deck of cards
// Precondition: 1/ The deck has not already been initialized
//               2/ the size of the deck array is 52
// Return: a deck of cards that has 2-ace of each suit
// Side Effect:
//

void initializeDeck(Deck deck);


//
// returnString
//
// Purpose: return the string of a card
// Argument(s):
// Precondition: cards have been initialized
// Return: a string for the name of the card
// Side Effect:
//

string returnString(const Card& card);


//
// testHigherValue
//
// Purpose: test if the first card is > 2nd card
// Argument(s): card1 - card #1 (card you are testing if > card2)
//                      card #2 (card you are comparing card1 to)
// Preconditions: cards have been initialized
// Side Effect:
//

bool testHigherValue(const Card& card1, const Card& card2);


//
// testIfSame
//
// Purpose: test if the first card is same as 2nd
// Argument(s): card1 - card #1 (card you are testing if = card2)
//                      card #2 (card you are comparing card1 to)
// Preconditions: cards have been initialized
// Side Effect:
//

bool testIfSame(const Card& card1, const Card& card2);

//
// shuffleDeck
//
// Purpose: to shuffle the deck of cards randomly
// Arguments(s): deck - global variable for deck of cards
//              pass it by reference and change the memory for deck
// Preconditions: cards have been initialized
// Side Effect:
//

#endif


Here is my cards.cpp file. There is something wrong with my functions (like initializeDeck) in the way that it determins where the position in the enum is. It needs to go by the position and not by what the name is (ex. for two, it needs to use the position = 2 (because i manually set that) and not two, in the for loop).
CPP / C++ / C Code:
// cards.cpp
//
//
//
//

#include "cards.h"
#include "random.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{


  initializeWithDefaultSeed();
  Card card1;
  Card card2;
  Card card;

  initializeDeck(deck);


return 0;
}

string returnString(const Card& card)
{
        string str;
        if(card.suit == spades)
        {
                str = "Spades ";
        }
        else if(card.suit == hearts)
        {
                str = "Hearts ";
        }
        else if(card.suit == diamonds)
        {
                str = "Diamonds ";
        }
        else if(card.suit == clubs)
        {
                str = "Clubs ";
        }
        if(card.rank == 2)
        {
                str += "2";
        }
        else if(card.rank == 3)
        {
                str += "3";
        }
        else if(card.rank == 4)
        {
                str += "4";
        }
        else if(card.rank == 5)
        {
                str += "5";
        }
        else if(card.rank == 6)
        {
                str += "6";
        }
        else if(card.rank == 7)
        {
                str += "7";
        }
        else if(card.rank == 8)
        {
                str += "8";
        }
        else if(card.rank == 9)
        {
                str += "9";
        }
        else if(card.rank == 10)
        {
                str += "Ten";
        }
        else if (card.rank == 11)
        {
                str += "Jack";
        }
        else if(card.rank == 12)
        {
                str += "Queen";
        }
        else if(card.rank == 13)
        {
                str += "King";
        }
        else if(card.rank == 14)
        {
                str += "Ace";
        }
        return str;
}




bool testIfSame(const Card& card1, const Card& card2)
{
  if (card1.rank == card2.rank && card1.suit == card2.suit)
    return true;
  else
    return false;
}

void initializeDeck(Deck deck)
{
  int i = 0;
  for(Suit suit = spades; suit <= clubs; suit = Suit(suit+1))
  {
    for(Rank rank = two; rank <= ace; rank = Rank(rank+1))
    {
       deck.card[i].suit = suit;
       deck.card[i].rank = rank;
       i++;
    }
  }
}

bool testHigherValue(const Card& card1, const Card& card2)
{
  if (card1.Rank(rank) < card2.Rank(rank))      //greater than because opp order.
    return true;
  else if (card1.Rank(rank) > card2.Rank(rank)) //if 2nd bigger, then false
    return false;
  else
  {
    if (card1.Suit(suit) < card2.Suit(suit))    //if suit better, then true
      return true;
    else
      return false;                             //if not, then false
  }
}

void shuffleDeck(Deck deck)
{
  int j;
  for(int i = 0; <= 50; i++)
  {
    j = nextRandInRange(52);
    Card temp = deck.card[i];
    deck.card[j] = deck.card[i];
    deck.card[i] = temp;
  }
}

void writeToFile(const Deck deck)
{
  ofstream outData;             //initialize file output
  outData.open("deck.txt");     //write data to file named deck.txt

  for(int i=0; i<52; i++)
    cout << cardInfo = returnString(deck.card[i]) << endl;

  outData.close();
}

void inputFromFile(Deck deck)
{
  ifstream inData;
  inData.open("deck.txt");

  for(int i=0; i<52; i++)
    cin >> deck.card[i].suit >> deck.card[i].rank;

  inData.close();
}

I know this seems long but really all you need to look at is how I made my data structure and then my functions in cards.cpp

And dont worry about the shuffle program its just a small side task which i just use a few functions, so in the makefile here just ignore it.

Makefile
CPP / C++ / C Code:
# Makefile

# Build all

all : prog

# Compilation of Source Files

cards.o : cards.cpp cards.h
        g++ -c cards.cpp

random.o : random.cpp random.h
        g++ -c random.cpp

shuffle.o : shuffle.cpp random.cpp random.h cards.cpp cards.h
        g++ -c shuffle.cpp

# Linking of object files

prog : cards.o random.o
        g++ cards.o random.o -o prog

shuffle : shuffle.o cards.o random.o
        g++ shuffle.o cards.o random.o -o shuffle

clean :
        rm -f *.o prog shuffle


I will just copy what my teacher posted for the assignment tasks so that it is very clear:

[45%] A deck of playing cards contains 52 cards. Each card belongs to one of four suits (i.e., Spades, Hearts, Diamonds, and Clubs). Each card also has a rank (i.e., ace, king, queen, jack, 10, 9, ..., 2). There is exactly one card with a given suit and a given rank.

Develop a playing card module (card.h/card.cpp) that offers the following services.

A) a record type (i.e., struct) for modeling a card

B) a function that returns the string representation of a given card

Remarks
The string representation of a card is its suit followed by its rank, with a white space in between. For example, the following are the string representation of some cards:

"Spade 5" "Heart ace" "Diamond king"

C) a function that compares if one card is more valuable than another card

Remarks
A card is more valuable than another card if the former has a higher rank than the latter, or if the two cards are of the same rank but the former belongs to a more valuable suit. Ranks are ordered, from higher to lower, as follows: ace, king, queen, jack, 10, 9, ..., 2. We follow the convention of Contract Bridge, and consider Spades the most valuable, followed by Hearts, and then Diamonds, and lastly Clubs.

D) a function that tests if two given cards are the same in suit and in rank

E) an array type, in the form of a typedef, for representing a deck of cards

F) a function that initializes a given deck array with the 52 standard playing cards

G) a function that randomly shuffles a given deck of cards

Remarks
To produce a random shuffling of an array A of 52 playing cards, follow the algorithm below:

for i stepping from 0 up to 50 do:
let j be a random number between i and 51 (inclusive)
swap A[i] and A[j]

H) a function that prints a given deck of playing cards to an output stream (i.e., an instance of ostream)

Remarks
The output must assume the following format. The output is composed of 52 lines, each containing the string representation of a card as specified in part b.

I) a function that reads a given deck of playing cards from an input stream (i.e., an instance of istream)




I have completed all these tasks in my program I just have to get it to work properly without bugs.

So if anyone has any spare time and could de-bug this for me that would be terrific because right now I'm going in circles. Time to get a few hours of shuteye (aka like 5) then I'll be back on here doing more work.

Thanks,

Kris
  #2  
Old 06-Oct-2005, 09:07
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,309
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Need Help with my Cards Program (C++)


Quote:
Originally Posted by krisopotamus
.
.
This is the header file for the random function the teacher made (So it works, skip checking over this)
.
.
Here is the random.cpp, the teacher also made this so it is in working order.

I wish I had a nickel every time that someone told me, "Don't bother to check this part; it works OK" and then gave me something that didn't work. I would have --- well, more than a nickel (lots more).

Here's a hint: when you have a project with multiple files, compile each one separately to eliminate syntax and other compile-time errors. Then put them together.

I started with the part that is supposed to be "ok".

Quote:
g++ -c random.cpp

random.cpp: In function `void initializeWithSeed(unsigned int)':
random.cpp:20: error: ISO C++ forbids declaration of `X' with no type
random.cpp:21: error: `initialized' undeclared (first use this function)
random.cpp:21: error: (Each undeclared identifier is reported only once for
each function it appears in.)
random.cpp: In function `unsigned int nextRandom()':
random.cpp:29: error: ISO C++ forbids declaration of `X' with no type

Since X is obviously supposed to be global (static) variable within this file, you shouldn't declare it inside each function. (But if you do declare a local "X" inside each function, be sure to use legal syntax.)
And what the heck happened with "initialized". Obviously supposed to be a global (static) function within this file also, but wasn't declared.

So you could try the following. Now, I can't be absolutely certain that this is how it's supposed to be. Note that the variable "initialized" is never used anywhere, so I doubt it does what the code's original author had in mind, but at least it will give you something that will compile so that you will have something to debug. As a matter of fact, handling the "initialized" thing seems kind of important in the long run for a real program, and the set of functions here needs a little work to be totally useful, but for now, let's just get on with it.

CPP / C++ / C Code:
//
// random.cpp
//

#include "random.h"

#include <cassert>
#include <sys/types.h>
#include <unistd.h>

static const unsigned int max_unsigned_int = 0 - (unsigned int) 1;
static const double unsigned_int_upper = max_unsigned_int + 1.0;

static const unsigned int a = 1664525;
static const unsigned int c = 1013904223;

unsigned int X;
bool initialized = false; //  <=== added this

void initializeWithSeed(unsigned int seed) {
  X = seed; // <=== global, static, already defined
  initialized = true;
}

void initializeWithDefaultSeed() {
  initializeWithSeed(getpid());
}

unsigned int nextRandom() {
  X = a * X + c;// <=== global, static, already defined
  return X;
}

double nextRandomAsDoubleFloat() {
  return nextRandom() / unsigned_int_upper;
}

unsigned int nextRandomInRange(unsigned int upper) {
  return (unsigned int) (upper * nextRandomAsDoubleFloat());
}

I compiled this with: g++ -c random.cpp -Wall -pedantic -ansi
and got no compiler warnings or errors. Note that this doesn't mean that it works as intended. (It very well may be OK, but I didn't analyze functionality--- that's for you do to.)


Quote:
Originally Posted by krisopotamus
.
.
Here is my cards.cpp file.
.
.

Once again, I won't bother with analyzing functionality. When I compiled this with g++ I got a ton of errors.

Here's another hint: when you see lots and lots (and lots) of errors: Dont Panic. Start at the top and work your way down. Sometimes a single fix will eliminate multiple errors (or, maybe, not).

This time, I'm not going to show everything that you need to change, but I will try to give a couple of clues:

I compiled this and got a few errors; I'll show the first two:

Quote:
g++ -c cards.cpp

cards.h:50: error: parse error before `&' token
cards.cpp: In function `void initializeDeck(Card*)':
cards.cpp:122: error: request for member `card' in `deck', which is of
non-class type `Card*'

Now, I can understand why the first error makes no sense to anyone who hasn't made this mistake a few times (and I have made the mistake more than a few --- but who's counting?).

What does line 50 look like:

CPP / C++ / C Code:
string returnString(const Card& card);

Now, my first reaction is to look carefully at the definition of Card, since it is the thing that was created in this program. Well, I looked and couldn't see anything wrong with it (that doesn't mean it's OK, but it means that I will look somewhere else for now).

There is nothing wrong with the syntax of this statement, so I look at the statements just before this one (not counting comments). Lots of times a missing semicolon or some other "oops" in previous lines cause compiler errors on later lines. Well the stuff just before this line looks OK too. What else could it be???? Well, what is "string"? It is a Standard C++ library class that we use all of the time, so I know nothing is wrong with "string"! However, we must tell the compiler what the heck a "string" is at compile time. In other words "string" is part of the library, not part of the language itself, so we need to #include the <string> header

I always include any system headers in each of my header files that needs them. So I put this at the beginning of cards.h. Remember, that as the compiler parses cards.h, it must know what a "string" is, regardless of what it knows in other parts of the program.

CPP / C++ / C Code:
#include <string>
using std::string;

enum Suit {spades, hearts, diamonds, clubs };

Now when I compile, that error message has gone away. I'll show you a couple more messages.

Quote:
cards.cpp: In function `void initializeDeck(Card*)':
cards.cpp:122: error: request for member `card' in `deck', which is of
non-class type `Card*'
cards.cpp:123: error: request for member `card' in `deck', which is of
non-class type `Card*'

Here are those two lines:
CPP / C++ / C Code:
.
       deck.card[i].suit = suit;
       deck.card[i].rank = rank;

What is deck? It is an array[52] of cards. Your syntax makes it look like deck is a struct with a member named "card". It isn't. I think you want card number i of the deck. What is card number i? It is deck[ i ]. So you could try this in place of those two lines:

CPP / C++ / C Code:
.
       deck[i].suit = suit;
       deck[i].rank = rank;

Now when I compile, those two errors have gone away.

You could try to fix everything else before recompiling, or you could fix one thing at a time, and recompile. Your choice.

I respectfully suggest that you start with the first error message each time and make sure you know how to get rid of it before going on to the next (don't say, "I don't understand that, so I will go on to other errors and return to that one later.") Whether you try to fix more than one for each compilation attempt, that's up to you.

I wish you well.

What I liked best about your post: it's a tie:
1. Code tags.
2. you included the makefile, so I could see what compiler you are using and how you intend to put the files together.

Regards,

Dave

"We can face our problem.
We can arrange such facts as we have
with order and method."

---Hercule Poirot
"Murder on the Orient Express"
Last edited by davekw7x : 06-Oct-2005 at 10:27.
  #3  
Old 06-Oct-2005, 16:48
krisopotamus krisopotamus is offline
New Member
 
Join Date: Sep 2005
Posts: 21
krisopotamus is on a distinguished road

Re: Need Help with my Cards Program (C++)


Thanks for the help I used it this morning. I managed to get my program working pretty good, had all the functions, just didnt have enough time to use them all. For my game part I didnt use I/O I just made it deal, shuffle, then test the cards.

I will still get the majority of the marks. I just got home from class and after 4.5 hours of sleep last night im dead, but have tons more hw, so cya.
 
 

Recent GIDBlogNot selected for officer school by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Airport Log program using 3D linked List : problem reading from file batrsau C Programming Language 11 29-Feb-2008 07:44
Type casts ? kai85 C++ Forum 12 23-Jun-2005 12:04
[TUTORIAL] Calling an external program in C (Linux) dsmith C Programming Language 4 22-Apr-2005 13:30
fltk-2.0 cvs Plumb FLTK Forum 20 13-Nov-2004 07:10
Need help with a C program (Long) McFury C Programming Language 3 29-Apr-2004 20:06

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 00:34.


vBulletin, Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.