Created
August 6, 2013 06:12
-
-
Save Kaminate/6162442 to your computer and use it in GitHub Desktop.
Describes a person and (alcoholic) drink class.
When a person drinks a drink, it takes the timestamp into account when calculating the person's BAC (blood alcohol concentration). I made this for 2013 Angelhack in Seattle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2013 Nathan Park | |
// Angelhack in Seattle | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
typedef float Date; | |
const float grams_per_lb = 453.592f; | |
const float lbs_per_gram = 1.0f / grams_per_lb; | |
const float oz_per_cg = 0.000352739619f; | |
const float cg_per_oz = 1.0f / oz_per_cg; | |
struct Drink // stored in a database | |
{ | |
Drink( | |
const std::string & name, | |
float volumeInOunces, | |
float calories, | |
float percentAlchohol) | |
: mName(name) | |
, mVolumeInOunces(volumeInOunces) | |
, mCalories(calories) | |
, mPercentAlchohol(percentAlchohol) | |
{} | |
std::string mName; | |
float mVolumeInOunces; | |
float mCalories; | |
float mPercentAlchohol; // [0,100] <-- scale is important | |
}; | |
// made some adjustments, based off | |
// http://dogsbody.psych.mun.ca/Tools/BAL/tutorial.html and wikipedia | |
// to account for the changing time | |
// mostly the same though | |
// -Nate | |
class Person | |
{ | |
public: | |
Person(bool isMale, float weightLbs) | |
: mCaloriesDrank(0) | |
, mOuncesOfAlchoholInSystem(0) | |
, mHasStartedDrinking(false) | |
{ | |
mMetabolismLbs = weightLbs; | |
mMetabolismLbs *= isMale ? sMaleGenderConstant : sFemaleGenderConstant; | |
} | |
void Consume(const Drink & drink, Date currTime) | |
{ | |
mConsumed.push_back(drink); | |
mCaloriesDrank += drink.mCalories; | |
UpdateBAC(currTime); | |
// divide the percentage[0,100] by 100 to go to [0,1] | |
float drinkAlOz = drink.mVolumeInOunces * drink.mPercentAlchohol / 100.0f; | |
mOuncesOfAlchoholInSystem += drinkAlOz; | |
mHasStartedDrinking = true; | |
mLastUpdateTime = currTime; | |
// cg oz cg lbs | |
// / / * / * / | |
// g lbs oz g | |
//mBAC += ( drinkAlOz / mMetabolismLbs ) * ( 1 / oz_per_cg) * (1 / grams_per_lb); | |
} | |
/* | |
@param alchohol | |
measured in oz | |
@return float | |
bac, measured in cg alchohol/g metabolism | |
*/ | |
float AlchoholToBAC(float alchohol) | |
{ | |
return alchohol * cg_per_oz * lbs_per_gram / mMetabolismLbs; | |
} | |
/* | |
@param bac | |
measured in cg alchohol/g metabolism | |
@return float | |
alchohol, measured in oz | |
*/ | |
float BACToAlchohol(float bac) | |
{ | |
return bac * mMetabolismLbs * grams_per_lb * oz_per_cg; | |
} | |
void UpdateBAC(Date currTime) | |
{ | |
if (!mHasStartedDrinking) return; | |
Date currentTime = currTime; | |
float hourDifference = currentTime - mLastUpdateTime; | |
mLastUpdateTime = currentTime; | |
// account for the time difference | |
float alchoholElimination = hourDifference * sNaturalBACReductionPerHr; | |
float bac = AlchoholToBAC(mOuncesOfAlchoholInSystem); | |
bac -= alchoholElimination; | |
if (bac < 0) | |
{ | |
mOuncesOfAlchoholInSystem = 0; | |
return; | |
} | |
// recalculate the alchohol in system | |
mOuncesOfAlchoholInSystem = BACToAlchohol(bac); | |
} | |
float GetBAC(Date currTime) | |
{ | |
UpdateBAC(currTime); | |
return AlchoholToBAC(mOuncesOfAlchoholInSystem); | |
} | |
float GetCaloriesDrunk()const{return mCaloriesDrank;} | |
private: | |
// ( total blood in the body measured in lbs) * genderConstant | |
float mMetabolismLbs; | |
float mCaloriesDrank; | |
float mOuncesOfAlchoholInSystem; | |
// http://en.wikipedia.org/wiki/Blood_alcohol_content | |
//float mBAC; // measured in mass 1/100 g/g = 1 cg alchohol/g metabolism | |
Date mLastUpdateTime; | |
bool mHasStartedDrinking; | |
std::vector<Drink> mConsumed; // for reference | |
static const float sNaturalBACReductionPerHr; | |
static const float sConversionRate; | |
static const float sMaleGenderConstant; | |
static const float sFemaleGenderConstant; | |
}; | |
// how much BAC the body removes per/hr | |
const float Person::sNaturalBACReductionPerHr = 0.015f; | |
const float Person::sConversionRate = 5.14f; | |
const float Person::sMaleGenderConstant = 0.73f; | |
const float Person::sFemaleGenderConstant = 0.66f; | |
int main() | |
{ | |
std::cout << std::endl; | |
// name vol cal al% | |
Drink milk ("milk" , 8, 136, 0); | |
Drink parrotBay ("parrot bay" , 1.5, 87, 20); | |
Drink budlightplat ("budlightplat", 12, 137, 6); | |
Drink captMorganBlk("captmorgblk" , 1.5, 117, 47.3f); | |
float weightInLbs = 190.0f; | |
bool isMale = true; | |
Person person(isMale, weightInLbs); | |
float currTimeInHrs = 0.0f; | |
person.Consume(parrotBay , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(parrotBay , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(parrotBay , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(parrotBay , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(parrotBay , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(budlightplat , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(budlightplat , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(budlightplat , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(budlightplat , currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(captMorganBlk, currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(captMorganBlk, currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(captMorganBlk, currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
person.Consume(captMorganBlk, currTimeInHrs); currTimeInHrs += 5.0f / 14.0f; | |
//std::cout << std::endl << person.GetCaloriesDrunk(); | |
std::cout << std::endl << person.GetBAC(currTimeInHrs); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment