Situatie
Solutie
Pasi de urmat
/*=================main.cpp===========================*/#include <iostream>#include "Solitaire.h"using namespace std;void HandleMove(Solitaire& game);void HandleMoveToAnswer(Solitaire& game);void ClearScreen();int main(int argc, char** argv){Solitaire game = Solitaire();game.PrintAllDetails();bool running = true;do{char option = ' ';cout<<endl<<endl;cout<<"1. move card between rows";cout<<"\n2. move to answers";cout<<"\n3. deal";cout<<"\n0. quit";cout<<"\nEnter option:";cin >> option;/* 48 - 55 ascii code is 0 - 7 */if(game.GameCompleted()){ClearScreen();cout<<"\n\n\n\t\t\t CONGRATULATIONS YOU WON!!!\n\n";cin.get();running = false;}else{switch((int)option){case 48:running = false;break;case 49:HandleMove(game);break;case 50:HandleMoveToAnswer(game);break;case 51:game.Deal(3);break;default:cout<<"\ninvalid option";cin.ignore(80,'\n');break;}ClearScreen();game.PrintAllDetails();}}while(running);return 0;}void HandleMove(Solitaire& game){char from = '0' ,to = '0';cout<<endl <<endl;cout<<"From (7 for deck):";cin >> from;cout<< "To: ";cin>> to;if( ((int)from >= 48 && (int)from <= 55) &&((int)from >= 48 && (int)to <= 54) ){game.MakeMoveRowToRow((int)from - 48,(int)to - 48);}else{cout<<"invalid input";cin.get();cin.get();}}void HandleMoveToAnswer(Solitaire& game){char from = 0;cout<<endl <<endl;cout<< "From (7 for deck): ";cin>> from;if((int)from >= 48 && (int)from <= 55)game.MakeSuitMove((int)from - 48);else{cout<<"invalid input";cin.get();cin.get();}}void ClearScreen(){#ifdef __linux__system("clear");#elif _WIN32system("cls");#endif}/*=============================================*//*=================Card.h=======================*/#pragma once#include <iostream>#ifdef _WIN32#include<windows.h>const static int BLACK = 0;const static int BLUE = 9;const static int RED = 12;const static int WHITE = 15;#elif __linux__#include "stdlib.h"#endifclass Card{public:Card(void);Card(char rank,char suit);~Card(void);void Flip();bool GetIsFaceUp();int GetSolitaireValue();char GetCardSuit();char GetCardRank();friend std::ostream & operator<< (std::ostream & os, Card& c);/*Used to navigate up anddown the cards in a row*/Card* parent;Card* child;private:char rank;char suit;bool isFaceUp;};/*=============================================*//*====================Card.cpp===================*/#include "Card.h"Card::Card(void){}Card::Card(char r, char s):rank(r),suit(s),isFaceUp(false),child(NULL),parent(NULL){}Card::~Card(void){}void Card::Flip(){isFaceUp = !isFaceUp;}bool Card::GetIsFaceUp(){return isFaceUp;}char Card::GetCardSuit(){return suit;}char Card::GetCardRank(){return rank;}int Card::GetSolitaireValue(){if(rank == 'A')return 1;else if(rank == 'T')return 10;else if(rank == 'J')return 11;else if(rank == 'Q')return 12;else if(rank == 'K')return 13;else{char c[] = {rank, '\0'};return atoi(c);}}std::ostream & operator<< (std::ostream & os, Card& c){#ifdef _WIN32HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);if(c.suit == 'c' || c.suit == 's')SetConsoleTextAttribute(handle, BLUE);elseSetConsoleTextAttribute(handle,RED);os<< c.suit << c.rank;SetConsoleTextAttribute(handle,WHITE);#elif __linux__if(c.suit == 'c' || c.suit == 's')os<<"\033[22;34m";elseos<<"\033[22;31m";os<< c.suit << c.rank;os<<"\033[22;30m";#endifreturn os;}/*=============================================*//*====================Deck.h====================*/#pragma once#include "Card.h"#include <ctime>#include <iostream>#include "TableCard.h"const static int RANK_SIZE = 13;const static int SUIT_SIZE = 4;const static char RANKS[] = {'A','2','3','4','5','6','7','8','9','T','J','Q','K'};const static char SUITS[] = {'h','d','s','c'};class Deck{public:Deck(void);~Deck(void);void Populate(void);void Shuffle(void);void PrintDeck(void);void PopulateVector(TableCard& aDeck);private:Card _deck[52];int currentIndex;};/*==============================================*//*====================Deck.cpp====================*/#include "Deck.h"Deck::Deck(void):currentIndex(0){srand((unsigned)time(0));Populate();}Deck::~Deck(void){}void Deck::Populate(){int index = 0;for(int i=0; i<SUIT_SIZE; i++){for(int j=0; j<RANK_SIZE;j++){_deck[index] = Card(RANKS[j],SUITS[i]);index++;}}}void Deck::Shuffle(){int max = SUIT_SIZE * RANK_SIZE;for(int i=0; i<max-1; i++){int randNum = rand() % 52;std::swap(_deck[i],_deck[randNum]);}}void Deck::PrintDeck(void){int max = SUIT_SIZE * RANK_SIZE;for(int i=0; i<max; i++){if(i %13 == 0)std::cout<< '\n' <<'\n';std::cout<< _deck[i] << " " << _deck[i].GetBlackjackValue() << " ";}}void Deck::PopulateVector(TableCard& aDeck){int max = SUIT_SIZE * RANK_SIZE;aDeck.Clear();for(int i=0; i<max; i++)aDeck.PushValueCopy(_deck[i]);}/*===============================================*//*====================TableCard.h===================*/#pragma once#include "Card.h"#include <vector>class TableCard{public:TableCard(int maxSize);~TableCard(void);Card& operator[](int index);bool Push(Card& card);bool PushValueCopy(Card card);int Size();bool empty();Card& top(void);bool RemoveAt(int index);bool Pop();void Clear();static void MoveBetween(TableCard& from, TableCard& to);private:int _maxSize;int _size;std::vector<Card*> _cards;};/*=============================================*//*====================TableCard.cpp================*/#include "TableCard.h"TableCard::TableCard(int maxSize):_size(0),_maxSize(maxSize){_cards.resize(maxSize);}TableCard::~TableCard(void){}bool TableCard::Push(Card& card){if(_size < _maxSize){_cards[_size] = &card;_size++;return true;}return false;}bool TableCard::PushValueCopy(Card card){if(_size < _maxSize);{_cards[_size] = new Card(card);_size++;return true;}return false;}void TableCard::Clear(){for(int i=0; i<_size; i++)_cards[i] = NULL;_size = 0;}bool TableCard::empty(){if(_size == 0)return true;return false;}Card& TableCard::top(void){if(_size > 0)return *_cards[_size-1];}bool TableCard::RemoveAt(int index){if(index >= 0 && index < _maxSize){_cards[index] = NULL;_size--;return true;}return false;}int TableCard::Size(){return _size;}bool TableCard::Pop(){if(_size > 0){_cards[_size - 1] = NULL;_size--;return true;}return false;}Card& TableCard::operator[](int index){if(index >= 0 && index <= _size)return *_cards[index];}void TableCard::MoveBetween(TableCard& from, TableCard& to){to.Push(from.top());from.Pop();}/*=============================================*//*====================Solitaire.h==================*/#pragma once#include <iostream>#include <vector>#include "Deck.h"#include "Card.h"#include "TableCard.h"const static int TABLE_SIZE = 7;class Solitaire{public:Solitaire(void);~Solitaire(void);void PopulateTable(void);void Deal(int numToDeal=1);/* Functions for validating and moving cards */void MakeSuitMove(int from);void MakeMoveBetweenRows(int from, int to);void MakeMoveDeckToRow(int to);void MakeMoveRowToRow(int from, int to);bool ValidMove(int from, int to);bool ValidRowToRowMove(Card* fromCard, int to);bool ValidSuitMove(int from);/* Checks to see if all answer sections full */bool GameCompleted();/* Functions for printing card details */void PrintAllDetails(void);void PrintSuitDetails(void);void PrintDeckDetails(void);private:TableCard _deck;TableCard _discardedCards;std::vector<TableCard> _tableCards;//Destination of cards. When all filled player winsstd::vector<TableCard> _suitCards;};/*==============================================*//*====================Solitaire.cpp=================*/#include "Solitaire.h"using namespace std;Solitaire::Solitaire(void):_deck(52),_discardedCards(52){//Uses the deck class to populate solitaire deck//Shuffle the deck to randomizeDeck deck = Deck();deck.Shuffle();deck.PopulateVector(_deck);for(int i=0; i<TABLE_SIZE; i++){TableCard tableCard = TableCard(20);_tableCards.push_back(tableCard);}//_suitCards.resize(4);for(int i=0; i<4; i++){TableCard suitCard = TableCard(13);_suitCards.push_back(suitCard);}PopulateTable();}Solitaire::~Solitaire(void){}void Solitaire::PopulateTable(void){for(int i=0; i<TABLE_SIZE; i++){for(int j=0; j<TABLE_SIZE -i; j++){if(j == (TABLE_SIZE - i) - 1)_deck.top().Flip();_tableCards[j].Push(_deck.top());_deck.Pop();}}}void Solitaire::Deal(int numToDeal){int size = _deck.Size();for(int i=0; i<size; i++){if(_deck.top().GetIsFaceUp()){_deck.top().Flip();_discardedCards.Push(_deck.top());_deck.Pop();}}if(_deck.empty()){for(int i=_discardedCards.Size()-1; i>=0; i--)_deck.Push(_discardedCards[i]);_discardedCards.Clear();}int index = 0;for(int i=0; i<numToDeal; i++){index = _deck.Size() -i -1;if(index >= 0){_deck[index].Flip();}elsebreak;}}void Solitaire::PrintSuitDetails(){cout<<"=============================================\n";for(int j=0; j<_suitCards.size(); j++){switch(j){case 0:cout<< "h :";break;case 1:cout<< "d :";break;case 2:cout<< "s :";break;case 3:cout<< "c :";break;}for(int i=0; i<_suitCards[j].Size(); i++){if(&_suitCards[j][i] != NULL)cout<<_suitCards[j][i] << " ";elsebreak;}cout<< endl;}cout<<"=============================================\n";cout<<endl;}void Solitaire::PrintDeckDetails(){cout<<"--------------------------------------------\n";cout<<"|Deck: ";for(unsigned int i=0; i<_deck.Size(); i++){if(_deck[i].GetIsFaceUp())cout<<_deck[i] << " ";}cout<<"\n--------------------------------------------\n";}void Solitaire::PrintAllDetails(){PrintDeckDetails();PrintSuitDetails();cout<< "| 6 | \t | 5 | \t | 4 | \t | 3 | \t | 2 | \t | 1 | \t | 0 |\n";cout<< "----- \t ----- \t ----- \t ----- \t ----- \t ----- \t -----\n";//Cannot be unsigned as number is always greater than or equal to 0 --int colMax = _tableCards.size();int rowMax = 0;for(int i=0; i<colMax; i++){if(_tableCards[i].Size() > rowMax){rowMax = _tableCards[i].Size();}}for(int i=0; i<rowMax; i++){for(int j=colMax-1; j>=0; j--){if(i >= _tableCards[j].Size()){cout<< " \t " ;continue;}if(_tableCards[j][i].GetIsFaceUp())cout << " " << _tableCards[j][i] << " \t ";elsecout << " " <<(char)254 << " \t ";}cout<<endl;}cout<<endl<<endl;//SHOW DISCARDED CARDS/*cout<<"\nCards in the used pile: \n\n";for(unsigned int i=0; i<_discardedCards.Size(); i++)cout<<_discardedCards[i] << " ";cout<<endl<<endl;*///DISPLAYS CHILDREN AND PARENTS/*for(int i=0; i<_tableCards.size(); i++){cout<< i << ": \n" ;for(int j= 0; j< _tableCards[i].Size(); j++){if(_tableCards[i][j].child != NULL){cout<< _tableCards[i][j] << "'s child is " << *_tableCards[i][j].child << endl;}if(_tableCards[i][j].parent != NULL){cout<< _tableCards[i][j] << "'s parent is " << *_tableCards[i][j].parent << endl;}}}*/}bool Solitaire::ValidMove(int from, int to){//start move and end move the sameif(from == to && from != 7)return false;Card* toCard;Card* fromCard;if(from == 7){if(!_deck.empty()){if(!_deck.top().GetIsFaceUp()){return false;}else{fromCard = &_deck.top();}}else{return false;}}else{//if no card in moving from row not validif(!_tableCards[from].empty())fromCard = &_tableCards[from].top();elsereturn false;}if(!_tableCards[to].empty())toCard = &_tableCards[to].top();//move king to empty spaceif(_tableCards[to].empty()){if(fromCard->GetCardRank() == 'K')return true;elsereturn false;}else if(fromCard->GetSolitaireValue() == toCard->GetSolitaireValue()-1 ){int toColor = 0, fromColor = 0;if(toCard->GetCardSuit() == 'h' || toCard->GetCardSuit() == 'd')toColor = 0;elsetoColor = 1;if(fromCard->GetCardSuit() =='h' || fromCard->GetCardSuit() == 'd')fromColor = 0;elsefromColor = 1;if(fromColor == toColor)return false;elsereturn true;}return false;}bool Solitaire::ValidSuitMove(int from){Card* fromCard;if(from == 7){if(!_deck.empty()){if(!_deck.top().GetIsFaceUp()){return false;}else{fromCard = &_deck.top();}}else{return false;}}else{if(!_tableCards[from].empty())fromCard = &_tableCards[from].top();elsereturn false;}char suit = fromCard->GetCardSuit();int moveIndex = 0;switch(suit){case 'h':moveIndex = 0;break;case 'd':moveIndex = 1;break;case 's':moveIndex = 2;break;case 'c':moveIndex = 3;break;}if(fromCard->GetSolitaireValue() ==_suitCards[moveIndex].Size() + 1 ){if(!_suitCards[moveIndex].Size() == 0){if(fromCard->parent != NULL)fromCard->parent->child = NULL;fromCard->parent = &_suitCards[moveIndex].top();_suitCards[moveIndex].top().child = fromCard;fromCard->child = NULL;}if(from != 7){TableCard::MoveBetween(_tableCards[from],_suitCards[moveIndex]);if(!_tableCards[from].empty()){if(!_tableCards[from].top().GetIsFaceUp())_tableCards[from].top().Flip();}}else{_suitCards[moveIndex].Push(_deck.top());_deck.Pop();}}return false;}void Solitaire::MakeSuitMove(int from){/* validSuit move also makes move */ValidSuitMove(from) ;}void Solitaire::MakeMoveBetweenRows(int from, int to){if(ValidMove(from,to)){if(!_tableCards[to].empty())_tableCards[to].top().child = &_tableCards[from].top();if(_tableCards[from].top().GetCardRank() != 'K')_tableCards[from].top().parent = &_tableCards[to].top();TableCard::MoveBetween(_tableCards[from], _tableCards[to]);if(!_tableCards[from].empty())if(!_tableCards[from].top().GetIsFaceUp())_tableCards[from].top().Flip();}}void Solitaire::MakeMoveDeckToRow(int to){if(ValidMove(7 ,to)){if(!_tableCards[to].empty())_tableCards[to].top().child = &_deck.top();if(_deck.top().GetCardRank() != 'K')_deck.top().parent = & _tableCards[to].top();_tableCards[to].Push(_deck.top());_deck.Pop();}}void Solitaire::MakeMoveRowToRow(int from, int to){if(from == 7){MakeMoveDeckToRow(to);return;}else if(_tableCards[from].Size() == 0)return;Card* fromCard;fromCard = &_tableCards[from].top();if(fromCard->parent == NULL)MakeMoveBetweenRows(from,to);else{int pos = _tableCards[from].Size()-1;bool checkParent = true;bool found = false;while(checkParent && !found){if(ValidRowToRowMove(fromCard,to))found = true;else if(fromCard->parent == NULL)checkParent = false;else{fromCard = fromCard->parent;pos--;}}if(found){bool hasChildren = true;if(fromCard->parent != NULL)fromCard->parent->child = NULL;while(hasChildren){if(!_tableCards[to].empty()){fromCard->parent = &_tableCards[to].top();_tableCards[to].top().child = fromCard;}_tableCards[to].Push(*fromCard);_tableCards[from].RemoveAt(pos);fromCard = fromCard->child;pos++;if(fromCard == NULL)hasChildren = false;}}if(!_tableCards[from].empty())if(!_tableCards[from].top().GetIsFaceUp())_tableCards[from].top().Flip();}}bool Solitaire::ValidRowToRowMove(Card* fromCard, int to){Card* toCard;if(!_tableCards[to].empty())toCard = &_tableCards[to].top();//move king to empty spaceif(_tableCards[to].empty()){if(fromCard->GetCardRank() == 'K')return true;elsereturn false;}else if(fromCard->GetSolitaireValue() == toCard->GetSolitaireValue()-1 ){int toColor = 0, fromColor = 0;if(toCard->GetCardSuit() == 'h' || toCard->GetCardSuit() == 'd')toColor = 0;elsetoColor = 1;if(fromCard->GetCardSuit() =='h' || fromCard->GetCardSuit() == 'd')fromColor = 0;elsefromColor = 1;if(fromColor == toColor)return false;elsereturn true;}return false;}bool Solitaire::GameCompleted(){for(int i=0; i<_suitCards.size(); i++)if(_suitCards[i].Size() < 13)return false;return true;}/*==============================================*/

Leave A Comment?