Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <iostream>
- #include <vector>
- #include <cstdlib>
- #include <fstream>
- #include <algorithm>
- using namespace std;
- struct hand;
- struct card;
- void trim(string &str);
- string getWord(string &str);
- int getCard(const string &str);
- string getCardName(int c);
- bool sortRank(card c1, card c2);
- bool areEqual(vector<card>&v1,vector<card>&v2);
- struct hand{
- vector<card> cards; //Cards in the hand.
- bool checkWin(); //Returns true if the hand wins.
- //Returns true if the hand is a set of size.
- bool checkSet(int size, hand &marker);
- //Returns true if the hand is a run of size
- int checkRun(int size, hand &marker);
- int winWithCard(const card &newCard);
- int winWithCard(const card &newCard, int j);
- hand(string &handString);
- void print();
- string printS();
- };
- struct card{
- string suit; //Suit of the card.
- int value; //Number of the card.
- card(string suit,int value);
- int points(); //Returns the point value of the card.
- void print();
- string printS();
- inline bool operator== (const card &rhs) {return rhs.value==this->value&&this->suit==rhs.suit;}
- };
- hand::hand(string &handString) {
- transform(handString.begin(),handString.end(),handString.begin(),::tolower);
- //Extract hand.
- while(handString.length()!=0) {
- //Get card value
- string temp=getWord(handString);
- int crd=getCard(temp);
- //Get rid of "of" and get suit;
- temp=getWord(handString);
- while(temp!="hearts"&&temp!="spades"&&temp!="diamonds"&&temp!="clubs"&&handString.length()!=0) {
- temp=getWord(handString);
- }
- cards.push_back({temp,crd});
- }
- }
- bool hand::checkWin() {
- //Sets up markers
- hand base=*this;
- base.cards.resize(1,{"null",-1});
- base.cards[0].value=-1;
- hand sMarker=base;
- hand rMarker=base;
- rMarker.cards[0].value=0;
- //Check for an initial run of 3 or 4.
- int runOf=checkRun(3,rMarker);
- if(runOf==3||runOf==4) {
- runOf= runOf==3?4:3; //if runOf is 3, it becomes 4 if it is 4, it becomes 3.
- if(checkRun(runOf,rMarker)) return true;
- if(checkSet(runOf,sMarker)) return true;
- }
- rMarker=base;
- sMarker=base;
- if(checkSet(3,sMarker)) {
- if(checkSet(4,sMarker)) return true;
- if(checkRun(4,rMarker)) return true;
- }
- return false;
- }
- int hand::checkRun(int size, hand &marker) {
- cout<<"\nChecking for a run of "<<size<<": ";
- int run=0;
- int j=0;
- //Ran for each suit.
- while(!run&&j<4) {
- string suit;
- hand hand2=*this;
- if (j==0) suit="hearts";
- else if (j==1) suit="spades";
- else if (j==2) suit="diamonds";
- else suit="clubs";
- cout<<"Checking "<<suit<<". ";
- //filter for cards with suit suit.
- for(unsigned int i=0;i!=hand2.cards.size();++i) {
- if(hand2.cards[i].suit!=suit) {
- hand2.cards.erase(hand2.cards.begin()+i);
- --i;
- }
- }
- sort(hand2.cards.begin(),hand2.cards.end(),sortRank);
- //Remove the previous meld from the possible list.
- //If they don't start at the same location, it will fail anyway.
- //Put on two lines with a variable to improve readability at the cost of performance.
- if(areEqual(hand2.cards,marker.cards)) {
- int size = (hand2.cards.size()<marker.cards.size())?hand2.cards.size():marker.cards.size();
- hand2.cards.erase(hand2.cards.begin(),hand2.cards.begin()+size);
- }
- if(hand2.cards.size()>=size) {
- unsigned int i=0;
- while(i+size<=hand2.cards.size()&&run<size) {
- unsigned int n=i;
- run=1;
- //Actually check to see if the cards are sequential
- while(n+1<hand2.cards.size()&&run<size){
- if(hand2.cards[n].value==hand2.cards[n+1].value-1){
- ++run;
- } else run=0;
- ++n;
- }
- if(run>=size) marker=hand2;
- ++i;
- }
- }
- ++j;
- }
- if(run){
- cout<<"Found a run of size "<<run;
- } else cout<<"Did not find a run.";
- return run;
- }
- bool hand::checkSet(int size, hand &marker) {
- cout<<"\nChecking for a set of "<<size<<": ";
- bool set=false;
- int j=0;
- while(!set&&j<14) {
- cout<<j<<' '; //Progress bar
- hand hand2=*this;
- for(unsigned int i=0;i!=hand2.cards.size();++i) {
- if (hand2.cards[i].value!=j) {
- hand2.cards.erase(hand2.cards.begin()+i);
- --i;
- }
- }
- set=((hand2.cards.size()>=size)&&!areEqual(hand2.cards,marker.cards))?true:false;
- ++j;
- if(set) marker=hand2;
- }
- cout<<"The result was "<<((set)?"true.":"false.");
- return set;
- }
- int hand::winWithCard(const card &newCard) {
- for(int i=6;i>0;--i) {
- hand modHand=*this;
- modHand.cards[i].value=newCard.value;
- modHand.cards[i].suit=newCard.suit;
- if(modHand.checkWin()) return i;
- }
- return -1;
- }
- int hand::winWithCard(const card &newCard, int i) {
- hand modHand=*this;
- modHand.cards[i].value=newCard.value;
- modHand.cards[i].suit=newCard.suit;
- if(modHand.checkWin()) return i;
- else return -1;
- }
- void hand::print() {
- string temp=" ";
- for(int i=0;i!=cards.size();++i) {
- char buffer[50];
- sprintf(buffer,"Card %d is the %s\n", i, cards[i].printS().c_str());
- temp+=buffer;
- }
- temp.erase(temp.begin());
- cout<<temp;
- }
- string hand::printS() {
- string temp=" ";
- for(int i=0;i!=cards.size();++i) {
- char buffer[50];
- sprintf(buffer,"Card %d is the %s\n", i, cards[i].printS().c_str());
- temp+=buffer;
- }
- temp.erase(temp.begin());
- return temp;
- }
- card::card(string suit2,int val) {
- suit=suit2;
- value=val;
- }
- int card::points() {
- if(value<10) return value; //0-9
- else if(value<=13) return 10; //Face cards (includes 10)
- else return 11; //Ace (always high here)
- }
- void card::print() {
- string temp = getCardName(value);
- string suit2=suit;
- temp[0]=toupper(temp[0]);
- suit2[0]=toupper(suit[0]);
- cout<<temp<<" of "<<suit2;
- }
- string card::printS() {
- string temp = getCardName(value);
- string suit2=suit;
- temp[0]=toupper(temp[0]);
- suit2[0]=toupper(suit[0]);
- return temp+" of "+suit2;
- }
- int main() {
- string handInfo;
- ifstream in;
- 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"
- cout<<"Player's info: ";
- getline(in,handInfo);
- cout<<handInfo<<'\n';
- hand h(handInfo);
- in.close();
- in.open("newCard.txt"); //"Five of Diamonds"
- cout<<"Next card: ";
- getline(in,handInfo);
- cout<<handInfo;
- hand n(handInfo); //I created a whole nother hand for the card because
- //I'm to lazy to make another card::card function
- //that inputs from a string.
- int crd=h.winWithCard(n.cards[0],6);
- cout<<"\n\n";
- if(crd>0) {
- cout<<"You can win by replacing the "<<h.cards[crd].printS();
- cout<<" with the "<<n.cards[0].printS();
- } else {
- cout<<"You cannot win by picking up the "<<n.cards[0].printS();
- }
- return 0;
- }
- void trim(string &str){
- while(!isalpha(str[0])) str.erase(0,1);
- }
- string getWord(string &str) {
- string out=" ";
- trim(str);
- while(isalpha(str[0])) {
- out+=str[0];
- str.erase(0,1);
- }
- return out.substr(1,out.length()-1);
- }
- int getCard(const string &str) {
- if(str=="ace") return 1;
- if(str=="two") return 2;
- if(str=="three") return 3;
- if(str=="four") return 4;
- if(str=="five") return 5;
- if(str=="six") return 6;
- if(str=="seven") return 7;
- if(str=="eight") return 8;
- if(str=="nine") return 9;
- if(str=="ten") return 10;
- if(str=="jack") return 11;
- if(str=="queen") return 12;
- if(str=="king") return 13;
- return 0;
- }
- string getCardName (int c) {
- if(c==1) return "ace";
- if(c==2) return "two";
- if(c==3) return "three";
- if(c==4) return "four";
- if(c==5) return "five";
- if(c==6) return "six";
- if(c==7) return "seven";
- if(c==8) return "eight";
- if(c==9) return "nine";
- if(c==10) return "ten";
- if(c==11) return "jack";
- if(c==12) return "queen";
- if(c==13) return "king";
- return "invalid card";
- }
- bool sortRank(card c1, card c2) {
- return c1.value<c2.value;
- }
- //Returns true if the first v2.size() digits match.
- bool areEqual(vector<card>&v1,vector<card>&v2) {
- int size= (v1.size()<v2.size())? v1.size():v2.size();
- for(int i=size-1;i>=0;--i) {
- if(!(v1[i]==v2[i])) {
- return false;
- }
- }
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment