Advertisement
macko9393

Untitled

Apr 12th, 2016
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.07 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. enum state { Out_Of_Poptarts, No_Credit, Has_Credit, Dispenses_Poptart }; //Declare enum variables for States Available in the poptart machine
  8. enum stateParameter { No_Of_Poptarts, Credit, Cost_Of_Poptart }; //As well as certain parameters used within the system, for example the amount of poptarts
  9. //left to use.
  10. class StateContext;
  11.  
  12. class State
  13. {
  14. protected:
  15.  
  16. StateContext* CurrentContext; //Create new pointer to the StateContext class called CurrentContext.
  17.  
  18. public:
  19.  
  20. State(StateContext* Context)
  21. {
  22. CurrentContext = Context; //Set CurrentContext to whatever is passed to the function.
  23. }
  24.  
  25. virtual ~State(void)
  26. {
  27. }
  28.  
  29. };
  30.  
  31. class StateContext
  32. {
  33. protected:
  34.  
  35. State* CurrentState = nullptr; //Create new pointer to State called CurrentState and initialize it to nullptr.
  36. int stateIndex = 0;
  37. vector<State*> availableStates; //Create a vector of pointers to States that are available in the current Context.
  38. vector<int> stateParameters; //Create a vector of integers that holds the values of variables stated in the
  39. //enum stateParameter.
  40. public:
  41.  
  42. virtual ~StateContext() //Destructor function.
  43. { //This function iterates through the vector of available states and removes all the
  44. for (int i = 0; i < this->availableStates.size(); i++) delete this->availableStates[i]; //data as well as the values of enum stateParameters.
  45. this->availableStates.clear();
  46. this->stateParameters.clear();
  47. }
  48.  
  49. virtual void setState(state newState) //Sets the Current state to the state passed in the function call.
  50. {
  51. this->CurrentState = availableStates[newState];
  52. this->stateIndex = newState;
  53.  
  54. }
  55.  
  56. virtual int getStateIndex(void) //Returns the current stateIndex.
  57. {
  58. return this->stateIndex;
  59. }
  60.  
  61. virtual void setStateParam(stateParameter SP, int value) //Sets the stateParameter SP to the value value, both are defined in the
  62. { //function call. This is used to, for example, store the amount of Credits
  63. this->stateParameters[SP] = value; //inserted by the customer.
  64. }
  65.  
  66. virtual int getStateParam(stateParameter SP) //Retrives the value of the stateParameter SP, for example to get the current amount of
  67. { //Credit available to the customer.
  68. return this->stateParameters[SP];
  69. }
  70. };
  71.  
  72. class Transition //This class is preventing the user from interacting with the program while the program is
  73. { //in the Transition state.
  74. public:
  75. //Automatically returns false on every function call and displays an Error message.
  76. virtual bool insertMoney(int) { cout << "Error!" << endl; return false; }
  77. virtual bool makeSelection(int) { cout << "Error!" << endl; return false; }
  78. virtual bool moneyRejected(void) { cout << "Error!" << endl; return false; }
  79. virtual bool addPoptart(int) { cout << "Error!" << endl; return false; }
  80. virtual bool dispense(void) { cout << "Error!" << endl; return false; }
  81.  
  82. };
  83.  
  84. class PoptartState : public State, public Transition //The parent function to control the current state of the Poptarts.
  85. {
  86. public:
  87. PoptartState(StateContext* Context) : State(Context) {}
  88. };
  89.  
  90. class OutOfPoptarts : public PoptartState //Class defining the situation when there's no Poptarts left in the machine and it has to be
  91. { //refilled.
  92. public:
  93. OutOfPoptarts(StateContext* Context) : PoptartState(Context) {}
  94.  
  95. bool insertMoney(int money) //When the machine is in the OutOfPoptarts State it will automatically reject any money
  96. { //inserted and it will display an error message.
  97. cout << "Error! No Poptarts left!" << endl;
  98. this->moneyRejected();
  99. return false;
  100. }
  101.  
  102. bool makeSelection(int option) //When there's no poptarts left the machine won't accept user input and it will display the
  103. { //error message.
  104. cout << "Error! No Poptarts left! No selection made!" << endl;
  105. return false;
  106. }
  107.  
  108. bool moneyRejected(void)
  109. {
  110. cout << "Ejecting!" << endl;
  111. return true;
  112. }
  113.  
  114. bool addPoptart(int number) //This function is available only when the machine is in the OutOfPoptarts state.
  115. { //It is used to increment the No_Of_Poptarts enum variable by the number defined in the
  116. this->CurrentContext->setStateParam(No_Of_Poptarts, number); //function call.
  117. this->CurrentContext->setState(No_Credit); //When the Poptarts are refilled, it will go to the No_Credit state and wait for the
  118. return true; //customer to insert money.
  119. }
  120.  
  121. bool dispense(void) //The machine will not attempt to dispense Poptarts when it's in the OutOfPoptarts state
  122. { //and it will only display the error message and return false to signalise that dispensing was
  123. cout << "Error! No Poptarts left! Nothing to dispense!" << endl; //not successful.
  124. return false;
  125. }
  126.  
  127. };
  128.  
  129. class NoCredit : public PoptartState //This is the state in which there are enough Poptarts available to dispense, but the user
  130. { //hasn't inserted any money yet and the machine is still waiting for the first coin to be
  131. public: //inserted.
  132.  
  133. NoCredit(StateContext* Context) : PoptartState(Context) {}
  134.  
  135. bool insertMoney(int money) //The function called when there's money inserted into the machine.
  136. {
  137. cout << "You inserted: " << money; //Displaying the amount inserted.
  138. this->CurrentContext->setStateParam(Credit, money); //Setting the Credit parameter to whatever was inserted.
  139. cout << " Total: " << money << endl; //Displaying the total.
  140. this->CurrentContext->setState(Has_Credit); //Changing the machine state to Has_Credit so other paths of interaction are available.
  141. return true;
  142. }
  143.  
  144. bool makeSelection(int option) //
  145. { //
  146. cout << "Error! No money!" << endl; //
  147. return false; //Since there was no money inserted yet, the machine ignores all the other user actions
  148. } //and displays error messages because these funcions aren't available until there are sufficient
  149. //funds inserted in the machine.
  150. bool moneyRejected(void) //
  151. { //
  152. cout << "Error! No money!" << endl; //
  153. return false; //
  154. }
  155.  
  156. bool addPoptart(int number) //This machine is in the No_Credit state which means that there are Poptarts available
  157. { //and there's no need to add more.
  158. cout << "Error! Already got Poptarts!" << endl;
  159. return false;
  160. }
  161.  
  162. bool dispense(void) //The machine can't dispense the Poptart because there's no funds available so
  163. { //it displays the error message instead and returns false.
  164. cout << "Error! No money!" << endl;
  165. return false;
  166. }
  167.  
  168. };
  169.  
  170. class HasCredit : public PoptartState //Has_Credit is a state used when there are funds inserted into the machine but no
  171. { //further action was taken.
  172. public:
  173.  
  174. HasCredit(StateContext* Context) : PoptartState(Context) {}
  175.  
  176. bool insertMoney(int money) //The machine is waiting for more coins to be inserted.
  177. {
  178. cout << "You inserted: " << money; //When there's more money inserted it will display the amount on the screen.
  179. money = money + this->CurrentContext->getStateParam(Credit); //The amount inserted is added to whatever is already stored in the Credit variable.
  180. this->CurrentContext->setStateParam(Credit, money); //The new value of "money" is stored in the Credit variable.
  181. cout << " Total: " << money << endl; //The program outputs the new total Credit vailable.
  182. this->CurrentContext->setState(Has_Credit); //The program loops back to the Has_Credit state to wait for further instructions.
  183. return true;
  184. }
  185.  
  186. bool makeSelection(int option); //When the selection is made, the poptart selected is passed to the function as option.
  187.  
  188. bool moneyRejected(void)
  189. {
  190. cout << "Money rejected!" << endl; //Display the information about rejecting money
  191. this->CurrentContext->setStateParam(Credit, 0); //Set the Credit parameter back to 0
  192. this->CurrentContext->setState(No_Credit); //Since the credit parameter is set to 0, there's no cash in the machine so the state
  193. return true; //is changed back to the No_Credit state.
  194. }
  195.  
  196. bool addPoptart(int number) //This machine is in the Has_Credit state which means that there are Poptarts available
  197. { //and there's no need to add more.
  198. cout << "Error! Already got Poptarts!" << endl;
  199. return false;
  200. }
  201.  
  202. bool dispense(void) //The machine is not able to dispense the Poptart because the user didn't make a selection
  203. { //yet.
  204. cout << "Error! No selection made!" << endl;
  205. return false;
  206. }
  207.  
  208. };
  209.  
  210. class DispensesPoptart : public PoptartState //This state is used to prevent the user from interacting with the Poptart machine
  211. { //while it is dispensing the Poptart.
  212. public:
  213.  
  214. DispensesPoptart(StateContext* Context) : PoptartState(Context) {}
  215.  
  216. bool insertMoney(int money)
  217. {
  218. cout << "Error! Busy dispensing!" << endl;
  219. return false;
  220. }
  221.  
  222. bool makeSelection(int option)
  223. {
  224. cout << "Error! Busy dispensing!" << endl;
  225. return false;
  226. }
  227.  
  228. bool moneyRejected(void)
  229. {
  230. cout << "Error! Busy dispensing!" << endl;
  231. return false;
  232. }
  233.  
  234. bool addPoptart(int number)
  235. {
  236. cout << "Error! Busy dispensing!" << endl;
  237. return false;
  238. }
  239.  
  240. bool dispense(void);
  241.  
  242. };
  243.  
  244. class Product //This is the superclass for the Base and Filling classes that stores the data and functions
  245. { //for it's subclasses.
  246. protected:
  247. string product_description; //Initialize the variables used by the Base class
  248. int itemCost = 0; //
  249. public:
  250. int cost(void) { return this->itemCost; } //Function that returns the cost of the base selected.
  251. string description(void) { return product_description; } //Function that returns the description of the base selected.
  252.  
  253. //Product* ReturnHighestCostItem(void);
  254. //void RemoveHighestCostItem(void);
  255.  
  256. };
  257.  
  258. class Base : public Product //A subclass to determine the type of base selected by the user.
  259. {
  260. public:
  261. Base(int option) //the option is passed through the function call.
  262. {
  263. switch (option) { //Based on the option chosen by the user, the switch case determines the
  264. case 1: //product_description and the itemCost of the Product that will be dispensed.
  265. this->product_description = "Plain";
  266. this->itemCost = 100;
  267. break;
  268.  
  269. case 2:
  270. this->product_description = "Spicy";
  271. this->itemCost = 150;
  272. break;
  273.  
  274. case 4:
  275. this->product_description = "Chocolate";
  276. this->itemCost = 200;
  277. break;
  278.  
  279. case 8:
  280. this->product_description = "Coconut";
  281. this->itemCost = 200;
  282. break;
  283.  
  284. case 16:
  285. this->product_description = "Fruity";
  286. this->itemCost = 200;
  287. break;
  288. }
  289.  
  290. }
  291. };
  292. /*
  293. class Filling : public Product
  294. {
  295. public:
  296. void consume(void)
  297. {
  298.  
  299. }
  300.  
  301. virtual void fillProduct(Product* NewBase)
  302. {
  303.  
  304. }
  305.  
  306. virtual int cost(void)
  307. {
  308.  
  309. }
  310.  
  311. virtual string description(void)
  312. {
  313.  
  314. }
  315.  
  316. //Product* ReturnHighestCostItem(void);
  317. //void RemoveHighestCostItem(void);
  318. };
  319. */
  320.  
  321. class Poptart_Dispenser : public StateContext, public Transition
  322. {
  323. friend class DispensesPoptart; //Friend classes that can access the private variables and functions of this class.
  324. friend class HasCredit; //
  325. private:
  326. PoptartState* PoptartCurrentState = nullptr; //Initialise various variables to their default values.
  327. bool itemDispensed = false;
  328. Product* DispensedItem = nullptr;
  329. bool itemRetrieved = false;
  330. public:
  331.  
  332. Poptart_Dispenser(int inventory_count) //The constructor method used when the object is initialised.
  333. {
  334. this->availableStates.push_back(new OutOfPoptarts(this)); //
  335. this->availableStates.push_back(new NoCredit(this)); //Adding all the available states to the availableStates Vector.
  336. this->availableStates.push_back(new HasCredit(this)); //
  337. this->availableStates.push_back(new DispensesPoptart(this)); //
  338. this->stateParameters.push_back(0);
  339. this->stateParameters.push_back(0); //Initialise both StateParameters to 0.
  340.  
  341. this->setState(Out_Of_Poptarts); //Setting the default state to Out_Of_Poptarts
  342. if (inventory_count > 0) //If the inventory_count is greater than 0 then poptarts will be added to the machine and
  343. { //it will automatically switch from the OutOfPoptarts state to the NoCredit state.
  344. this->addPoptart(inventory_count);
  345. }
  346.  
  347. }
  348.  
  349. ~Poptart_Dispenser(void) //Destructor function to free up the resources allocated to this class.
  350. {
  351. if (!this->itemRetrieved)
  352. {
  353. delete this->DispensedItem;
  354. }
  355. }
  356.  
  357. bool insertMoney(int money) //Sets the current state of the Poptart to the CurrentState.
  358. {
  359. PoptartCurrentState = (PoptartState*) this->CurrentState;
  360. return this->PoptartCurrentState->insertMoney(money);
  361. }
  362.  
  363. bool makeSelection(int option) //Passes the option selected by the user to the makeSelection function and returns whatever
  364. { //is returned by that function call.
  365. PoptartCurrentState = (PoptartState*) this->CurrentState;
  366. return this->PoptartCurrentState->makeSelection(option);
  367. }
  368.  
  369. bool moneyRejected(void)
  370. {
  371. PoptartCurrentState = (PoptartState*) this->CurrentState;
  372. return this->PoptartCurrentState->moneyRejected();
  373. }
  374.  
  375. bool addPoptart(int number) //Passes the number of poptarts selected by the user to the addPoptart function and
  376. { //returns whatever is returned by that function call.
  377. PoptartCurrentState = (PoptartState*) this->CurrentState;
  378. return this->PoptartCurrentState->addPoptart(number);
  379. }
  380.  
  381. bool dispense(void) //Executes the dispense function and returns whatever is returned by that function call.
  382. {
  383. PoptartCurrentState = (PoptartState*) this->CurrentState;
  384. return this->PoptartCurrentState->dispense();
  385. }
  386.  
  387. Product* getProduct(void)
  388. {
  389. if (this->itemDispensed) //If the item has been dispensed then:
  390. {
  391. this->itemDispensed = false; //reset the itemDispensed bool variable to false.
  392. this->itemRetrieved = true;
  393. return this->DispensedItem; //Return the object that has been dispensed.
  394. }
  395.  
  396. return nullptr; //Otherwise return a null pointer.
  397. }
  398. virtual void setStateParam(stateParameter SP, int value) //Set the StateParam enum to a value determined by the user.
  399. {
  400. if (SP == Cost_Of_Poptart) return;
  401. this->stateParameters[SP] = value;
  402. }
  403.  
  404. virtual int getStateParam(stateParameter SP) //Retrive the value of a stateParam entry defined by the user.
  405. {
  406. if (SP == Cost_Of_Poptart)
  407. {
  408. if (DispensedItem == nullptr) return 0;
  409. return DispensedItem->cost();
  410. }
  411. return this->stateParameters[SP];
  412. }
  413.  
  414. };
  415.  
  416. bool HasCredit::makeSelection(int option) //When the program is in the Has_Credit state, the user is allowed to make the selection
  417. { //and select the type of Poptart he wants.
  418. cout << "Selection made!" << endl;
  419. if (!((Poptart_Dispenser*)this->CurrentContext)->itemRetrieved) //If the itemRetrived is false then Delete the item dispensed, assuming that the
  420. { //customer took the dispensed Poptart out of the machine.
  421. delete ((Poptart_Dispenser*)this->CurrentContext)->DispensedItem;
  422. }
  423. ((Poptart_Dispenser*)this->CurrentContext)->DispensedItem = new Base(option); //Initialise new Base object and pass the option to determine the type required by the user.
  424. ((Poptart_Dispenser*)this->CurrentContext)->itemRetrieved = false; //Reset the itemRetrived variable to false.
  425. this->CurrentContext->setState(Dispenses_Poptart); //Set the state to Dispenses_Poptart while the Poptart.
  426. return true;
  427. }
  428.  
  429. bool DispensesPoptart::dispense(void)
  430. {
  431. if (this->CurrentContext->getStateParam(Credit) >= this->CurrentContext->getStateParam(Cost_Of_Poptart)) //check if the user has enough Credit to dispense the Poptart he wants.
  432. {
  433. cout << "Dispensing " << ((Poptart_Dispenser*)this->CurrentContext)->DispensedItem->description() << " Poptart." << endl; //If the use has enough, display the message about dispensing it.
  434. this->CurrentContext->
  435. setStateParam(Credit, this->CurrentContext->getStateParam(Credit) //Subtract the cost of the Poptart from the Credits available to the user.
  436. - this->CurrentContext->getStateParam(Cost_Of_Poptart)); //
  437.  
  438. this->CurrentContext->setStateParam(No_Of_Poptarts, this->CurrentContext->getStateParam(No_Of_Poptarts) - 1); //Subtract the Poptart dispensed from the total.
  439. ((Poptart_Dispenser*)this->CurrentContext)->itemDispensed = true; //Set the itemDispensed to true.
  440. cout << "Remaining credit: " << this->CurrentContext->getStateParam(Credit) << "." << endl; //Display the Credit remaining available to the user.
  441. }
  442. else
  443. {
  444. cout << "Error! Not enough money" << endl; //If the user doesn't have enough for the desired Poptart, display the error message.
  445. }
  446.  
  447. if (this->CurrentContext->getStateParam(Credit) > 0) //When there's still more than 0 Credits in the machine, go to the Has_Credit state.
  448. {
  449. this->CurrentContext->setState(Has_Credit);
  450. }
  451. else
  452. {
  453. this->CurrentContext->setState(No_Credit); //When there's no Credits left, go to the No_Credit state.
  454. }
  455.  
  456. if (this->CurrentContext->getStateParam(No_Of_Poptarts) == 0) //If there's no poptarts left, go to the Out_Of_Poptarts state.
  457. {
  458. this->CurrentContext->setState(Out_Of_Poptarts);
  459. }
  460. return true;
  461. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement