Skip to content

Instantly share code, notes, and snippets.

@addamh
Created January 12, 2011 19:30
Show Gist options
  • Save addamh/776716 to your computer and use it in GitHub Desktop.
Save addamh/776716 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cstdlib>
#include <string>
#include <ncurses.h>
#define WIDTH 30
#define HEIGHT 10
int startx = 0;
int starty = 0;
int insertedChange = 0;
int changeArray[] = {0, 0, 0, 0};
char *drinkChoices[] = {
"Coke",
"DrPepper",
"Sprite",
"MrPibb",
"Pepsi",
"Exit",
"Maintenence Mode"
};
char *serviceChoices[] = {
"Check drink inventory",
"Check cash bin",
"Quit Maintenance Menu"
};
char *moneyChoices[] = {
"Dollar Bills",
"Quarters",
"Dimes",
"Nickles",
"Finish"
};
int n_dChoices = sizeof(drinkChoices) / sizeof(char *);
int n_sChoices = sizeof(serviceChoices) / sizeof(char *);
int n_mChoices = sizeof(moneyChoices) / sizeof(char *);
using namespace std;
//////
// Vending Class
/////
class Vending
{
public:
static int cash;
static int change[];
//////
// Vending::Drink Class
/////
class Drink
{
public:
double drinkPrice;
char drinkName[10];
int drinkQuantity;
void setInfo(char *i_drinkName, double i_drinkPrice, int i_drinkQuantity)
{
strncpy(drinkName, i_drinkName, 10);
drinkPrice = i_drinkPrice;
drinkQuantity = i_drinkQuantity;
}
void Print() {
cout << "Name: " << drinkName << " Cost: " <<
drinkPrice << " Quantity Remaining: " << drinkQuantity << "\n";
}
};
void print_menu(WINDOW *menu_win, int highlight)
{
int x, y, i;
x = 2;
y = 2;
box(menu_win, 0, 0);
for(i = 0; i < n_dChoices; ++i)
{ if(highlight == i + 1) /* High light the present choice */
{ wattron(menu_win, A_REVERSE);
mvwprintw(menu_win, y, x, "%s", drinkChoices[i]);
wattroff(menu_win, A_REVERSE);
}
else
mvwprintw(menu_win, y, x, "%s", drinkChoices[i]);
++y;
}
wrefresh(menu_win);
};
void print_maintenance_menu(WINDOW *menu_win, int highlight)
{
int x, y, i;
x = 2;
y = 2;
box(menu_win, 0, 0);
for(i = 0; i < n_sChoices; ++i)
{ if(highlight == i + 1) /* High light the present choice */
{ wattron(menu_win, A_REVERSE);
mvwprintw(menu_win, y, x, "%s", serviceChoices[i]);
wattroff(menu_win, A_REVERSE);
}
else
mvwprintw(menu_win, y, x, "%s", serviceChoices[i]);
++y;
}
wrefresh(menu_win);
};
void print_currency_menu(WINDOW *menu_win, int highlight)
{
int x, y, i;
x = 1;
y = 1;
box(menu_win, 0, 0);
for(i = 0; i < n_mChoices; ++i)
{ if(highlight == i + 1) /* High light the present choice */
{ wattron(menu_win, A_REVERSE);
mvwprintw(menu_win, y, x, "%s", moneyChoices[i]);
wattroff(menu_win, A_REVERSE);
}
else
mvwprintw(menu_win, y, x, "%s", moneyChoices[i]);
++y;
}
wrefresh(menu_win);
};
//////
// End Vending::Drink Class
/////
//////
// Function to calulate change based off given cash
// Input: double tenderedChange, double DrinkCost
// Output: returnedChange in pennies
/////
int calculateChange (double insertedChange, double drinkCost)
{
mvprintw(7,10,"-------------------------------");
mvprintw(8,10,"Making change --> ");
mvprintw(9,10,"Tendered: $%.2f", insertedChange / 100);
mvprintw(10,10,"Cost: $%.2f", drinkCost);
int price_pennies = drinkCost * 100;
int cash_pennies = insertedChange;
int dollars;
int quarters;
int dimes;
int nickels;
if (Vending::change[0] >= (cash_pennies - price_pennies) / 100){
dollars = ((cash_pennies - price_pennies) / 100);
Vending::change[0] = Vending::change[0] - dollars;
} else { dollars = 0;}
int remainder = (cash_pennies - price_pennies - (dollars * 100));
quarters = (remainder / 25);
Vending::change[1] = Vending::change[1] - quarters;
dimes = (remainder - quarters * 25) / 10;
Vending::change[2] = Vending::change[2] - dimes;
nickels = (remainder - quarters * 25 - dimes * 10) / 5;
Vending::change[3] = Vending::change[3] - nickels;
mvprintw(11,10, "Total Change: $%.2f", (cash_pennies - price_pennies));
mvprintw(12,10, "Change: dollars (%d), quarters (%d), dimes (%d), nickels (%d)", dollars, quarters, dimes, nickels);
mvprintw(13,10, "-------------------------------");
return (cash_pennies - price_pennies);
}
bool mainScreen(Vending::Drink drinks[]){
for(int i=0; i<=4; i++){
if(drinks[i].drinkQuantity < 1){
mvprintw(3,10, "<--- NEEDS SERVICE --->");
}
}
WINDOW *menu_win;
int highlight = 1;
int choice = 0;
int c;
double tenderedChange;
int returnedChange;
bool stop = false;
bool serviceFlag = false;
clear();
cbreak(); /* Line buffering disabled. pass on everything */
startx = (80 - WIDTH) / 2;
starty = (29 - HEIGHT) / 2;
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
keypad(menu_win, TRUE);
mvprintw(1, 22, "-------------------------------------");
mvprintw(2, 22, "| Welcome to Vending Machine v1.0 |");
mvprintw(3, 22, "-------------------------------------");
//Check if any of the drinks are out
for(int i=0; i<=4; i++){
if(drinks[i].drinkQuantity < 1){
serviceFlag = true;
}
}
//Check if any of the coins are out
for(int i=0; i<=3; i++){
if(Vending::change[i] < 1){
serviceFlag = true;
}
}
//Display Needs Service message if serviceFlag is true
if(serviceFlag){
mvprintw(5, 28, "<--- NEEDS SERVICE --->");
}
mvprintw(7, 10, "Use arrow keys to go up and down, Press enter to select a choice");
refresh();
print_menu(menu_win, highlight);
while(1)
{ c = wgetch(menu_win);
switch(c)
{ case KEY_UP:
if(highlight == 1)
highlight = n_dChoices;
else
--highlight;
break;
case KEY_DOWN:
if(highlight == n_dChoices)
highlight = 1;
else
++highlight;
break;
case 10:
choice = highlight;
break;
default:
refresh();
break;
}
print_menu(menu_win, highlight);
if(choice != 0) /* User did a choice come out of the infinite loop */
break;
}
clrtoeol();
refresh();
clear();
if((choice!=6)&&(choice!=7)){
if((drinks[choice-1].drinkQuantity < 1)){
mvprintw(10,23,"Please choose another drink. %s is out", drinks[choice-1].drinkName);
return false;
}
}
if(choice >= 1 && choice <= 5 ){
do {
stop = currencyMenu(drinks, choice);
for(int i=0; i<4; i++)
{ cout << changeArray[i] << "\n"; }
if((insertedChange / 100) < drinks[choice-1].drinkPrice){
mvprintw(24,0,"You did not insert enough money");
refresh();
stop = false;
}
} while (stop!=true);
clear();
mvprintw(1,10,"You chose %s", drinks[choice-1].drinkName);
mvprintw(2,10,"The cost of %s is $%.2f", drinks[choice-1].drinkName, drinks[choice-1].drinkPrice);
mvprintw(3,10,"Vending %s...", drinks[choice-1].drinkName);
mvprintw(4,10,"-------------------------------");
mvprintw(5,10,"Drink deployed to basket below");
mvprintw(6,10,"-------------------------------");
refresh();
drinks[choice-1].drinkQuantity--;
returnedChange = calculateChange(insertedChange, drinks[choice-1].drinkPrice);
Vending::cash = Vending::cash - (returnedChange);
return false;
} else if (choice == 6) {
clear();
mvprintw(23,0,"Canceling transaction and exiting.");
refresh();
return true;
} else if (choice == 7) {
do {
stop = maintenanceModeMenu(drinks);
} while (stop!=true);
return false;
} else {
cout << "Not a valid selection";
}
}
bool currencyMenu(Vending::Drink drinks[], int drinkChoice)
{
WINDOW *menu_win;
int highlight = 1;
int choice = 0;
int c;
int dollars;
int quarters;
int dimes;
int nickles;
bool stop = false;
if(((drinks[drinkChoice-1].drinkPrice * 100.0) - insertedChange) <= 0){ return true; }
clear();
cbreak(); /* Line buffering disabled. pass on everything */
startx = (80 - WIDTH) / 2;
starty = (29 - HEIGHT) / 2;
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
keypad(menu_win, TRUE);
mvprintw(1, 22, "-------------------------------------");
mvprintw(2, 22, "| Insert your change |");
mvprintw(3, 22, "-------------------------------------");
mvprintw(7, 10, "Use arrow keys to go up and down, Press enter to select a choice");
mvprintw(20, 5, "Total change inserted: $%.2f", (insertedChange / 100.0));
mvprintw(21, 5, "Change needed: $%.2f", ((drinks[drinkChoice-1].drinkPrice * 100.0) - insertedChange) / 100.0);
refresh();
print_currency_menu(menu_win, highlight);
while(1)
{ c = wgetch(menu_win);
switch(c)
{ case KEY_UP:
if(highlight == 1)
highlight = n_dChoices;
else
--highlight;
break;
case KEY_DOWN:
if(highlight == n_dChoices)
highlight = 1;
else
++highlight;
break;
case 10:
choice = highlight;
break;
default:
refresh();
break;
}
print_currency_menu(menu_win, highlight);
if(choice != 0) /* User did a choice come out of the infinite loop */
break;
}
clrtoeol();
refresh();
switch(choice)
{
case 1:
mvprintw(22,0,"How many dollar bills: ");
scanw("%d", &dollars);
mvprintw(19,0, "Entered dollars: %d", dollars);
insertedChange = insertedChange + 100 * dollars;
changeArray[0] = dollars;
Vending::change[0] = Vending::change[0] + dollars;
clrtoeol();
refresh();
clear();
break;
case 2:
mvprintw(22,0,"How many quarters: ");
scanw("%d", &quarters);
mvprintw(19,0, "Entered dollars: %d", quarters);
insertedChange = insertedChange + 25 * quarters;
changeArray[1] = quarters;
Vending::change[1] = Vending::change[1] + quarters;
clrtoeol();
refresh();
clear();
break;
case 3:
mvprintw(22,0,"How many dimes: ");
scanw("%d", &dimes);
mvprintw(19,0, "Entered dollars: %d", dimes);
insertedChange = insertedChange + 10 * dimes;
changeArray[2] = dimes;
Vending::change[2] = Vending::change[2] + dimes;
clrtoeol();
refresh();
clear();
break;
case 4:
mvprintw(22,0,"How many nickles: ");
scanw("%d", &nickles);
mvprintw(19,0, "Entered dollars: %d", nickles);
insertedChange = insertedChange + 5 * nickles;
changeArray[3] = nickles;
Vending::change[3] = Vending::change[3] + nickles;
clrtoeol();
refresh();
clear();
break;
case 5:
clrtoeol();
refresh();
clear();
return true;
break;
default:
return true;
break;
}
}
//////
// End Vending Class Member Functions
/////
//////
// Vending Class Maintenance Function Block
/////
bool maintenanceModeMenu(Vending::Drink drinks[])
{
WINDOW *menu_win;
int highlight = 1;
int choice = 0;
int c;
cbreak(); /* Line buffering disabled. pass on everything */
startx = (80 - WIDTH) / 2;
starty = (24 - HEIGHT) / 2;
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
keypad(menu_win, TRUE);
mvprintw(1, 22, "-------------------------------------");
mvprintw(2, 22, "| Vending Machive Service Menu |");
mvprintw(3, 22, "-------------------------------------");
mvprintw(6, 10, "Use arrow keys to go up and down, Press enter to select a choice");
refresh();
print_maintenance_menu(menu_win, highlight);
while(1)
{ c = wgetch(menu_win);
switch(c)
{ case KEY_UP:
if(highlight == 1)
highlight = n_sChoices;
else
--highlight;
break;
case KEY_DOWN:
if(highlight == n_sChoices)
highlight = 1;
else
++highlight;
break;
case 10:
choice = highlight;
break;
default:
refresh();
break;
}
print_maintenance_menu(menu_win, highlight);
if(choice != 0) /* User did a choice come out of the infinite loop */
break;
}
clrtoeol();
refresh();
switch(choice)
{
case 1:
getDrinkInventory(drinks);
mvprintw(25,0,"<-Press Any Key->"); /* tell the user to press a key */
getch();
clear();
return false;
break;
case 2:
mvprintw(18,0,"There is $%.2f remaining in the machine", (Vending::cash / 100.0));
mvprintw(25,0,"<-Press Any Key->"); /* tell the user to press a key */
getch();
clear();
return false;
case 3:
clear();
return true;
break;
default:
break;
}
}
void getDrinkInventory(Vending::Drink drinks[])
{
for(int i=0; i<=4; i++){
mvprintw(18+i,0,"Name: %s Cost: %.2f Quantity: %d",drinks[i].drinkName, drinks[i].drinkPrice, drinks[i].drinkQuantity);
}
}
//////
// End Vending Class Maintenance Function Block
/////
};
//////
// End Vending Class
/////
//Initialize static class member fortotal cash in the machine
int Vending::change[] = {50, 1, 65, 50};
int Vending::cash = 2000;
//////
// Main System Loop
/////
int main (int argc, char const *argv[])
{
Vending::Drink drinks[5];
drinks[0].setInfo("Coke", 1.00, 1);
drinks[1].setInfo("DrPepper", 1.50, 5);
drinks[2].setInfo("Sprite", 1.50, 5);
drinks[3].setInfo("MrPibb", 1.50, 5);
drinks[4].setInfo("Pepsi", 1.50, 5);
bool done = false;
char continueChoice;
initscr();
do {
Vending vendingTransaction;
done = vendingTransaction.mainScreen(drinks);
if (done != false) {
clear();
endwin();
return 0;
}
mvprintw(15, 20, "Would you like to make another purchase (y/n): ");
refresh();
continueChoice = getch();
while (continueChoice != 'Y' && continueChoice != 'y' && continueChoice != 'N' && continueChoice != 'n') {
continueChoice = getch();
}
if (continueChoice=='Y' || continueChoice=='y') {
done = false;
insertedChange = 0;
} else { done = true; }
} while (!done);
endwin();
return 0;
}
//////
// End Main System Loop
/////
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment