Website Summary Files Commits Branches @commit @diff @stats
path: root / pract KN / week7 / solution / game.cpp
blob: 9b00b01a3b0555b30cfb80b0588d28b1c088e71b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "game.h"
#include<iostream>
#include<time.h>
#include<cmath>

void game::generateNumber() {
	srand(time(NULL));

	number = rand() % 100 + 1;
}

void game::validateBet(double& bet, double currentMoney) const {
	std::cout << "How much money would you like to bet? " << std::endl
		<< "Your money now: " << currentMoney << std::endl;

	bool fail = false;

	do {
		if (fail)
			std::cout << "Invalid input" << std::endl;

		std::cin >> bet;

		fail = true;

		// Проверява дали сме въвели текстов низ вместо число
		// и поправя потока.
		if (!(bool)(std::cin)) {
			std::cin.clear();
			std::cin.ignore(255, '\n');
		}

	} while (bet > currentMoney || bet < 0);
}

void game::validateNumber(int& num) const {
	std::cout << "Enter your number: ";

	bool fail = false;

	do {
		if (fail)
			std::cout << "Try again" << std::endl;

		std::cin >> num;

		if (!(bool)(std::cin)) {
			std::cin.clear();
			std::cin.ignore(255, '\n');
		}

		fail = true;

	} while (num < 20 || num > 60);
}

double game::getRate(betType currentBet) const {
	double rate = 0;
	int myNumber = 0;

	switch (currentBet) {
	case betType::isEven:
		rate = !(number % 2) ? 0.2 : -1;
		break;
	case betType::isNotEven:
		rate = !(number % 2) ? -1 : 0.2;
		break;
	case betType::isPrime:
		rate = isPrime(number) ? 0.5 : -1;
		break;
	case betType::isPowerOfTwo:
		rate = isPowerOfTwo(number) ? 1 : -1;
		break;
	case betType::isBiggerThan:
		validateNumber(myNumber);
		rate = (myNumber > number) ? 0.25 : -1;
		break;
	case betType::isSmallerThan:
		validateNumber(myNumber);
		rate = (myNumber < number) ? 0.25 : -1;
		break;
	case betType::isTheSameAs:
		validateNumber(myNumber);
		rate = (myNumber == number) ? 10 : -1;
		break;
	}

	return rate;
}

void game::play(player& p) {
	if (p.getAge() < 18) {
		std::cout << "You are too young" << std::endl;
		return;
	}

	char buff[20];
	std::cout << "Enter your password, " << p.getName() << ": ";
	std::cin.getline(buff, 20, '\n');

	if (!p.comparePassword(buff)) {
		std::cout << "Wrong password. Goodbye.";
		return;
	}

	while (!p.isBroke()) {
		double myBet = 0;

		betType currentBet = p.makeBet();

		generateNumber();

		validateBet(myBet, p.getMoney());
		
		p.updateMoney(myBet, getRate(currentBet));

		std::cout << "The number was: " << number << std::endl;
	}

	std::cout << "You lost all your money!" << std::endl;
}


// Bonus:
// https://math.mit.edu/~stevenj/18.335/newton-sqrt.pdf
double newtonSquareRoot(double num, int l = 100) {
	double result = 1;
	double temp = 1;

	for (int i = 0; i < l; i++) {
		temp = 0.5 * (result + num / result);

		if (temp == result && result != 1)
			return result;

		result = temp;
	}

	return result;
}

bool isPrime(int num) {
	// int border = sqrt(num); is fine
	int border = newtonSquareRoot(num);

	for (int i = 2; i <= border; i++)
		if (num % i == 0)
			return false;
	return true;
}

bool isPowerOfTwo(int num) {
	return num != 0 && ((num & (num - 1)) == 0);
}