fork(2) download
  1. #include <iostream>
  2. #include <vector>
  3. #include <memory>
  4.  
  5. using std::shared_ptr;
  6. using std::make_shared;
  7.  
  8. int const income_interval = 6;
  9. int const start_money = 650;
  10. int const start_income = 50;
  11. //just under 07:00 minutes is usually when the game ends
  12. int const game_time = 400;
  13.  
  14. // multiple of time required to be spent
  15. int const require_spent_multiple = 10;
  16. // initial delay before spending is required
  17. int const require_spent_delay = 30;
  18.  
  19. struct plan {
  20. //plan acquisition cost
  21. int cost;
  22. //resulting increase in revenue
  23. int increase;
  24. //timeout before repeat purchase
  25. int regen;
  26. };
  27. std::vector<plan> plans({
  28. { 50, 2, 4 },
  29. { 300, 15, 13 },
  30. { 1000, 70, 60 },
  31. });
  32.  
  33. struct game_state {
  34. // how much money we have now
  35. int money;
  36. //income on each income interval
  37. int income;
  38. //total money we had/have
  39. int total;
  40. //money spent on upgrades
  41. int spent;
  42. //money invested for income
  43. int invested;
  44. //block purchase of the plan for regen time
  45. std::vector<int> plan_timeout;
  46. //total elapsed time
  47. int time;
  48.  
  49. game_state() {
  50. money = start_money;
  51. income = start_income;
  52. total = money;
  53. plan_timeout.resize( plans.size(), 0 );
  54. time = 0;
  55. spent = 0;
  56. invested = 0;
  57. }
  58.  
  59. void step() {
  60. time++;
  61.  
  62. //step plan regen time
  63. for( auto & pt : plan_timeout ) {
  64. if( pt > 0 ) {
  65. pt--;
  66. }
  67. }
  68.  
  69. //add new money each interval
  70. if( time % income_interval == 0 ) {
  71. money += income;
  72. total += income;
  73. }
  74. }
  75.  
  76. bool can_buy_plan(size_t i) {
  77. return money >= plans[i].cost
  78. && plan_timeout[i] == 0;
  79. }
  80.  
  81. void buy_plan(int i) {
  82. plan_timeout[i] += plans[i].regen;
  83. invested += plans[i].cost;
  84. money -= plans[i].cost;
  85. income += plans[i].increase;
  86. }
  87. };
  88.  
  89. struct strategy {
  90. shared_ptr<game_state> state;
  91. //name of this strategy
  92. std::string name;
  93. //stop investing at this time, if -1 then never stop
  94. int stop_invest_when;
  95.  
  96. strategy( std::string const & name ) :
  97. state( new game_state ),
  98. name(name) {
  99. stop_invest_when = -1;
  100. }
  101. strategy( std::string const & name, shared_ptr<game_state> state ) :
  102. state( state ),
  103. name( name ) {
  104. stop_invest_when = -1;
  105. }
  106.  
  107. void step(int spend) {
  108. //ensure we're spending enough
  109. if( state->spent < spend ) {
  110. int a = std::min( spend, state->money );
  111. state->money -= a;
  112. state->spent += a;
  113. }
  114.  
  115. state->step();
  116. step_impl();
  117. }
  118.  
  119. virtual void step_impl() = 0;
  120.  
  121. virtual bool should_buy_plan( int i ) {
  122. if( stop_invest_when >= 0 && state->time >= stop_invest_when ) {
  123. return false;
  124. }
  125. return state->can_buy_plan(i);
  126. }
  127. };
  128.  
  129. struct buy_all : public strategy {
  130. buy_all() : strategy( "buy_all" ) { }
  131.  
  132. void step_impl() {
  133. for( int i=plans.size()-1; i >=0; --i ) {
  134. if( should_buy_plan(i) ) {
  135. state->buy_plan(i);
  136. }
  137. }
  138. }
  139. };
  140.  
  141. struct buy_one_plan : public strategy {
  142. static std::string plan_name( int i ) {
  143. char buf[32];
  144. sprintf( buf, "Plan%d", i );
  145. return buf;
  146. }
  147.  
  148. int plan;
  149.  
  150. buy_one_plan(int i) :
  151. strategy( plan_name(i) ),
  152. plan(i) {
  153. }
  154.  
  155. void step_impl() {
  156. if( should_buy_plan(plan) ) {
  157. state->buy_plan(plan);
  158. }
  159. }
  160. };
  161.  
  162. struct buy_none : public strategy {
  163. buy_none() :
  164. strategy( "none" ) {
  165. }
  166.  
  167. void step_impl() {
  168. }
  169. };
  170.  
  171. typedef std::vector<shared_ptr<strategy>> strategies;
  172.  
  173. /**
  174. The main simulation driver. It steps through the strategies and outputs
  175. the results at regular intervals.
  176. */
  177. void run( std::string const & name, strategies const & all ) {
  178. std::cout << std::endl;
  179. std::cout << " - - " << name << " - - " << std::endl;
  180.  
  181. for( int i=0; i < game_time; ++i ) {
  182. //must have spent at least this much by this time
  183. int spend = i * require_spent_multiple;
  184. if( i < require_spent_delay ) {
  185. spend = 0;
  186. }
  187.  
  188. for( auto & s : all ) {
  189. s->step(spend);
  190. }
  191.  
  192. //write opdate regularly
  193. if( i % 30 == 0 ) {
  194. for( auto & s : all ) {
  195. std::cout << s->name << ": " << s->state->money << "/" << s->state->total << "\t";
  196. }
  197. std::cout << std::endl;
  198. }
  199. }
  200.  
  201. std::cout << "Spent/Invested" << std::endl;
  202. for( auto & s : all ) {
  203. std::cout << s->name << ": " << (s->state->spent+s->state->money)
  204. << "/" << s->state->invested << "\t";
  205. }
  206. std::cout << std::endl;
  207. }
  208.  
  209. //build a stopping strategy
  210. shared_ptr<strategy> stop_at( int time, shared_ptr<strategy> st ) {
  211. st->stop_invest_when = time;
  212.  
  213. char buf[32];
  214. sprintf( buf, "Stop@%d", time );
  215. st->name += buf;
  216.  
  217. return st;
  218. }
  219.  
  220. int main() {
  221. run( "Variety", {
  222. make_shared<buy_none>(),
  223. make_shared<buy_all>(),
  224. make_shared<buy_one_plan>(0),
  225. make_shared<buy_one_plan>(1),
  226. make_shared<buy_one_plan>(2),
  227. });
  228.  
  229. //buy_all appears best, so check when to stop
  230. run( "Stopping", {
  231. stop_at( 180, make_shared<buy_all>() ),
  232. stop_at( 240, make_shared<buy_all>() ),
  233. stop_at( 300, make_shared<buy_all>() ),
  234. stop_at( 360, make_shared<buy_all>() ),
  235. });
  236.  
  237. //with spending the Plan0/1 appears good
  238. run( "Stopping Plan0", {
  239. stop_at( 180, make_shared<buy_one_plan>(1) ),
  240. stop_at( 240, make_shared<buy_one_plan>(1) ),
  241. stop_at( 300, make_shared<buy_one_plan>(1) ),
  242. stop_at( 360, make_shared<buy_one_plan>(1) ),
  243. });
  244. }
  245.  
