24F-0781 OOP Assignment 3
24F-0781 OOP Assignment 3
Code:
Main.cpp:
#include"HeaderFiles.h"
#include"Code.cpp"
using namespace std;
int main() {
srand(time(0));
cout << "1. New Game\n2. Load Saved Game\nChoose: ";
int choice;
cin >> choice;
AdventureQuest game(5);
if (choice == 2) {
game.loadGame();
game.start();
}
else {
game.start();
}
return 0;
} HeaderFiles.h:
#pragma once
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <string>
#include <fstream>
#include<Windows.h>
using namespace std;
class Item {
public:
int position;
string name;
Item(string n, int pos) : name(n), position(pos) {}
virtual void interaction_with_player(class GamePlayer& player) = 0;
};
class Coin : public Item {
public:
int value;
Coin(string n, int pos, int val) : Item(n, pos), value(val) {}
void interaction_with_player(class GamePlayer& player) override;
};
class Hurdle : public Item {
public:
int turnsToWait;
string requiredHelper;
Hurdle(string n, int pos, int wt, string rh) : Item(n, pos), turnsToWait(wt), requiredHelper(rh) {}
void interaction_with_player(class GamePlayer& player) override;
};
class Helper : public Item {
public:
Helper(string n, int pos) : Item(n, pos) {}
void interaction_with_player(class GamePlayer& player) override;
};
class GamePlayer {
public:
string name;
int position, points, goldCoins, silverCoins, swordUses, turnsToWait;
bool hasShield, hasWater, hasKey;
GamePlayer(string n): name(n), position(0), points(0), goldCoins(10),
silverCoins(20),swordUses(2), hasShield(false), hasWater(false), hasKey(false), turnsToWait(0) {}
void displayStatus(int boardSize);
};
class Board {
public:
int size;
Item** cells;
Board(int sz);
~Board();
void generateItems();
void display(const GamePlayer& p1, const GamePlayer& p2);
};
class AdventureQuest {
public:
Board* board;
GamePlayer p1, p2;
AdventureQuest(int boardSize);
~AdventureQuest();
void start();
bool kyaGameKhatam();
int target_position();
void playerTurn(GamePlayer& player, int a);
void showResults();
void saveGame();
void loadGame();
bool p1Reached = false;
bool p2Reached = false;
};
Code.cpp:
#include"HeaderFiles.h"
using namespace std;
void GamePlayer::displayStatus(int boardSize) {
cout << endl << " " << name << " STATUS" << endl
<< " Points : " << points << endl
<< " Position : " << position << "/" << (boardSize * boardSize - 1) << endl
<< " Gold Coins : " << goldCoins << endl
<< " Silver Coins : " << silverCoins << endl
<< " Sword Uses : " << swordUses << endl
<< " Shield : " << (hasShield ? "Yes" : "No") << endl
<< " Water : " << (hasWater ? "Yes" : "No") << endl
<< " Key : " << (hasKey ? "Yes" : "No") << endl
<< " Wait Turns : " << turnsToWait << endl;
}
void Coin::interaction_with_player(GamePlayer& player) {
if (name == "Gold") {
player.goldCoins++;
player.points = player.points + 10;
cout << " Picked up a Gold Coin (+10 points)" << endl;
}
else {
player.silverCoins++;
player.points = player.points + 5;
cout << " Pickd up a silver Coin (+5 points)" << endl;
}
}
void Hurdle::interaction_with_player(GamePlayer& player) {
cout << " Touched hurdle " << name;
if (requiredHelper == "None") {
cout << ". Wait for " << turnsToWait << " turns." << endl;
player.turnsToWait = turnsToWait;
return;
}
bool usedHelper = false;
if ((requiredHelper == "Sword" and player.swordUses > 0) or (requiredHelper == "Shield" and
player.hasShield) or (requiredHelper == "Water" and player.hasWater) or (requiredHelper ==
"Key" and player.hasKey)) {
cout << ". Used " << requiredHelper << "!" << endl;
if (requiredHelper == "Sword") {
player.swordUses--;
}
else if (requiredHelper == "Shield") {
player.hasShield = false;
}
else if (requiredHelper == "Water") {
player.hasWater = false;
}
else if (requiredHelper == "Key") {
player.hasKey = false;
}
usedHelper = true;
}
if (!usedHelper) {
if (name == "Snake") {
cout << ". Bitten by a Snake, Mving back 3 steps" << endl;
player.position -= 3;
if (player.position < 0) player.position = 0;
}
else {
cout << ". No " << requiredHelper << "wait for " << turnsToWait << " turns." << endl;
player.turnsToWait = turnsToWait;
}
}
}
void Helper::interaction_with_player(GamePlayer& player) {
cout << " Item collected: " << name << ". ";
if (name == "Sword") player.swordUses++;
else if (name == "Shield") player.hasShield = true;
else if (name == "Water") player.hasWater = true;
else if (name == "Key") player.hasKey = true;
cout << "Added to inventory.\n";
}
Board::Board(int sz) : size(sz) {
cells = new Item * [sz * sz];
for (int i = 0; i < sz * sz; ++i)
cells[i] = nullptr;
}
Board::~Board() {
for (int i = 0; i < size * size; ++i)
delete cells[i];
delete[] cells;
}
void Board::generateItems() {
int minimum_items, maximum_items;
if (size * 2 > 4) {
minimum_items = size * 2;
}
else {
minimum_items = 4;
}
if (size * 4 < (size * size) / 2) {
maximum_items = size * 4;
}
else {
maximum_items = (size * size) / 2;
}
int num_objects = minimum_items + rand() % (maximum_items - minimum_items + 1);
for (int i = 0; i < num_objects; i++) {
int pos = rand() % (size * size);
if (cells[pos] != nullptr) continue;
int type = rand() % 3;
if (type == 0)
cells[pos] = new Coin("Gold", pos, 10);
else if (type == 1)
cells[pos] = new Coin("Silver", pos, 5);
else if (type == 2) {
string hurdleNames[5] = { "Fire", "Snake", "Ghost", "Lion", "Lock" };
string helpers[5] = { "Water", "Sword", "Shield", "Sword", "Key" };
int waitTimes[5] = { 2, 3, 1, 4, 5 };
int index = rand() % 5;
cells[pos] = new Hurdle(hurdleNames[index], pos, waitTimes[index], helpers[index]);
}
}
}
void Board::display(const GamePlayer& p1, const GamePlayer& p2) {
Sleep(1000);
system("cls");
cout << " +";
for (int j = 0; j < size - 1; j++)
cout << "==========+";
cout << "==========+\n";
int totalCells = size * size;
for (int i = 0; i < totalCells; i += size) {
cout << " |";
for (int j = 0; j < size; j++) {
int index = i + j;
string content = " ";
string color = "\033[0m";
if (p1.position == index) {
content = " P1 ";
color = "\033[92m";
}
else if (p2.position == index) {
content = " P2 ";
color = "\033[93m";
}
else if (cells[index]) {
string name = cells[index]->name;
if (name == "Gold") color = "\033[93m"; // Bright Yellow
else if (name == "Silver") color = "\033[96m"; // Bright Cyan
else if (name == "Fire") color = "\033[91m"; // Bright Red
else if (name == "Snake") color = "\033[95m"; // Bright Magenta
else if (name == "Ghost") color = "\033[94m"; // Bright Blue
else if (name == "Lion") color = "\033[31m"; // Red
else if (name == "Lock") color = "\033[92m"; // Bright Green
else if (name == "Sword") color = "\033[90m"; // Bright Black (Gray)
else if (name == "Armor") color = "\033[97m"; // Bright White
else if (name == "Liquid") color = "\033[35m"; // Magenta
else if (name == "Access Key") color = "\033[34m"; // Blue
content = " " + name.substr(0, 8) + " ";
}
cout << color << left << setw(10) << content << "\033[0m|";
}
cout << "\n";
cout << " +";
for (int j = 0; j < size - 1; j++)
cout << "==========+";
cout << "==========+" << endl;
}
}
AdventureQuest::AdventureQuest(int boardSize)
: board(new Board(boardSize)), p1("PLAYER_ONE"), p2("PLAYER_TWO") {
p1.position = boardSize - 1;
p2.position = boardSize * (boardSize - 1);
}
AdventureQuest::~AdventureQuest() {
delete board;
}
void AdventureQuest::start() {
board->generateItems();
cout << "WELCOME TO ADVENTURE QUEST!" << endl;
while (!kyaGameKhatam()) {
board->display(p1, p2);
p1.displayStatus(board->size);
p2.displayStatus(board->size);
playerTurn(p1, 1);
if (kyaGameKhatam())
break;
playerTurn(p2, 2);
if (kyaGameKhatam()) break;
}
showResults();
}
bool AdventureQuest::kyaGameKhatam() {
if (p1.position == target_position()) p1Reached = true;
if (p2.position == target_position()) p2Reached = true;
return (p1Reached && p2Reached);
}
int AdventureQuest::target_position() {
return (board->size * board->size) / 2;
}
void AdventureQuest::playerTurn(GamePlayer& player, int a) {
if (player.turnsToWait > 0) {
cout << player.name << " waits for " << player.turnsToWait << " turn(s)\n";
player.turnsToWait--;
return;
}
if (player.position == target_position()) {
cout << player.name << " has already reached the goal and skips turn.\n";
return;
}
cout << endl << player.name << " turn menu: [1] move, [2] buy helper, [3] place hurdle, [4]
save game ";
int choice;
cin >> choice;
if (choice == 2) {
cout << "Which helper do you want to buy?\n";
cout << "1. Sword\n";
cout << "2. Shield\n";
cout << "3. Water\n";
cout << "4. Key\n";
cout << "Enter your choice (1-4): ";
int itemChoice;
cin >> itemChoice;
if (player.goldCoins >= 2) {
switch (itemChoice) {
case 1:
player.swordUses++;
cout << "sword added" << endl;
break;
case 2:
player.hasShield = true;
cout << "shield added" << endl;
break;
case 3:
player.hasWater = true;
cout << "water added" << endl;
break;
case 4:
player.hasKey = true;
cout << "key added" << endl;
break;
default:
cout << "wromg choice" << endl;
return;
}
player.goldCoins -= 2;
}
else {
cout << "low gold" << endl;
}
return;
}
else if (choice == 3) {
int targetPos;
cout << "enter position to place snake(must be empty): ";
cin >> targetPos;
if (targetPos >= 0 && targetPos < board->size * board->size && board->cells[targetPos]
== nullptr) {
board->cells[targetPos] = new Hurdle("Snake", targetPos, 3, "Sword");
player.goldCoins -= 2;
player.points -= 5;
cout << "Hurdle placed at position " << targetPos << endl;
}
else {
cout << "Invalid cell" << endl;
}
return;
}
else if (choice == 4) {
saveGame();
cout << "Game saved successfully!" << endl;
return;
}
else if (choice == 1) {
int row, col;
row = player.position / board->size;
col = player.position % board->size;
if (a == 1) {
if (row % 2 == 0) {
if (col > 0) col--;
else if (row + 1 < board->size) row++, col = 0;
}
else {
if (col < board->size - 1) col++;
else if (row + 1 < board->size) row++, col = board->size - 1;
}
}
else {
if ((board->size - 1 - row) % 2 == 0) {
if (col < board->size - 1) col++;
else if (row > 0) row--, col = board->size - 1;
}
else {
if (col > 0) col--;
else if (row > 0) row--, col = 0;
}
}
int next_position = row * board->size + col;
int other_player_position = (a == 1) ? p2.position : p1.position;
if (next_position == other_player_position && next_position != target_position()) {
cout << "cell occupied by other playr" << endl;
return;
}
player.position = next_position;
cout << "Moved to position " << next_position << endl;
if (board->cells[next_position]) {
board->cells[next_position]->interaction_with_player(player);
delete board->cells[next_position];
board->cells[next_position] = nullptr;
}
}
}
void AdventureQuest::showResults() {
cout << "\nFINAL RESULT" << endl;
p1.displayStatus(board->size);
p2.displayStatus(board->size);
if (p1.position == target_position() && p1.points > p2.points) {
cout << "PLAYER_ONE Wins" << endl;
}
else if (p2.position == target_position() && p2.points > p1.points) {
cout << "PLAYER_TWO Wins" << endl;
}
else {
cout << "Draw!" << endl;
}
char next;
cout << "Do you want to play the next level with a bigger board? (Y/N): ";
cin >> next;
if (next == 'Y' || next == 'y') {
int newSize = board->size + 2;
if (newSize > 11) {
cout << "Maximum board size reached. Game over.\n";
return;
}
delete board;
board = new Board(newSize);
int p1g = p1.goldCoins + 3;
int p1s = p1.silverCoins + 5;
int p2g = p2.goldCoins + 3;
int p2s = p2.silverCoins + 5;
p1 = GamePlayer("PLAYER_ONE");
p2 = GamePlayer("PLAYER_TWO");
p1.goldCoins = p1g; p1.silverCoins = p1s;
p2.goldCoins = p2g; p2.silverCoins = p2s;
p1.position = newSize - 1;
p2.position = newSize * (newSize - 1);
p1Reached = p2Reached = false;
board->generateItems();
start();
}
}
void AdventureQuest::saveGame() {
ofstream file("savegame.txt");
file << board->size << endl;
for (int i = 0; i < board->size * board->size; i++) {
if (board->cells[i]) {
file << board->cells[i]->name << " " << board->cells[i]->position << " ";
if (dynamic_cast<Coin*>(board->cells[i])) {
file << "Coin " << ((Coin*)board->cells[i])->value << endl;
}
else if (dynamic_cast<Hurdle*>(board->cells[i])) {
file << "Hurdle " << ((Hurdle*)board->cells[i])->turnsToWait << " " <<
((Hurdle*)board->cells[i])->requiredHelper << endl;
}
else if (dynamic_cast<Helper*>(board->cells[i])) {
file << "Helper" << endl;
}
}
else {
file << "Empty" << endl;
}
}
file << p1.name << " " << p1.position << " " << p1.points << " " << p1.goldCoins << " "
<< p1.silverCoins << " " << p1.swordUses << " " << p1.hasShield << " " << p1.hasWater << "
" << p1.hasKey << " " << p1.turnsToWait << endl;
file << p2.name << " " << p2.position << " " << p2.points << " " << p2.goldCoins << " "
<< p2.silverCoins << " " << p2.swordUses << " " << p2.hasShield << " " << p2.hasWater << "
" << p2.hasKey << " " << p2.turnsToWait << endl;
file.close();
cout << "Game saved" << endl;
}
void AdventureQuest::loadGame() {
ifstream file("savegame.txt");
if (!file.is_open()) {
cout << "No saved game found" << endl;
return;
}
int size;
file >> size;
delete board;
board = new Board(size);
for (int i = 0; i < size * size; i++) {
string itemType;
file >> itemType;
if (itemType == "Empty") {
board->cells[i] = nullptr;
}
else {
string name; int pos;
name = itemType;
file >> pos >> itemType;
if (itemType == "Coin") {
int val; file >> val;
board->cells[i] = new Coin(name, pos, val);
}
else if (itemType == "Hurdle") {
int wt; string req;
file >> wt >> req;
board->cells[i] = new Hurdle(name, pos, wt, req);
}
else if (itemType == "Helper") {
board->cells[i] = new Helper(name, pos);
}
}
}
file >> p1.name >> p1.position >> p1.points >> p1.goldCoins >> p1.silverCoins >>
p1.swordUses >> p1.hasShield >> p1.hasWater >> p1.hasKey >> p1.turnsToWait;
file >> p2.name >> p2.position >> p2.points >> p2.goldCoins >> p2.silverCoins >>
p2.swordUses >> p2.hasShield >> p2.hasWater >> p2.hasKey >> p2.turnsToWait;
file.close();
cout << "Game loaded successfully!" << endl;
}
Output: