Skip to main content
Loading...

More C++ Posts

//Leif Messinger
//Finds all sets of 5 5 letter words that don't have duplicate letters in either themselves or each other.
//First it reads the words in and puts them in groups of their bitmasks
//After that, we recurse on each group. Before doing that, we remove the group from the set of other groups to check it against.
#include <cstdio> //getchar, printf
#include <cassert> //assert
#include <vector>
#include <set>
#include <algorithm> //std::copy_if
#include <iterator> //std::back_inserter

#define CHECK_FOR_CRLF true
#define MIN_WORDS 5
#define MAX_WORDS 5
#define WORD_TOO_LONG(len) (len != 5)

const unsigned int charToBitmask(const char bruh){
	assert(bruh >= 'a' && bruh <= 'z');
	return (1 << (bruh - 'a'));
}

void printBitmask(unsigned int bitmask){
	char start = 'a';
	while(bitmask != 0){
		if(bitmask & 1){
			putchar(start);
		}

		bitmask >>= 1;
		++start;
	}
}

//Pointer needs to be deleted
const std::set<unsigned int>* getBitmasks(){
	std::set<unsigned int>* bitmasksPointer = new std::set<unsigned int>;
	std::set<unsigned int>& bitmasks = (*bitmasksPointer);

	unsigned int bitmask = 0;
	unsigned int wordLength = 0;
	bool duplicateLetters = false;
	for(char c = getchar(); c >= 0; c = getchar()){
		if(CHECK_FOR_CRLF && c == '\r'){
			continue;
		}
		if(c == '\n'){
			if(!(WORD_TOO_LONG(wordLength) || duplicateLetters)) bitmasks.insert(bitmask);
			bitmask = 0;
			wordLength = 0;
			duplicateLetters = false;
			continue;
		}
		if((bitmask & charToBitmask(c)) != 0) duplicateLetters = true;
		bitmask |= charToBitmask(c);
		++wordLength;
	}

	return bitmasksPointer;
}

void printBitmasks(const std::vector<unsigned int>& bitmasks){
	for(unsigned int bruh : bitmasks){
		printBitmask(bruh);
		putchar(','); putchar(' ');
	}
	puts("");
}

//Just to be clear, when I mean "word", I mean a group of words with the same letters.
void recurse(std::vector<unsigned int>& oldBitmasks, std::vector<unsigned int> history, const unsigned int currentBitmask){
	//If there's not enough words left
	if(oldBitmasks.size() + (-(history.size())) + (-MIN_WORDS) <= 0){
		//If there's enough words
		if(history.size() >= MIN_WORDS){
			//Print the list
			printBitmasks(history);
		}
		return;
	//To make it faster, we can stop it after 5 words too
	}else if(history.size() >= MAX_WORDS){
		//Print the list
		printBitmasks(history);
		return;
	}

	//Thin out the array with only stuff that matches the currentBitmask.
	std::vector<unsigned int> newBitmasks;
	std::copy_if(oldBitmasks.begin(), oldBitmasks.end(), std::back_inserter(newBitmasks), [&currentBitmask](unsigned int bruh){
		return (bruh & currentBitmask) == 0;
	});

	while(newBitmasks.size() > 0){
		//I know this modifies 'oldBitmasks' too. It's intentional.
		//This makes it so that the word is never involved in any of the child serches or any of the later searches in this while loop.
		const unsigned int word = newBitmasks.back(); newBitmasks.pop_back();

		std::vector<unsigned int> newHistory = history;
		newHistory.push_back(word);

		recurse(newBitmasks, newHistory, currentBitmask | word);
	}
}

int main(){
	const std::set<unsigned int>* bitmasksSet = getBitmasks();
	std::vector<unsigned int> bitmasks(bitmasksSet->begin(), bitmasksSet->end());
	delete bitmasksSet;

	recurse(bitmasks, std::vector<unsigned int>(), 0);

	return 0;
}
#include <iostream>
#include <vector>
#include <limits>

#define DEBUG_TRIAL false

class Trial{
    public:
        const size_t HEIGHT;
        std::string record;
        
        //Breaking height is the index of the floor, so 0 is the bottom floor, height-1 is the top floor.
        //Eggs is the eggs remaining.
        //Start is the bottom floor.
        //End is one above the top floor.
        const size_t BREAKING_HEIGHT;
        size_t eggs;
        size_t start;
        size_t end;
        
        
        size_t floorsLeft(){
            return (end-start);
        }
        
        size_t middle(){
            return start + (floorsLeft()/2UL);
        }
        
        size_t drops = 0;
        Trial(const size_t BREAKING_HEIGHT, size_t eggs, size_t start, size_t end): BREAKING_HEIGHT(BREAKING_HEIGHT), eggs(eggs), start(start), end(end), HEIGHT(end), record(end, '_'){
            record[BREAKING_HEIGHT] = 'B'; //Marking the breaking point
        }
        
        bool foundAnswer(){
            return ((record[0] == 'X') || (record.find("OX")!=std::string::npos));
        }
        
        //returns true if the egg broke.
        //height is the index of the floor, so 0 is the bottom floor, height-1 is the top floor.
        bool drop(size_t height){
            
            #if DEBUG_TRIAL
                std::cout << "Start: " << start << ". End: " << end << ". Floors Left: " << floorsLeft() << ". Middle Index: " << middle() << std::endl;
            #endif
            
            drops++;
            bool cracked = height >= BREAKING_HEIGHT;
            if(cracked) --eggs;
            
            //Update the record
            record[height] = (height >= BREAKING_HEIGHT)? 'X' : 'O';
            
            #if DEBUG_TRIAL
                //Print the record
                std::cout << record << std::endl;
            #endif
        
            return cracked;
        }
        
        size_t nowWhat(){
            if(foundAnswer()){
                return drops;
            }else if(eggs <= 0){ //Ran out of eggs
                throw "Algorithm failed! No more eggs!";
                return 1UL;
            }else if(eggs > 1){
                return wrecklessSearch();
            }else{
                return safeSearch();
            }
        }
        
        size_t safeSearch(){
            if(drop(start)){
                --end;
            }else{
                ++start;
            }
            
            return nowWhat();
        }
        
        size_t wrecklessSearch(){
            //If the egg breaks
            if(drop(middle())){
                end -= (floorsLeft()/2UL);
            }else{ //egg doesn't crack
                start += (floorsLeft()/2UL);
            }
            
            return nowWhat();
        }
        
        //returns the amount of drops needed to find the answer
        size_t search(){
            return nowWhat();
        }
};

//Height is the height of the building in floors.
//Breaking height is the index of the floor, so 0 is the bottom floor, height-1 is the top floor.
//Eggs is the eggs given.
//returns the amount of drops needed to find the answer
size_t search(const size_t height, const size_t BREAKING_HEIGHT, size_t eggs){
    Trial trial(BREAKING_HEIGHT, eggs, 0, height);
    return trial.search();
}

class TrialStats {
    public:
        size_t min = std::numeric_limits<size_t>::max();
        size_t max = 0;
        double mean = -1.0;
        
        void printStats(){
            // Print the results
            std::cout << "Minimum drops: " << min << std::endl;
            std::cout << "Maximum drops: " << max << std::endl;
            std::cout << "Mean drops: " << mean << std::endl;
        }
};

//Benchmarks all the possible breaking points of a single building height with a number of eggs.
TrialStats trial(const size_t HEIGHT, const size_t eggs){
    
    TrialStats stats;
    int totaldrops = 0;

    //Test every possible breaking point
    //Breaking height is the index of the floor, so 0 is the bottom floor, height-1 is the top floor.
    for (int breakingHeight = 0; breakingHeight < HEIGHT; ++breakingHeight) {
        size_t drops = search(HEIGHT, breakingHeight, eggs);

        stats.min = std::min(stats.min, drops);
        stats.max = std::max(stats.max, drops);
        totaldrops += drops;
    }

    // Calculate the mean number of drops
    stats.mean = static_cast<double>(totaldrops) / HEIGHT;
    
    return stats;
}

//Benchmarks a single building height from 1 egg to MAX_EGGS
void testTower(const size_t height, const size_t MAX_EGGS){
    //Drop every amount of eggs that you'd need.
    for (int eggs = 1; eggs <= MAX_EGGS; ++eggs) {
        std::cout << "Building height: " << height << ". Num eggs: " << eggs << std::endl;
        
        TrialStats stats = trial(height, eggs);
        stats.printStats();
        
        std::cout << std::endl << std::endl;
    }
}

//Benchmarks all buildings from 0 to MAX_HEIGHT
void benchmark(const size_t MAX_HEIGHT){
    const size_t MAX_EGGS = 2;
    //Test every building
    for (size_t height = 1; height <= MAX_HEIGHT; ++height) {
        testTower(height, std::min(height, MAX_EGGS));
    }
}

int main() {
    constexpr size_t MAX_HEIGHT = 36;
    
    benchmark(MAX_HEIGHT);

    return 0;
}
//Get data file at https://codecatch.net/post.php?postID=91e87d73
//Iteration 1 of Wing Project. Solution breaks down around n=35

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
using namespace std;

int getSum(map<int, int> list);
void readData(map<int, float>* data);
void lowestPrice();
void findSums(int n, vector<map<int, int>>* sumsList, map<int, float>* data);
//void findSum(map<int, int> currList, int x, int n, vector<map<int, int>>* sumsList);
void findSum(map<int, int> currList, int x, int n, vector<map<int, int>>* sumsList, map<int, float>* data);
float getPrice(map<int, int> set, map<int, float>* data);

template <typename S>
ostream& operator<<(ostream& os, const vector<S>& vector)
{
	// Printing all the elements using <<
	for (auto element : vector) {
	os << element << " ";
	}
	return os;
}

bool operator==(map<int, int> m1, map<int, int> m2)
{
	if(m1.size() != m2.size())
	return false;

	bool ret = true;

	for(auto it = m1.begin(); it !=m1.end() && ret; it++)
	{
	if(ret && m1.count(it->first) != m2.count(it->first))
	ret = false;

	if(ret && m1.count(it->first) == 1)
	{
	if(m1.at(it->first) != m2.at(it->first))
	ret = false;
	}
	}

	return ret;
}


int main()
{
	map<int, float> data;
	readData(&data);

	vector<map<int, int>> *sumsList;
	sumsList = new vector<map<int, int>>;
	findSums(40, sumsList, &data);

	for(auto el : *sumsList)
	{
	for(auto it = el.begin(); it != el.end(); it++)
	{
	cout << it->first << "->" << it->second << " ";
	}
	cout << getPrice(el, &data) << endl;
	}

	return 0;
}

/* Returns the price of wings given a set of numbers of wings to buy.
	* Returns -1 if the set contains a number that is not possible to buy.
	*/
float getPrice(map<int, int> set, map<int, float>* data)
{
	float price = 0;
	for(auto it = set.begin(); it != set.end(); it++)
	{
	//If data doesn't contain an element of set, return -1
	if(data->count(it->first) == 0)
	return -1;
	
	price += data->at(it->first) * it->second; //pricePerPacket * qtyOfPackets
	}

	return price;
}

/* Adds the elements of list.
	* Suppose mapping is <num, qty>.
	* Returns sum(num*qty)
	*/
int getSum(map<int, int> list)
{
	int sum = 0;
	for(auto it = list.begin(); it != list.end(); it++)
	sum += it->first * it->second;
	return sum;
}

void findSums(int n, vector<map<int, int>>* sumsList, map<int, float>* data)
{
	map<int, int> currList;

	//Recur when currSum < n
	auto it = data->begin();
	while(it->first <= n && it != data->end())
	{
	findSum(currList, it->first, n, sumsList, data);
	it++;
	}
}

void findSum(map<int, int> currList, int x, int n, vector<map<int, int>>* sumsList, map<int, float>* data)
{
	//Append x to currList
	if(currList.count(x) == 0)
	currList.emplace(x, 1);
	else
	{
	int val = 1+ currList.at(x);
	currList.erase(x);
	currList.emplace(x, val);
	}

	//Determine current sum, check for return cases
	int currSum = getSum(currList);

	if(currSum > n)
	return;
	else if(currSum == n)
	{

	//Check to make sure no duplicates
	for(auto list : *sumsList)
	{
	if(list == currList)
	return;
	}

	sumsList->push_back(currList);
	return;
	}

	//Recur when currSum < n
	auto it = data->begin();
	while(it->first <= n-x && it != data->end())
	{
	findSum(currList, it->first, n, sumsList, data);
	it++;
	}
}

void readData(map<int, float>* data)
{
	ifstream file ("./data", ifstream::in);

	if(file.is_open())
	{
	int i = 0;
	while(!file.eof())
	{
	float wings, price;
	string skipnl;
	file >> wings;
	file >> price;

	data->emplace(wings, price);

	getline(file, skipnl);
	i++;
	}
	}
}
#include<iostream>
#include<fstream>
#include<vector>
#include<stdio.h> 
#include<time.h>
#include<stdlib.h>
using namespace std;

//data storage for parking lot info, admin, managers, users, and tickets
struct Parking_Lot_info{
	int total_Space;
	int regular;
	int motorcycle;
	int disability;
};
struct Admin{
	string name;
	string id;
	string password;
};
struct Manager{
	string name;
	string id;
	string password;
}; 
struct User{
	string id;
	string name;
	string password;
	string makeModel1;
	string makeModel2;
	string year;
	string plate;
};
struct Ticket{
	string ticket_Number;
	string ticket_Amount;
	string ticket_Issued;
	string ticket_Status;
	string reason; 
	string plate;
}; 


//prototypes
vector<Admin>admin_Vector;
vector<Admin>::iterator admin_it;
vector<Manager>manager_Vector;
vector<Manager>::iterator manager_it;
vector<User>user_Vector;
vector<User>::iterator user_it;
vector<Ticket>ticket_Vector;
vector<Ticket>::iterator ticket_it;
void Initial_Admin_Vector(char admin_People_File_Name[]);
void Initial_Manager_Vector(char management_People_File_Name[]);
void Initial_User_Vector(char user_People_File_Name[]);
void Initial_Ticket_Vector();
void Login_System();
void Checking_Id_Password();
void Admin_Menu();
void Management_Menu();
void User_Menu();
void Add_Admin();
void Remove_Admin();
void Display_All_Admin();
void Search_Admin();
void Change_Password_Admin();
void Add_Manager();
void Remove_Manager();
void Display_All_Manager();
void Search_Manager();
void Add_User();
void Display_All_User();
void Remove_User();
void Search_User();
void Change_Password_User();
void Change_Vehicle_Info();
void Display_All_Vehicle();
void Add_Ticket();
void Display_All_Ticket();
void Search_Ticket();
void Remove_Ticket();
void User_Display_Ticket();
void Pay_Ticket();
void Change_Password_Manager();
void Store_Admin_Data(char admin_People_File_Name[]);
void Store_Manager_Data(char manager_People_File_Name[]);
void Store_User_Data(char user_People_File_Name[]);
void Store_Ticket_Data();

void Initial_Admin_Vector(char admin_People_File_Name[]){
	ifstream in;
	Admin a;
	in.open(admin_People_File_Name);
	while(getline(in,a.name,',')){
		getline(in,a.id,',');
		getline(in,a.password);
		admin_Vector.push_back(a);
	}
	in.close();
}

void Initial_Manager_Vector(char management_People_File_Name[]){
	ifstream in;
	Manager m;
	in.open(management_People_File_Name);
	while(getline(in,m.name,',')){
		getline(in,m.id,',');
		getline(in,m.password);
		manager_Vector.push_back(m);
	}
	in.close();
}
void Initial_User_Vector(char user_People_File_Name[]){
	ifstream in;
	User u;
	in.open(user_People_File_Name);
	while(getline(in,u.name,',')){
		getline(in,u.id,',');
		getline(in,u.password,',');
		getline(in,u.makeModel1,',');
		getline(in,u.makeModel2,',');
		getline(in,u.year,',');
		getline(in,u.plate);
		user_Vector.push_back(u);
	}
	in.close();
}
void Initial_Ticket_Vector(){
	ifstream in;
	Ticket t;
	in.open("ticket.csv");
	while(getline(in,t.ticket_Number,',')){
		getline(in,t.ticket_Amount,',');
		getline(in,t.ticket_Issued,',');
		getline(in,t.ticket_Status,',');
		getline(in,t.reason,',');
		getline(in,t.plate);
		ticket_Vector.push_back(t);
	}
	in.close();
}



void Login_System(){
	int first_Option;
	bool flag = true;
	do{
		cout << "Type in 1 to Log in to the system." << endl;
		cout << "Type in 2 to register to the system." << endl;
		cout << "Type in 3 to exit the system." << endl;
		cout << "Option: ";
		cin >> first_Option;
		switch(first_Option){
		case 1:
			Checking_Id_Password();
			flag = false;
			break;
		case 2:
			Add_User();
			break;
		case 3:
			flag = false;
			break;		
		}
	}while(flag);
}
void Checking_Id_Password(){
	string Id1;
	string Password1;
	bool flag = true;
	do{
		cout << "Enter id: ";
		cin >> Id1;
		cout << "Enter password: ";
		cin >> Password1;
		for(admin_it = admin_Vector.begin(); admin_it != admin_Vector.end(); admin_it++){
			if(Id1 == admin_it->id && Password1 == admin_it->password){
				cout << endl;
				Admin_Menu();
				flag = false;
				break;
			}
		}
		for(manager_it = manager_Vector.begin(); manager_it != manager_Vector.end(); manager_it++){
			if(Id1 == manager_it->id && Password1 == manager_it->password){
				cout << endl;
				Management_Menu();
				flag = false;
				break;
			}
		}
		for(user_it = user_Vector.begin(); user_it != user_Vector.end(); user_it++){
			if(Id1 == user_it->id && Password1 == user_it->password){
				cout << endl;
				User_Menu();
				flag = false;
				break;
			}
		}
		if(flag){
			cout << "ID or Password is wrong. Enter your credentials again."<<endl<<endl;
		}
	}while(flag);
}

void Admin_Menu(){
	int Admin_Option;
	bool flag = true;
	do{
		cout << "Select the following option for a particular task." << endl;
		cout << "Select 1 to add new administrative employee." << endl;
		cout << "Select 2 to remove an administrative employee." << endl;
		cout << "Select 3 to view all administrative employee information." << endl;
		cout << "Select 4 to search information of a specific administrative employee." << endl;
		cout << "Select 5 to change password." << endl;
		cout << "Select 6 to add new management employee." << endl;
		cout << "Select 7 to remove a management employee." << endl;
		cout << "Select 8 to view all management employee information." << endl;
		cout << "Select 9 to search information of a specific management employee." << endl;
		cout << "Select 10 to remove an user." << endl;
		cout << "Select 11 to view all user information." << endl;
		cout << "Select 12 to search information of a specific user." << endl;
		cout << "Select 15 to Log out." << endl;
		cout << "Option: ";
		cin >> Admin_Option;
		switch(Admin_Option){   //switch to manage the option selection
			case 1:
				Add_Admin();
				break;
			case 2:
				Remove_Admin();
				break;
			case 3:
				Display_All_Admin();
				break;
			case 4:
				Search_Admin();
				break;
			case 5:
				Change_Password_Admin();
				break;
			case 6:
				Add_Manager();
				break;
			case 7:
				Remove_Manager();
				break;
			case 8:
				Display_All_Manager();
				break;
			case 9:
				Search_Manager();
				break;
			case 10:
				Remove_User();
				break;
			case 11:
				Display_All_User();
				break;
			case 12:
				Search_User();
				break; 
			case 15:
				flag = false;
				cout << endl;
				Login_System();
				break;
		}
	}while(flag);
}
void Management_Menu(){
	int Manager_Option;
	bool flag = true;
	do{
		cout << "Select the following option for a particular task." << endl;
		cout << "Select 1 to remove an user." << endl;
		cout << "Select 2 to view all user information." << endl;
		cout << "Select 3 to search information of a specific user." << endl;
		cout << "Select 4 to issue a ticket." << endl;
		cout << "Select 5 to view all the ticket information." << endl;
		cout << "Select 6 to view a specific ticket information in details." << endl;
		cout << "Select 7 to remove a specific ticket information." << endl;
		cout << "Select 8 to change password." << endl;
		cout << "Select 9 to Log out." << endl;
		cout << "Option: ";
		cin >> Manager_Option;
		switch(Manager_Option){ //ditto
			case 1:
				Remove_User();
				break;
			case 2:
				Display_All_User();
				break;
			case 3:
				Search_User();
				break;
			case 4:
				Add_Ticket();
				break;
			case 5:
				Display_All_Ticket();
				break;
			case 6:
				Search_Ticket();
				break;
			case 7:
				Remove_Ticket();
				break;
			case 8:
				Change_Password_Manager();
				break;
			case 9:
				flag = false;
				cout << endl;
				Login_System();
				break;
		}
	}while(flag);
}
void User_Menu(){
	int User_Option;
	bool flag = true;
	do{
		cout << "Select the following option for a particular task." << endl;
		cout << "Select 1 to change password." << endl;
		cout << "Select 2 to change vehicle information." << endl;
		cout << "Select 3 to view vehicle information." << endl;
		cout << "Select 4 to view all ticket information." << endl;
		cout << "Select 5 to pay a ticket amount." << endl;
		cout << "Select 8 to Log out." << endl;
		cout << "Option: ";
		cin >> User_Option;
		switch(User_Option){
			case 1:
				Change_Password_User();
				break;
			case 2:
				Change_Vehicle_Info();
				break;
			case 3:
				Display_All_Vehicle();
				break;
			case 4:
				User_Display_Ticket();
				break;
			case 5:
				Pay_Ticket();
				break;
			case 8:
				flag = false;
				cout << endl;
				Login_System();
				break;	
		}
	}while(flag);
}
void Add_Admin(){
	string add_name;
	string add_id;
	string add_password;
	Admin a;
	srand((unsigned)time(NULL));
	bool flag = true;
	char temp1[100];
	int temp2;	
	
	cout << "Enter administrative employee name: ";
	cin.ignore();
	getline(cin,add_name);
	cout << "Auto generated id for this administrative employee account is: ";
	do{
		temp2 = rand()%400 + 101;
		sprintf(temp1, "%d", temp2);
		add_id = temp1;
		for(admin_it = admin_Vector.begin(); admin_it != admin_Vector.end(); admin_it++){
			if(add_id == admin_it->id){
				break;
			}
		}
		if(admin_it == admin_Vector.end()){
			flag = false;
		}
	}while(flag);
	cout << add_id << endl;
	cout << "Set a password for this administrative employee account: ";
	getline(cin,add_password);
	cout << "administrative employee entry is complete." << endl << endl;
	
	a.name = add_name;
	a.id = add_id;
	a.password = add_password;
	admin_Vector.push_back(a); 
}
void Remove_Admin(){
	bool flag = true;
	string remove_id;
	cout << "Enter the administrative employee's Id: ";
	cin >> remove_id;
	for(admin_it = admin_Vector.begin(); admin_it != admin_Vector.end(); admin_it++){
		if(admin_it->id == remove_id){
			admin_Vector.erase(admin_it);
			cout << "Administrative employee is removed." <<endl <<endl;
			flag = false;
			break;
		}
	}
	if(flag){
		cout << "Fail to remove the administrative employee's information!" << endl <<endl;
	}
}
void Display_All_Admin(){
	cout << "All Administrative Employee Information" << endl;
	cout << "---------------------------------------" << endl;
	cout << "             Name                ID" << endl;
	cout << "-----------------------------------" << endl;
	for(admin_it = admin_Vector.begin(); admin_it != admin_Vector.end(); admin_it++){
		cout << admin_it->name << "\t" << "\t" << "\t";
		cout << admin_it->id << endl;
	}
	cout <<endl << endl;
}
void Search_Admin(){
	bool flag = true;
	string search_id;
	cout << "Enter the administrative employee's id: ";
	cin >> search_id;
	cout << "             Name                ID" << endl;
	cout << "-----------------------------------" << endl;		
	for(admin_it = admin_Vector.begin(); admin_it != admin_Vector.end(); admin_it++){
		if(admin_it->id == search_id){
			cout << admin_it->name << "\t" << "\t" << "\t";
			cout << admin_it->id << endl << endl;
			flag = false;
			break;
		}
	}
	if(flag){
		cout << "Can't find this administrative employee's information!" << endl << endl;
	}
	cout <<endl << endl;
}
void Change_Password_Admin(){
	string new_password;
	cout << "Enter a new password: ";
	cin >> new_password;
	admin_it->password = new_password;
	cout << "You have changed your password successfully!" <<endl;
	cout << endl;
}
void Add_Manager(){
	string add_name;
	string add_id;
	string add_password;
	Manager m;
	srand((unsigned)time(NULL));
	bool flag = true;
	char temp1[100];
	int temp2;	
	
	cout << "Enter management employee name: ";
	cin.ignore();
	getline(cin,add_name);
	cout << "Auto generated id for this management employee account is: ";
	do{
		temp2 = rand()%500 + 501;
		sprintf(temp1, "%d", temp2);
		//itoa(temp2,temp1,10);
		add_id = temp1;
		for(manager_it = manager_Vector.begin(); manager_it != manager_Vector.end(); manager_it++){
			if(add_id == manager_it->id){
				break;
			}
		}
		if(manager_it == manager_Vector.end()){
			flag = false;
		}
	}while(flag);
	cout << add_id << endl;
	cout << "Set a password for this management employee account: ";
	getline(cin,add_password);
	cout << "Management employee entry is complete." << endl << endl;
	
	m.name = add_name;
	m.id = add_id;
	m.password = add_password;
	manager_Vector.push_back(m); 
}
void Remove_Manager(){
	bool flag = true;
	string remove_id;
	cout << "Enter the management employee's id: ";
	cin >> remove_id;
	for(manager_it = manager_Vector.begin(); manager_it != manager_Vector.end(); manager_it++){
		if(manager_it->id == remove_id){
			manager_Vector.erase(manager_it);
			cout << "Management employee is removed." <<endl <<endl;
			flag = false;
			break;
		}
	}
	if(flag){
		cout << "Fail to remove the management employee's information!" << endl <<endl;
	}
}
void Display_All_Manager(){
	cout << "------All Employee Information-----" << endl;
	cout << "-----------------------------------" << endl;
	cout << "             Name                ID" << endl;
	cout << "-----------------------------------" << endl;
	for(manager_it = manager_Vector.begin(); manager_it != manager_Vector.end(); manager_it++){
		cout << manager_it->name << "\t" << "\t" << "\t";
		cout << manager_it->id << endl;
	}
	cout <<endl << endl;
}
void Search_Manager(){
	bool flag = true;
	string search_id;
	cout << "Enter the management employee's id: ";
	cin >> search_id;
	cout << "             Name                ID" << endl;
	cout << "-----------------------------------" << endl;		
	for(manager_it = manager_Vector.begin(); manager_it != manager_Vector.end(); manager_it++){
		if(manager_it->id == search_id){
			cout << manager_it->name << "\t" << "\t" << "\t";
			cout << manager_it->id << endl << endl;
			flag = false;
			break;
		}
	}
	if(flag){
		cout << "Can't find this management employee's information!" << endl << endl;
	}
	cout << endl << endl;
}
void Add_User(){
	string add_name;
	string add_id;
	string add_password;
	string add_makeModel1;
	string add_makeModel2;
	string add_year;
	string add_plate;
	User u;
	bool flag = true;
	
	cout << "Enter name: ";
	cin.ignore();
	getline(cin,add_name);
	do{
		cout << "Enter id: ";	
		//cin.ignore();
		getline(cin,add_id);
		for(user_it = user_Vector.begin(); user_it != user_Vector.end(); user_it++){
			if(add_id == user_it->id){
				cout << "This id is already in use! Please Enter again!" << endl;
				break;
			}
		}
		if(user_it == user_Vector.end()){
			flag = false;
		}
	}while(flag); 
	cout << "Enter password: ";
	//cin.ignore();
	getline(cin,add_password);
	cout << "Now enter your vehicle information..." << endl;
	cout << "Enter vehicle make: ";
	//cin.ignore();
	getline(cin,add_makeModel1);
	cout << "Enter vehicle model: ";
	//cin.ignore();
	getline(cin,add_makeModel2);
	cout << "Enter vehicle year: ";
	//cin.ignore();
	getline(cin,add_year);
	cout << "Enter vehicle plate number: ";
	//cin.ignore();
	getline(cin,add_plate);
	cout << "Registration is complete" << endl << endl;
	
	u.name = add_name;
	u.id = add_id;
	u.password = add_password;
	u.makeModel1 = add_makeModel1;
	u.makeModel2 = add_makeModel2;
	u.year = add_year;
	u.plate = add_plate;
	user_Vector.push_back(u); 	
}
void Remove_User(){
	bool flag = true;
	string remove_id;
	cout << "Enter the user's id: ";
	cin >> remove_id;
	for(user_it = user_Vector.begin(); user_it != user_Vector.end(); user_it++){
		if(user_it->id == remove_id){
			user_Vector.erase(user_it);
			cout << "User is removed." <<endl <<endl;
			flag = false;
			break;
		}
	}
	if(flag){
		cout << "Fail to remove the user's information!" << endl <<endl;
	}
}
void Display_All_User(){
	cout << "-----------------------------------------------------All User Information-------------------------------------------------------" << endl;
	cout << "--------------------------------------------------------------------------------------------------------------------------------" << endl;
	cout << "	Name                          ID               Make               Model                 Year           Plate Number" << endl;
	cout << "--------------------------------------------------------------------------------------------------------------------------------" << endl;
	for(user_it = user_Vector.begin(); user_it != user_Vector.end(); user_it++){
		cout << user_it->name << "\t" << "\t" << "\t";
		cout << user_it->id << "\t" << "\t";
		cout << user_it->makeModel1 << "\t"<< "\t";
		cout << user_it->makeModel2 << "\t" << "\t"<< "\t";
		cout << user_it->year << "\t" << "\t";
		cout << user_it->plate << endl;
	}
	cout <<endl << endl;
}
void Search_User(){
	bool flag = true;
	string search_id;
	cout << "Enter the user's id: ";
	cin >> search_id;
	cout << "	Name                          ID               Make               Model                 Year           Plate Number" << endl;
	cout << "--------------------------------------------------------------------------------------------------------------------------------" << endl;		
	for(user_it = user_Vector.begin(); user_it != user_Vector.end(); user_it++){
		if(user_it->id == search_id){
			cout << user_it->name << "\t" << "\t" << "\t";
			cout << user_it->id << "\t" << "\t";
			cout << user_it->makeModel1 << "\t"<< "\t";
			cout << user_it->makeModel2 << "\t" << "\t"<< "\t";
			cout << user_it->year << "\t" << "\t";
			cout << user_it->plate << endl;
			flag = false;
			break;
		}
	}
	if(flag){
		cout << "Can't find this user's information!" << endl << endl;
	}
	cout << endl << endl;
}
void Change_Password_User(){
	string new_password;
	cout << "Enter a new password: ";
	cin >> new_password;
	user_it->password = new_password;
	cout << "You have changed your password successfully!" <<endl;
	cout << endl;
}
void Change_Vehicle_Info(){
	string new_MakeModel1;
	string new_MakeModel2;
	string new_Year;
	string new_Plate;
	cout << "Enter the new vehicle make: ";
	cin.ignore();
	getline(cin,new_MakeModel1);
	cout << "Enter the new vehicle model: ";
	//cin.ignore();
	getline(cin,new_MakeModel2);
	cout << "Enter the new vehicle year: ";
	//cin.ignore();
	getline(cin,new_Year);
	cout << "Enter the new vehicle plate number: ";
	//cin.ignore();
	getline(cin,new_Plate);
	user_it->makeModel1 = new_MakeModel1;
	user_it->makeModel2 = new_MakeModel2;
	user_it->year = new_Year;
	user_it->plate = new_Plate;
	cout << "You have changed your vehicle information successfully!" <<endl << endl;
}
void Display_All_Vehicle(){
	cout << endl;
	cout << "Vehicle make: " << user_it->makeModel1 << endl;
	cout << "Vehicle model: " << user_it->makeModel2 << endl;
	cout << "Vehicle year: " << user_it->year << endl;
	cout << "Vehicle plate number: " << user_it->plate << endl << endl;
}
void Add_Ticket(){
	string add_ticket_number;
	string add_ticket_amount;
	string add_Reason;
	string add_plate;
	Ticket t;
	srand((unsigned)time(NULL));
	bool flag = true;
	char temp1[100];
	int temp2;	
	string ticketIssued;
	string ticketStat;
	
	cout << "Auto generated ticket number is: ";
	do{
		temp2 = rand()%49000 + 1001;
		sprintf(temp1, "%d", temp2);
		//itoa(temp2,temp1,10);
		add_ticket_number = temp1;
		for(ticket_it = ticket_Vector.begin(); ticket_it != ticket_Vector.end(); ticket_it++){
			if(add_ticket_number == ticket_it->ticket_Number){
				break;
			}
		}
		if(ticket_it == ticket_Vector.end()){
			flag = false;
		}
	}while(flag);
	cout << add_ticket_number << endl;
	cout << "Enter ticket amount: ";
	cin.ignore();
	getline(cin,add_ticket_amount);
	cout << "Reason of ticket: ";
	getline(cin,add_Reason);
	cout << "Enter vehicle plate number: ";
	getline(cin,add_plate);
	cout << "Ticket has been recorded successfully."<<endl<<endl;
	ticketIssued = manager_it->id;
	ticketStat = "Unpaid";
	
	t.ticket_Number = add_ticket_number;
	t.ticket_Amount = add_ticket_amount;
	t.ticket_Issued = ticketIssued;
	t.ticket_Status = ticketStat;
	t.reason = add_Reason;
	t.plate = add_plate;
	ticket_Vector.push_back(t);
}
void Display_All_Ticket(){
	cout << "Ticket number     Ticket amount     Issued by     Ticket Status     Reason" << endl;
	cout << "--------------------------------------------------------------------------" << endl;
	for(ticket_it = ticket_Vector.begin(); ticket_it != ticket_Vector.end(); ticket_it++){
		cout << "\t" << ticket_it->ticket_Number << "\t" << "\t";
		cout << "$" << ticket_it->ticket_Amount << "\t" << "\t";
		cout << ticket_it->ticket_Issued << "\t"<< "\t";
		cout << ticket_it->ticket_Status << "\t"<< "\t";
		cout << ticket_it->reason << endl;
	}
	cout <<endl << endl;
}
void Search_Ticket(){
	bool flag = true;
	string search_number;
	cout << "Enter the ticket number: ";
	cin.ignore();
	getline(cin,search_number);
	cout << "Ticket number     Ticket amount     Issued by     Ticket Status     Reason" << endl;
	cout << "--------------------------------------------------------------------------" << endl;
	for(ticket_it = ticket_Vector.begin(); ticket_it != ticket_Vector.end(); ticket_it++){
		if(ticket_it->ticket_Number == search_number){
			cout << "\t" << ticket_it->ticket_Number << "\t" << "\t";
			cout << "$" << ticket_it->ticket_Amount << "\t" << "\t";
			cout << ticket_it->ticket_Issued << "\t"<< "\t";
			cout << ticket_it->ticket_Status << "\t"<< "\t";
			cout << ticket_it->reason << endl;
		}
	}
	cout <<endl << endl;
}
void Remove_Ticket(){
	bool flag = true;
	string remove_number;
	cout << "Enter the ticket number: ";
	cin.ignore();
	getline(cin,remove_number);
	for(ticket_it = ticket_Vector.begin(); ticket_it != ticket_Vector.end(); ticket_it++){
		if(ticket_it->ticket_Number == remove_number){
			ticket_Vector.erase(ticket_it);
			cout << endl;
			cout << "Ticket is removed." <<endl <<endl;
			flag = false;
			break;
		}
	}
	if(flag){
		cout << "Fail to remove the ticket!" << endl <<endl;
	}
}
void Change_Password_Manager(){
	string new_password;
	cout << "Enter a new password: ";
	cin >> new_password;
	manager_it->password = new_password;
	cout << "You have changed your password successfully!" <<endl;
	cout << endl;
}
void User_Display_Ticket(){
	cout << "Ticket number     Ticket amount     Issued by     Ticket Status     Reason" << endl;
	cout << "--------------------------------------------------------------------------" << endl;
	for(ticket_it = ticket_Vector.begin(); ticket_it != ticket_Vector.end(); ticket_it++){
		if(user_it->plate == ticket_it->plate){
			cout << "\t" << ticket_it->ticket_Number << "\t" << "\t";
			cout << "$" << ticket_it->ticket_Amount << "\t" << "\t";
			cout << ticket_it->ticket_Issued << "\t"<< "\t";
			cout << ticket_it->ticket_Status << "\t"<< "\t";
			cout << ticket_it->reason << endl;
			break;
		}
	}
	cout <<endl << endl;
}
void Pay_Ticket(){
	string YorN;
	cout << "Do you want to pay $" << ticket_it->ticket_Amount << " right now? (Type in Yes or No):";
	cin >> YorN;
	if(YorN == "Yes" || YorN == "YES" || YorN == "yes"){
		for(ticket_it = ticket_Vector.begin(); ticket_it != ticket_Vector.end(); ticket_it++){
			if(user_it->plate == ticket_it->plate){
				ticket_it->ticket_Amount = "0";
				ticket_it->ticket_Status = "Paid";
				cout << "The ticket amount is paid off." << endl << endl;
				break;
			}
		}
	}
	else if(YorN == "No" || YorN == "NO" || YorN == "no"){
		cout << endl << endl;
	}
		
}
void Store_Admin_Data(char admin_People_File_Name[]){  //Store all the changes to the admin's data in to the file.
	ofstream out;
	out.open(admin_People_File_Name);
	for(admin_it = admin_Vector.begin(); admin_it != admin_Vector.end(); admin_it++){
		out << admin_it->name << ",";
		out << admin_it->id << ",";
		out << admin_it->password << endl;
	}
	out.close();
}
void Store_Manager_Data(char management_People_File_Name[]){  //Store all the changes to the manager's data in to the file.
	ofstream out;
	out.open(management_People_File_Name);
	for(manager_it = manager_Vector.begin(); manager_it != manager_Vector.end(); manager_it++){
		out << manager_it->name << ",";
		out << manager_it->id << ",";
		out << manager_it->password << endl;
	}
	out.close();
}
void Store_User_Data(char user_People_File_Name[]){  //Store all the changes to the user's data in to the file.
	ofstream out;
	out.open(user_People_File_Name);
	for(user_it = user_Vector.begin(); user_it != user_Vector.end(); user_it++){
		out << user_it->name << ",";
		out << user_it->id << ",";
		out << user_it->password << ",";
		out << user_it->makeModel1 << ",";
		out << user_it->makeModel2 << ",";
		out << user_it->year << ",";
		out << user_it->plate << endl;
	}
	out.close();
}
void Store_Ticket_Data(){  //Store all the changes to the ticket's data in to the file.
	ofstream out;
	out.open("ticket.csv");
	for(ticket_it = ticket_Vector.begin(); ticket_it != ticket_Vector.end(); ticket_it++){
		out << ticket_it->ticket_Number << ",";
		out << ticket_it->ticket_Amount << ",";
		out << ticket_it->ticket_Issued << ",";
		out << ticket_it->ticket_Status << ",";
		out << ticket_it->reason << ",";
		out << ticket_it->plate << endl;
	}
	out.close();
}

int main(){
    
    //char array to store the user input for the file search
	char input_File_Name[100]; 
	char admin_People_File_Name[100];
	char management_People_File_Name[100];
	char user_People_File_Name[100];
	
	ifstream in; 
	Parking_Lot_info *pli; //Structure pointer
	int pln; //Parking lot number
	int max_Space = 8; // Max number of parking space in a row
	int t = 0; //Determine when it needs to switch to the next row
	
	//relevant strings for admin, management, and users
	string admin_Name, admin_Id, admin_Password;
	string management_Name, management_Id, management_Password;
	string user_Name, user_Id, user_Password;
	
	string user_Make_Model1, user_Make_Model2, user_Year, user_Plate_Number;

    //get filename
	cout << "Enter file name: "; 
	cin.getline(input_File_Name,100);
	in.open(input_File_Name);
	if(!in){
		cout << "Can't open the file!" << endl; //error check
		return 0;
	}

	in >> pln;
	pli = new Parking_Lot_info[pln];
	
	//read data in for parking lot
	for(int i=0; i<pln; i++){
		in >> pli[i].regular;
		in >> pli[i].motorcycle;
		in >> pli[i].disability;
		pli[i].total_Space = pli[i].regular + pli[i].motorcycle + pli[i].disability;
		//display the initial read in data for parking lot
		cout << "Parking lot number: " << i+1 << endl;
		cout << "Number of parking space: " << pli[i].total_Space << endl;
		cout << "Number of regular parking space: " << pli[i].regular << endl;
		cout << "Number of motorcycle parking space: " << pli[i].motorcycle << endl;
		cout << "Number of disability parking space: " << pli[i].disability << endl;			
		cout << "Parking space layout is shown below." << endl;
		cout << "---------------------------------" << endl;
		cout << "|";
		t = 0; //Reset t to 0;
		for(int j=0; j <pli[i].motorcycle; j++){
			t++;
			cout << " M " << "|";
			if(t%max_Space == 0){
				cout << endl;
				cout << "---------------------------------" << endl;
			}
		}
		for(int k=0; k <pli[i].disability; k++){
			t++;	
			cout << " D " << "|";		
			if(t%max_Space == 0){
				cout << endl;
				cout << "---------------------------------" << endl;
			}
		}	
		for(int l=0; l <pli[i].regular; l++){
			t++;	
			cout << " R " << "|";		
			if(t%max_Space == 0){
				cout << endl;
				cout << "---------------------------------" << endl;
			}
		}
		cout << endl;
		cout << "---------------------------------" << endl;
		cout << endl;
	} 		
    //read in admin, management, and user data
	in >> admin_People_File_Name;
	in >> management_People_File_Name;
	in >> user_People_File_Name;
	in.close();
	
	//display initial administrative employee info
	in.open(admin_People_File_Name);
	cout << "All Administrative Employee Information" << endl;
	cout << "---------------------------------------" << endl;
	cout << "             Name                ID" << endl;
	cout << "-----------------------------------" << endl;
	while(getline(in,admin_Name,',')){
		cout << admin_Name << "\t" << "\t" << "\t";
		getline(in,admin_Id,',');
		cout << admin_Id << endl;
		getline(in,admin_Password);
	}
	cout << endl;
	in.close();
	//display all employee information
	in.open(management_People_File_Name);
	cout << "------All Employee Information-----" << endl;
	cout << "-----------------------------------" << endl;
	cout << "             Name                ID" << endl;
	cout << "-----------------------------------" << endl;
	while(getline(in,management_Name,',')){
		cout << management_Name << "\t" << "\t" << "\t";
		getline(in,management_Id,',');
		cout << management_Id << endl;
		getline(in,management_Password);
	}
	cout << endl;
	in.close();
	
	//display all user information
	in.open(user_People_File_Name);
	cout << "-----------------------------------------------------All User Information-------------------------------------------------------" << endl;
	cout << "--------------------------------------------------------------------------------------------------------------------------------" << endl;
	cout << "	Name                          ID               Make               Model                 Year           Plate Number" << endl;
	cout << "--------------------------------------------------------------------------------------------------------------------------------" << endl;
	while(getline(in,user_Name,',')){
		cout << user_Name << "\t" << "\t" << "\t";
		getline(in,user_Id,',');
		cout << user_Id << "\t" << "\t";
		getline(in,user_Password,',');
		getline(in,user_Make_Model1,',');
		cout << user_Make_Model1 << "\t"<< "\t";
		getline(in,user_Make_Model2,',');
		cout << user_Make_Model2 << "\t" << "\t"<< "\t";
		getline(in,user_Year,',');
		cout << user_Year << "\t" << "\t";
		getline(in,user_Plate_Number);
		cout << user_Plate_Number << endl;
	}
	cout << endl;
	in.close();
	
	
	Initial_Admin_Vector(admin_People_File_Name);
	Initial_Manager_Vector(management_People_File_Name);
	Initial_User_Vector(user_People_File_Name);
	Initial_Ticket_Vector();
	Login_System();
	
	//store NEW admin, manager, user, and ticket data
	Store_Admin_Data(admin_People_File_Name);
	Store_Manager_Data(management_People_File_Name);
	Store_User_Data(user_People_File_Name);
	Store_Ticket_Data();
	
	return 0;
}
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <chrono>
using namespace std;

#include <stdio.h>
#include <Windows.h>

int nScreenWidth = 120;			// Console Screen Size X (columns)
int nScreenHeight = 40;			// Console Screen Size Y (rows)
int nMapWidth = 16;				// World Dimensions
int nMapHeight = 16;

float fPlayerX = 14.7f;			// Player Start Position
float fPlayerY = 5.09f;
float fPlayerA = 0.0f;			// Player Start Rotation
float fFOV = 3.14159f / 4.0f;	// Field of View
float fDepth = 16.0f;			// Maximum rendering distance
float fSpeed = 5.0f;			// Walking Speed

int main()
{
	// Create Screen Buffer
	wchar_t *screen = new wchar_t[nScreenWidth*nScreenHeight];
	HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
	SetConsoleActiveScreenBuffer(hConsole);
	DWORD dwBytesWritten = 0;

	// Create Map of world space # = wall block, . = space
	wstring map;
	map += L"#########.......";
	map += L"#...............";
	map += L"#.......########";
	map += L"#..............#";
	map += L"#......##......#";
	map += L"#......##......#";
	map += L"#..............#";
	map += L"###............#";
	map += L"##.............#";
	map += L"#......####..###";
	map += L"#......#.......#";
	map += L"#......#.......#";
	map += L"#..............#";
	map += L"#......#########";
	map += L"#..............#";
	map += L"################";

	auto tp1 = chrono::system_clock::now();
	auto tp2 = chrono::system_clock::now();
	
	while (1)
	{
		// We'll need time differential per frame to calculate modification
		// to movement speeds, to ensure consistant movement, as ray-tracing
		// is non-deterministic
		tp2 = chrono::system_clock::now();
		chrono::duration<float> elapsedTime = tp2 - tp1;
		tp1 = tp2;
		float fElapsedTime = elapsedTime.count();


		// Handle CCW Rotation
		if (GetAsyncKeyState((unsigned short)'A') & 0x8000)
			fPlayerA -= (fSpeed * 0.75f) * fElapsedTime;

		// Handle CW Rotation
		if (GetAsyncKeyState((unsigned short)'D') & 0x8000)
			fPlayerA += (fSpeed * 0.75f) * fElapsedTime;
		
		// Handle Forwards movement & collision
		if (GetAsyncKeyState((unsigned short)'W') & 0x8000)
		{
			fPlayerX += sinf(fPlayerA) * fSpeed * fElapsedTime;;
			fPlayerY += cosf(fPlayerA) * fSpeed * fElapsedTime;;
			if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
			{
				fPlayerX -= sinf(fPlayerA) * fSpeed * fElapsedTime;;
				fPlayerY -= cosf(fPlayerA) * fSpeed * fElapsedTime;;
			}			
		}

		// Handle backwards movement & collision
		if (GetAsyncKeyState((unsigned short)'S') & 0x8000)
		{
			fPlayerX -= sinf(fPlayerA) * fSpeed * fElapsedTime;;
			fPlayerY -= cosf(fPlayerA) * fSpeed * fElapsedTime;;
			if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
			{
				fPlayerX += sinf(fPlayerA) * fSpeed * fElapsedTime;;
				fPlayerY += cosf(fPlayerA) * fSpeed * fElapsedTime;;
			}
		}

		for (int x = 0; x < nScreenWidth; x++)
		{
			// For each column, calculate the projected ray angle into world space
			float fRayAngle = (fPlayerA - fFOV/2.0f) + ((float)x / (float)nScreenWidth) * fFOV;

			// Find distance to wall
			float fStepSize = 0.1f;		  // Increment size for ray casting, decrease to increase										
			float fDistanceToWall = 0.0f; //                                      resolution

			bool bHitWall = false;		// Set when ray hits wall block
			bool bBoundary = false;		// Set when ray hits boundary between two wall blocks

			float fEyeX = sinf(fRayAngle); // Unit vector for ray in player space
			float fEyeY = cosf(fRayAngle);

			// Incrementally cast ray from player, along ray angle, testing for 
			// intersection with a block
			while (!bHitWall && fDistanceToWall < fDepth)
			{
				fDistanceToWall += fStepSize;
				int nTestX = (int)(fPlayerX + fEyeX * fDistanceToWall);
				int nTestY = (int)(fPlayerY + fEyeY * fDistanceToWall);
				
				// Test if ray is out of bounds
				if (nTestX < 0 || nTestX >= nMapWidth || nTestY < 0 || nTestY >= nMapHeight)
				{
					bHitWall = true;			// Just set distance to maximum depth
					fDistanceToWall = fDepth;
				}
				else
				{
					// Ray is inbounds so test to see if the ray cell is a wall block
					if (map.c_str()[nTestX * nMapWidth + nTestY] == '#')
					{
						// Ray has hit wall
						bHitWall = true;

						// To highlight tile boundaries, cast a ray from each corner
						// of the tile, to the player. The more coincident this ray
						// is to the rendering ray, the closer we are to a tile 
						// boundary, which we'll shade to add detail to the walls
						vector<pair<float, float>> p;

						// Test each corner of hit tile, storing the distance from
						// the player, and the calculated dot product of the two rays
						for (int tx = 0; tx < 2; tx++)
							for (int ty = 0; ty < 2; ty++)
							{
								// Angle of corner to eye
								float vy = (float)nTestY + ty - fPlayerY;
								float vx = (float)nTestX + tx - fPlayerX;
								float d = sqrt(vx*vx + vy*vy); 
								float dot = (fEyeX * vx / d) + (fEyeY * vy / d);
								p.push_back(make_pair(d, dot));
							}

						// Sort Pairs from closest to farthest
						sort(p.begin(), p.end(), [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; });
						
						// First two/three are closest (we will never see all four)
						float fBound = 0.01;
						if (acos(p.at(0).second) < fBound) bBoundary = true;
						if (acos(p.at(1).second) < fBound) bBoundary = true;
						if (acos(p.at(2).second) < fBound) bBoundary = true;
					}
				}
			}
		
			// Calculate distance to ceiling and floor
			int nCeiling = (float)(nScreenHeight/2.0) - nScreenHeight / ((float)fDistanceToWall);
			int nFloor = nScreenHeight - nCeiling;

			// Shader walls based on distance
			short nShade = ' ';
			if (fDistanceToWall <= fDepth / 4.0f)			nShade = 0x2588;	// Very close	
			else if (fDistanceToWall < fDepth / 3.0f)		nShade = 0x2593;
			else if (fDistanceToWall < fDepth / 2.0f)		nShade = 0x2592;
			else if (fDistanceToWall < fDepth)				nShade = 0x2591;
			else											nShade = ' ';		// Too far away

			if (bBoundary)		nShade = ' '; // Black it out
			
			for (int y = 0; y < nScreenHeight; y++)
			{
				// Each Row
				if(y <= nCeiling)
					screen[y*nScreenWidth + x] = ' ';
				else if(y > nCeiling && y <= nFloor)
					screen[y*nScreenWidth + x] = nShade;
				else // Floor
				{				
					// Shade floor based on distance
					float b = 1.0f - (((float)y -nScreenHeight/2.0f) / ((float)nScreenHeight / 2.0f));
					if (b < 0.25)		nShade = '#';
					else if (b < 0.5)	nShade = 'x';
					else if (b < 0.75)	nShade = '.';
					else if (b < 0.9)	nShade = '-';
					else				nShade = ' ';
					screen[y*nScreenWidth + x] = nShade;
				}
			}
		}

		// Display Stats
		swprintf_s(screen, 40, L"X=%3.2f, Y=%3.2f, A=%3.2f FPS=%3.2f ", fPlayerX, fPlayerY, fPlayerA, 1.0f/fElapsedTime);

		// Display Map
		for (int nx = 0; nx < nMapWidth; nx++)
			for (int ny = 0; ny < nMapWidth; ny++)
			{
				screen[(ny+1)*nScreenWidth + nx] = map[ny * nMapWidth + nx];
			}
		screen[((int)fPlayerX+1) * nScreenWidth + (int)fPlayerY] = 'P';

		// Display Frame
		screen[nScreenWidth * nScreenHeight - 1] = '\0';
		WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
	}

	return 0;
}