From dcfd43f8f48072754b9d952b621bac1cddbb7103 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Sat, 29 Jan 2011 12:13:21 -0600 Subject: Initial commit --- Makefile | 44 ++++++++++++++ card.cpp | 91 ++++++++++++++++++++++++++++ card.h | 29 +++++++++ cardpile.cpp | 88 +++++++++++++++++++++++++++ cardpile.h | 43 +++++++++++++ game.cpp | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ game.h | 57 +++++++++++++++++ main.cpp | 71 ++++++++++++++++++++++ opponent.cpp | 44 ++++++++++++++ opponent.h | 22 +++++++ user.cpp | 45 ++++++++++++++ user.h | 24 ++++++++ 12 files changed, 753 insertions(+) create mode 100644 Makefile create mode 100644 card.cpp create mode 100644 card.h create mode 100644 cardpile.cpp create mode 100644 cardpile.h create mode 100644 game.cpp create mode 100644 game.h create mode 100644 main.cpp create mode 100644 opponent.cpp create mode 100644 opponent.h create mode 100644 user.cpp create mode 100644 user.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..468cd4c --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +# Kamil Kaminski +# NetID: kkamin8 +# +# CS340 +# Project 1, Poker Game +# +# Makefile + +PROG = poker +OBJS = main.o cardpile.o card.o game.o user.o opponent.o +CC = g++ +DBGFLAGS = -g -O0 +ifdef DEBUG + CFLAGS = $(DBGFLAGS) -D DEBUG -std=c++98 -pedantic-errors -Wall +else + CFLAGS = -O2 -std=c++98 -pedantic-errors -Wall +endif +LDFLAGS = -lm + +$(PROG): $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) -o $(PROG) + +main.o: %.o: %.cpp cardpile.h card.h + $(CC) -c $(CFLAGS) $< + +cardpile.o: %.o: %.cpp %.h card.h + $(CC) -c $(CFLAGS) $< + +card.o: %.o: %.cpp %.h + $(CC) -c $(CFLAGS) $< + +game.o: %.o: %.cpp %.h + $(CC) -c $(CFLAGS) $< + +user.o: %.o: %.cpp %.h + $(CC) -c $(CFLAGS) $< + +opponent.o: %.o: %.cpp %.h + $(CC) -c $(CFLAGS) $< + +.PHONY: clean + +clean: + rm -f ./$(OBJS) ./$(PROG) diff --git a/card.cpp b/card.cpp new file mode 100644 index 0000000..36704b8 --- /dev/null +++ b/card.cpp @@ -0,0 +1,91 @@ +/* + * card.cpp + * + * + */ + +#include "card.h" + +Card::Card(void) : type(""), rank(0) +{ + +} + +Card::Card(string &str) +{ + type = str; +} + +string Card::getType(void) +{ + return type; +} + +void Card::rankCard(void) +{ + char c; + c = getType()[0]; + + switch (c) + { + case 'A': + rank = 13; + break; + case 'K': + rank = 12; + break; + case 'Q': + rank = 11; + break; + case 'J': + rank = 10; + break; + case 'T': + rank = 9; + break; + case '9': + rank = 8; + break; + case '8': + rank = 7; + break; + case '7': + rank = 6; + break; + case '6': + rank = 5; + break; + case '5': + rank = 4; + break; + case '4': + rank = 3; + break; + case '3': + rank = 2; + break; + case '2': + rank = 1; + break; + default: + std::cerr << "something went wrong while ranking a card" << endl; + break; + } +} + +void Card::sortCards(Card **cards) +{ + /* bubble sort */ + int i, j; + Card *tmp; + + for (i = 0; i < 5; i++) + for (j = 0; j < 5-i-1; j++) + if (cards[j]->rank < cards[j+1]->rank) + { + tmp = cards[j]; + cards[j] = cards[j+1]; + cards[j+1] = tmp; + } +} + diff --git a/card.h b/card.h new file mode 100644 index 0000000..d97cb70 --- /dev/null +++ b/card.h @@ -0,0 +1,29 @@ +#ifndef _CARD_H_ +#define _CARD_H_ + +#include +#include + +using std::string; +using std::cout; +using std::endl; + +class Card +{ + private: + /* card + suit */ + string type; + int rank; + + public: + Card(void); + Card(string &); + + /* could be overloaded with cout's << operator */ + string getType(void); + void rankCard(void); + void sortCards(Card **); +}; + +#endif + diff --git a/cardpile.cpp b/cardpile.cpp new file mode 100644 index 0000000..f5bed61 --- /dev/null +++ b/cardpile.cpp @@ -0,0 +1,88 @@ +/* + * cardpile.cpp + * + * Notes: This class is inherited multiple of times, so virtual keyword will need + * to be used to avoid making multiple instances of this class and to avoid + * ambiguities. + * + */ + +#include "cardpile.h" + +CardPile::CardPile(void) : deckCurrIndex(51), discardPileCurrIndex(0) +{ + /* generate deck of 52 cards */ + int i, j; + int k = 0; + string suit[4] = {"C","D","H","S"}; + string c[13] = {"A","2","3","4","5","6","7","8","9","T","J","Q","K"}; + string tmp; + + for (i = 0; i < 4; i++) + for (j = 0; j < 13; j++, k++) + { + tmp = c[j] + suit[i]; + deck[k] = new Card(tmp); + deck[k]->rankCard(); + } +} + +CardPile::~CardPile(void) +{ + int i; + for (i = 0; i < 52; i++) + delete deck[i]; +} + +Card CardPile::getCard(int index) +{ + if ((index >= 0) && (index < 52)) + return *deck[index]; + else + return Card(); +} + +void CardPile::printPile(void) +{ + int i; + for (i = 1; i <= deckCurrIndex + 1; i++) + { + if (deck[i]) + cout << deck[i-1]->getType() << " "; + + if ( (i % 13) == 0 && i != deckCurrIndex+1) + cout << endl; + } + + cout << endl; +} + +Card *CardPile::getCardFromDeck(int index) +{ + return deck[index]; +} + +void CardPile::putCardToDeck(int index, Card *card) +{ + deck[index] = card; +} + +void CardPile::putCardToDiscardPile(Card *card) +{ + discardPile[discardPileCurrIndex] = card; + discardPileCurrIndex++; +} + +Card *CardPile::PopCardFromDeck(void) +{ + if (deckCurrIndex >= 0) + return deck[deckCurrIndex--]; + else + return NULL; +} + +void CardPile::resetDeck(void) +{ + deckCurrIndex = 51; +} + diff --git a/cardpile.h b/cardpile.h new file mode 100644 index 0000000..eb38e83 --- /dev/null +++ b/cardpile.h @@ -0,0 +1,43 @@ +#ifndef _CARDPILE_H_ +#define _CARDPILE_H_ + +#include "card.h" +#include +#include + +using std::cout; +using std::endl; + +using std::string; + +class CardPile : public Card +{ + private: + /* draw pile */ + Card *deck[52]; + int deckCurrIndex; + + /* discard pile */ + Card *discardPile[52]; + int discardPileCurrIndex; + + protected: + + public: + CardPile(void); + ~CardPile(void); + + Card getCard(int); + void printPile(void); + + /* used by sorting algorithm to peek at the card or to assign new card */ + Card *getCardFromDeck(int); + void putCardToDeck(int, Card *); + + void putCardToDiscardPile(Card *); + Card *PopCardFromDeck(void); + void resetDeck(void); +}; + +#endif + diff --git a/game.cpp b/game.cpp new file mode 100644 index 0000000..390fd82 --- /dev/null +++ b/game.cpp @@ -0,0 +1,195 @@ +/* + * game.cpp + * + * + */ + +#include "game.h" +#include + +/* forward declaration of hands array, very interesting, I didn't know C++ needs this */ +string *Game::hands[10]; + +Game::Game(void) +{ + hands[0] = new string("Royal Flush"); + hands[1] = new string("Straight Flush"); + hands[2] = new string("Four of a Kind"); + hands[3] = new string("Full House"); + hands[4] = new string("Flush"); + hands[5] = new string("Straight"); + hands[6] = new string("Three of a Kind"); + hands[7] = new string("Two Pair"); + hands[8] = new string("One Pair"); + hands[9] = new string("High Card"); +} + +void Game::shufflePile(void) +{ + /* interesting algorithm that was discussed in the class */ + Card *tmp; + int i, j; + for (i = 0; i < 52; i++) + { + j = rand() % 52; + tmp = getCardFromDeck(i); + + putCardToDeck(i, getCardFromDeck(j)); + putCardToDeck(j, tmp); + } +} + +int Game::parseInt(string *msg, int rangeA, int rangeB) +{ + int tmp; + bool continueAsking = true; + + while (continueAsking) + { + if (msg) + cout << *msg; + + if (!(cin >> tmp)) + { + cin.clear(); + cin.ignore(std::numeric_limits::max(), '\n'); + PRINT_COLOR(ANSI_COLOR_RED, "Invalid input!\n"); + continue; + } + + if ((tmp >= rangeA) && (tmp <= rangeB)) + continueAsking = false; + else + PRINT_COLOR(ANSI_COLOR_YELLOW, "Number not in the range!\n"); + } + + return tmp; +} + +void Game::askForNumberOfOpponents(void) +{ + bool continueAsking = true; + while (continueAsking) + { + cout << "Enter the amount of opponents between 1 to 3: "; + + if (!(cin >> numOfOpponents)) + { + cin.clear(); + cin.ignore(std::numeric_limits::max(), '\n'); + PRINT_COLOR(ANSI_COLOR_RED, "Invalid character(s)!\n"); + continue; + } + + if ((numOfOpponents >= 1) && (numOfOpponents <= 3)) + continueAsking = false; + else + PRINT_COLOR(ANSI_COLOR_YELLOW, "Number not in the range!\n"); + } +} + +void Game::repeatGame(bool *quit) +{ + bool continueAsking = true; + char play_again; + cout << endl; + while (continueAsking) + { + cout << "Play again? (y/n) "; + cin >> play_again; + play_again = tolower(play_again); + + if (play_again == 'y') + continueAsking = false; + + else if (play_again == 'n') + { + continueAsking = false; + *quit = true; + } + } +} + +int Game::howManyCardsOfSameSuit(Card **cards) +{ + char c, l; + l = cards[0]->getType()[1]; + + int i; + for (i = 1; i < 5; i++) + { + c = cards[i]->getType()[1]; + if (c != l) + break; + } + + return i; +} + +bool Game::pairOrBetter(Card **cards) +{ + char c1, c2; + int ret = 0; + + int i, j; + for (i = 0; i < 5; i++) + { + c1 = cards[i]->getType()[0]; + + for (j = i+1; j < 5; j++) + { + c2 = cards[j]->getType()[0]; + if (c1 == c2) + { + ret++; + break; + } + } + } + + return (ret != 0); +} + +/* returns max number of same cards, returns 0 when all cards are different */ +int Game::numOfSameCards(Card **cards) +{ + char c1, c2; + int same = 0; + int max = 0; + + int i, j; + for (i = 0; i < 5; i++) + { + c1 = cards[i]->getType()[0]; + + for (j = i+1; j < 5; j++) + { + c2 = cards[j]->getType()[0]; + same = 1; + + if (c1 == c2) + { + same++; + if (same > max) + max = same; + } + else + { + same = 0; + c1 = c2; + } + } + } + + return max; +} + +void Game::opponentAI(Card **cards) +{ + if (pairOrBetter(cards)) + { + /* discard 4 other cards*/ + return; + } +} + diff --git a/game.h b/game.h new file mode 100644 index 0000000..f3f24de --- /dev/null +++ b/game.h @@ -0,0 +1,57 @@ +#ifndef _GAME_H_ +#define _GAME_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "cardpile.h" +#include "user.h" +#include "opponent.h" + +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_GREEN "\x1b[32m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_BLUE "\x1b[34m" +#define ANSI_COLOR_MAGENTA "\x1b[35m" +#define ANSI_COLOR_CYAN "\x1b[36m" +#define ANSI_COLOR_RESET "\x1b[0m" +#define PRINT_COLOR(C, S) printf("%s%s%s", C, S, ANSI_COLOR_RESET) + +using std::cout; +using std::endl; +using std::cin; + +class Game : virtual public CardPile, public User, public Opponent +{ + private: + + protected: + static string *hands[10]; + + public: + Game(void); + void shufflePile(void); + void askForNumberOfOpponents(void); + void repeatGame(bool *); + + /* asks user for a number, param1 = msg, 2 = rangeA, 3 = rangeB */ + int parseInt(string *, int, int); + int howManyCardsOfSameSuit(Card **); + bool pairOrBetter(Card **cards); + int numOfSameCards(Card **); + + void opponentAI(Card **cards); + + /* variables */ + int numOfOpponents; + int handsPlayed; + int handsWon; +}; + +#endif + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..75bc9dc --- /dev/null +++ b/main.cpp @@ -0,0 +1,71 @@ +/* Kamil Kaminski + * NetID: kkamin8 + * + * CS340 + * Project 1, Poker Game + * + * + */ + +#include "game.h" + +int main(int argc, char *argv[]) +{ + /* seed rand() */ + srand((unsigned int ) time(NULL)); + + /* pokerGame instance */ + Game *pokerGame = new Game(); + PRINT_COLOR(ANSI_COLOR_GREEN, "\tWelcome to Poker Game\n\n"); + + /* number of opponents user input */ + pokerGame->askForNumberOfOpponents(); + + /* pokerGame loop */ + bool quit = false; + while (!quit) + { + cout << "\nThe deck is being shuffled" << endl; + pokerGame->shufflePile(); + +#ifdef DEBUG + cout << "Deck after shuffle" << endl; + pokerGame->printPile(); +#endif + + cout << "\nDealing cards to the user" << endl; + pokerGame->dealUserCards(); + pokerGame->sortUserCards(); + cout << "Cards in your hand: "; + pokerGame->printUserCards(); + + cout << "Number of same cards: " << + pokerGame->numOfSameCards(pokerGame->getUserCards()) << endl; + + if ( pokerGame->pairOrBetter(pokerGame->getUserCards())) + cout << "User has pair or better" << endl; + + cout << "\nDealing cards to opponent(s)" << endl; + pokerGame->dealOpponentCards(pokerGame->numOfOpponents); + pokerGame->sortOpponentCards(pokerGame->numOfOpponents); + cout << "Opponents' cards:" << endl; + pokerGame->printOpponentCards(pokerGame->numOfOpponents); + +#ifdef DEBUG + cout << "\nDeck after being delt to opponents and user" << endl; + pokerGame->printPile(); +#endif + + /* ask to repeat the game and reset the deck of cards */ + pokerGame->repeatGame(&quit); + pokerGame->resetDeck(); + } + + cout << "\nThank you for playing\n" << pokerGame->handsPlayed << ": Hands played\n" + << pokerGame->handsWon << ": Hands won" << endl; + + delete pokerGame; + + return 0; +} + diff --git a/opponent.cpp b/opponent.cpp new file mode 100644 index 0000000..82f297a --- /dev/null +++ b/opponent.cpp @@ -0,0 +1,44 @@ +/* + * opponent.cpp + * + * + */ + +#include "opponent.h" + +Opponent::Opponent(void) : whatHand(9) +{ + +} + +void Opponent::dealOpponentCards(int opponentsAmount) +{ + /* the cards will be dealt from end of the deck array using deckCurrIndex */ + int i, j; + for (j = 0; j < opponentsAmount; j++) + for (i = 0; i < 5; i++) + opponentCards[j][i] = PopCardFromDeck(); +} + +void Opponent::printOpponentCards(int opponentsAmount) +{ + int j; + for (j = 0; j < opponentsAmount; j++) + { + cout << "Opponent " << j+1 << ": "; + + int i; + for (i = 0; i < 5; i++) + if (opponentCards[j][i]) + cout << i+1 << ") " << opponentCards[j][i]->getType() << " "; + cout << endl; + } +} + +void Opponent::sortOpponentCards(int opponentsAmount) +{ + int j; + for (j = 0; j < opponentsAmount; j++) + sortCards(opponentCards[j]); +} + diff --git a/opponent.h b/opponent.h new file mode 100644 index 0000000..d90146e --- /dev/null +++ b/opponent.h @@ -0,0 +1,22 @@ +#ifndef _OPPONENT_H_ +#define _OPPONENT_H_ + +#include "cardpile.h" + +class Opponent : virtual public CardPile +{ + private: + int whatHand; + + protected: + Card *opponentCards[3][5]; + + public: + Opponent(void); + void dealOpponentCards(int); + void printOpponentCards(int); + void sortOpponentCards(int); +}; + +#endif + diff --git a/user.cpp b/user.cpp new file mode 100644 index 0000000..679ee9d --- /dev/null +++ b/user.cpp @@ -0,0 +1,45 @@ +/* + * user.cpp + * + * + */ + +#include "user.h" + +User::User(void) : whatHand(9) +{ + +} + +void User::dealUserCards(void) +{ + /* the cards will be dealt from end of the deck array using deckCurrIndex */ + int i; + for (i = 0; i < 5; i++) + userCards[i] = PopCardFromDeck(); +} + +void User::printUserCards(void) +{ + int i; + for (i = 0; i < 5; i++) + if (userCards[i]) + cout << i+1 << ") " << userCards[i]->getType() << " "; + cout << endl; +} + +void User::sortUserCards(void) +{ + sortCards(userCards); +} + +void User::discardCards(void) +{ + cout << "List the cards' numbers you wish to discard: "; +} + +Card **User::getUserCards(void) +{ + return userCards; +} + diff --git a/user.h b/user.h new file mode 100644 index 0000000..44009ed --- /dev/null +++ b/user.h @@ -0,0 +1,24 @@ +#ifndef _USER_H_ +#define _USER_H_ + +#include "cardpile.h" + +class User : virtual public CardPile +{ + private: + int whatHand; + + protected: + Card *userCards[5]; + + public: + User(void); + void dealUserCards(void); + void printUserCards(void); + void sortUserCards(void); + void discardCards(void); + Card **getUserCards(void); +}; + +#endif + -- cgit v1.2.3