// // 1 on 1 basketball simulator. // Rafael Arce Nazario - 2014 // // This program simulates a 1 on 1 game between two players // based only on their shooting percentages, rebounds per game. // #include #include #include using namespace std; typedef unsigned int uint; class BBPlayer { private: string _name; uint _shotsTaken; uint _shotsMade; uint _gamesPlayed; uint _rebounds; uint _score; public: BBPlayer(); BBPlayer(string name, int shotsTaken, int shotsMade, int gamesPlayed, int rebounds); float shotPercentage() const; float reboundsPerGame() const; void shotMissed(); void shotMade(); void reboundMade(); void addGame(); void setAll(string name, int shotsTaken, int shotsMade, int gamesPlayed, int rebounds); uint score() const; string name() const; void printStats() const; }; BBPlayer::BBPlayer() { _shotsTaken = _shotsMade = _gamesPlayed = _rebounds = _score = 0; } BBPlayer::BBPlayer(string name, int shotsTaken, int shotsMade, int gamesPlayed, int rebounds) { _name = name; _shotsTaken = shotsTaken >= 0 ? shotsTaken : 0; _shotsMade = shotsMade >= 0 ? shotsMade : 0; _shotsMade = shotsMade <= shotsTaken ? shotsMade : shotsTaken; _gamesPlayed = gamesPlayed >= 0 ? gamesPlayed : 0; _rebounds = rebounds >= 0 ? rebounds : 0; _score = 0; if (_gamesPlayed == 0 && (_shotsTaken | _rebounds) ) { cout << "You've just declared a magical player. No games played. " << "Yet he has rebounds or shots taken." << "Please verify object definition" << endl; } } void BBPlayer::setAll(string name, int shotsTaken, int shotsMade, int gamesPlayed, int rebounds) { _name = name; _shotsTaken = shotsTaken >= 0 ? shotsTaken : 0; _shotsMade = shotsMade >= 0 ? shotsMade : 0; _shotsMade = shotsMade <= shotsTaken ? shotsMade : shotsTaken; _gamesPlayed = gamesPlayed >= 0 ? gamesPlayed : 0; _rebounds = rebounds >= 0 ? rebounds : 0; _score = 0; if (_gamesPlayed == 0 && (_shotsTaken | _rebounds) ) { cout << "You've just declared a magical player. No games played. " << "Yet s/he has rebounds or shots taken." << "Please verify object definition" << endl; } } string BBPlayer::name() const{ return _name; } float BBPlayer::shotPercentage() const { return _shotsTaken == 0 ? .5 : static_cast(_shotsMade) / _shotsTaken; } float BBPlayer::reboundsPerGame() const { return _gamesPlayed == 0 ? 3 : static_cast(_rebounds) / _gamesPlayed; } void BBPlayer::shotMissed() { _shotsTaken++; } void BBPlayer::shotMade() { _shotsTaken++; _shotsMade++; _score += 2; } void BBPlayer::reboundMade() { _rebounds++; } void BBPlayer::addGame() { _gamesPlayed++; } uint BBPlayer::score() const { return _score; } void BBPlayer::printStats() const { cout << "Stats for " << _name << endl; cout << "Games played: " << _gamesPlayed << endl; cout << "Rebounds: " << _rebounds << endl; cout << "Shots taken: " << _shotsTaken << endl; cout << "Shots made: " << _shotsMade << endl; } void test_BBPlayer() { BBPlayer T("Chemba", 100, 65, 10, 35); // Test the name() method assert( T.name() == "Chemba" ); // Test the initial shot pct assert( abs( T.shotPercentage() - 0.65) < 0.00001 ); // Test after a shot is made T.shotMade(); assert( abs( T.shotPercentage() - (1.0 * 66 / 101) ) < 0.00001) ; // Test after a shot is missed T.shotMissed(); assert( abs( T.shotPercentage() - (1.0 * 66 / 102) ) < 0.00001 ); // Test the initial rebounds per game assert( abs( T.reboundsPerGame() - 3.5 ) < 0.00001 ); // Test the score up to this point assert( T.score() == 2); // Make two shots, then test score and pct T.shotMade(); T.shotMade(); assert( T.score() == 6); assert( abs( T.shotPercentage() - (1.0 * 68 / 104) ) < 0.00001 ); // Make two rebounds then test T.reboundMade(); T.reboundMade(); assert( abs( T.reboundsPerGame() - 3.7 ) < 0.00001 ); // Tests if the number of game has increased. T.addGame(); assert( abs( T.reboundsPerGame() - (1.0 * 37 / 11) ) < 0.00001 ); cout << "All unit tests passed!!!" << endl; } int main() { test_BBPlayer(); const uint GOAL_SCORE = 32; // create the two players BBPlayer P[2]; P[0].setAll("Chemba", 100, 65, 10, 35); P[1].setAll("Wes", 100, 56, 10, 1); srand(time(NULL)); // the index of the player in offense, randomly determined int playerIdx = rand() % 2; // the player who won, -1 if no one has won int playerWon = -1; // the result of a dice throw, a number between [0.0,1.0] float diceThrow; cout << "The game starts...." << endl; P[0].addGame(); P[1].addGame(); while (playerWon == -1) { // the offensive player takes a shot cout << P[playerIdx].name() << " shoots .... "; diceThrow = static_cast( rand() ) / RAND_MAX; // determine if shot is made based on shooting percentage if ( diceThrow < P[playerIdx].shotPercentage() ) { cout << "and scores!!!" << endl; P[playerIdx].shotMade(); cout << "The score is " << P[0].name() << ":"<< P[0].score() << " to " << P[1].name() << ":"<< P[1].score() << endl; if (P[playerIdx].score() >= GOAL_SCORE) playerWon = playerIdx; else playerIdx = (playerIdx + 1) % 2; } else { cout << "and misses :-(" << endl; P[playerIdx].shotMissed(); // determine who gets the rebound float chanceOfense = P[playerIdx].reboundsPerGame(); float chanceDefense = P[(playerIdx + 1) % 2].reboundsPerGame() * 2; diceThrow = static_cast( rand() ) / RAND_MAX; diceThrow = diceThrow * ( chanceOfense + chanceDefense); playerIdx = diceThrow < chanceOfense ? playerIdx : (playerIdx + 1) % 2; cout << P[playerIdx].name() << " gets the rebound .... " << endl; } } cout << P[playerWon].name() << " wins the game!" << endl << endl; cout << "Final statistics . . . " << endl; cout << "---------------------------" << endl; P[0].printStats(); cout << "---------------------------" << endl; P[1].printStats(); cout << "---------------------------" << endl; return 0; }