Success #stdin #stdout 0s 3440KB
stdin
Standard input is empty
stdout
 - - Variety - - 
none: 650/650	buy_all: 300/650	Plan0: 600/650	Plan1: 350/650	Plan2: 650/650	
none: 600/900	buy_all: 0/1049	Plan0: 248/948	Plan1: 0/1035	Plan2: 600/900	
none: 540/1150	buy_all: 0/1539	Plan0: 24/1300	Plan1: 0/1510	Plan2: 540/1150	
none: 250/1400	buy_all: 0/2079	Plan0: 0/1700	Plan1: 0/1985	Plan2: 250/1400	
none: 50/1650	buy_all: 0/2669	Plan0: 0/2150	Plan1: 190/2460	Plan2: 50/1650	
none: 300/1900	buy_all: 0/3309	Plan0: 0/2650	Plan1: 220/2980	Plan2: 300/1900	
none: 200/2150	buy_all: 0/3999	Plan0: 0/3200	Plan1: 250/3590	Plan2: 200/2150	
none: 150/2400	buy_all: 154/4741	Plan0: 0/3800	Plan1: 0/4245	Plan2: 150/2400	
none: 150/2650	buy_all: 46/5553	Plan0: 0/4450	Plan1: 130/4975	Plan2: 150/2650	
none: 200/2900	buy_all: 282/6492	Plan0: 0/5150	Plan1: 70/5870	Plan2: 200/2900	
none: 100/3150	buy_all: 221/7572	Plan0: 104/5902	Plan1: 230/6900	Plan2: 100/3150	
none: 100/3400	buy_all: 156/8817	Plan0: 296/6716	Plan1: 350/8080	Plan2: 100/3400	
none: 50/3650	buy_all: 431/10314	Plan0: 338/7600	Plan1: 275/9425	Plan2: 50/3650	
none: 0/3900	buy_all: 586/12027	Plan0: 946/8558	Plan1: 1140/10890	Plan2: 0/3900	
Spent/Invested
none: 3950/0	buy_all: 4896/7500	Plan0: 4908/3850	Plan1: 5810/5400	Plan2: 3950/0	

 - - Stopping - - 
buy_allStop@180: 300/650	buy_allStop@240: 300/650	buy_allStop@300: 300/650	buy_allStop@360: 300/650	
buy_allStop@180: 0/1049	buy_allStop@240: 0/1049	buy_allStop@300: 0/1049	buy_allStop@360: 0/1049	
buy_allStop@180: 0/1539	buy_allStop@240: 0/1539	buy_allStop@300: 0/1539	buy_allStop@360: 0/1539	
buy_allStop@180: 0/2079	buy_allStop@240: 0/2079	buy_allStop@300: 0/2079	buy_allStop@360: 0/2079	
buy_allStop@180: 0/2669	buy_allStop@240: 0/2669	buy_allStop@300: 0/2669	buy_allStop@360: 0/2669	
buy_allStop@180: 0/3309	buy_allStop@240: 0/3309	buy_allStop@300: 0/3309	buy_allStop@360: 0/3309	
buy_allStop@180: 0/3999	buy_allStop@240: 0/3999	buy_allStop@300: 0/3999	buy_allStop@360: 0/3999	
buy_allStop@180: 284/4709	buy_allStop@240: 154/4741	buy_allStop@300: 154/4741	buy_allStop@360: 154/4741	
buy_allStop@180: 284/5419	buy_allStop@240: 346/5553	buy_allStop@300: 46/5553	buy_allStop@360: 46/5553	
buy_allStop@180: 994/6129	buy_allStop@240: 840/6393	buy_allStop@300: 282/6492	buy_allStop@360: 282/6492	
buy_allStop@180: 142/6839	buy_allStop@240: 672/7233	buy_allStop@300: 271/7572	buy_allStop@360: 221/7572	
buy_allStop@180: 852/7549	buy_allStop@240: 1512/8073	buy_allStop@300: 940/8747	buy_allStop@360: 156/8817	
buy_allStop@180: 1562/8259	buy_allStop@240: 2352/8913	buy_allStop@300: 235/9922	buy_allStop@360: 481/10314	
buy_allStop@180: 2272/8969	buy_allStop@240: 504/9753	buy_allStop@300: 1410/11097	buy_allStop@360: 1292/11929	
Spent/Invested
buy_allStop@180: 6961/2150	buy_allStop@240: 7121/2800	buy_allStop@300: 7082/4250	buy_allStop@360: 6102/6150	

 - - Stopping Plan0 - - 
Plan1Stop@180: 350/650	Plan1Stop@240: 350/650	Plan1Stop@300: 350/650	Plan1Stop@360: 350/650	
Plan1Stop@180: 0/1035	Plan1Stop@240: 0/1035	Plan1Stop@300: 0/1035	Plan1Stop@360: 0/1035	
Plan1Stop@180: 0/1510	Plan1Stop@240: 0/1510	Plan1Stop@300: 0/1510	Plan1Stop@360: 0/1510	
Plan1Stop@180: 0/1985	Plan1Stop@240: 0/1985	Plan1Stop@300: 0/1985	Plan1Stop@360: 0/1985	
Plan1Stop@180: 190/2460	Plan1Stop@240: 190/2460	Plan1Stop@300: 190/2460	Plan1Stop@360: 190/2460	
Plan1Stop@180: 220/2980	Plan1Stop@240: 220/2980	Plan1Stop@300: 220/2980	Plan1Stop@360: 220/2980	
Plan1Stop@180: 250/3590	Plan1Stop@240: 250/3590	Plan1Stop@300: 250/3590	Plan1Stop@360: 250/3590	
Plan1Stop@180: 0/4215	Plan1Stop@240: 0/4245	Plan1Stop@300: 0/4245	Plan1Stop@360: 0/4245	
Plan1Stop@180: 625/4840	Plan1Stop@240: 430/4975	Plan1Stop@300: 130/4975	Plan1Stop@360: 130/4975	
Plan1Stop@180: 1250/5465	Plan1Stop@240: 775/5750	Plan1Stop@300: 70/5870	Plan1Stop@360: 70/5870	
Plan1Stop@180: 625/6090	Plan1Stop@240: 310/6525	Plan1Stop@300: 530/6900	Plan1Stop@360: 230/6900	
Plan1Stop@180: 1250/6715	Plan1Stop@240: 1085/7300	Plan1Stop@300: 860/7975	Plan1Stop@360: 350/8080	
Plan1Stop@180: 1875/7340	Plan1Stop@240: 1860/8075	Plan1Stop@300: 1935/9050	Plan1Stop@360: 275/9425	
Plan1Stop@180: 2500/7965	Plan1Stop@240: 2635/8850	Plan1Stop@300: 430/10125	Plan1Stop@360: 1650/10800	
Spent/Invested
Plan1Stop@180: 6590/1500	Plan1Stop@240: 6905/2100	Plan1Stop@300: 7040/3300	Plan1Stop@360: 6575/4500