BAHRIA UNIVERSITY ISLAMABAD
H-11 Campus
Assignment 4
COURSE: Object Oriented Programming
NAME: Muhammad Asheer Ali
ENROLMENT: 09-134242-007
Dice Duel Game
Real-World Use Case
Simulates a competitive dice-based board game match, demonstrating player behavior and
outcomes.
Objective
To design and implement a simple console-based game that demonstrates the core
principles of OOP along with robust exception handling using custom and standard
exceptions.
OOP Concept Implementation
OOP Concept How It’s Implemented
Encapsulation Protected/private data members (`name`,
`score`) and public getter methods.
Abstraction `Player` is an abstract base class with a
pure virtual `rollDice()` method.
Inheritance `NormalPlayer`, `LuckyPlayer`, and
`CheaterPlayer` inherit from `Player`.
Static Polymorphism `rollDice()` function is overloaded to
support multiple signatures.
Dynamic Polymorphism `rollDice()` is overridden in derived classes
and used via base class pointer.
Pure Virtual Function `rollDice()` is declared as a pure virtual
function in the abstract class.
Exception Handling Custom exceptions like
`InvalidRollException` and
`CheatingException` are used with try-
catch blocks.
Code:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class InvalidRollException {
public:
const char* what() {
return "Invalid roll: Dice value out of range.";
};
class CheatingException {
public:
const char* what() {
return "Cheating detected! Dice value too high.";
};
class Player {
protected:
string name;
int score;
public:
Player(string n) {
name = n;
score = 0;
virtual int rollDice() = 0;
string getName() {
return name;
int getScore() {
return score;
void addScore(int s) {
score += s;
virtual ~Player() {}
};
class NormalPlayer : public Player {
public:
NormalPlayer(string n) : Player(n) {}
int rollDice() {
int roll = rand() % 6 + 1;
if (roll < 1 || roll > 6) throw InvalidRollException();
return roll;
};
class LuckyPlayer : public Player {
public:
LuckyPlayer(string n) : Player(n) {}
int rollDice() {
int roll = rand() % 4 + 3;
if (roll > 6) throw CheatingException();
return roll;
};
class CheaterPlayer : public Player {
public:
CheaterPlayer(string n) : Player(n) {}
int rollDice() {
int roll = rand() % 4 + 5;
if (roll > 6) throw CheatingException();
return roll;
};
int calculatePoints(int roll) {
return roll * 2;
int calculatePoints(int roll1, int roll2) {
return roll1 + roll2;
void playGame(Player* p1, Player* p2) {
cout << "\nStarting Dice Duel between " << p1->getName() << " and " << p2->getName()
<< "!\n";
for (int i = 0; i < 3; ++i) {
try {
int r1 = p1->rollDice();
int r2 = p2->rollDice();
cout << "Round " << i + 1 << ":\n";
cout << p1->getName() << " rolled: " << r1 << endl;
cout << p2->getName() << " rolled: " << r2 << endl;
p1->addScore(calculatePoints(r1));
p2->addScore(calculatePoints(r2));
catch (InvalidRollException& e) {
cout << "Exception: " << e.what() << endl;
catch (CheatingException& e) {
cout << "Exception: " << e.what() << endl;
cout << "\nFinal Scores:\n";
cout << p1->getName() << ": " << p1->getScore() << endl;
cout << p2->getName() << ": " << p2->getScore() << endl;
if (p1->getScore() > p2->getScore()) cout << p1->getName() << " wins!\n";
else if (p2->getScore() > p1->getScore()) cout << p2->getName() << " wins!\n";
else cout << "It's a tie!\n";
}
int main() {
srand((unsigned int)time(0));
Player* player1 = new NormalPlayer("Alice");
Player* player2 = new CheaterPlayer("Bob");
playGame(player1, player2);
delete player1;
delete player2;
return 0;