Commit 19f2e4da authored by kimon-satan's avatar kimon-satan
Browse files

initial commit

parents
Caterpillar
===========
This is the home of Caterpillar or Cat for short.
Clone the repository and RUNME to get started.
If you've come here straight from the Mock Turtle then head over to http://igor.gold.ac.uk/~skata001/underland/pt3/classc.html and watch the videos first
Enjoy, but not too much !
#!/bin/bash
os=$(uname -s)
os=${os:0:4}
if [ $os == "MSYS" ]; then
var="#define WIN64"
sed -i '3s/.*/#define WIN64/' shrooms/A.cpp
sed -i '3s/.*/#define WIN64/' shrooms/G.h
sed -i '3s/.*/#define WIN64/' shrooms/V.h
fi
function pause {
local count=0
while [ $count -lt $1 ]; do
echo ...
sleep 2
let count=count+1
done
}
clear
pause 2
echo "Hey dude"
pause 1
echo "I'm Caterpillar but you can call me the Cat"
pause 1
echo "Underland getting you down eh ?"
pause 1
echo "It does that to every cat in the end."
pause 1
echo "Nevermind I have a little pickmeup… if you know what I mean."
pause 2
clear
pause 1
echo "Take a look inside the folder shrooms"
pause 1
echo "Inside there is purest collection of C++ in the whole of Underland"
pause 1
echo "You got A's you got B's you got C's ... "
pause 1
echo "Well you catch my drift"
pause 2
clear
pause 1
echo "But listen you can't do that stuff raw you know"
pause 1
echo "Gotta compile it b4 you run it dude"
pause 2
echo "Why don't you compile up some A.cpp"
pause 2
echo "You won't be disappointed"
if [ $os == "MSYS" ]; then
pause 2
echo "Hey are you using Windows and MSYS ?"
pause 2
echo "If so you'll need to add the compiler flag '-std=c++11' to your g++ commands"
fi
#include "cauldron.h"
#include "utils.h"
using namespace std;
using namespace Utils;
void StartBoil(){
printVerticalDots(5,200);
cout << "bubble \n";
pause(1);
cout << "gurgle \n";
pause(1);
cout << "bubble \n";
pause(2);
cout << "Great the water is boiling \n";
pause(1);
cout << "We're almosssssst ready \n";
pause(1);
cout << "All I need now is my cookbook \n";
pause(1);
cout << "This is a dynamic library \n";
pause(2);
cout << "First you have to make it \n";
pause(1);
cout << "Find the right recipe in the makefile and make it \n";
pause(1);
cout << "Have a look in the folder libs and you should see libcookbook.dylib (cookbook.dll for windows) right there \n";
pause(2);
cout << "Once you have done that you need to add the correct library search paths to the makefile \n";
pause(1);
cout << "Do this by adding the path with a -L to the variable LIBRARY_PATHS \n"; pause(1);
cout << "Then you need to to add the library to the shrooms recipe using a -l flag \n";
pause(1);
cout << "After all this we finally will be ready to make ssssome sssssshrooms. Make shrooms and then run the output \n";
pause(2);
}
#pragma once
void StartBoil();
#include <stdio.h>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
#include <stdlib.h>
#ifdef WIN64
#include "windows.h"
#endif
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
using namespace std;
namespace Utils{
struct Line {
string level;
string crc;
string word;
};
struct Level
{
string level;
int points;
string word;
};
string username;
int errors;
map<string, Line> lineMap;
void submitAnswer(string level, string word);
bool checkScoreFilePath();
void readScoreFile(string fp);
void writeScoreFile(string fp);
void setUsername(string s);
string decryptWord(string word, string crc);
string encryptWord(string word, string crc);
string encryptLevel(string level, string crc);
string decryptLevel(string str);
string calcrc(string st);
string calcrc(const char * ptr);
string addCRCs(string a, string b);
string subCRCs(string a, string b);
void millisleep(int ms);
void pause(int n);
void printVerticalDots(int num, int ms);
string intToString(int a);
void split(const string& s, char c, vector<string>& v);
int stringToInt(string s);
void submitAnswer(string level, string word)
{
Line line;
line.crc = calcrc(word); //1. calcrc of word
if(level == "000") //username stages 2 & 4 not applicable
{
line.level = encryptLevel(level, line.crc);
string t_crc = line.level + line.crc;
line.word = encryptWord(word ,t_crc); //3. use this to make wordEncrypt (encrypt with temporary level code)
lineMap[level] = line;
}
else
{
if(lineMap.find("000") == lineMap.end())
{
cout << "ERROR: username not found \n";
return;
}
line.crc = addCRCs(lineMap["000"].crc, line.crc); //2. add usernameCrc to wordCrc
string t_crc = encryptLevel(level, line.crc);
t_crc += line.crc;
line.word = encryptWord(word ,t_crc); //3. use this to make wordEncrypt
int ilevel = stringToInt(level);
int sl = ilevel%100;
int ml = ilevel/100;
for(int i = 0; i < sl; i++)
{
string slevel = intToString(ml * 100 + i);
if(lineMap.find(slevel) != lineMap.end()) //just total up the keys to a level
{
line.crc = addCRCs(lineMap[slevel].crc, line.crc); //4. add previous levels wordCrcs to wordCrc
}else{
cout << "ERROR: sublevel " << slevel << "is missing \n";
return;
}
}
line.level = encryptLevel(level, line.crc);
lineMap[level] = line;
}
}
bool checkScoreFilePath(string fp)
{
ifstream scoreFile;
scoreFile.open(fp);
if(scoreFile.is_open())
{
scoreFile.close();
return true;
}else{
return false;
}
}
void readScoreFile(string fp)
{
ifstream scoreFile;
scoreFile.open(fp);
if(scoreFile.is_open())
{
lineMap.clear();
string str;
while(getline (scoreFile, str))
{
if(str.length() > 0)
{
string ld = decryptLevel(str);
Line line;
line.level = str.substr (0,3);
line.crc = str.substr(3,5);
line.word = str.substr(8);
lineMap[ld] = line;
//cout << ld << "::" << line.level << "," << line.crc << "," << line.word << endl;
}
}
scoreFile.close();
}else{
cout << "WARNING: Path to score file is incorrect \n";
}
if(lineMap.find("000") != lineMap.end())
{
string t_crc = lineMap["000"].level + lineMap["000"].crc;
username = decryptWord(lineMap["000"].word , t_crc);
cout << "username: " << username << endl;
}
}
void writeScoreFile(string fp)
{
//NB Line objects remain encrypted
ofstream scoreFile;
scoreFile.open(fp, std::ofstream::out | std::ofstream::trunc);
if(scoreFile.is_open())
{
map<string, Line> :: iterator it = lineMap.begin();
while(it != lineMap.end()){
string line = "";
line = it->second.level + it->second.crc + it->second.word;
line += "\n";
scoreFile << line;
it++;
}
scoreFile.close();
}else{
cout << "WARNING: Path to score file is incorrect \n";
}
}
void setUsername(string s)
{
username = s;
submitAnswer("000", username);
}
string encryptWord(string word, string crc)
{
int mul = atoi(crc.c_str());
vector<int> cypher;
for(int i = 0; i < crc.length(); i++)
{
char c = crc[i];
cypher.push_back(((c - '0' + 1) * mul)%13 + 1);
}
for(int i = 0; i < word.length(); i++)
{
word[i] -= cypher[i%cypher.size()];
}
return word;
}
string decryptWord(string word, string crc)
{
int mul = atoi(crc.c_str());
vector<int> cypher;
for(int i = 0; i < crc.length(); i++)
{
char c = crc[i];
cypher.push_back(((c-'0' + 1) * mul)%13 + 1);
}
for(int i = 0; i < word.length(); i++)
{
word[i] += cypher[i%cypher.size()];
}
return word;
}
string encryptLevel(string level, string crc)
{
if(level.length() <= crc.length())
{
string sub = crc.substr(0, level.length()); //encode the level code by subtracting digits from the crc
//this will be the final stage when more encryption is added later
string cryptLevel = subCRCs(level, sub);
return cryptLevel;
}
else
{
cout << "ERROR: key is too long \n";
return "";
}
}
string decryptLevel(string str)
{
string level = str.substr(0,3);
string ansCrc = str.substr(3, 3);
level = addCRCs(level, ansCrc);
return level;
}
string calcrc(string st)
{
char * ptr = new char[st.length() + 1];
strcpy(ptr, st.c_str());
char * savedPtr = ptr;
string crc = calcrc(ptr);
delete []savedPtr;
return crc;
}
string calcrc(const char * ptr)
{
int count = strlen(ptr);
unsigned short crc;
crc = 0;
//
for(int j = 0; j < count; j++)
{
int p = *ptr;
p = p << 8;
crc = crc ^ p;
for(int i = 0; i < 8; i++)
{
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
}
++ptr;
}
string str = intToString(crc);
//fill with zeroes before the first digit
while(str.length() < 5)
{
str = "0" + str;
}
return str;
}
string addCRCs(string a, string b)
{
if(a.length() == b.length())
{
string str(a.length(), ' ');
for(int i = 0; i < a.length(); i++)
{
char ac = a[i];
char bc = b[i];
int ai = ac - '0';
int bi = bc - '0';
str[i] = '0' + (ai + bi)%10;
}
return str;
}
else
{
cout << "error: crc mismatch:: " << a.length() << " to " << b.length() << endl;
return "";
}
}
string subCRCs(string a, string b)
{
if(a.length() == b.length())
{
string str(a.length(), ' ');
for(int i = 0; i < a.length(); i++)
{
char ac = a[i];
char bc = b[i];
int ai = ac - '0';
int bi = bc - '0';
int r = (ai - bi);
if(r < 0) r += 10;
str[i] = '0' + r;
}
return str;
}
else
{
cout << "error: crc mismatch:: " << a.length() << " to " << b.length() << endl;
return "";
}
}
void millisleep(int ms)
{
#ifdef WIN64
Sleep(ms);
#else
struct timespec ts = {0}, rem;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000000L;
while(nanosleep(&ts, &rem))
{
ts.tv_sec = rem.tv_sec;
ts.tv_nsec = rem.tv_nsec;
}
#endif
}
void pause(int n)
{
for(int i = 0; i < n; i++)
{
printf( "... \n" );
millisleep(700);
}
}
void printVerticalDots(int num, int ms)
{
for(int i = 0; i < num; i++)
{
printf(".\n");
millisleep(ms);
}
}
string intToString(int a)
{
stringstream ss;
ss << a;
return ss.str();
}
int stringToInt(string s)
{
int Number;
if ( ! (istringstream(s) >> Number) ) Number = 0;
return Number;
}
void split(const string& s, char c, vector<string>& v)
{
string::size_type i = 0;
string::size_type j = s.find(c);
if(j == string::npos){
v.push_back(s);
}
while (j != string::npos)
{
v.push_back(s.substr(i, j-i));
i = ++j;
j = s.find(c, j);
if (j == string::npos)
{
v.push_back(s.substr(i, s.length()));
}
}
}
}
/////////////////////////////////////////////////////////
int main( int argc, const char* argv[] )
{
string scoreFilePath = "";
bool isValidFile = true;
if(argc < 2)
{
isValidFile = false;
}
else
{
scoreFilePath = string(argv[1]);
isValidFile = Utils::checkScoreFilePath(scoreFilePath);
}
if(!isValidFile)
{
cout << "Dude \n";
Utils::printVerticalDots(2, 1000);
cout << "To catch this trip, you need to pass a valid path to your score file as an argument.\n";
Utils::printVerticalDots(2, 1000);
cout << "For example ~/Desktop/aiw_skata001" << endl;
Utils::printVerticalDots(2, 1000);
cout << "Relax dude. Have another go." << endl;
return 0;
}
Utils::readScoreFile(scoreFilePath);
Utils::submitAnswer("300", "dude");
Utils::writeScoreFile(scoreFilePath);
for(int i = 0; i < 100; i++){
for(int j =0 ; j < i+1; j++){
printf(".");
}
printf( "\n" );
Utils::millisleep(50);
}
for(int i = 0; i < 100; i++){
for(int j =100 - i; j > 0; j--){
printf(".");
}
printf( "\n" );
Utils::millisleep(50);
}
for(int i = 0; i < 20; i++){
printf( ".\n" );
Utils::millisleep(200);
}
printf( "Whoah ! \n");