Guest User

Rummy

a guest
Jul 10th, 2014
324
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.95 KB | None | 0 0
  1. #include <string>
  2. #include <iostream>
  3. #include <vector>
  4. #include <cstdlib>
  5. #include <fstream>
  6. #include <algorithm>
  7. using namespace std;
  8.  
  9. struct hand;
  10. struct card;
  11.  
  12. void trim(string &str);
  13. string getWord(string &str);
  14. int getCard(const string &str);
  15. string getCardName(int c);
  16. bool sortRank(card c1, card c2);
  17. bool areEqual(vector<card>&v1,vector<card>&v2);
  18.  
  19. struct hand{
  20.     vector<card> cards;         //Cards in the hand.
  21.     bool checkWin();            //Returns true if the hand wins.
  22.     //Returns true if the hand is a set of size.
  23.     bool checkSet(int size, hand &marker);
  24.     //Returns true if the hand is a run of size
  25.     int checkRun(int size, hand &marker);
  26.     int winWithCard(const card &newCard);
  27.     int winWithCard(const card &newCard, int j);
  28.     hand(string &handString);
  29.     void print();
  30.     string printS();
  31. };
  32.  
  33. struct card{
  34.     string suit;    //Suit of the card.
  35.     int value;      //Number of the card.
  36.     card(string suit,int value);
  37.     int points();   //Returns the point value of the card.
  38.     void print();
  39.     string printS();
  40.     inline bool operator== (const card &rhs) {return rhs.value==this->value&&this->suit==rhs.suit;}
  41. };
  42.  
  43. hand::hand(string &handString) {
  44.     transform(handString.begin(),handString.end(),handString.begin(),::tolower);
  45.     //Extract hand.
  46.     while(handString.length()!=0) {
  47.         //Get card value
  48.         string temp=getWord(handString);
  49.         int crd=getCard(temp);
  50.  
  51.         //Get rid of "of" and get suit;
  52.         temp=getWord(handString);
  53.         while(temp!="hearts"&&temp!="spades"&&temp!="diamonds"&&temp!="clubs"&&handString.length()!=0) {
  54.             temp=getWord(handString);
  55.         }
  56.         cards.push_back({temp,crd});
  57.     }
  58. }
  59.  
  60. bool hand::checkWin() {
  61.     //Sets up markers
  62.     hand base=*this;
  63.     base.cards.resize(1,{"null",-1});
  64.     base.cards[0].value=-1;
  65.     hand sMarker=base;
  66.     hand rMarker=base;
  67.     rMarker.cards[0].value=0;
  68.  
  69.     //Check for an initial run of 3 or 4.
  70.     int runOf=checkRun(3,rMarker);
  71.     if(runOf==3||runOf==4) {
  72.         runOf= runOf==3?4:3;    //if runOf is 3, it becomes 4 if it is 4, it becomes 3.
  73.         if(checkRun(runOf,rMarker)) return true;
  74.         if(checkSet(runOf,sMarker)) return true;
  75.     }
  76.  
  77.     rMarker=base;
  78.     sMarker=base;
  79.     if(checkSet(3,sMarker)) {
  80.         if(checkSet(4,sMarker)) return true;
  81.         if(checkRun(4,rMarker)) return true;
  82.     }
  83.     return false;
  84. }
  85.  
  86. int hand::checkRun(int size, hand &marker) {
  87.     cout<<"\nChecking for a run of "<<size<<": ";
  88.     int run=0;
  89.     int j=0;
  90.     //Ran for each suit.
  91.     while(!run&&j<4) {
  92.         string suit;
  93.         hand hand2=*this;
  94.         if (j==0) suit="hearts";
  95.         else if (j==1) suit="spades";
  96.         else if (j==2) suit="diamonds";
  97.         else suit="clubs";
  98.         cout<<"Checking "<<suit<<". ";
  99.  
  100.         //filter for cards with suit suit.
  101.         for(unsigned int i=0;i!=hand2.cards.size();++i) {
  102.             if(hand2.cards[i].suit!=suit) {
  103.                 hand2.cards.erase(hand2.cards.begin()+i);
  104.                 --i;
  105.             }
  106.         }
  107.  
  108.         sort(hand2.cards.begin(),hand2.cards.end(),sortRank);
  109.  
  110.         //Remove the previous meld from the possible list.
  111.         //If they don't start at the same location, it will fail anyway.
  112.         //Put on two lines with a variable to improve readability at the cost of performance.
  113.         if(areEqual(hand2.cards,marker.cards)) {
  114.             int size = (hand2.cards.size()<marker.cards.size())?hand2.cards.size():marker.cards.size();
  115.             hand2.cards.erase(hand2.cards.begin(),hand2.cards.begin()+size);
  116.         }
  117.  
  118.         if(hand2.cards.size()>=size) {
  119.             unsigned int i=0;
  120.             while(i+size<=hand2.cards.size()&&run<size) {
  121.                 unsigned int n=i;
  122.                 run=1;
  123.  
  124.                 //Actually check to see if the cards are sequential
  125.                 while(n+1<hand2.cards.size()&&run<size){
  126.                     if(hand2.cards[n].value==hand2.cards[n+1].value-1){
  127.                         ++run;
  128.                     } else run=0;
  129.  
  130.                     ++n;
  131.                 }
  132.                 if(run>=size) marker=hand2;
  133.                 ++i;
  134.             }
  135.         }
  136.         ++j;
  137.     }
  138.     if(run){
  139.         cout<<"Found a run of size "<<run;
  140.     } else cout<<"Did not find a run.";
  141.     return run;
  142. }
  143.  
  144. bool hand::checkSet(int size, hand &marker) {
  145.     cout<<"\nChecking for a set of "<<size<<": ";
  146.     bool set=false;
  147.     int j=0;
  148.     while(!set&&j<14) {
  149.         cout<<j<<' ';    //Progress bar
  150.         hand hand2=*this;
  151.  
  152.         for(unsigned int i=0;i!=hand2.cards.size();++i) {
  153.             if (hand2.cards[i].value!=j) {
  154.                 hand2.cards.erase(hand2.cards.begin()+i);
  155.                 --i;
  156.             }
  157.         }
  158.  
  159.         set=((hand2.cards.size()>=size)&&!areEqual(hand2.cards,marker.cards))?true:false;
  160.         ++j;
  161.         if(set) marker=hand2;
  162.     }
  163.     cout<<"The result was "<<((set)?"true.":"false.");
  164.     return set;
  165. }
  166.  
  167. int hand::winWithCard(const card &newCard) {
  168.     for(int i=6;i>0;--i) {
  169.         hand modHand=*this;
  170.         modHand.cards[i].value=newCard.value;
  171.         modHand.cards[i].suit=newCard.suit;
  172.         if(modHand.checkWin()) return i;
  173.     }
  174.     return -1;
  175. }
  176.  
  177. int hand::winWithCard(const card &newCard, int i) {
  178.     hand modHand=*this;
  179.     modHand.cards[i].value=newCard.value;
  180.     modHand.cards[i].suit=newCard.suit;
  181.     if(modHand.checkWin()) return i;
  182.     else return -1;
  183. }
  184.  
  185. void hand::print() {
  186.     string temp=" ";
  187.     for(int i=0;i!=cards.size();++i) {
  188.         char buffer[50];
  189.         sprintf(buffer,"Card %d is the %s\n", i, cards[i].printS().c_str());
  190.         temp+=buffer;
  191.     }
  192.     temp.erase(temp.begin());
  193.     cout<<temp;
  194. }
  195.  
  196. string hand::printS() {
  197.     string temp=" ";
  198.     for(int i=0;i!=cards.size();++i) {
  199.         char buffer[50];
  200.         sprintf(buffer,"Card %d is the %s\n", i, cards[i].printS().c_str());
  201.         temp+=buffer;
  202.     }
  203.     temp.erase(temp.begin());
  204.     return temp;
  205. }
  206.  
  207. card::card(string suit2,int val) {
  208.     suit=suit2;
  209.     value=val;
  210. }
  211.  
  212. int card::points() {
  213.     if(value<10) return value;  //0-9
  214.     else if(value<=13) return 10; //Face cards (includes 10)
  215.     else return 11;  //Ace (always high here)
  216. }
  217.  
  218. void card::print() {
  219.     string temp = getCardName(value);
  220.     string suit2=suit;
  221.     temp[0]=toupper(temp[0]);
  222.     suit2[0]=toupper(suit[0]);
  223.  
  224.     cout<<temp<<" of "<<suit2;
  225. }
  226.  
  227. string card::printS() {
  228.     string temp = getCardName(value);
  229.     string suit2=suit;
  230.     temp[0]=toupper(temp[0]);
  231.     suit2[0]=toupper(suit[0]);
  232.  
  233.     return temp+" of "+suit2;
  234. }
  235.  
  236. int main() {
  237.     string handInfo;
  238.     ifstream in;
  239.     in.open("hand.txt"); //"Two of Diamonds, Three of Diamonds, Four of Diamonds, Seven of Diamonds, Seven of Clubs, Seven of Hearts, Jack of Hearts"
  240.     cout<<"Player's info: ";
  241.     getline(in,handInfo);
  242.     cout<<handInfo<<'\n';
  243.     hand h(handInfo);
  244.     in.close();
  245.  
  246.     in.open("newCard.txt"); //"Five of Diamonds"
  247.     cout<<"Next card: ";
  248.     getline(in,handInfo);
  249.     cout<<handInfo;
  250.     hand n(handInfo);       //I created a whole nother hand for the card because
  251.                             //I'm to lazy to make another card::card function
  252.                             //that inputs from a string.
  253.     int crd=h.winWithCard(n.cards[0],6);
  254.     cout<<"\n\n";
  255.     if(crd>0) {
  256.         cout<<"You can win by replacing the "<<h.cards[crd].printS();
  257.         cout<<" with the "<<n.cards[0].printS();
  258.     } else {
  259.         cout<<"You cannot win by picking up the "<<n.cards[0].printS();
  260.     }
  261.     return 0;
  262. }
  263.  
  264. void trim(string &str){
  265.     while(!isalpha(str[0])) str.erase(0,1);
  266. }
  267.  
  268. string getWord(string &str) {
  269.     string out=" ";
  270.     trim(str);
  271.     while(isalpha(str[0])) {
  272.         out+=str[0];
  273.         str.erase(0,1);
  274.     }
  275.     return out.substr(1,out.length()-1);
  276. }
  277.  
  278. int getCard(const string &str) {
  279.     if(str=="ace") return 1;
  280.     if(str=="two") return 2;
  281.     if(str=="three") return 3;
  282.     if(str=="four") return 4;
  283.     if(str=="five") return 5;
  284.     if(str=="six") return 6;
  285.     if(str=="seven") return 7;
  286.     if(str=="eight") return 8;
  287.     if(str=="nine") return 9;
  288.     if(str=="ten") return 10;
  289.     if(str=="jack") return 11;
  290.     if(str=="queen") return 12;
  291.     if(str=="king") return 13;
  292.     return 0;
  293. }
  294.  
  295. string getCardName (int c) {
  296.     if(c==1) return "ace";
  297.     if(c==2) return "two";
  298.     if(c==3) return "three";
  299.     if(c==4) return "four";
  300.     if(c==5) return "five";
  301.     if(c==6) return "six";
  302.     if(c==7) return "seven";
  303.     if(c==8) return "eight";
  304.     if(c==9) return "nine";
  305.     if(c==10) return "ten";
  306.     if(c==11) return "jack";
  307.     if(c==12) return "queen";
  308.     if(c==13) return "king";
  309.     return "invalid card";
  310. }
  311.  
  312. bool sortRank(card c1, card c2) {
  313.     return c1.value<c2.value;
  314. }
  315.  
  316. //Returns true if the first v2.size() digits match.
  317. bool areEqual(vector<card>&v1,vector<card>&v2) {
  318.     int size= (v1.size()<v2.size())? v1.size():v2.size();
  319.     for(int i=size-1;i>=0;--i) {
  320.         if(!(v1[i]==v2[i])) {
  321.             return false;
  322.         }
  323.     }
  324.  
  325.     return true;
  326. }
Advertisement
Add Comment
Please, Sign In to add comment