summaryrefslogtreecommitdiff
path: root/BlankConsoleLab/BlankConsoleLab.cpp
blob: 898ab8b32bde03ca2036939fa4af1b9b6719cc8a (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
#include <iostream>
#include <string> //used for converting things to strings
#include <vector> //feeding my crippling addiction to overengineering everything
#include <tuple>  //^^^
#include <windows.h> //colored couts go brrrr :)

using namespace std;

const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

//Prints in full color with (optional) automatic line breaks. Requires <windows.h> Returns nothing and takes up to 4 parameters:
//console (HANDLE): Used for colored text. Always set it to hConsole and don't worry about it.
//text (string): The text to be printed. Don't put a newline at the end.
//color (int): The color code of the text. Optional, defaults to white.
//linebreak (bool): Whether to end the line after printing. Optional, defaults to true.
void colorPrint(string text, int color = 15, bool linebreak = true, HANDLE console = hConsole)
{
	SetConsoleTextAttribute(console, color); //Use black magic (native OS commands) to change the color of any text we print.
	cout << text;
	SetConsoleTextAttribute(console, 15); //Use more black magic to set the color back to white so that we don't start randomly printing other colors.
	if (linebreak) //Add a line break to the end of the text unless told not to
	{
		cout << endl;
	}
}

void multiColorPrint(vector<tuple<string, int, bool> > text, HANDLE console = hConsole)
{
	string fragmentText;
	int fragmentColor;
	bool fragmentBreak;
	for (auto i : text) {
		tie(fragmentText, fragmentColor, fragmentBreak) = i;
		colorPrint(fragmentText, fragmentColor, fragmentBreak, console);
	}
}

//Super messy and really just here because if you're reusing more than one line, you're doing something wrong.
float getWidthOrHeight(string d)
{
	float input;
	vector<tuple< string, int, bool> > text;
	text.push_back(make_tuple("Please enter the ", 15, false));
	text.push_back(make_tuple(d, 11, false));
	text.push_back(make_tuple(" of your kite in ", 15, false));
	text.push_back(make_tuple("cm", 11, false));
	text.push_back(make_tuple(": ", 15, false));
	while (true)
	{
		multiColorPrint(text);
		if (cin >> input) //This feels so wrong but it does in fact work.
		{
			break;
		}
		colorPrint("Oh no! It looks like something went wrong.\nPlease make sure your width is a number and try again.", 12);
		cin.clear();
		cin.ignore(80, '\n');
	}
	return input;
}

//Return the kite's area in square meters.
float calulateKiteArea(float width, float height)
{
	return ((width * height) / 2) / 10000;
}

//Computes and prints aspect ratio
void aspectRatio(float width, float height)
{
	float ratio = width / height;
	multiColorPrint(vector<tuple<string, int, bool> > {make_tuple("Your kite has an aspect ratio of ", 15, false), make_tuple(to_string(ratio), 11, false), make_tuple(". ", 15, false)});
	if (ratio >= 5) {
		colorPrint("That number should be above 1, yes, but this seems a little overkill.", 6);
	}
	else if (ratio >= 1) {
		colorPrint("Your kite will fly nice and stable, provided you actually know how to fly it.", 10);
	}
	else
	{
		colorPrint("Your kite is too wide and will be unstable. Or you could just, like, fly it sideways or something.", 6);
	}
}

int main()
{
	float width, height;

	colorPrint("Welcome to Kite Calculator, can I take your order.", 13);

	colorPrint("Let's start with getting the dimensions of your kite.", 9);
	width = getWidthOrHeight("width");
	height = getWidthOrHeight("height");
	cout << endl;

	//Tell the user what they just entered, because...reasons.
	colorPrint("Great job. Let's do some math.", 10);
	multiColorPrint(vector<tuple<string, int, bool> > {make_tuple("Your kite is ", 15, false), make_tuple(to_string(width) + "cm", 11, false), make_tuple(" wide and ", 15, false), make_tuple(to_string(height) + "cm", 11, false), make_tuple(" high.", 15, true), }); //I hate this but its still better than stacking like 20 couts.
	colorPrint("I'm sure it's beautiful.\n", 9);

	//Calculate the kite's area and tell it to the user.
	float area = calulateKiteArea(width, height);
	multiColorPrint(vector<tuple<string, int, bool> > {make_tuple("Your kite has an area of ", 15, false), make_tuple(to_string(area) + " square meters", 11, false), make_tuple(". ", 15, true));
	cout << endl;

	//Do aspect ratio stuff.
	aspectRatio(width, height);

	return 0;
}