Hi,
For my final project this semester, we were asked to make a modified poker-like game in which the player must try his/her best to match a type of poker hand and they are paid in accordance to what hand they create and how much they wager. Anyway, I believe I have most of the assignment finished (I still have to setup a wager system, a better card printing function, and a few other things). Anyway, The code I have this far is giving me a segmentation fault after completing one cycle of the while loop in the main function. I tried debugging my code with valgrind and it is directing me to my call to "cin." I cannot figure out why cin would cause a segfault. Anyway, here's my code. Different code blocks represent different source and header files
Homework5.cpp
functions.cppCode://============================================================================
// Name : Homework5.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include "hand.h"
#include "deck.h"
#include "prototypes.h"
using namespace std;
int main()
{
hand myHand;
deck myDeck;
int i,j, handType;
string answer;
bool playAgain = true;
//play game
while(playAgain == true)
{
myDeck.shuffle();
//print out deck for debugging purposes only
for(i=0;i<52;++i) cout<<myDeck.getValue(i)<<"*"<<myDeck.getSuit(i)<<endl;
j = deal(myDeck,myHand);
cout<<myHand.getValue(0)<<"*"<<myHand.getSuit(0)<<" "<<myHand.getValue(1)<<"*"<<myHand.getSuit(1)<<" "<<myHand.getValue(2)<<"*"<<myHand.getSuit(2)<<" "<<myHand.getValue(3)<<"*"<<myHand.getSuit(3)<<" "<<myHand.getValue(4)<<"*"<<myHand.getSuit(4)<<endl;
for(i=0;i<5;++i)
{
cout<<"Discard card number "<<i+1<<"?";
cin>>answer;
cout<<endl;
if(answer == "yes")
{
myHand.setValue(i,myDeck.getValue(j));
myHand.setSuit(i,myDeck.getSuit(j));
++j;
}
cout<<myHand.getValue(0)<<"*"<<myHand.getSuit(0)<<" "<<myHand.getValue(1)<<"*"<<myHand.getSuit(1)<<" "<<myHand.getValue(2)<<"*"<<myHand.getSuit(2)<<" "<<myHand.getValue(3)<<"*"<<myHand.getSuit(3)<<" "<<myHand.getValue(4)<<"*"<<myHand.getSuit(4)<<endl;
}
handType = myHand.handType();
cout<<"Hand Type: "<<handType<<(handType > 0 ? '\a':' ')<<endl;
cout<<endl<<"Play Again? ";
cin>>answer;
if(answer != "yes") playAgain = false;
}
return 0;
}
card.hCode:#include "hand.h"
#include "deck.h"
int deal(deck &myDeck, hand &myHand)
{
int i;
for(i=0; i<5;++i)
{
myHand.setValue(i,myDeck.getValue(i));
myHand.setSuit(i,myDeck.getSuit(i));
}
return i;
}
deck.hCode:#ifndef CARD_H_
#define CARD_H_
class card
{
private:
int value;
int suit; // 1=clubs, 2=spades,3=hearts,4=diamonds
public:
card(){setValue(2); setSuit(1);}
card(int v, int c) {setValue(v); setSuit(c);}
void setValue(int v) {value = v;}
void setSuit(int c) {suit = c;}
int getValue(){return value;}
int getSuit(){return suit;}
};
#endif
deck.cppCode:#ifndef DECK_H_
#define DECK_H_
#include "card.h"
class deck
{
private:
card cards[52];
public:
deck();
void setValue(int i, int v) {cards[i].setValue(v);}
void setSuit(int i, int c) {cards[i].setSuit(c);}
int getValue(int i) {return cards[i].getValue();}
int getSuit(int i) {return cards[i].getSuit();}
void shuffle(void);
};
#endif
hand.hCode:#include <ctime>
#include <cstdlib>
#include <unistd.h>
#include<iostream>
#include "deck.h"
using namespace std;
deck::deck()
{
int i=0,j,k;
for(j = 1; j < 5; ++j)
{
for(k = 2; k<15 ;++k)
{
cards[i].setValue(k);
cards[i].setSuit(j);
++i;
}
}
}
void deck::shuffle()
{
card temp;
int i,j;
cout<<"shuffling..."<<endl;
for(i = 0; i < 52; ++i)
{
temp = cards[i];
sleep(1);
srand(time(NULL));
j = rand()%51;
cards[i] = cards[j];
cards[j] = temp;
}
}
hand.cppCode:#ifndef HAND_H_
#define HAND_H_
#include "card.h"
#include <iostream>
class hand
{
private:
card cards[5];
int valueCounter[15]; // J=11, Q=12, K=13, A=14
int suitCounter[5]; // 1=clubs, 2=spades,3=hearts,4=diamonds
public:
hand() {}
void initializeCounters() {int i=0; while(i<15) {valueCounter[i] = 0, suitCounter[i] = 0; ++i;}}
void countCards(void);
void setValue(int i, int v) {cards[i].setValue(v);}
void setSuit(int i, int c) {cards[i].setSuit(c);}
int getValue(int i) {return cards[i].getValue();}
int getSuit(int i) {return cards[i].getSuit();}
int handType(void);
//string printHand(void);
};
#endif
Any help would be much appreciated. Thanks! Below is the valgrind output and program output.Code:#include "card.h"
#include "hand.h"
#include <iostream>
using namespace std;
void hand::countCards(void)
{
initializeCounters();
int cardVal = 2, suitVal=1, cardNum=0;
while(cardNum<5)
{
while(cardVal<15)
{
if(cardVal == cards[cardNum].getValue()) {++valueCounter[cardVal]; cardVal=2; break;}
++cardVal;
}
while(suitVal<5)
{
if(suitVal == cards[cardNum].getSuit()) {++suitCounter[suitVal]; suitVal=1; break;}
++suitVal;
}
++cardNum;
}
}
int hand::handType()
{
enum hands {none,onePair, twoPair, threeOfAKind, straight, flush, fullHouse, fourOfAKind, straightFlush, royalFlush};
countCards();
int i,j, pair = 0, threeKind = 0;
for(i=1; i<5; ++i)
{
if(suitCounter[i] == 5)
{
if(valueCounter[10] == 1 && valueCounter[11] == 1 && valueCounter[12] == 1 && valueCounter[13] == 1 && valueCounter[14] == 1) return (int)royalFlush;
else
{
for(j=2;j<15;++j)
{
if(valueCounter[j] == 1 && valueCounter[j+1] == 1 && valueCounter[j+2] == 1 && valueCounter[j+3] == 1 && valueCounter[j+4] == 1) return (int)straightFlush;
}
return (int)flush;
}
}
for(i=2;i<15;++i)
{
if(valueCounter[i] == 4) return (int)fourOfAKind;
if(valueCounter[i] == 3) ++threeKind;
if(valueCounter[i] == 2) ++pair;
}
if(pair == 1 && threeKind == 1) return (int)fullHouse;
else if(pair == 2) return (int)twoPair;
else if(pair == 1) return (int)onePair;
}
return none; //none of the above
}
Quote:
shuffling...
5*3
7*2
10*1
13*1
12*2
13*3
8*1
8*4
4*1
10*4
6*1
13*2
14*3
12*3
5*2
7*4
14*1
6*2
2*2
8*3
7*1
14*4
4*4
10*2
11*3
9*2
11*2
12*1
9*1
7*3
11*1
14*2
3*2
9*4
4*2
8*2
5*1
3*4
10*3
4*3
2*4
6*3
11*4
13*4
5*4
12*4
2*3
3*3
3*1
9*3
6*4
2*1
5*3 7*2 10*1 13*1 12*2
Discard card number 1?yes
13*3 7*2 10*1 13*1 12*2
Discard card number 2?yes
13*3 8*1 10*1 13*1 12*2
Discard card number 3?yes
13*3 8*1 8*4 13*1 12*2
Discard card number 4?no
13*3 8*1 8*4 13*1 12*2
Discard card number 5?no
13*3 8*1 8*4 13*1 12*2
Hand Type: 2
Play Again? yes
==26986== Invalid read of size 8
==26986== at 0x36D5A6F680: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /usr/lib64/libstdc++.so.6.0.16)
==26986== by 0x4012B3: main (Homework5.cpp:53)
==26986== Address 0xffffffffffffffe8 is not stack'd, malloc'd or (recently) free'd
==26986==
==26986==
==26986== Process terminating with default action of signal 11 (SIGSEGV)
==26986== Access not within mapped region at address 0xFFFFFFFFFFFFFFE8
==26986== at 0x36D5A6F680: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /usr/lib64/libstdc++.so.6.0.16)
==26986== by 0x4012B3: main (Homework5.cpp:53)
==26986== If you believe this happened as a result of a stack
==26986== overflow in your program's main thread (unlikely but
==26986== possible), you can try to increase the size of the
==26986== main thread stack using the --main-stacksize= flag.
==26986== The main thread stack size used in this run was 8388608.
==26986==
==26986== FILE DESCRIPTORS: 3 open at exit.
==26986== Open file descriptor 2: /dev/pts/0
==26986== <inherited from parent>
==26986==
==26986== Open file descriptor 1: /dev/pts/0
==26986== <inherited from parent>
==26986==
==26986== Open file descriptor 0: /dev/pts/0
==26986== <inherited from parent>
==26986==
==26986==
==26986== HEAP SUMMARY:
==26986== in use at exit: 29 bytes in 1 blocks
==26986== total heap usage: 3 allocs, 2 frees, 82 bytes allocated
==26986==
==26986== 29 bytes in 1 blocks are definitely lost in loss record 1 of 1
==26986== at 0x4A06FC7: operator new(unsigned long) (vg_replace_malloc.c:261)
==26986== by 0x36D5AA2E48: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==26986== by 0x36D5AA3BBA: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib64/libstdc++.so.6.0.16)
==26986== by 0x36D5AA3C9F: std::string::reserve(unsigned long) (in /usr/lib64/libstdc++.so.6.0.16)
==26986== by 0x36D5A6F820: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /usr/lib64/libstdc++.so.6.0.16)
==26986== by 0x400FB6: main (Homework5.cpp:37)
==26986==
==26986== LEAK SUMMARY:
==26986== definitely lost: 29 bytes in 1 blocks
==26986== indirectly lost: 0 bytes in 0 blocks
==26986== possibly lost: 0 bytes in 0 blocks
==26986== still reachable: 0 bytes in 0 blocks
==26986== suppressed: 0 bytes in 0 blocks
==26986==
==26986== For counts of detected and suppressed errors, rerun with: -v
==26986== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)