PPL Assignment
IRM2015006
couple.cpp
Go to the documentation of this file.
1 #include <cstdlib>
2 #include <iostream>
3 #include <algorithm>
4 #include <string>
5 
6 #include "couple.h"
7 
9 {
10  return (c1.findHappiness() > c2.findHappiness());
11 }
12 
14 {
15  return (c1.findCompatibility() > c2.findCompatibility());
16 }
17 
19 {
20  return (g.gifted || g.type != luxury);
21 }
22 
24 {
25  boy = b;
26  girl = g;
27  boy->committed = true;
29  girl->committed = true;
31 }
32 
34 {
35  float boyHapp = boy->getHappiness();
36  float girlHapp = girl->getHappiness();
37  return boyHapp + girlHapp;
38 }
39 
41 {
42  boy->committed = false;
43  girl->committed = false;
44  boy->makeCouple(NULL);
45  girl->makeCouple(NULL);
46 }
47 
48 void Couple::makeGiftBasket(std::vector<Gift> giftsList, Logger *logger)
49 {
50  if (giftsList.empty()) return;
51 
52  gifts.clear();
53 
54  /* This is the maximum money to be spent.
55  It is different for different types of boys.
56  */
57  int expenseLimit = 0;
58 
59  switch (boy->getNature()) {
60  case miser:
61  case geek:
62  expenseLimit = girl->budget;
63  std::sort (giftsList.begin(), giftsList.end(), compareOnPriceAsc);
64  break;
65 
66  case generous:
67  expenseLimit = boy->budget;
68  std::sort (giftsList.begin(), giftsList.end(), compareOnPriceDesc);
69  break;
70  }
71 
72  /* start forming the basket */
73  for (auto it = giftsList.begin(); it != giftsList.end() && expenseLimit > 0; it++) {
74  expenseLimit -= (*it).price;
75  gifts.push_back(*it);
76  (*it).gifted = true;
77  logger->log("Gift", boy->name+" gifted "+(*it).name + " to "+ girl->name, true);
78  }
79 
80  /* if no gifts have been given, then raise the budget of the boy */
81  if (gifts.empty()) {
82  boy->budget = expenseLimit = gifts[0].price;
83  gifts.push_back(gifts[0]);
84  logger->log("Budget", boy->name+ " raised his budget to "+ std::to_string(boy->budget), true);
85  logger->log("Gift", boy->name+" gifted "+ gifts[0].name + " to "+ girl->name, true);
86  }
87 
88  /* geek boys want to give a luxury gift */
89  if (expenseLimit > 0 && boy->getNature() == geek) {
90  /* find a luxury gift */
91  std::remove_if(giftsList.begin(), giftsList.end(), giftRemovalPred);
92  if (! giftsList.empty())
93  gifts.push_back(giftsList[0]);
94  logger->log("Luxury", boy->name+" gifted luxury gift "+ gifts[0].name + " to "+ girl->name, true);
95  }
96 
99 }
100 
101 void Couple::makeGiftBasket2(std::vector<Gift> giftsList, Logger *logger)
102 {
103  if (giftsList.empty()) return;
104 
105  gifts.clear();
106 
107  int expenseLimit = boy->budget;
108  /* Here the boy has to gift one gift of each type,
109  * even if it surpasses his budget
110  */
111  std::vector<Gift> essentialGifts (giftsList.size());
112  std::vector<Gift> luxuryGifts (giftsList.size());
113  std::vector<Gift> utilityGifts (giftsList.size());
114 
115  auto it = std::copy_if (giftsList.begin(), giftsList.end(), essentialGifts.begin(), [](Gift g) { return (g.type != luxury) && (g.type != utility); });
116  essentialGifts.resize(std::distance(essentialGifts.begin(), it)); // resize to shrink container space
117  it = std::copy_if (giftsList.begin(), giftsList.end(), luxuryGifts.begin(), [](Gift g) { return (g.type != essential) && (g.type != utility); });
118  luxuryGifts.resize(std::distance(luxuryGifts.begin(), it)); // resize to shrink container space
119  it = std::copy_if (giftsList.begin(), giftsList.end(), utilityGifts.begin(), [](Gift g) { return (g.type != luxury) && (g.type != essential); });
120  utilityGifts.resize(std::distance(utilityGifts.begin(), it)); // resize to shrink container space
121 
122  if (essentialGifts.size() == 1 || luxuryGifts.size() == 1 || utilityGifts.size() == 1) {
123  logger->log("critical", "There is one gift possible for each type", true);
124  }
125 
126  /* gift one gift of each type */
127  gifts.push_back(essentialGifts[0]); gifts.push_back(luxuryGifts[0]); gifts.push_back(utilityGifts[0]);
128  logger->log("Gift", boy->name+" has money of value "+std::to_string(expenseLimit), true);
129  logger->log("Gift", boy->name+" gifted "+ essentialGifts[0].name + " & " + luxuryGifts[0].name + " & " + utilityGifts[0].name + " to "+ girl->name, true);
130  for (auto g : gifts)
131  expenseLimit -= g.price;
132 
133  logger->log("Gift", boy->name+" is left with "+std::to_string(expenseLimit), true);
134 
135  /* This gifting policy gifts essential gifts first, utitliy gifts next, and luxury gifts last */
136  int ess_pos = 1, lux_pos = 1, uti_pos = 1;
137  int ess_last = essentialGifts.size(), lux_last = luxuryGifts.size(), uti_last = utilityGifts.size();
138  while (expenseLimit > 0) {
139  if (ess_pos < ess_last) {
140  gifts.push_back(essentialGifts[ess_pos]);
141  expenseLimit -= essentialGifts[ess_pos].price;
142  logger->log("Gift", boy->name+" gifted "+ essentialGifts[ess_pos].name + " to "+ girl->name, true);
143  ess_pos++;
144  continue;
145  } else if (lux_pos < lux_last) {
146  gifts.push_back(luxuryGifts[lux_pos]);
147  expenseLimit -= luxuryGifts[lux_pos].price;
148  logger->log("Gift", boy->name+" gifted "+ luxuryGifts[lux_pos].name + " to "+ girl->name, true);
149  lux_pos++;
150  continue;
151  } else if (uti_pos < uti_last) {
152  gifts.push_back(utilityGifts[uti_pos]);
153  expenseLimit -= utilityGifts[uti_pos].price;
154  logger->log("Gift", boy->name+" gifted " + utilityGifts[uti_pos].name + " to "+ girl->name, true);
155  uti_pos++;
156  continue;
157  }
158  }
159 
160  boy->setGiftBasket(&gifts);
161  girl->setGiftBasket(&gifts);
162 }
163 
165 {
166  return (boy->budget - girl->budget) +
167  abs(boy->attr - girl->attr) +
168  abs(boy->intel - girl->intel);
169 }
bool committed
Definition: boy.h:32
void makeCouple(Girl *girl)
Definition: boy.cpp:18
void makeGiftBasket(std::vector< Gift > giftlist, Logger *logger)
Definition: couple.cpp:48
void log(const std::string type, const std::string msg, bool print=false)
Definition: logger.cpp:27
float findCompatibility()
Definition: couple.cpp:164
virtual float getHappiness()=0
int attr
Definition: boy.h:25
Boy * boy
Definition: couple.h:16
Definition: logger.h:8
Girl * girl
Definition: couple.h:17
Definition: boy_type.h:6
Couple(Boy *b, Girl *g)
Definition: couple.cpp:23
Definition: couple.h:10
bool compareOnPriceAsc(Gift g1, Gift g2)
Definition: gift.cpp:8
bool gifted
Definition: gift.h:21
virtual float getHappiness()=0
void makeCouple(Boy *boy)
Definition: girl.cpp:37
void makeGiftBasket2(std::vector< Gift > giftlist, Logger *logger)
Definition: couple.cpp:101
std::string name
Definition: girl.h:24
GiftType type
Definition: gift.h:18
Definition: girl.h:18
int budget
Definition: boy.h:27
int intel
Definition: boy.h:26
float findHappiness()
Definition: couple.cpp:33
virtual BoyNature getNature()=0
bool compareOnPriceDesc(Gift g1, Gift g2)
Definition: gift.cpp:13
std::vector< Gift > gifts
Definition: couple.h:14
Definition: boy.h:20
Definition: gift.h:9
Definition: gift.h:8
std::string name
Definition: boy.h:24
Definition: gift.h:14
void breakup()
Definition: couple.cpp:40
int attr
Definition: girl.h:25
Definition: boy_type.h:8
void setGiftBasket(std::vector< Gift > *gifts)
Definition: boy.cpp:29
int budget
Definition: girl.h:27
Definition: gift.h:10
void setGiftBasket(std::vector< Gift > *gifts)
Definition: girl.cpp:42
bool giftRemovalPred(Gift g)
Definition: couple.cpp:18
bool compareOnHappiness(Couple c1, Couple c2)
Definition: couple.cpp:8
bool committed
Definition: girl.h:23
int intel
Definition: girl.h:26
bool compareOnCompatibility(Couple c1, Couple c2)
Definition: couple.cpp:13