Just finished the section of the Unreal course on pure C++ where you make Triple X
I already have knowledge of C# and Python so I was able to spice it up a bit (and make it more difficult).
I added an “animated” intro that makes it feel like you’re logging on to an old computer,
added a loading screen of sorts between codes,
allowed the player to select the difficulty parameters at the start of the game (between set values that you can change in the code, I’ve set them at 1 and 20),
and most of all generated codes of n length, meaning the game is a lot more difficult as codes can go to a length of 22 (with the hard coded difficulty limits)
Here’s the code:
#include <iostream>
#include <thread>
#include <chrono>
#include <string>
#include <ctime>
#include <vector>
bool GameLogic(int Difficulty);
// Printing functions
void PrintIntro();
void PrintLoading(std::string Text);
void SlowPrint(std::string Text, int Delay);
// Maths functions
int ClampInteger(int Input, const int Range[2]);
int SumVector(std::vector<int> Vector);
int ProductVector(std::vector<int> Vector);
int main()
{
srand(time(NULL));
const int DifficultyRange[2] = {1, 20};
int InputLevelDifficulty, InputMaxDifficulty;
std::cout << "* TripleX DOS varient *\n";
std::cout << "Specify an integer between " << DifficultyRange[0] << " and " << DifficultyRange[1] << " for starting difficulty: ";
std::cin >> InputLevelDifficulty;
std::cout << "Specify an integer between " << DifficultyRange[0] << " and " << DifficultyRange[1] << " for maximum difficulty: ";
std::cin >> InputMaxDifficulty;
if (InputMaxDifficulty < InputLevelDifficulty)
{
InputMaxDifficulty = InputLevelDifficulty;
}
PrintIntro();
int LevelDifficulty = ClampInteger(InputLevelDifficulty, DifficultyRange);
const int MaxDifficulty = ClampInteger(InputMaxDifficulty, DifficultyRange);
while (LevelDifficulty <= MaxDifficulty)
{
bool bLevelComplete = GameLogic(LevelDifficulty);
std::cin.clear();
std::cin.ignore();
if (!bLevelComplete)
{
std::cout << "Code incorrect\n";
std::cout << "Your hard disk has been encrypted to secure your data from possible intruders\n";
std::system("Pause");
return 0;
}
++LevelDifficulty;
}
std::cout << "\nPassword reset successfull, new temporary password: admin\n";
std::system("Pause");
return 0;
}
bool GameLogic(int Difficulty)
{
std::vector<int> Codes = {};
const int NumberOfCodes = rand() % Difficulty + 3;
for (int i = 0; i < NumberOfCodes; i++)
{
// Still using + 1 rather than + Difficulty as with varying code sizes would be impossible
Codes.push_back(rand() % Difficulty + 1);
}
const int CodeSum = SumVector(Codes);
const int CodeProduct = ProductVector(Codes);
PrintLoading("Generating Code");
std::cout << "\nCode difficulty: " << Difficulty << "\n";
std::cout << "[#] There are " << NumberOfCodes << " segments in the code\n";
std::cout << "[#] The segments in the code add up to " << CodeSum << "\n";
std::cout << "[#] The segments in the code multiply to " << CodeProduct << "\n";
// Store player input
std::vector<int> Guesses = {};
for (int i = 0; i < NumberOfCodes; i++)
{
int Guess;
std::string Input;
while (true)
{
std::cout << "C:\\> ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Found this online to ignore spaces
std::cin >> Input;
try
{
Guess = std::stoi(Input);
break;
}
catch (const std::exception &e)
{
std::cout << "Input not a number\n";
}
}
Guesses.push_back(Guess);
}
int GuessSum = SumVector(Guesses);
int GuessProduct = ProductVector(Guesses);
// Check win condition
if (GuessSum == CodeSum && GuessProduct == CodeProduct)
{
return true;
}
else
{
return false;
}
}
void PrintIntro()
{
using namespace std::this_thread;
using namespace std::chrono;
PrintLoading("Starting MS-DOS");
std::cout << "\nPlease enter your password:";
std::cout << "\nC:\\> ";
sleep_for(1s);
SlowPrint("reset password", 100);
std::cout << "\nTo reset your password please complete the following security check\n";
std::cout << "You will be reqired to solve a number of codes of varying length\n";
std::cout << "To enter a segment of a code, simply type a number and press enter\n";
std::system("Pause");
}
void PrintLoading(std::string Text)
{
using namespace std::this_thread;
using namespace std::chrono;
const int Delay = 300;
for (int i = 0; i < 3; i++)
{
std::system("CLS");
std::cout << Text << ".";
sleep_for(milliseconds(Delay));
std::cout << ".";
sleep_for(milliseconds(Delay));
std::cout << ".";
sleep_for(milliseconds(Delay));
}
}
void SlowPrint(std::string Text, int Delay)
{
using namespace std::this_thread;
using namespace std::chrono;
for (int i = 0; i < Text.length(); i++)
{
std::cout << Text[i];
sleep_for(milliseconds(Delay));
}
}
int ClampInteger(int Input, const int Range[2])
{
if (Input < Range[0])
{
Input = Range[0];
}
else if (Input > Range[1])
{
Input = Range[1];
}
return Input;
}
int SumVector(std::vector<int> Vector)
{
int Sum = 0;
for (int i = 0; i < Vector.size(); i++)
{
Sum += Vector[i];
}
return Sum;
}
int ProductVector(std::vector<int> Vector)
{
int Product = 1;
for (int i = 0; i < Vector.size(); i++)
{
Product *= Vector[i];
}
return Product;
}
Edit:
After playing around with it for a bit I’ve noticed if you don’t enter a number for the first segment of a code (works fine otherwise) then it doesn’t try and validate your input, but waits for more.
It’s not a game breaking bug so I’m just going to continue with the course and leave it in there.
Edit 2:
Noticed the win screen didn’t pause and closes the game instantly, fixed above.