Thread: I can't find the bug(s)! Please Help

  1. #1
    Registered User
    Join Date
    Aug 2014
    Posts
    20

    I can't find the bug(s)! Please Help

    Hi everyone,

    I havent used C++ in a while and going back is more difficult than i thought. I have a seg fault and the bug lies somewhere in PokerGame.cpp. am i passing my arrays incorrectly? why isnt my cardNum array incrementing? Please help!!

    Any feedback would be greatly appreciated. thank you.


    Here is Poker.cpp (MAIN)
    Code:
    /*
     * Poker.cpp
     *
     *  Created on: Jan 15, 2016
     *      Author: allen
     */
    /*    In the card game poker, a hand consists of five cards and are ranked,
        from lowest to highest, in the following way:
    
            High Card: Highest value card.
            One Pair: Two cards of the same value.
            Two Pairs: Two different pairs.
            Three of a Kind: Three cards of the same value.
            Straight: All cards are consecutive values.
            Flush: All cards of the same suit.
            Full House: Three of a kind and a pair.
            Four of a Kind: Four cards of the same value.
            Straight Flush: All cards are consecutive values of same suit.
            Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
    
            The cards are valued in the order:
            2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
    
        If two players have the same ranked hands then the rank made up of the
        highest value wins; for example, a pair of eights beats a pair of fives
        (see example 1 below). But if two ranks tie, for example, both
        players have a pair of queens, then highest cards in each hand are compared
        (see example 4 below); if the
        highest cards tie then the next highest cards are compared, and so on.
    
        Consider the following five hands dealt to two players:
        Hand         Player 1                 Player 2                         Winner
        1             5H 5C 6S 7S KD                 2C 3S 8S 8D TD                 Player 2
                    Pair of Fives                Pair of Eights
    
        2             5D 8C 9S JS AC                 2C 5C 7D 8S QH                 Player 1
                    Highest card Ace            Highest card Queen
    
        3             2D 9C AS AH AC                3D 6D 7D TD QD                 Player 2
                    Three Aces                    Flush with Diamonds
    
        4             4D 6S 9H QH QC                3D 6D 7H QD QS                 Player 1
                    Pair of Queens                Pair of Queens
                    Highest card Nine            Highest card Seven
    
        5             2H 2D 4C 4D 4S                3C 3D 3S 9S 9D                Player 1
                    Full House                    Full House
                    With Three Fours            with Three Threes
    
        The file, poker.txt, contains one-thousand random hands dealt to two players.
        Each line of the file contains ten cards (separated by a single space): the first
        five are Player 1's cards and the last five are Player 2's cards. You can assume that
        all hands are valid (no invalid characters or repeated cards), each player's hand is
        in no specific order, and in each hand there is a clear winner.
    
        How many hands does Player 1 win? 
    */
    
    #include "Player.hpp"
    #include "PokerGame.hpp"
    #include <iostream>
    #include <cstdlib>
    #include <stdio.h>
    using namespace std;
    
    
    int main() {
        PokerGame pokerGame;
        Player player1;
        Player player2;
    
        player1.setHand("5H5C6S7SKD");
    
        player2.setHand("3D6D7HQDQS");
    
        if(pokerGame.callHand(player1.getHand(), player2.getHand())) {
            player1.incWinCount();
        }
    
        printf("%d", player1.getWinCount());
    
    }
    Here is PokerGame.hpp

    Code:
    #ifndef POKERGAME_HPP_
    #define POKERGAME_HPP_
    
    
    #include <iostream>
    #include "string"
    using namespace std;
    
    class PokerGame {
    
    private:
        enum Rank { HIGH_CARD = 1, PAIR, TWO_PAIR, TRIPS, STRAIGHT, FLUSH, FULL_HOUSE, FOUR_OF_A_KIND, STRAIGHT_FLUSH, ROYAL_FLUSH };
        static int cardValues;
    
    
        void callHandUtil(string hand, int* cardNum);
        int findPairsTripsAndFours(int* cardNum);
        bool findFlush(string player);
        int findStraight(string player, int* cardNum);
        int findPairsTripsAndFours();
        int findHighCard(int* numCard);
    
    
    public:
    
        bool callHand(string player1, string player2);
    
    
    };
    
    #endif /* POKERGAME_HPP_ */
    Here is PokerGame.cpp

    Code:
    #include "PokerGame.hpp"
    using namespace std;
    
    /*
            High Card: Highest value card.
            One Pair: Two cards of the same value.
            Two Pairs: Two different pairs.
            Three of a Kind: Three cards of the same value.
                Straight: All cards are consecutive values.
                Flush: All cards of the same suit.
            Full House: Three of a kind and a pair.
            Four of a Kind: Four cards of the same value.
                Straight Flush: All cards are consecutive values of same suit.
                Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
    
            The cards are valued in the order:
            2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
     */
    
    int PokerGame::cardValues = 13;
    
    bool PokerGame::callHand(string player1, string player2) {
    
        string playerOne = player1;
        string playerTwo = player2;
    
        int cardNum1[13] = {0}
        int cardNum2[13] = {0};
    
        callHandUtil(playerOne, cardNum1);
        callHandUtil(playerTwo, cardNum2);
    
        int playerOneHand = 0, playerTwoHand = 0;
        bool playerOneFlush = false, playerTwoFlush = false;
    
        playerOneFlush = findFlush(playerOne);
        playerTwoFlush = findFlush(playerTwo);
    
        int playerOneStraight = findStraight(playerOne, cardNum1);            // 0 = no straight
                                                                        // 1 = straight
        int playerTwoStraight = findStraight(playerTwo, cardNum2);        // 2 = royal
    
        if (playerOneStraight == 1) {
            if (playerOneFlush == true) {
                playerOneHand = STRAIGHT_FLUSH;
            } else {
                if (playerOneHand < FLUSH) {
                    playerOneHand = STRAIGHT;
                }
            }
        }
    
        if (playerOneStraight == 2) {
            if (playerOneFlush == true) {
                playerOneHand = ROYAL_FLUSH;
            } else {
                if (playerTwoHand < FLUSH) {
                    playerOneHand = STRAIGHT;
                }
            }
        }
    
        int playerOneOther = findPairsTripsAndFours(cardNum1);
        int playerTwoOther = findPairsTripsAndFours(cardNum2);
    
        if (playerOneOther == 4) {    // four of a kind
            if (playerOneHand < FOUR_OF_A_KIND) {
                playerOneHand = FOUR_OF_A_KIND;
            }
        } else if (playerOneOther == 5) { // boat
            if (playerOneHand < FULL_HOUSE) {
                playerOneHand = FULL_HOUSE;
            }
        } else if (playerOneOther == 3) { // trips
            if (playerOneHand < TRIPS) {
                playerOneHand = TRIPS;
            }
        } else if (playerOneOther == 2) { // two pair
            if (playerOneHand < TWO_PAIR) {
                playerOneHand = TWO_PAIR;
            }
        } else if (playerOneOther == 1) { // pair
            if (playerOneHand < PAIR) {
                playerOneHand = PAIR;
            }
        }
    
        if (playerTwoOther == 4) {    // four of a kind
            if (playerTwoHand < FOUR_OF_A_KIND) {
                playerTwoHand = FOUR_OF_A_KIND;
            }
        } else if (playerTwoOther == 5) { // boat
            if (playerTwoHand < FULL_HOUSE) {
                playerTwoHand = FULL_HOUSE;
            }
        } else if (playerTwoOther == 3) { // trips
            if (playerTwoHand < TRIPS) {
                playerTwoHand = TRIPS;
            }
        } else if (playerTwoOther == 2) { // two pair
            if (playerTwoHand < TWO_PAIR) {
                playerTwoHand = TWO_PAIR;
            }
        } else if (playerTwoOther == 1) { // pair
            if (playerTwoHand < PAIR) {
                playerTwoHand = PAIR;
            }
        }
    
        if (playerOneHand == playerTwoHand) {
    
            int playerOneKicker = findHighCard(cardNum1);
            int playerTwoKicker = findHighCard(cardNum2);
    
            if (playerOneKicker > playerTwoKicker) {
                playerOneHand = 1;
                playerTwoHand = 0;
            } else {
                playerOneHand = 0;
                playerTwoHand = 1;
            }
        }
    
        return playerOneHand > playerTwoHand ? true : false;
    }
    
    void PokerGame::callHandUtil(string hand, int* cardNum) {
        for (int i = 0; i < hand.length(); i = i + 2) {
            if (hand[i] == 'A') {
                cardNum[12] = cardNum[12] + 1;
            } else if (hand[i] == 'K') {
                cardNum[11] = cardNum[11] + 1;
            } else if (hand[i] == 'Q') {
                cardNum[10] = cardNum[10] + 1;
            } else if (hand[i] == 'J') {
                cardNum[9] = cardNum[9] + 1;
            } else {
                cardNum[hand[i] - 1] = cardNum[hand[i] - 1] + 1;
            }
        }
    }
    
    int PokerGame::findPairsTripsAndFours(int* cardNum) {        //returns 1 if one pair, 2 if two pairs, 3 if trips, 4 if four of A Kind, 5 if full house
    
        int pair = 0, trips = 0, fourOfAKind;
    
        for (int i = 0; i < cardValues; i++) {
            if (cardNum[i] == 2) {
                pair++;
            } else if (cardNum[i] == 3) {
                trips++;
            } else if (cardNum[i] == 4) {
                fourOfAKind++;
            }
        }
    
        if (fourOfAKind > 0) {
            return 4;
        } else if (pair > 0 && trips >0) {
            return 5;
        } else if (trips > 0) {
            return 3;
        } else if (pair > 1) {
            return 2;
        } else if (pair == 1) {
            return 1;
        } else {
            return 0;
        }
    }
    
    bool PokerGame::findFlush(string player) {
        if (player[1] == player[3] && player[3] == player[5] && player[5] == player[7]  && player[7] == player[9]) {
            return true;
        } else {
            return false;
        }
    }
    
    int PokerGame::findStraight(string hand, int *cardNum) {
        bool royal = false;
        int consecutive = 0;
        int returnValue = 0;
    
        for (int i = 0; i < cardValues && consecutive < 5; i++) {
            if (cardNum[i] > 1) {
                returnValue = 0;        // no flush
                break;
            } else if (consecutive > 0) {
                if (cardNum[i] == 0) {
                    returnValue = 0;        // no flush
                    break;
                } else {
                    consecutive++;    // continue counting
                }
            } else {
                if (cardNum[i] == 1) {
                    if (i == 10) {
                        royal = true;
                    }
                    consecutive++;
                }
            }
        }
    
        if (consecutive == 5) {
            if (royal) {
                returnValue = 2;
            } else {
                returnValue = 1;
            }
        }
    
        return returnValue;
    }
    
    int PokerGame::findHighCard(int* numCard) {
    
        int highCard = 0;
        for (int i = 13; i > 0; i--) {
            if (numCard[i] == 1) {        //cant be part of a double, triple, or four of a kind
                highCard = i;
                break;
            }
        }
        return highCard;
    }
    Here is Player.hpp

    Code:
    /*
     * Player.hpp
     *
     *  Created on: Jan 15, 2016
     *      Author: allen
     */
    
    #ifndef PLAYER_HPP_
    #define PLAYER_HPP_
    
    #include <string>
    #include <iostream>
    #include <cstdlib>
    #include <stdio.h>
    using namespace std;
    
    
    class Player {
    private:
        string hand;
        int winCount;
    
    public:
        Player();
        ~Player();
    
        string getHand();
    
        void setHand(string hand);
    
        int getWinCount();
    
        void incWinCount();
    
    };
    
    
    
    #endif /* PLAYER_HPP_ */
    Finally, here is my Player.cpp

    Code:
    /*
     * Player.cpp
     *
     *  Created on: Jan 15, 2016
     *      Author: allen
     */
    
    
        //    char hand[2][5];
        //  [] value [] suit
        //    winCount;
    
    #include "Player.hpp"
    using namespace std;
    
    Player::Player() {
        winCount = 0;
    }
    
    Player::~Player() {
    
    }
    
    string Player::getHand() {
        return hand;
    }
    
    void Player::setHand(string stringHand) {
        hand = stringHand;
    }
    
    int Player::getWinCount() {
        return winCount;
    }
    
    void Player::incWinCount() {
        winCount++;
    }

  2. #2
    Guest
    Guest
    Those raw pointers make me uneasy. Try taking out PokerGame::callHandUtil() (or turning it into a simple placeholder) and see if that's the culprit.

    edit:
    Code:
    src/PokerGame.cpp: In member function ‘bool PokerGame::callHand(std::__cxx11::string, std::__cxx11::string)’:
    src/PokerGame.cpp:28:5: error: expected ‘,’ or ‘;’ before ‘int’
         int cardNum2[13] = {0};
         ^
    src/PokerGame.cpp:31:29: error: ‘cardNum2’ was not declared in this scope
         callHandUtil(playerTwo, cardNum2);
                                 ^
    src/PokerGame.cpp:41:9: warning: unused variable ‘playerTwoStraight’ [-Wunused-variable]
         int playerTwoStraight = findStraight(playerTwo, cardNum2);        // 2 = ro
             ^
    src/PokerGame.cpp: In member function ‘void PokerGame::callHandUtil(std::__cxx11::string, int*)’:
    src/PokerGame.cpp:128:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int i = 0; i < hand.length(); i = i + 2) {
                           ^
    makefile:13: recipe for target 'obj/PokerGame.o' failed
    make: *** [obj/PokerGame.o] Error 1
    Last edited by Guest; 01-16-2016 at 07:59 AM.

  3. #3
    Registered User
    Join Date
    Aug 2014
    Posts
    20
    Hi, sorry i realized i missed the semicolon after initializing the array. That was somehow missed when copying and pasting the code. That throws everything off. i didnt get the other errors though. i actually didnt get any warning or errors during compiling. I'm dealing with a seg fault

  4. #4
    Registered User
    Join Date
    Aug 2014
    Posts
    20
    Got it! I guess all it takes is some rest and a clear mind. i was passing the array correctly, but was indexing incorrectly, thus getting an out of bounds exception. I should've used try catch but wanted to write quick and dirty code... and it was certainly dirty. thanks for the assistance!

  5. #5
    Guest
    Guest
    Use standard library containers instead of passing around pointers, it's no more work. C++ isn't just meant to be used as "C with classes", it's a different approach that helps you reduce code and errors.

    i didnt get the other errors though.
    Increase your compiler warning level then. The last warning you should not ignore because it can lead to unexpected behaviour.
    Code:
    for (int i = 0; i < hand.length(); i = i + 2)
    hand.length() returns an unsigned integer (a 64bit one at that, if your system is) but you're using a signed integer for your counting. Since the [] operator takes an unsigned value as well, that's yet another conversion. Instead consider one of the following:
    Code:
    for (string::size_type i = 0; i < hand.length(); i += 2)
    for (size_t i = 0; i < hand.length(); i += 2)
    for (decltype(hand.length()) i = 0; i < hand.length(); i += 2)
    for (auto end = hand.length(), i = 0 * end; i < end; i += 2)
    And take a look at references and how to use them as function parameters, combined with const. There are many opportunities to make things less bug prone and easier to manage.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can't find where the value changes
    By nirvana619 in forum C Programming
    Replies: 4
    Last Post: 08-10-2010, 12:22 PM
  2. std::string::find vs std::find
    By petry in forum C++ Programming
    Replies: 17
    Last Post: 07-08-2009, 05:26 PM
  3. Need help to find a bug
    By serge in forum C++ Programming
    Replies: 17
    Last Post: 05-09-2008, 04:06 PM
  4. How to find the???
    By Shidlingayya in forum C Programming
    Replies: 8
    Last Post: 12-12-2007, 11:32 AM
  5. gcc can't find gtk.h
    By silk.odyssey in forum Linux Programming
    Replies: 9
    Last Post: 07-05-2004, 03:02 PM

Tags for this Thread