Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Bridge Card Playing Game

Status
Not open for further replies.

tmcneil

Technical User
Nov 17, 2000
294
US
All,

I have an assigment that I have to write several Classes for. I have an input text file of, say, 7 lines with 13 values per line.
Code:
QH 3D JD 7H 4C KC 9D 2H QC 6H JH QS 8C 
4S 4C 9H 5H QC 8H JH 6C 3D 5S 9D 2C TH 
AH TS AS QH QC TD 7H KS 2C 3S QS 3D 8D 
8H TD 6D 8S JS 5C TS 3S KS 9S 6S 8D KD 
7H 3C TC 4H QD JC 9H TS KH AC 6H 6D 9S 
2C JH 3H JD TS 8C 7C 3D 5S TC 4S KD KS 
JD QD JH 5S 3H 2S 5H QS 4D 2H AD 4H 7H
Each value represents a card. I'm supposed to design a class to retrieve a card, CardReader, sends to the Hand class to build a hand of 13 playing cards. I can easily read the entire file into a large array or read only the 1st 13 values into an array. What I am not sure of is why I need two classes, one to send the value to another class that builds the hand. I find this redundant, but it is what I have to do. So, how would one read a card one at a time, send it to an array built in another class and stop after 13 cards or at the end of the line. How would one do this for every line after the previous one is processed and counted up for the amount of points in the hand?

It's obvious that I am not a bridge player, but have a lot of questions since I have only written programs with one class in it. I have included some code that I have written already.

CardReader class
Code:
// cardreader.h: interface for the CardReader class.

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

const int CARDS = 100;

//Declare an array of class CardReader
#ifndef CARDREADER
#define CARDREADER
class CardReader
{
	 private:
         ifstream infile;                     //input file declaration
         char theCards[CARDS][2];
         char oneCard[2];
         int size, count;

	 public:
		 CardReader(void);           //constructor
		 ~CardReader(void);          //destructor
         void readCards (void);       //reads cards from a text file and stores
                                      //into array
         //void printCards (void);      //print of cards
}; //end class CardReader
#endif

//*****************************************************************************
// readCards(): method reads data in the file, hands.txt, into the
// array and keeps track of (count) the number of cards read.
//-----------------------------------------------------------------------------
void CardReader::readCards (void)
{
    count = 0;

    while (!infile.eof())  //read all cards from file
    {
        infile >> oneCard;    //read into temporary card first
        strcpy(theCards[count], oneCard);   //store word read in array        
        count++;
    }
}//end readCards

Hand Class:
Code:
// hand.h: interface for the Hand class.

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

const int HAND_SIZE = 13;

//Declare an array of class Hand
#ifndef HAND
#define HAND
class Hand
{
	 private:
         ifstream infile;                     //input file declaration
         char theHand[HAND_SIZE][2];
         char oneCard[2];
         int size, count;

	 public:
		 Hand(void);           //constructor
		 ~Hand(void);          //destructor
         void buildHand (void);       //reads cards from a text file and stores
                                      //into array
         void printHand (void);      //print of cards
}; //end class Hand
#endif


void Hand::buildHand (void)
{
    count = 0;

    while (count < 13)  //read no more than 13 cards
    {
        //infile >> oneCard;    //read into temporary card first
        strcpy(theHand[count], oneCard);   //store word read in array
        
        count++;
        // read next card in temporary location
    }
}//end

Any help would be greatly appreciated.

Thanks,
Todd
 
Code:
#ifndef CARDREADER
#define CARDREADER
This should be at the very beginning of your header file.


Code:
using namespace std;
Never do this in a header file. Only in .cpp files.
It usually doesn't cause a problem, but for much larger programs with many files, it could cause namespace problems for some people.


Code:
char theCards[CARDS][2];
char oneCard[2];
You should be using STL strings & vectors instead of char arrays. It's much safer and more flexible.

Member variable names should be prefixed with something (most people like myself use m_MemberName) to make them easier to distinguish from local function variables. It helps a lot on larger projects, especially when multiple people are working together.

As for why you need to have 2 classes, I'd say it's because they're supposed to do different jobs. The CardReader reads the data from the file and builds the Hands. The Hands are probably used by another class or function to play the game. Therefore, the Hand class doesn't need to know anything about reading data from a file, it just stores a bunch of cards. The CardReader doesn't have to know anything about playing the game; it just needs to build the Hands and give them to the players.
 
It's weird about the namespace thing because our prfessor gave us three files that were written by him for sorting and evaluating the hand. In one of the files, he used the namespace and gave it his name. Not sure why or how it improved the code.

