Advertisement
Mothrayas

BBRouter

Nov 25th, 2013
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.26 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <algorithm>
  5.  
  6. const enum Requires
  7. {
  8.     REQUIRE_GOLDEN,
  9.     REQUIRE_CLOCKS
  10. };
  11.  
  12. const enum Verbosity
  13. {
  14.     QUIET,
  15.     VERBOSE
  16. };
  17.  
  18. const enum Eras
  19. {
  20.     NOWHERE,
  21.     STONE,
  22.     MEDIEVAL,
  23.     PIRATE,
  24.     THIRTIES,
  25.     SPACE
  26. };
  27.  
  28. struct Level
  29. {
  30.     char* LevelName;
  31.     char LevelNameFiller[31];
  32.     int Era;
  33.     int Clocks;
  34.     int GoldenCarrots;
  35.     int RequireCount;
  36.     bool RequireClocks;
  37.  
  38.     bool RequireSpellJump;
  39.     bool RequireSpellMusic;
  40.     bool RequireSpellFan;
  41.     bool RequireSpellPassword;
  42.  
  43.     bool ObtainSpellJump;
  44.     bool ObtainSpellMusic;
  45.     bool ObtainSpellFan;
  46.     bool ObtainSpellPassword;
  47.  
  48.     Level(char* _n, int _e, int _c, int _gc, int _r, bool _rc,
  49.           bool _rsj, bool _rsm, bool _rsf, bool _rsp,
  50.           bool _gsj, bool _gsm, bool _gsf, bool _gsp )
  51.         : LevelName(_n), Era (_e), Clocks(_c), GoldenCarrots(_gc), RequireCount(_r), RequireClocks(_rc),
  52.           RequireSpellJump(_rsj), RequireSpellMusic(_rsm), RequireSpellFan(_rsf), RequireSpellPassword(_rsp),
  53.           ObtainSpellJump(_gsj), ObtainSpellMusic(_gsm), ObtainSpellFan(_gsf), ObtainSpellPassword(_gsp){};
  54. };
  55.  
  56. struct Route
  57. {  
  58.     Level* routeOrder[27];
  59.     int routeSize;
  60.  
  61.     int Clocks;
  62.     int GoldenCarrots;
  63.  
  64.     int TotalRate;
  65.  
  66.     bool SpellJump;
  67.     bool SpellMusic;
  68.     bool SpellFan;
  69.     bool SpellPassword;
  70.  
  71.     //add level to route
  72.     void AddLevel(Level* _l)
  73.     {
  74.         routeOrder[routeSize++] = _l;
  75.         Clocks += _l->Clocks;
  76.         GoldenCarrots += _l->GoldenCarrots;
  77.  
  78.         SpellJump = _l->ObtainSpellJump ? true : SpellJump;
  79.         SpellMusic = _l->ObtainSpellMusic ? true : SpellMusic;
  80.         SpellFan = _l->ObtainSpellFan ? true : SpellFan;
  81.         SpellPassword = _l->ObtainSpellPassword ? true : SpellPassword;
  82.     }
  83.  
  84.     //check if level can be added to route
  85.     bool CheckLevelPossible(Level* _l)
  86.     {
  87.         //check level not already done
  88.         for(int i=0; i<routeSize; ++i)
  89.         {
  90.             if(routeOrder[i] == _l) return false;
  91.         }
  92.  
  93.         //check required amount of clocks/GCs
  94.         if(Clocks < _l->RequireCount && _l->RequireClocks == REQUIRE_CLOCKS) return false;
  95.         if(GoldenCarrots < _l->RequireCount && _l->RequireClocks == REQUIRE_GOLDEN) return false;
  96.  
  97.         //check required spells
  98.         if(!SpellJump && _l->RequireSpellJump) return false;
  99.         if(!SpellMusic && _l->RequireSpellMusic) return false;
  100.         if(!SpellFan && _l->RequireSpellFan) return false;
  101.         if(!SpellPassword && _l->RequireSpellPassword) return false;
  102.  
  103.         return true;
  104.     }
  105.  
  106.     //Returns a number, weighing the 'distance' between two levels.
  107.     //Levels in the same era return less, further away eras return higher numbers.
  108.     int CalcRoutePreference(Level* _level1, Level* _level2)
  109.     {
  110.         int val = 5;
  111.  
  112.         //get era distance between two levels
  113.         int EraDiff = _level1->Era - _level2->Era;
  114.         {
  115.             if(EraDiff > 3) EraDiff -= 6;
  116.             if(EraDiff < -3) EraDiff += 6;
  117.             if(EraDiff < 0) EraDiff *= -1;
  118.         }
  119.  
  120.         //if second level is in a different era, add value
  121.         if(EraDiff != 0)
  122.         {
  123.             val += 10 + EraDiff;
  124.         }
  125.  
  126.         return val;
  127.     }
  128. };
  129.  
  130.  
  131. //first visit The Greatest Escape: 5/6 clocks, 13/15 GCs
  132. //
  133. //first visit What's Cookin Doc:
  134. //clocks: 9: prison, prison>key, forest hidden area, merlin's house, spinning tower cage, lava section, lava section, lava section, bossfight
  135. //gcs: mainland: 8: prison guard, prison>key, overworld guard, above water, above water, water cage, waterfall, overworld knight
  136. //gcs: forest: 7: daffy hood, tree, tree, tree, forest near river, merlin's house, jump on witch hazel
  137. //castle: 7: spinning tower, cannonball puzzle, castle walls, lava section, lava section knight, lava section knight, lava section endpoint knight
  138. //...and two others
  139. //
  140. //total: 9 clocks 24 GCs
  141. //
  142. //second visit What's Cookin Doc:
  143. //
  144. //first 99 carrots by The Greatest Escape 1
  145.  
  146. Level levels[] = {
  147. //     Name                                  Era       Cl, GC, Req.,Req. what,      req.jump/music/fan/passwrd, get jump/music/fan/passwrd
  148. Level("Nowhere"                            , NOWHERE , 1 , 10, 0  , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //0
  149.  
  150. Level("Wabbit on the Run"                  , STONE   , 9 , 22, 1  , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //1
  151. Level("Guess Who Needs a Kick Start"       , STONE   , 1 , 5 , 5  , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //2
  152. Level("Wabbit or Duck Season"              , STONE   , 1 , 0 , 50 , REQUIRE_GOLDEN, false, false, false, false, false, false, false, false), //3
  153. Level("Magic Hare Blower"                  , STONE   , 14, 31, 80 , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //4
  154.  
  155. Level("Hey, What's Up, Doc?"               , PIRATE  , 9 , 17, 5  , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //5
  156. Level("Follow the Red Pirate Road 1"       , PIRATE  , 3 , 3 , 11 , REQUIRE_CLOCKS, true , false, false, false, false, false, false, false), //6
  157. Level("Follow the Red Pirate Road 2"       , PIRATE  , 1 , 6 , 11 , REQUIRE_CLOCKS, true , false, false, true , false, false, false, false), //7
  158. Level("When Sam met Bunny"                 , PIRATE  , 1 , 2 , 35 , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //8
  159. Level("Mine or Mine?"                      , PIRATE  , 10, 41, 100, REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //9
  160.  
  161. Level("The Big Bank Withdrawal"            , THIRTIES, 6 , 15, 15 , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //10
  162. Level("The Greatest Escape 1"              , THIRTIES, 5 , 13, 25 , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //11
  163. Level("The Greatest Escape 2"              , THIRTIES, 1 , 2 , 25 , REQUIRE_CLOCKS, true , false, false, false, false, false, false, false), //12
  164. Level("Objects in the mirror..."           , THIRTIES, 4 , 15, 50 , REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //13
  165. Level("La Corrida"                         , THIRTIES, 1 , 5 , 150, REQUIRE_GOLDEN, false, false, false, false, false, false, false, false), //14
  166. Level("The Carrot Factory"                 , THIRTIES, 8 , 15, 90,  REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //15
  167.  
  168. Level("What's Cookin', doc? 1"             , MEDIEVAL, 9 , 24, 30,  REQUIRE_CLOCKS, false, false, false, false, true , false, false, false), //16
  169. Level("What's Cookin', doc? 2"             , MEDIEVAL, 4 , 12, 30,  REQUIRE_CLOCKS, false, true , false, false, true , false, false, false), //17
  170. Level("What's Cookin', doc? 3"             , MEDIEVAL, 2 , 1 , 30,  REQUIRE_CLOCKS, false, false, true , false, true , false, false, false), //18
  171. Level("Witch Way to Albuquerque?"          , MEDIEVAL, 1 , 8 , 65,  REQUIRE_CLOCKS, false, false, false, false, false, true , false, false), //19
  172. Level("The Carrot-Henge Mystery"           , MEDIEVAL, 8 , 20, 73,  REQUIRE_CLOCKS, false, false, false, false, false, false, true , true ), //20
  173. Level("Downhill Duck"                      , MEDIEVAL, 1 , 0 , 250, REQUIRE_GOLDEN, false, false, false, false, false, false, false, false), //21
  174.  
  175. Level("The Planet X File"                  , SPACE   , 14, 26, 40,  REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //22
  176. Level("Vort X Room"                        , SPACE   , 4 , 0 , 60,  REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //23
  177. Level("The Conquest of Planet X"           , SPACE   , 1 , 14, 70,  REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //24
  178. Level("Train Your Brain"                   , SPACE   , 5 , 21, 117, REQUIRE_CLOCKS, false, false, false, false, false, false, false, false), //25
  179.  
  180. Level("END"                                , NOWHERE , 0 , 5,  124, REQUIRE_CLOCKS, true , true , true , true , false, false, false, false)  //26
  181. };
  182.  
  183. /*
  184.  
  185. LEVEL IDS:
  186.  
  187. 0  - Nowhere
  188. 1  - Wabbit on the Run
  189. 2  - Guess Who Needs a Kick Start
  190. 3  - Wabbit or Duck Season
  191. 4  - Magic Hare Blower
  192. 5  - Hey, What's Up, Doc?
  193. 6  - Follow the Red Pirate Road 1
  194. 7  - Follow the Red Pirate Road 2
  195. 8  - When Sam met Bunny
  196. 9  - Mine or Mine?
  197. 10 - The Big Bank Withdrawal
  198. 11 - The Greatest Escape 1
  199. 12 - The Greatest Escape 2
  200. 13 - Objects in the mirror...
  201. 14 - La Corrida
  202. 15 - The Carrot Factory
  203. 16 - What's Cookin', doc? 1  
  204. 17 - What's Cookin', doc? 2
  205. 18 - What's Cookin', doc? 3
  206. 19 - Witch Way to Albuquerque?
  207. 20 - The Carrot-Henge Mystery
  208. 21 - Downhill Duck
  209. 22 - The Planet X File
  210. 23 - Vort X Room
  211. 24 - The Conquest of Planet X  
  212. 25 - Train Your Brain
  213. 26 - END
  214.  
  215.  */
  216.  
  217. //Array used for random numbers
  218. int Random27Array[27] =
  219. {
  220.     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
  221. };
  222.  
  223. void SetArray(int _Array[27])
  224. {
  225.     for(int i=0; i<27; ++i)
  226.     {
  227.         _Array[i] = i;
  228.     }
  229. }
  230.  
  231. void RandomizeArray(int _Array[27])
  232. {
  233.     std::random_shuffle(_Array, _Array + 27);
  234. }
  235.  
  236. int GlobalEraDiffRates[27][27]; //precalculated
  237.  
  238. //Calculate a route that finishes the game using a random seed.
  239. int CalculateRandomRoute(int seed, bool verbose = false)
  240. {
  241.     srand(seed);
  242.     SetArray(Random27Array);
  243.     RandomizeArray(Random27Array);
  244.  
  245.     Route r = Route();
  246.     r.AddLevel(&levels[0]);
  247.  
  248.     if(verbose) printf("ROUTE: 00 %s (%d, %d) (rating: %d)\n", r.routeOrder[r.routeSize-1]->LevelName, r.Clocks, r.GoldenCarrots, 0);
  249.  
  250.     int EraDiffRates[27];
  251.     int lastID = 0;
  252.  
  253.     while(r.routeSize < 27)
  254.     {
  255.         memset(EraDiffRates, -1, sizeof(EraDiffRates));
  256.  
  257.         for(int i=0; i<27; ++i)
  258.         {
  259.             if(r.CheckLevelPossible(&levels[i]))
  260.             {
  261.                 EraDiffRates[i] = GlobalEraDiffRates[lastID][i];
  262.             }
  263.         }
  264.  
  265.         int LowestRate = -1;
  266.         int id = -1;
  267.  
  268.         if(r.routeSize <= 5)
  269.         {
  270.                 //the first 6 stages have to be in order
  271.                 //(done to speed up route calculations)
  272.  
  273.                 if(r.routeSize == 1)
  274.                 {
  275.                     id = 1;
  276.                 }
  277.                 else if(r.routeSize == 2)
  278.                 {
  279.                     id = 2;
  280.                 }
  281.                 else if(r.routeSize == 3)
  282.                 {
  283.                     id = 5;
  284.                 }
  285.                 else if(r.routeSize == 4)
  286.                 {
  287.                     id = 10;
  288.                 }
  289.                 else if(r.routeSize == 5)
  290.                 {
  291.                     id = 11;
  292.                 }
  293.         }
  294.         else
  295.         {
  296.             for(int i=0; i<27; ++i)
  297.             {
  298.                 if(EraDiffRates[Random27Array[i]] > 0)
  299.                 {
  300.                     id = Random27Array[i];
  301.                     break;
  302.                 }
  303.             }
  304.  
  305.             if(id == -1)
  306.             {
  307.                     printf("ERROR: Route not possible.\n");
  308.                     return 999;
  309.             }
  310.         }
  311.  
  312.         LowestRate = EraDiffRates[id];
  313.  
  314.         r.AddLevel(&levels[id]);
  315.         r.TotalRate += LowestRate;
  316.  
  317.         if(LowestRate > 5)
  318.         {
  319.             if(verbose)
  320.                 printf("\n");
  321.         }
  322.         if(verbose)
  323.             printf("ROUTE: %.2d %s (%d, %d) (rating: %d)\n", id, r.routeOrder[r.routeSize-1]->LevelName, r.Clocks, r.GoldenCarrots, LowestRate);
  324.         lastID = id;
  325.     }
  326.  
  327.     if(verbose)
  328.         printf("ROUTE: Total rate: %d", r.TotalRate);
  329.  
  330.     return r.TotalRate;
  331. }
  332.  
  333. //Calculate route using a preset array as a route order.
  334. int CalculatePresetRoute(int _r[27], bool verbose = false)
  335. {
  336.     Route r = Route();
  337.     for(int i = 0; i < 27; ++i)
  338.     {
  339.         if(r.CheckLevelPossible(&levels[_r[i]]) == false)
  340.         {
  341.             if(verbose)
  342.                 printf("ERROR: Route not possible. ");
  343.             return -1;
  344.         }
  345.  
  346.         r.AddLevel(&levels[_r[i]]);
  347.         int rating = 0;
  348.         if(i > 0)
  349.         {
  350.             rating = r.CalcRoutePreference(r.routeOrder[r.routeSize-2], &levels[_r[i]]);
  351.             r.TotalRate += rating;
  352.         }
  353.  
  354.         if(rating > 5)
  355.         {
  356.             if(verbose) printf("\n");
  357.         }
  358.  
  359.         if(verbose) printf("ROUTE: %.2d %s (%d, %d) (rating: %d)\n", _r[i], r.routeOrder[r.routeSize-1]->LevelName, r.Clocks, r.GoldenCarrots, rating);
  360.     }
  361.     if(verbose) printf("ROUTE: Total rate: %d", r.TotalRate);
  362.  
  363.     return r.TotalRate;
  364.  
  365. }
  366.  
  367. /*
  368.  
  369. LEVEL IDS:
  370.  
  371. 0  - Nowhere
  372. 1  - Wabbit on the Run
  373. 2  - Guess Who Needs a Kick Start
  374. 3  - Wabbit or Duck Season
  375. 4  - Magic Hare Blower
  376. 5  - Hey, What's Up, Doc?
  377. 6  - Follow the Red Pirate Road 1
  378. 7  - Follow the Red Pirate Road 2
  379. 8  - When Sam met Bunny
  380. 9  - Mine or Mine?
  381. 10 - The Big Bank Withdrawal
  382. 11 - The Greatest Escape 1
  383. 12 - The Greatest Escape 2
  384. 13 - Objects in the mirror...
  385. 14 - La Corrida
  386. 15 - The Carrot Factory
  387. 16 - What's Cookin', doc? 1  
  388. 17 - What's Cookin', doc? 2
  389. 18 - What's Cookin', doc? 3
  390. 19 - Witch Way to Albuquerque?
  391. 20 - The Carrot-Henge Mystery
  392. 21 - Downhill Duck
  393. 22 - The Planet X File
  394. 23 - Vort X Room
  395. 24 - The Conquest of Planet X  
  396. 25 - Train Your Brain
  397. 26 - END
  398.  
  399.  */
  400.  
  401. //Array used for calculating a preset route
  402. int PresetRouteArray[27] =
  403. {
  404.     0, 1, 2, 5, 10, 11, 16, 6, 8, 22, 12, 13, 14, 23, 19, 17, 20, 18, 3, 4, 15, 9, 7, 21, 24, 25, 26
  405. };
  406.  
  407. //Amount of random tries
  408. long long iterations = 99999;
  409.  
  410. int main()
  411. {
  412.     {
  413.         //Precalculate all combinations of level transition/'distance' values
  414.         Route t;
  415.  
  416.         for(int x=0; x<27; ++x)
  417.         {
  418.             for(int y=0; y<27; ++y)
  419.             {
  420.                 GlobalEraDiffRates[x][y] = t.CalcRoutePreference(&levels[y],&levels[x]);
  421.             }
  422.         }
  423.     }
  424.    
  425.    
  426.  
  427.  
  428.     /*
  429.     int lowest = 999;
  430.     int topseed = 0;
  431.  
  432.     //Find fastest route after [iterations] amount of random tries
  433.     for(int i=0; i<iterations; ++i)
  434.     {
  435.         int l = CalculateRandomRoute(i);
  436.         if(l <= lowest && l > 0)
  437.         {
  438.             lowest = l;
  439.             topseed = i;
  440.             printf("Route seed %d gets rate %d\n", i, l);
  441.         }
  442.     }
  443.     printf("Done.\n\n\n");
  444.  
  445.     //Display fastest found route
  446.     CalculateRandomRoute(topseed, VERBOSE);
  447.     //*/
  448.  
  449.     //First random seed to return fastest route on my rig
  450.     //Fastest route found so far should have a length of 304
  451.     //CalculateRandomRoute(139490435, VERBOSE);
  452.  
  453.     //Calculate and display preset route
  454.     CalculatePresetRoute(PresetRouteArray, VERBOSE);
  455.  
  456.     getchar();
  457.     return 0;
  458. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement