Summary Files Commits Branches @commit @diff @stats
path: root / Year 1 / Object-oriented Programming
diff options
context:
space:
mode:
Commit30420a6ea65aa58389b9ffa0ba67130de376c079 (patch)
Author
 Syndamia <kamen.d.mladenov@protonmail.com>
2022-04-06 10:29:54 +0300
Committer
 Syndamia <kamen.d.mladenov@protonmail.com>
2022-04-06 10:29:54 +0300
Files12981a8607166b51b9dbbee5ab8e1d965bff509b /Year 1/Object-oriented Programming
uni-projects-30420a6ea65aa58389b9ffa0ba67130de376c079.tar
uni-projects-30420a6ea65aa58389b9ffa0ba67130de376c079.tar.gz
uni-projects-30420a6ea65aa58389b9ffa0ba67130de376c079.zip
Parent2cf8d711c3dd110555c16913941f865841aa3175 (diff)
Implemented overall functionality for yesterdays practice exercise
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.cpp b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.cpp
index ae5fcc0..14274f9 100644
--- a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.cpp
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.cpp
@@ -1,29 +1,58 @@
#include "Game.h"
+/* Helpers */
+
+double getRandomBetween(int a, int b) {
+ if (a > b) {
+ int temp = b;
+ b = a;
+ a = temp;
+ }
+
+ srand(time(NULL));
+ return a + (double(rand()) / RAND_MAX) * (b - a);
+}
+
/* Private */
-void Game::turn(Player& player, double& bet) {
+void Game::copyFrom(const Game& other) {
+ this->caseCount = other.caseCount;
+
+ cases = new GameCase[this->caseCount];
+ for (int i = 0; i < this->caseCount; i++)
+ cases[i] = other.cases[i];
+}
+
+void Game::free() {
+ delete[] cases;
+}
+
+TurnResult Game::turn(double& bet) {
std::cout << "Enter command: ";
char buffer;
std::cin >> buffer;
bool result = false;
- for (int i = 0; i < this->caseCount; i++) {
- if (cases[i].get_comm() == buffer) {
- result = cases[i].exec(player, bet);
- break;
- }
- }
+ int caseI = 0;
+ while (cases[caseI].get_comm() != buffer && caseI < this->caseCount)
+ caseI++;
+
+ if (caseI < this->caseCount)
+ result = cases[caseI].exec(bet);
+ else
+ std::cout << "Invalid command! ";
if (result) {
- std::cout << "You win!";
- player.addToBalance("", bet);
+ std::cout << "You won this turn. Your current bet is " << bet << std::endl << "Do you want to continue? [y/n] ";
+ std::cin >> buffer;
+ return (buffer == 'N' || buffer == 'n') ? Win : Continue;
}
- else {
- std::cout << "You lost!";
- player.deductFromBalance("", bet);
+ else if (bet > 0) {
+ std::cout << "Do you want to quit? [y/n] ";
+ std::cin >> buffer;
+ return (buffer == 'N' || buffer == 'n') ? Continue : Quit;
}
- std::cout << " Current balance: " << player.get_balance() << std::endl;
+ return Lost;
}
/* Public */
@@ -34,4 +63,55 @@ Game::Game(const GameCase* cases, unsigned casesCount) {
this->cases[i] = cases[i];
}
+Game::Game(const Game& other) {
+ this->copyFrom(other);
+}
+
+Game& Game::operator=(const Game& other) {
+ if (this != &other) {
+ this->free();
+ this->copyFrom(other);
+ }
+ return *this;
+}
+
+Game::~Game() {
+ this->free();
+}
+
+void Game::play(Player& player) {
+ if (player.get_age() < 18) {
+ std::cout << "You must be at least 18 years old to play." << std::endl;
+ return;
+ }
+
+ std::cout << "Password: ";
+ char password[2048];
+ std::cin >> password;
+
+ std::cout << "Your current balance: " << player.get_balance() << std::endl << "Enter bet: ";
+ double bet;
+ std::cin >> bet;
+
+ player.deductFromBalance(password, bet);
+ TurnResult result = Continue;
+ while (result == Continue)
+ result = this->turn(bet);
+
+ switch (result) {
+ case Win:
+ std::cout << "You've won! " << bet << " will be added to your account." << std::endl;
+ player.addToBalance(password, bet);
+ break;
+
+ case Quit: // If your bet drops to 0, you'll automatically lose, so you'll never quit with bet of 0.
+ std::cout << "Quitting game. " << bet << " will be added to your account." << std::endl;
+ player.addToBalance(password, bet);
+ break;
+
+ default:
+ std::cout << "You lost! Your balance is " << player.get_balance() << "." << std::endl;
+ break;
+ }
+}
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.h b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.h
index 96feeaf..8915196 100644
--- a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.h
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Game.h
@@ -1,13 +1,25 @@
#include <iostream>
+#include <stdlib.h> // srand, time and rand
#include "Player.h"
#include "GameCase.h"
+double getRandomBetween(int, int);
+
+enum TurnResult {
+ Quit,
+ Continue,
+ Win,
+ Lost
+};
+
class Game {
GameCase* cases;
unsigned caseCount;
- void turn(Player&, double&);
+ void copyFrom(const Game&);
+ void free();
+ TurnResult turn(double&);
public:
Game(const GameCase*, unsigned);
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.cpp b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.cpp
index 713c94c..f16e72b 100644
--- a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.cpp
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.cpp
@@ -3,11 +3,15 @@
GameCase::GameCase() : GameCase('\0', nullptr)
{}
-GameCase::GameCase(char command, bool func(const Player&, double&)) {
+GameCase::GameCase(char command, bool func(double&)) {
this->command = command;
this->func = func;
}
-bool GameCase::exec(const Player& player, double& bet) const {
- return this->func(player, bet);
+char GameCase::get_comm() const {
+ return this->command;
+}
+
+bool GameCase::exec(double& bet) const {
+ return this->func(bet);
}
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.h b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.h
index bf5030f..8efd039 100644
--- a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.h
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/GameCase.h
@@ -2,12 +2,12 @@
class GameCase {
char command;
- bool (*func)(const Player&, double&);
+ bool (*func)(double&);
public:
GameCase();
- GameCase(char, bool f(const Player&, double&));
+ GameCase(char, bool f(double&));
char get_comm() const;
- bool exec(const Player&, double&) const;
+ bool exec(double&) const;
};
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/NumberHelpers.cpp b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/NumberHelpers.cpp
new file mode 100644
index 0000000..d7843b4
--- /dev/null
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/NumberHelpers.cpp
@@ -0,0 +1,35 @@
+#include "NumberHelpers.h"
+
+bool isEven(int x) {
+ return x % 2 == 0;
+}
+
+// The following functions are taken from my own Interval task solution
+
+bool isPowerOfTwo(int x)
+{
+ return x > 0 && // No (normal) power of 2 creates negatives or 0
+ (x & (x - 1)) == 0; // Thanks https://stackoverflow.com/a/600306/12036073, original implementation was a lot less efficient
+}
+
+bool isPrime(int num) // Forked from my own implementation - https://gitlab.com/Syndamia/algorithms/-/blob/master/C/IsPrime.c
+{
+ if (num < 0) num *= -1; // This is required, since we calculate sqrt(num)
+
+ if (num == 2 || num == 3 || num == 5 || num == 7 || num == 11 || num == 13)
+ return true;
+
+ // A lot of numbers are divisible by these ones, so we're going to do a bit of simple optimization
+ if (num == 0 || num == 1 || num % 2 == 0 || num % 3 == 0 || num % 5 == 0 || num % 7 == 0 || num % 11 == 0 || num % 13 == 0)
+ return false;
+
+ // All primes follow the formula 6n +- 1 (where n >= 1). Since we've already checked up to 13, we're going to
+ // start with 18 - 1 = 17. Also using root of number to eliminate a lot of checks.
+ // Primary source: https://en.wikipedia.org/wiki/Primality_test#Simple_methods
+ for (int i = 18, root = sqrt(num); i - 1 <= root; i += 6)
+ {
+ if (num % (num - 1) == 0 || num % (num + 1) == 0)
+ return false;
+ }
+ return true;
+}
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/NumberHelpers.h b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/NumberHelpers.h
index 2e1050b..159f0f3 100644
--- a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/NumberHelpers.h
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/NumberHelpers.h
@@ -1,3 +1,5 @@
+#include <math.h>
+
bool isEven(int);
-bool isPrimary(int);
bool isPowerOfTwo(int);
+bool isPrime(int);
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Player.cpp b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Player.cpp
index eaca839..cb76553 100644
--- a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Player.cpp
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/Player.cpp
@@ -23,7 +23,7 @@ bool Player::isValidPassword(const char* passwordAttempt) {
/* Public */
-Player::Player(const char* name, const char* pass, unsigned age, double currentBalance) {
+Player::Player(const char* name, const char* pass, unsigned age, double balance) {
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
this->pass = new char[strlen(pass) + 1];
diff --git a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/source.cpp b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/source.cpp
index e69de29..1a3f4ba 100644
--- a/Year 1/Object-oriented Programming/07-Practice-05.04.2022/source.cpp
+++ b/Year 1/Object-oriented Programming/07-Practice-05.04.2022/source.cpp
@@ -0,0 +1,98 @@
+#include "Game.h"
+#include "NumberHelpers.h"
+
+bool gameCase_evenOrOdd(double& bet) {
+ int rnd = getRandomBetween(1, 100);
+ std::cout << "Is the number [e]ven or [o]dd? ";
+ char buffer;
+ std::cin >> buffer;
+
+ while (buffer != 'e' && buffer != 'o') {
+ std::cout << "Unknown option '" << buffer << "', choice must be either 'e' or 'o'." << std::endl << "Is the number [e]ven or [o]dd? ";
+ std::cin >> buffer;
+ }
+
+ bool result = isEven(rnd) == (buffer == 'e');
+ bet = (result) ? bet / 5 : 0;
+ std::cout << "The number was: " << rnd << std::endl;
+ return result;
+}
+
+bool gameCase_isPrime(double& bet) {
+ int rnd = getRandomBetween(1, 100);
+
+ bool result = isPrime(rnd);
+ bet = (result) ? bet / 2 : 0;
+ std::cout << "The number was: " << rnd << std::endl;
+ return result;
+}
+
+bool gameCase_isPowerOfTwo(double& bet) {
+ int rnd = getRandomBetween(1, 100);
+
+ bool result = isPowerOfTwo(rnd);
+ bet = (result) ? bet / 2 : 0;
+ std::cout << "The number was: " << rnd << std::endl;
+ return result;
+}
+
+bool gameCase_higherOrLower(double& bet) {
+ int rnd = getRandomBetween(1, 100);
+
+ std::cout << "Your number [20...60] ";
+ int num;
+ std::cin >> num;
+
+ while (num < 20 || num > 60) {
+ std::cout << "Number not in range! Enter number [20...60] ";
+ std::cin >> num;
+ }
+
+ std::cout << num << " will be [h]igher or [l]ower than random? ";
+ char guess;
+ std::cin >> guess;
+
+ while (guess != 'h' && guess != 'l') {
+ std::cout << "Invalid option '" << guess << "', must be either 'h' or 'l'." << std::endl << num << " will be [h]igher or [l]ower than random? ";
+ std::cin >> guess;
+ }
+
+ bool result = (rnd > num) == (guess == 'h');
+ bet = (result) ? bet / 4 : 0;
+ std::cout << "The number was: " << rnd << std::endl;
+ return result;
+}
+
+bool gameCase_guess(double& bet) {
+ int rnd = getRandomBetween(1, 100);
+
+ std::cout << "Your guess: ";
+ int num;
+ std::cin >> num;
+
+ bool result = num == rnd;
+ bet = (result) ? bet * 10 : 0;
+ std::cout << "The number was: " << rnd << std::endl;
+ return result;
+}
+
+int main() {
+ GameCase numberGambleCases[] = {
+ GameCase('e', gameCase_evenOrOdd),
+ GameCase('p', gameCase_isPrime),
+ GameCase('t', gameCase_isPowerOfTwo),
+ GameCase('h', gameCase_higherOrLower),
+ GameCase('g', gameCase_guess)
+ };
+ Game numberGamble(numberGambleCases, 5);
+
+ Player yorgus("Yorgus", "yorgus", 23, 57741.39);
+
+ char buffer = '\0';
+ while (buffer != 'n' && buffer != 'N') {
+ numberGamble.play(yorgus);
+ std::cout << "Do you want to play again? [y/n] ";
+ std::cin >> buffer;
+ }
+ std::cout << "Your balance: " << yorgus.get_balance() << std::endl;
+}