The member variable names should be like, m_Count instead of count. Or if count was in a method like readCards, it should be m_readCards_count.

I just heard from my professor and I believe the CardReader reads the data from the file, and passes it by reference to the Hand class. The Hand class compiles the 13 element array or vector as you stated. I guess I'm very foggy from my last c++ class and forget how to do some of these things. I can read the file, but I am not sure how to pass it from one class to another and then store it. Any ideas?

Todd
 
Defining a new namespace in the header file is fine, but if you put a using namespace std; statement in the header, you're telling the compiler to try to resolve names from the std namespace. The idea being that you can just use string instead of std::string... The problem is, if it's in the header, then any file that includes that header will now be using namespace std too, even if they don't want to.
If someone writes their own function which has the same name as one that is in the std namespace; when they call that function, the compiler won't know which function you are referring to.
Here's an example that shows this problem:
Code:
#include <iostream>

namespace test
{
	void func()
	{
		std::cout << std::endl << "test::func() called." << std::endl;
	}
};

using namespace test;

void func()
{
	std::cout << std::endl << "func() called." << std::endl;
}


int main()
{
	func();	// error C2668: 'func' : ambiguous call to overloaded function
			   // could be 'void func(void)' or 'void test::func(void)'

	return 0;
}

As for member names, any variable declared in the class definition should be m_something, whereas local variables declared in functions shouldn't have the m_ prefix.
For example:
Code:
// person.h header file.
#ifndef person_header
#define person_header

#include <string>

class CPerson
{
private:
   int          m_Age;
   std::string  m_Name;

public:
   void Talk();
};

#endif  // person_header
Code:
// person.cpp file.
#include <iostream>
#include "person.h"

using namespace std;

void CPerson::Talk()
{
   string age;

   cout << "Hi, my name is " << m_Name << ".  I'm " << m_Age
        << " years old." << endl << "How old are you?" << endl;

   cin >> age;
...
}

To pass cards from the CardReader class to the Hand class, just create something like an AddCard() function in the Hand class that takes a card as a parameter, then that function adds the card to a vector member variable of that class...
 
I have this as my hand.h file:
Code:
#ifndef HAND
#define HAND
// hand.h: interface for the Hand class.

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

const int c_handSize = 13;

class Hand
{
	 private:
         //ifstream infile;                     //input file declaration
         string m_Hand[c_handSize];
         //char m_Card[2];
         int m_Size, m_Count;

	 public:
		 Hand(void);           //constructor
		 ~Hand(void);          //destructor
         void addCards (string &m_Card);  //reads cards from a text file and stores
                                           //into array
         void printCards (void);      //print of cards
}; //end class Hand
#endif

method:

Code:
void Hand::addCards (string &m_Card)
{
    m_Hand[m_Count] = m_Card;
    //strcpy(m_Hand[m_Count], m_Card);   //store word read in array
}//end addCards

CardReader header:
Code:
#ifndef CARDREADER
#define CARDREADER
// cardreader.h: interface for the CardReader class.

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

const int c_CARDS = 100;

class CardReader
{
	 private:
         ifstream infile;                     //input file declaration
         //char m_Cards[c_CARDS][2];
         string m_Card;
         int m_Count;

	 public:
		 CardReader(void);           //constructor
		 ~CardReader(void);          //destructor
         void readCards (void);       //reads cards from a text file and stores
                                      //into array
         //void printCards (void);      //print of cards
}; //end class CardReader
#endif

cardreader method:
Code:
void CardReader::readCards (void) 
{
    m_Count = 0;

    while (!infile.eof() && m_Count < 13)  //read all cards from file
    {
        infile >> m_Card;    //read into temporary card first
        // instantiate Hand Class
        Hand card;
        //pass oneCard to buildHand of Hand() Class
        card.addCards(m_Card);
        //strcpy(m_Cards[m_Count], m_Card);   //store word read in array        
        m_Count++;
    }
}//end readCards

This all compiles, however, when I step through CardReader:readCards, the card.addCards(m_Card) line never executes like I think it should. Not sure what's wrong with it.
Todd
 
I'm not sure how you think it should execute, but I can see several problems with it.

Code:
m_Hand[m_Count] = m_Card;
If this is the only line in Hand::addCards(), then how can m_Count ever get incremented?
Also, the name addCard() might be a better choice since you can only add a single card each time you call the function.


Code:
Hand card;
This line in CardReader::readCards() is creating a new Hand for each iteration of the while loop. It also isn't saving the cards it reads anywhere, so all that data disappears after the while loop ends.
BTW, a Hand isn't a card; it's a set of cards. So you shouldn't store only a single card in each Hand.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top