philRG

[Tryout] 2016 FB magus code usage for Sogeti contest

Aug 1st, 2021 (edited)
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 51.33 KB | None | 0 0
  1. //#pragma GCC optimize("-O3")
  2. #pragma GCC optimize("-O0")
  3. #pragma GCC optimize("inline")
  4. #pragma GCC optimize("omit-frame-pointer")
  5. #pragma GCC optimize("unroll-loops")
  6.  
  7. #include <iostream>
  8. #include <chrono>
  9. #include <string>
  10. #include <algorithm>
  11. #include <math.h>
  12.  
  13. using namespace std;
  14. using namespace std::chrono;
  15.  
  16. #define PROFILE
  17. #define PROD
  18. // #define DEBUG
  19.  
  20. #ifdef PROFILE
  21. const int DURATIONS_COUNT = 1;
  22.     double durations[DURATIONS_COUNT];
  23.     high_resolution_clock::time_point starts[DURATIONS_COUNT];
  24.  
  25. #define PS(i)   starts[i] = NOW;
  26. #define PE(i)   durations[i] = durations[i] + duration_cast<duration<double>>(NOW - starts[i]).count();
  27. #else
  28. #define PS(i)
  29. #define PE(i)
  30. #endif
  31.  
  32. high_resolution_clock::time_point start;
  33. #define NOW high_resolution_clock::now()
  34. #define TIME duration_cast<duration<double>>(NOW - start).count()
  35.  
  36. // ***********************************************************
  37. constexpr double WIDTH = 16000.0;
  38. constexpr double HEIGHT = 7500.0;
  39.  
  40. constexpr double E = 0.00001;
  41. constexpr int VERTICAL = 1;
  42. constexpr int HORIZONTAL = 2;
  43. constexpr double INF = 16000 * 16000 + 7500 * 7500;
  44. constexpr int WIZARD = 1;
  45. constexpr int SNAFFLE = 2;
  46. constexpr int BLUDGER = 3;
  47. constexpr int POLE = 4;
  48. constexpr double TO_RAD = M_PI / 180.0;
  49.  
  50. constexpr double ANGLES[] = {0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0, 120.0, 130.0,
  51.                              140.0, 150.0, 160.0, 170.0, 180.0, 190.0, 200.0, 210.0, 220.0, 230.0, 240.0, 250.0, 260.0,
  52.                              270.0, 280.0, 290.0, 300.0, 310.0, 320.0, 330.0, 340.0, 350.0};
  53. constexpr int ANGLES_LENGTH = 36;
  54.  
  55. constexpr int DEPTH = 4;
  56. constexpr int SPELL_DEPTH = 8;
  57. constexpr int POOL = 50;
  58. constexpr double MUTATION = 2;
  59.  
  60. // ***********************************************************
  61.  
  62. double cosAngles[ANGLES_LENGTH];
  63. double sinAngles[ANGLES_LENGTH];
  64.  
  65. int myTeam;
  66. int mana = 0;
  67. int turn = 0;
  68. int myScore = 0;
  69. int hisScore = 0;
  70. double energy = 0;
  71. int depth = 0;
  72.  
  73. int smana;
  74. int smyScore;
  75. int shisScore;
  76.  
  77. class Point;
  78.  
  79. class Unit;
  80.  
  81. class Wizard;
  82.  
  83. class Snaffle;
  84.  
  85. class Bludger;
  86.  
  87. class Spell;
  88.  
  89. class Pole;
  90.  
  91. Wizard *myWizard1;
  92. Wizard *myWizard2;
  93. Wizard *hisWizard1;
  94. Wizard *hisWizard2;
  95. Point *myGoal;
  96. Point *hisGoal;
  97. Point *mid;
  98.  
  99. Unit *units[20];
  100. int unitsFE = 0;
  101.  
  102. Unit *unitsById[24];
  103.  
  104. Snaffle *snaffles[20];
  105. int snafflesFE = 0;
  106.  
  107. Wizard *wizards[4];
  108. Bludger *bludgers[2];
  109. Pole *poles[4];
  110.  
  111. Unit *spellTargets[20];
  112. int spellTargetsFE;
  113.  
  114. bool doLog = false;
  115.  
  116. Spell *spells[4];
  117.  
  118. int victory;
  119.  
  120. // ***********************************************************
  121.  
  122. static unsigned int g_seed;
  123.  
  124. inline void fast_srand(int seed) {
  125.     //Seed the generator
  126.     g_seed = seed;
  127. }
  128.  
  129. inline int fastrand() {
  130.     //fastrand routine returns one integer, similar output value range as C lib.
  131.     g_seed = (214013 * g_seed + 2531011);
  132.     return (g_seed >> 16) & 0x7FFF;
  133. }
  134.  
  135. inline int fastRandInt(int maxSize) {
  136.     return fastrand() % maxSize;
  137. }
  138.  
  139. inline int fastRandInt(int a, int b) {
  140.     return (a + fastRandInt(b - a));
  141. }
  142.  
  143. inline double fastRandDouble() {
  144.     return static_cast<double>(fastrand()) / 0x7FFF;
  145. }
  146.  
  147. inline double fastRandDouble(double a, double b) {
  148.     return a + (static_cast<double>(fastrand()) / 0x7FFF) * (b - a);
  149. }
  150.  
  151. // ****************************************************************************************
  152.  
  153. class Solution {
  154. public:
  155.     double energy;
  156.     int moves1[DEPTH];
  157.     int moves2[DEPTH];
  158.  
  159.     int spellTurn1;
  160.     Unit *spellTarget1;
  161.     int spell1;
  162.  
  163.     int spellTurn2;
  164.     Unit *spellTarget2;
  165.     int spell2;
  166.  
  167.     Solution *merge(Solution *solution) {
  168.         Solution *child = new Solution();
  169.  
  170.         for (int i = 0; i < DEPTH; ++i) {
  171.             if (fastRandInt(2)) {
  172.                 child->moves1[i] = solution->moves1[i];
  173.                 child->moves2[i] = solution->moves2[i];
  174.             } else {
  175.                 child->moves1[i] = moves1[i];
  176.                 child->moves2[i] = moves2[i];
  177.             }
  178.         }
  179.  
  180.         // TEST without Spells
  181. /*        if (fastRandInt(2)) {
  182.             child->spellTurn1 = solution->spellTurn1;
  183.             child->spellTarget1 = solution->spellTarget1;
  184.         } else {
  185.             child->spellTurn1 = spellTurn1;
  186.             child->spellTarget1 = spellTarget1;
  187.         }
  188.  
  189.         if (fastRandInt(2)) {
  190.             child->spellTurn2 = solution->spellTurn2;
  191.             child->spellTarget2 = solution->spellTarget2;
  192.         } else {
  193.             child->spellTurn2 = spellTurn2;
  194.             child->spellTarget2 = spellTarget2;
  195.         }*/
  196.  
  197.         return child;
  198.     }
  199.  
  200.     void copy(Solution *solution) {
  201.         for (int i = 0; i < DEPTH; ++i) {
  202.             moves1[i] = solution->moves1[i];
  203.             moves2[i] = solution->moves2[i];
  204.         }
  205.  
  206.         // TEST without Spells
  207. /*
  208.         spellTurn1 = solution->spellTurn1;
  209.         spellTarget1 = solution->spellTarget1;
  210.         spellTurn2 = solution->spellTurn2;
  211.         spellTarget2 = solution->spellTarget2;*/
  212.  
  213.         this->energy = solution->energy;
  214.     }
  215.  
  216.     void mutate();
  217.  
  218.     void randomize();
  219.  
  220. };
  221.  
  222.  
  223.  
  224. // ****************************************************************************************
  225.  
  226. class Point {
  227. public:
  228.     double x;
  229.     double y;
  230.  
  231.     Point() {};
  232.  
  233.     Point(double x, double y) {
  234.         this->x = x;
  235.         this->y = y;
  236.     }
  237.  
  238. };
  239.  
  240. inline double dist(double x1, double y1, double x2, double y2) {
  241.     return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  242. }
  243.  
  244. inline double dist2(double x1, double y1, double x2, double y2) {
  245.     return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
  246. }
  247.  
  248. inline double dist(Point *p, double x2, double y2) {
  249.     return dist(p->x, p->y, x2, y2);
  250. }
  251.  
  252. inline double dist2(Point *p, double x2, double y2) {
  253.     return dist2(p->x, p->y, x2, y2);
  254. }
  255.  
  256. inline double dist(Point *u1, Point *u2) {
  257.     return dist(u1->x, u1->y, u2->x, u2->y);
  258. }
  259.  
  260. inline double dist2(Point *u1, Point *u2) {
  261.     return dist2(u1->x, u1->y, u2->x, u2->y);
  262. }
  263.  
  264. // ****************************************************************************************
  265.  
  266. class Collision {
  267. public:
  268.     double t;
  269.     int dir;
  270.     Unit *a;
  271.     Unit *b;
  272.  
  273.     Collision() {}
  274.  
  275.     Collision *update(double t, Unit *a, int dir) {
  276.         b = NULL;
  277.         this->t = t;
  278.         this->a = a;
  279.         this->dir = dir;
  280.  
  281.         return this;
  282.     }
  283.  
  284.     Collision *update(double t, Unit *a, Unit *b) {
  285.         dir = 0;
  286.         this->t = t;
  287.         this->a = a;
  288.         this->b = b;
  289.  
  290.         return this;
  291.     }
  292. };
  293.  
  294. Collision **collisionsCache;
  295. int collisionsCacheFE = 0;
  296.  
  297. // ****************************************************************************************
  298.  
  299. class Spell {
  300. public:
  301.     Wizard *caster;
  302.     Unit *target;
  303.  
  304.     Unit *starget;
  305.  
  306.     void cast(Unit *target);
  307.  
  308.     void apply();
  309.  
  310.     void save();
  311.  
  312.     void reset() {
  313.         target = starget;
  314.     }
  315.  
  316.     void reloadTarget();
  317.  
  318.     virtual void effect() {}
  319.  
  320.     virtual void print() {}
  321. };
  322.  
  323. // ****************************************************************************************
  324.  
  325. class Wingardium : public Spell {
  326. public:
  327.     Wingardium(Wizard *caster) {
  328.         this->caster = caster;
  329.     }
  330.  
  331.     virtual void print();
  332.  
  333.     virtual void effect();
  334. };
  335.  
  336. // ****************************************************************************************
  337.  
  338. class Unit : public Point {
  339. public:
  340.     int id;
  341.     int type;
  342.     int state;
  343.     bool dead = false;
  344.     double r;
  345.     double m;
  346.     double f;
  347.     double vx;
  348.     double vy;
  349.  
  350.     double sx;
  351.     double sy;
  352.     double svx;
  353.     double svy;
  354.  
  355.     Wizard *carrier = NULL;
  356.     Snaffle *snaffle = NULL;
  357.  
  358.     int grab = 0;
  359.  
  360. #ifndef PROD
  361.     double lx;
  362.     double ly;
  363.     double lvx;
  364.     double lvy;
  365.     Wizard* lcarrier;
  366.     Snaffle* lsnaffle;
  367.     bool ldead;
  368.  
  369.     void store() {
  370.         lx = x;
  371.         ly = y;
  372.         lvx = vx;
  373.         lvy = vy;
  374.         lcarrier = carrier;
  375.         lsnaffle = snaffle;
  376.         ldead = dead;
  377.     }
  378.  
  379.     void compare();
  380. #endif
  381.  
  382.     void update(int id, int x, int y, int vx, int vy, int state) {
  383.         this->id = id;
  384.         this->x = x;
  385.         this->y = y;
  386.         this->vx = vx;
  387.         this->vy = vy;
  388.         this->state = state;
  389.     }
  390.  
  391.     double speedTo(Point *p) {
  392.         double d = 1.0 / dist(this, x, y);
  393.  
  394.         // vitesse dans la direction du checkpoint - (vitesse orthogonale)^2/dist au cheeckpoint
  395.         double dx = (p->x - this->x) * d;
  396.         double dy = (p->y - this->y) * d;
  397.         double nspeed = vx * dx + vy * dy;
  398.         double ospeed = dy * vx - dx * vy;
  399.  
  400.         return nspeed - (5 * ospeed * ospeed * d);
  401.     }
  402.  
  403.     double speed() {
  404.         return sqrt(vx * vx + vy * vy);
  405.     }
  406.  
  407.     inline void thrust(double thrust, Point *p, double distance) {
  408.         double coef = (thrust / m) / distance;
  409.         vx += (p->x - x) * coef;
  410.         vy += (p->y - y) * coef;
  411.     }
  412.  
  413.     inline void thrust(double thrust, double x, double y, double distance) {
  414.         double coef = (thrust / m) / distance;
  415.         vx += (x - this->x) * coef;
  416.         vy += (y - this->y) * coef;
  417.     }
  418.  
  419.     virtual void move(double t) {
  420.         x += vx * t;
  421.         y += vy * t;
  422.     }
  423.  
  424.     virtual Collision *collision(double from) {
  425.         double tx = 2.0;
  426.         double ty = tx;
  427.  
  428.         if (x + vx < r) {
  429.             tx = (r - x) / vx;
  430.         } else if (x + vx > WIDTH - r) {
  431.             tx = (WIDTH - r - x) / vx;
  432.         }
  433.  
  434.         if (y + vy < r) {
  435.             ty = (r - y) / vy;
  436.         } else if (y + vy > HEIGHT - r) {
  437.             ty = (HEIGHT - r - y) / vy;
  438.         }
  439.  
  440.         int dir;
  441.         double t;
  442.  
  443.         if (tx < ty) {
  444.             dir = HORIZONTAL;
  445.             t = tx + from;
  446.         } else {
  447.             dir = VERTICAL;
  448.             t = ty + from;
  449.         }
  450.  
  451.         if (t <= 0.0 || t > 1.0) {
  452.             return NULL;
  453.         }
  454.  
  455.         return collisionsCache[collisionsCacheFE++]->update(t, this, dir);
  456.     }
  457.  
  458.     virtual Collision *collision(Unit *u, double from) {
  459.         double x2 = x - u->x;
  460.         double y2 = y - u->y;
  461.         double r2 = r + u->r;
  462.         double vx2 = vx - u->vx;
  463.         double vy2 = vy - u->vy;
  464.         double a = vx2 * vx2 + vy2 * vy2;
  465.  
  466.         if (a < E) {
  467.             return NULL;
  468.         }
  469.  
  470.         double b = -2.0 * (x2 * vx2 + y2 * vy2);
  471.         double delta = b * b - 4.0 * a * (x2 * x2 + y2 * y2 - r2 * r2);
  472.  
  473.         if (delta < 0.0) {
  474.             return NULL;
  475.         }
  476.  
  477.         // double sqrtDelta = sqrt(delta);
  478.         // double d = 1.0/(2.0*a);
  479.         // double t1 = (b + sqrtDelta)*d;
  480.         // double t2 = (b - sqrtDelta)*d;
  481.         // double t = t1 < t2 ? t1 : t2;
  482.  
  483.         double t = (b - sqrt(delta)) * (1.0 / (2.0 * a));
  484.  
  485.         if (t <= 0.0) {
  486.             return NULL;
  487.         }
  488.  
  489.         t += from;
  490.  
  491.         if (t > 1.0) {
  492.             return NULL;
  493.         }
  494.  
  495.         return collisionsCache[collisionsCacheFE++]->update(t, this, u);
  496.     }
  497.  
  498.     virtual void bounce(Unit *u) {
  499.         double mcoeff = (m + u->m) / (m * u->m);
  500.         double nx = x - u->x;
  501.         double ny = y - u->y;
  502.         double nxnydeux = nx * nx + ny * ny;
  503.         double dvx = vx - u->vx;
  504.         double dvy = vy - u->vy;
  505.         double product = (nx * dvx + ny * dvy) / (nxnydeux * mcoeff);
  506.         double fx = nx * product;
  507.         double fy = ny * product;
  508.         double m1c = 1.0 / m;
  509.         double m2c = 1.0 / u->m;
  510.  
  511.         vx -= fx * m1c;
  512.         vy -= fy * m1c;
  513.         u->vx += fx * m2c;
  514.         u->vy += fy * m2c;
  515.  
  516.         // Normalize vector at 100
  517.         double impulse = sqrt(fx * fx + fy * fy);
  518.         if (impulse < 100.0) {
  519.             double min = 100.0 / impulse;
  520.             fx = fx * min;
  521.             fy = fy * min;
  522.         }
  523.  
  524.         vx -= fx * m1c;
  525.         vy -= fy * m1c;
  526.         u->vx += fx * m2c;
  527.         u->vy += fy * m2c;
  528.     }
  529.  
  530.     virtual void bounce(int dir) {
  531.         if (dir == HORIZONTAL) {
  532.             vx = -vx;
  533.         } else {
  534.             vy = -vy;
  535.         }
  536.     }
  537.  
  538.     virtual void end() {
  539.         x = round(x);
  540.         y = round(y);
  541.         vx = round(vx * f);
  542.         vy = round(vy * f);
  543.     }
  544.  
  545.     bool can(Unit *u) {
  546.         if (type == SNAFFLE) {
  547.             return !carrier && !dead && !u->snaffle && !u->grab;
  548.         } else if (u->type == SNAFFLE) {
  549.             return !u->carrier && !u->dead && !snaffle && !grab;
  550.         }
  551.  
  552.         return true;
  553.     }
  554.  
  555.     virtual void print() {}
  556.  
  557.     virtual void save() {
  558.         sx = x;
  559.         sy = y;
  560.         svx = vx;
  561.         svy = vy;
  562.     }
  563.  
  564.     virtual void reset() {
  565.         x = sx;
  566.         y = sy;
  567.         vx = svx;
  568.         vy = svy;
  569.     }
  570. };
  571.  
  572. // ****************************************************************************************
  573. class Pole : public Unit {
  574. public:
  575.  
  576.     Pole(int id, double x, double y) {
  577.         this->id = id;
  578.         r = 300;
  579.         m = INF;
  580.         type = POLE;
  581.         this->x = x;
  582.         this->y = y;
  583.         vx = 0;
  584.         vy = 0;
  585.         dead = false;
  586.         f = 0.0;
  587.     }
  588.  
  589.     virtual void move(double t) {}
  590.  
  591.     virtual void save() {}
  592.  
  593.     virtual void reset() {}
  594.  
  595.     virtual Collision *collision(double from) {
  596.         return NULL;
  597.     }
  598. };
  599.  
  600. // ****************************************************************************************
  601.  
  602. class Wizard : public Unit {
  603. public:
  604.     int team;
  605.     Spell *spell;
  606.  
  607.     int sgrab;
  608.     Snaffle *ssnaffle;
  609.  
  610.     Unit *spellTarget;
  611.  
  612.     Wizard(int team) {
  613.         this->team = team;
  614.         this->r = 400.0;
  615.         this->m = 1;
  616.         this->f = 0.75;
  617.  
  618.         snaffle = NULL;
  619.         grab = 0;
  620.         type = WIZARD;
  621.  
  622.         spell = new Wingardium(this);
  623.  
  624.         spellTarget = NULL;
  625.     }
  626.  
  627.     inline void grabSnaffle(Snaffle *snaffle);
  628.  
  629.     void apply(int move);
  630.  
  631.     void output(int move, int spellTurn, Unit *target) {
  632.         spellTurn = true; // added for debug
  633.         if (!spellTurn) {
  634.             cout << "WINGARDIUM " << target->id << " " << myGoal->x << " " << myGoal->y << endl;
  635.             return;
  636.         }
  637.  
  638.         // Adjust the targeted point for this angle
  639.         // Find a point with the good angle
  640.         double px = x + cosAngles[move] * 10000.0;
  641.         double py = y + sinAngles[move] * 10000.0;
  642.  
  643.         if (snaffle) {
  644.             cout << "THROW " << round(px) << " " << round(py) << " 500";
  645.         } else {
  646.             cout << "MOVE " << round(px) << " " << round(py) << " 150";
  647.         }
  648.  
  649.         cout << endl;
  650.         // cerr << "output wizard team #" << team << endl;
  651.     }
  652.  
  653.     bool cast(Unit *target) {
  654.         if (target->dead) {
  655.             return false;
  656.         }
  657.  
  658.         spellTarget = target;
  659.  
  660.         return true;
  661.     }
  662.  
  663.     virtual Collision *collision(Unit *u, double from) {
  664.         if (u->type == SNAFFLE) {
  665.             u->r = -1.0;
  666.             Collision *result = Unit::collision(u, from);
  667.             u->r = 150.0;
  668.  
  669.             return result;
  670.         } else {
  671.             return Unit::collision(u, from);
  672.         }
  673.     }
  674.  
  675.     virtual void bounce(Unit *u);
  676.  
  677.     void play();
  678.  
  679.     virtual void end();
  680.  
  681.     virtual void save() {
  682.         Unit::save();
  683.  
  684.         sgrab = grab;
  685.         ssnaffle = snaffle;
  686.     }
  687.  
  688.     virtual void reset() {
  689.         Unit::reset();
  690.  
  691.         grab = sgrab;
  692.         snaffle = ssnaffle;
  693.     }
  694.  
  695.     virtual void print();
  696.  
  697.     void updateSnaffle();
  698.  
  699.     void apply(Solution *solution, int turn, int index) {
  700.         if (index == 1) {
  701.             if (solution->spellTurn1 == turn) {
  702.                 if (!myWizard1->cast(solution->spellTarget1)) {
  703.                     myWizard1->apply(solution->moves1[turn]);
  704.                 }
  705.             } else {
  706.                 myWizard1->apply(solution->moves1[turn]);
  707.             }
  708.         } else {
  709.             if (solution->spellTurn2 == turn) {
  710.                 if (!myWizard2->cast(solution->spellTarget2)) {
  711.                     myWizard2->apply(solution->moves2[turn]);
  712.                 }
  713.             } else {
  714.                 myWizard2->apply(solution->moves2[turn]);
  715.             }
  716.         }
  717.     }
  718. };
  719.  
  720. // ****************************************************************************************
  721.  
  722. class Snaffle : public Unit {
  723. public:
  724.     Wizard *scarrier;
  725.  
  726.  
  727.     Snaffle() {
  728.         this->r = 150.0;
  729.         this->m = 0.5;
  730.         this->f = 0.75;
  731.  
  732.         carrier = NULL;
  733.         type = SNAFFLE;
  734.     }
  735.  
  736.     virtual Collision *collision(double from) {
  737.         if (carrier || dead) {
  738.             return NULL;
  739.         }
  740.  
  741.         double tx = 2.0;
  742.         double ty = tx;
  743.  
  744.         if (x + vx < 0.0) {
  745.             tx = -x / vx;
  746.         } else if (x + vx > WIDTH) {
  747.             tx = (WIDTH - x) / vx;
  748.         }
  749.  
  750.         if (y + vy < r) {
  751.             ty = (r - y) / vy;
  752.         } else if (y + vy > HEIGHT - r) {
  753.             ty = (HEIGHT - r - y) / vy;
  754.         }
  755.  
  756.         int dir;
  757.         double t;
  758.  
  759.         if (tx < ty) {
  760.             dir = HORIZONTAL;
  761.             t = tx + from;
  762.         } else {
  763.             dir = VERTICAL;
  764.             t = ty + from;
  765.         }
  766.  
  767.         if (t <= 0.0 || t > 1.0) {
  768.             return NULL;
  769.         }
  770.  
  771.         return collisionsCache[collisionsCacheFE++]->update(t, this, dir);
  772.     }
  773.  
  774.     virtual Collision *collision(Unit *u, double from) {
  775.         if (u->type == WIZARD) {
  776.             r = -1.0;
  777.             Collision *result = Unit::collision(u, from);
  778.             r = 150.0;
  779.  
  780.             return result;
  781.         } else {
  782.             return Unit::collision(u, from);
  783.         }
  784.     }
  785.  
  786.     virtual void bounce(Unit *u) {
  787.         if (u->type == WIZARD) {
  788.             Wizard *target = (Wizard *) u;
  789.             if (!target->snaffle && !target->grab && !dead && !carrier) {
  790.                 target->grabSnaffle(this);
  791.             }
  792.         } else {
  793.             Unit::bounce(u);
  794.         }
  795.     }
  796.  
  797.     virtual void bounce(int dir) {
  798.         if (dir == HORIZONTAL && y >= 1899.0 && y <= 5599.0) {
  799.             dead = true;
  800.  
  801.             if (!myTeam) {
  802.                 if (x > 8000) {
  803.                     myScore += 1;
  804.                 } else {
  805.                     hisScore += 1;
  806.                 }
  807.             } else {
  808.                 if (x > 8000) {
  809.                     hisScore += 1;
  810.                 } else {
  811.                     myScore += 1;
  812.                 }
  813.             }
  814.         } else {
  815.             Unit::bounce(dir);
  816.         }
  817.     }
  818.  
  819.     virtual void move(double t) {
  820.         if (!dead && !carrier) {
  821.             Unit::move(t);
  822.         }
  823.     }
  824.  
  825.     virtual void end() {
  826.         if (!dead && !carrier) {
  827.             Unit::end();
  828.         }
  829.     }
  830.  
  831.     virtual void save() {
  832.         Unit::save();
  833.  
  834.         scarrier = carrier;
  835.     }
  836.  
  837.     virtual void reset() {
  838.         Unit::reset();
  839.  
  840.         carrier = scarrier;
  841.         dead = false;
  842.     }
  843.  
  844.     virtual void print() {
  845.         if (dead) {
  846.             cerr << "Snaffle " << id << " dead";
  847.         } else {
  848.             cerr << "Snaffle " << id << " " << x << " " << y << " " << vx << " " << vy << " " << speed() << " "
  849.                  << " | ";
  850.  
  851.             if (carrier) {
  852.                 cerr << "Carrier " << carrier->id << " | ";
  853.             }
  854.         }
  855.  
  856.         cerr << endl;
  857.     }
  858. };
  859.  
  860. // ****************************************************************************************
  861.  
  862. class Bludger : public Unit {
  863. public:
  864.     Wizard *last;
  865.     int ignore[2];
  866.  
  867.     Wizard *slast;
  868.  
  869.     Bludger() {
  870.         this->r = 200.0;
  871.         this->m = 8;
  872.         this->f = 0.9;
  873.  
  874.         last = NULL;
  875.         ignore[0] = -1;
  876.         ignore[1] = -1;
  877.         type = BLUDGER;
  878.     }
  879.  
  880.     virtual void print() {
  881.         cerr << "Bludger " << id << " " << x << " " << y << " " << vx << " " << vy << " " << speed() << " " << ignore[0]
  882.              << " " << ignore[1] << " | ";
  883.  
  884.         if (last) {
  885.             cerr << "Last " << last->id << " | ";
  886.         }
  887.  
  888.         cerr << endl;
  889.     }
  890.  
  891.     virtual void save() {
  892.         Unit::save();
  893.  
  894.         slast = last;
  895.     }
  896.  
  897.     virtual void reset() {
  898.         Unit::reset();
  899.  
  900.         last = slast;
  901.         ignore[0] = -1;
  902.         ignore[1] = -1;
  903.     }
  904.  
  905.     virtual void bounce(Unit *u) {
  906.         if (u->type == WIZARD) {
  907.             last = (Wizard *) u;
  908.         }
  909.  
  910.         Unit::bounce(u);
  911.     }
  912.  
  913.     void play() {
  914.         // Find our target
  915.         Wizard *target = NULL;
  916.         double d;
  917.  
  918.         for (int i = 0; i < 4; ++i) {
  919.             Wizard *wizard = wizards[i];
  920.  
  921.             if ((last && last->id == wizard->id) || wizard->team == ignore[0] || wizard->team == ignore[1]) {
  922.                 continue;
  923.             }
  924.  
  925.             double d2 = dist2(this, wizard);
  926.  
  927.             if (!target || d2 < d) {
  928.                 d = d2;
  929.                 target = wizard;
  930.             }
  931.         }
  932.  
  933.         if (target) {
  934.             thrust(1000.0, target, sqrt(d));
  935.         }
  936.  
  937.         ignore[0] = -1;
  938.         ignore[1] = -1;
  939.     }
  940. };
  941.  
  942. // ****************************************************************************************
  943.  
  944. void Wingardium::print() {
  945.     if (target != NULL)
  946.         cerr << "Wingardium " << target->id << endl;
  947.     else
  948.         cerr << "No target defined for spell Windardium!! " << endl;
  949. }
  950.  
  951. void Spell::cast(Unit *target) {
  952.     this->target = target;
  953. }
  954.  
  955. void Spell::apply() {
  956.     if (!target->dead)
  957.         effect();
  958. }
  959.  
  960. void Spell::reloadTarget() {
  961.     if (target->dead) {
  962.         // Cancel the spell
  963.         target = NULL;
  964.     }
  965. }
  966.  
  967. void Spell::save() {
  968.     starget = target;
  969. }
  970.  
  971. void Wingardium::effect() {
  972.     ((Bludger *) target)->ignore[caster->team] = caster->team;
  973. }
  974. /*
  975. void Petrificus::effect() {
  976.     target->vx = 0.0;
  977.     target->vy = 0.0;
  978. }
  979.  
  980. void Accio::effect() {
  981.     double d = dist(caster, target);
  982.  
  983.     if (d < 10.0) {
  984.         return;
  985.     }
  986.  
  987.     double dcoef = d*0.001;
  988.     double power = 3000.0 / (dcoef*dcoef);
  989.  
  990.     if (power > 1000.0) {
  991.         power = 1000.0;
  992.     }
  993.  
  994.     dcoef = 1.0 / d;
  995.     power = power / target->m;
  996.     target->vx -= dcoef * power * (target->x - caster->x);
  997.     target->vy -= dcoef * power * (target->y - caster->y);
  998. }
  999.  
  1000. void Flipendo::effect() {
  1001.     double d = dist(caster, target);
  1002.  
  1003.     if (d < 10.0) {
  1004.         return;
  1005.     }
  1006.  
  1007.     double dcoef = d*0.001;
  1008.     double power = 6000.0 / (dcoef*dcoef);
  1009.  
  1010.     if (power > 1000.0) {
  1011.         power = 1000.0;
  1012.     }
  1013.  
  1014.     dcoef = 1.0 / d;
  1015.     power = power / target->m;
  1016.     target->vx += dcoef * power * (target->x - caster->x);
  1017.     target->vy += dcoef * power * (target->y - caster->y);
  1018. }*/
  1019.  
  1020. // ****************************************************************************************
  1021.  
  1022. #ifndef PROD
  1023. void Unit::compare() {
  1024.     if (lx != x || ly != y || lvx != vx || lvy != vy || lcarrier != carrier || lsnaffle != snaffle || ldead != dead) {
  1025.         cerr << "Diff " << id << " : "
  1026.              << (x - lx) << " "
  1027.              << (y - ly) << " "
  1028.              << dist(x, y, lx, ly) << " | "
  1029.              << (vx - lvx) << " "
  1030.              << (vy - lvy) << " "
  1031.              << (speed() - sqrt(lvx*lvx + lvy*lvy)) << " | "
  1032.              << carrier << " " << lcarrier << " | "
  1033.              << snaffle << " " << lsnaffle << " | ";
  1034.  
  1035.         if (ldead) {
  1036.             cerr << "dead";
  1037.         }
  1038.  
  1039.         cerr << endl;
  1040.     }
  1041. }
  1042. #endif
  1043.  
  1044. void Wizard::print() {
  1045.     cerr << "Wizard " << id << " " << x << " " << y << " " << vx << " " << vy << " " << speed() << " " << grab << " | ";
  1046.  
  1047.     if (snaffle) {
  1048.         cerr << "Snaffle " << snaffle->id << " | ";
  1049.     }
  1050.  
  1051. //    for (int i = 0; i < 4; ++i) {
  1052. //        spells[i]->print();
  1053. //    }
  1054.  
  1055.     cerr << endl;
  1056. }
  1057.  
  1058. void Wizard::updateSnaffle() {
  1059.     if (state) {
  1060.         for (int i = 0; i < snafflesFE; ++i) {
  1061.             Snaffle *snaffle = snaffles[i];
  1062.  
  1063.             if (snaffle->x == x && snaffle->y == y && snaffle->vx == vx && snaffle->vy == vy) {
  1064.                 this->snaffle = snaffle;
  1065.                 snaffle->carrier = this;
  1066.             }
  1067.         }
  1068.  
  1069.         grab = 3;
  1070.     } else {
  1071.         if (grab) {
  1072.             grab -= 1;
  1073.         }
  1074.         snaffle = NULL;
  1075.     }
  1076. }
  1077.  
  1078. void Wizard::play() {
  1079.     // Relacher le snaffle qu'on porte dans tous les cas
  1080.     if (snaffle) {
  1081.         snaffle->carrier = NULL;
  1082.         snaffle = NULL;
  1083.     }
  1084. }
  1085.  
  1086. void Wizard::end() {
  1087.     Unit::end();
  1088.  
  1089.     if (grab) {
  1090.         grab -= 1;
  1091.  
  1092.         if (!grab) {
  1093.             // Check if we can grab a snaffle
  1094.             for (int i = 0; i < snafflesFE; ++i) {
  1095.                 Snaffle *snaffle = snaffles[i];
  1096.  
  1097.                 if (!snaffle->dead && !snaffle->carrier && dist2(this, snaffle) < 159201.0) {
  1098.                     grabSnaffle(snaffle);
  1099.                     break;
  1100.                 }
  1101.             }
  1102.         }
  1103.     }
  1104.  
  1105.     if (snaffle) {
  1106.         snaffle->x = x;
  1107.         snaffle->y = y;
  1108.         snaffle->vx = vx;
  1109.         snaffle->vy = vy;
  1110.     }
  1111.  
  1112.     if (spellTarget) {
  1113.         spell->cast(spellTarget);
  1114.         spellTarget = NULL;
  1115.     }
  1116. }
  1117.  
  1118. void Wizard::bounce(Unit *u) {
  1119.     if (u->type == SNAFFLE) {
  1120.         Snaffle *target = (Snaffle *) u;
  1121.         if (!snaffle && !grab && !target->dead && !target->carrier) {
  1122.             grabSnaffle(target);
  1123.         }
  1124.     } else {
  1125.         if (u->type == BLUDGER) {
  1126.             ((Bludger *) u)->last = this;
  1127.         }
  1128.  
  1129.         Unit::bounce(u);
  1130.     }
  1131. }
  1132.  
  1133. inline void Wizard::grabSnaffle(Snaffle *snaffle) {
  1134.     grab = 4;
  1135.     snaffle->carrier = this;
  1136.     this->snaffle = snaffle;
  1137.  
  1138. }
  1139.  
  1140. void Wizard::apply(int move) {
  1141. #ifdef DEBUG
  1142.     cerr << "DEBUG 5 : Wizard::apply" <<endl;
  1143. #endif
  1144.     if (snaffle) {
  1145.         double coef = 500.0 * (1.0 / snaffle->m);
  1146.         snaffle->vx += cosAngles[move] * coef;
  1147.         snaffle->vy += sinAngles[move] * coef;
  1148.     } else {
  1149.         vx += cosAngles[move] * 150.0;
  1150.         vy += sinAngles[move] * 150.0;
  1151.     }
  1152. }
  1153.  
  1154. void Solution::mutate() {
  1155.     // TEST WITHOUT SPELLS
  1156.     int r = fastRandInt(2);
  1157. //    int r = fastRandInt(4);
  1158.  
  1159.     if (!r) {
  1160.         // Change a moves1
  1161.         moves1[fastRandInt(DEPTH)] = fastRandInt(ANGLES_LENGTH);
  1162.     } else if (r == 1) {
  1163.         // Change a moves2
  1164.         moves2[fastRandInt(DEPTH)] = fastRandInt(ANGLES_LENGTH);
  1165.     } else if (r == 2) {
  1166.         // Change spell1
  1167.         spellTurn1 = fastRandInt(SPELL_DEPTH);
  1168.         spellTarget1 = spellTargets[fastRandInt(spellTargetsFE)];
  1169.     } else {
  1170.         // Change spell2
  1171.         spellTurn2 = fastRandInt(SPELL_DEPTH);
  1172.         spellTarget2 = spellTargets[fastRandInt(spellTargetsFE)];
  1173.         spellTarget2->speed();
  1174.     }
  1175.  
  1176. }
  1177.  
  1178. void Solution::randomize() {
  1179.     for (int i = 0; i < DEPTH; ++i) {
  1180.         moves1[i] = fastRandInt(ANGLES_LENGTH);
  1181.         moves2[i] = fastRandInt(ANGLES_LENGTH);
  1182. //        cerr << "moves1 -> " << moves1[i] <<endl;
  1183. //        cerr << "moves2 -> " << moves2[i] <<endl;
  1184.     }
  1185.  
  1186.     // TEST WITHOUT SPELLS
  1187. /*    spellTurn1 = fastRandInt(SPELL_DEPTH);
  1188.     spellTarget1 = spellTargets[fastRandInt(spellTargetsFE)];
  1189.     spellTurn2 = fastRandInt(SPELL_DEPTH);
  1190.     spellTarget2 = spellTargets[fastRandInt(spellTargetsFE)];*/
  1191.  
  1192. }
  1193.  
  1194. // ****************************************************************************************
  1195.  
  1196. bool mustErase(Collision *col, Unit *a, Unit *b) {
  1197.     if (a->id == col->a->id) {
  1198.         return true;
  1199.     }
  1200.  
  1201.     if (b != NULL && col->b != NULL) {
  1202.         if (a->id == col->b->id
  1203.             || b->id == col->a->id
  1204.             || b->id == col->b->id) {
  1205.             return true;
  1206.         }
  1207.     } else if (b != NULL) {
  1208.         if (b->id == col->a->id) {
  1209.             return true;
  1210.         }
  1211.     } else if (col->b != NULL) {
  1212.         if (a->id == col->b->id) {
  1213.             return true;
  1214.         }
  1215.     }
  1216.  
  1217.     return false;
  1218. }
  1219.  
  1220. Collision **collisions;
  1221. int collisionsFE = 0;
  1222.  
  1223. Collision **tempCollisions;
  1224. int tempCollisionsFE = 0;
  1225.  
  1226. Collision *fake;
  1227.  
  1228. void move() {
  1229.     double t = 0.0;
  1230.     double delta;
  1231.  
  1232.     Collision *next = fake;
  1233.     collisionsCacheFE = 0;
  1234.     collisionsFE = 0;
  1235.     tempCollisionsFE = 0;
  1236.  
  1237.     Collision *col;
  1238.     Unit *a;
  1239.     Unit *b;
  1240.     Unit *u;
  1241.     int i, j;
  1242.  
  1243.     // Get first collisions
  1244.     for (i = 0; i < unitsFE; ++i) {
  1245.         a = units[i];
  1246.  
  1247.         col = a->collision(t);
  1248.  
  1249.         if (col) {
  1250.             collisions[collisionsFE++] = col;
  1251.  
  1252.             if (col->t < next->t) {
  1253.                 next = col;
  1254.             }
  1255.         }
  1256.  
  1257.         for (j = i + 1; j < unitsFE; ++j) {
  1258.             b = units[j];
  1259.  
  1260.             if (a->can(b)) {
  1261.                 col = a->collision(b, t);
  1262.  
  1263.                 if (col) {
  1264.                     collisions[collisionsFE++] = col;
  1265.  
  1266.                     if (col->t < next->t) {
  1267.                         next = col;
  1268.                     }
  1269.                 }
  1270.             }
  1271.         }
  1272.     }
  1273.  
  1274.     while (t < 1.0) {
  1275.         if (next == fake) {
  1276.             for (i = 0; i < unitsFE; ++i) {
  1277.                 units[i]->move(1.0 - t);
  1278.             }
  1279.  
  1280.             break;
  1281.         } else {
  1282.             // Move to the collision time
  1283.             delta = next->t - t;
  1284.             for (i = 0; i < unitsFE; ++i) {
  1285.                 units[i]->move(delta);
  1286.             }
  1287.  
  1288.             t = next->t;
  1289.  
  1290.             if (next->dir) {
  1291.                 /*if (doLog) {
  1292.                     cerr << next->a->id << " bounce with wall at " << t << endl;
  1293.                 }*/
  1294.                 next->a->bounce(next->dir);
  1295.             } else {
  1296.                 /*if (doLog) {
  1297.                     cerr << next->a->id << " bounce with " << next->b->id << " at " << t << endl;
  1298.                 }*/
  1299.                 next->a->bounce(next->b);
  1300.             }
  1301.  
  1302.             a = next->a;
  1303.             b = next->b;
  1304.  
  1305.             // Invalid previous collisions for the concerned units and get new ones
  1306.             next = fake;
  1307.  
  1308.             for (i = 0; i < collisionsFE; ++i) {
  1309.                 col = collisions[i];
  1310.  
  1311.                 if (!mustErase(col, a, b)) {
  1312.                     if (col->t < next->t) {
  1313.                         next = col;
  1314.                     }
  1315.  
  1316.                     tempCollisions[tempCollisionsFE++] = col;
  1317.                 }
  1318.             }
  1319.  
  1320.             Collision **temp = tempCollisions;
  1321.             tempCollisions = collisions;
  1322.             collisions = temp;
  1323.  
  1324.             collisionsFE = tempCollisionsFE;
  1325.             tempCollisionsFE = 0;
  1326.  
  1327.             // Find new collisions for a
  1328.             col = a->collision(t);
  1329.             if (col) {
  1330.                 collisions[collisionsFE++] = col;
  1331.  
  1332.                 if (col->t < next->t) {
  1333.                     next = col;
  1334.                 }
  1335.             }
  1336.  
  1337.             for (i = 0; i < unitsFE; ++i) {
  1338.                 u = units[i];
  1339.  
  1340.                 if (a->id != u->id && a->can(u)) {
  1341.                     col = a->collision(u, t);
  1342.  
  1343.                     if (col) {
  1344.                         collisions[collisionsFE++] = col;
  1345.  
  1346.                         if (col->t < next->t) {
  1347.                             next = col;
  1348.                         }
  1349.                     }
  1350.                 }
  1351.             }
  1352.  
  1353.             // Find new collisions for b
  1354.             if (b) {
  1355.                 col = b->collision(t);
  1356.  
  1357.                 if (col) {
  1358.                     collisions[collisionsFE++] = col;
  1359.  
  1360.                     if (col->t < next->t) {
  1361.                         next = col;
  1362.                     }
  1363.                 }
  1364.  
  1365.                 for (i = 0; i < unitsFE; ++i) {
  1366.                     u = units[i];
  1367.  
  1368.                     if (b->id != u->id && b->can(u)) {
  1369.                         col = b->collision(u, t);
  1370.  
  1371.                         if (col) {
  1372.                             collisions[collisionsFE++] = col;
  1373.  
  1374.                             if (col->t < next->t) {
  1375.                                 next = col;
  1376.                             }
  1377.                         }
  1378.                     }
  1379.                 }
  1380.             }
  1381.         }
  1382.     }
  1383. }
  1384.  
  1385. void play() {
  1386.     // TEST WITHOUT SPELLS
  1387.  
  1388. /*    for (int i = 0; i < 4; ++i) {
  1389.         if (spells[i] != NULL)
  1390.             spells[i]->apply();
  1391.         else
  1392.             cerr << "play() method wizard " << i << ": no target defined for spell Windardium!! " <<endl;
  1393.     }*/
  1394.  
  1395.     bludgers[0]->play();
  1396.     bludgers[1]->play();
  1397.     wizards[0]->play();
  1398.     wizards[1]->play();
  1399.     wizards[2]->play();
  1400.     wizards[3]->play();
  1401.  
  1402.  
  1403.     move();
  1404.  
  1405.     for (int i = 0; i < unitsFE; ++i) {
  1406.         units[i]->end();
  1407.     }
  1408.  
  1409.     if (mana != 100) {
  1410.         mana += 1;
  1411.     }
  1412. }
  1413.  
  1414. double eval() {
  1415.     // Hidden ;)
  1416.     int score = 0;
  1417.     for (int i = 0; i < snafflesFE; ++i) {
  1418.         if (!snaffles[i]->dead) {
  1419.             score -= dist(snaffles[i], myGoal);
  1420.         }
  1421.     }
  1422.     return score;
  1423. }
  1424.  
  1425. void reset() {
  1426.     for (int i = 0; i < unitsFE; ++i) {
  1427.         units[i]->reset();
  1428.     }
  1429.     // TEST WITHOUT SPELLS
  1430. /*    for (int i = 0; i < 4; ++i) {
  1431.         spells[i]->reset();
  1432.     }*/
  1433.  
  1434.     mana = smana;
  1435.     myScore = smyScore;
  1436.     hisScore = shisScore;
  1437. }
  1438.  
  1439. void dummies() {
  1440.     if (hisWizard1->snaffle) {
  1441.         hisWizard1->snaffle->thrust(500.0, hisGoal, dist(hisWizard1, hisGoal));
  1442.     } else {
  1443.         Snaffle *target = NULL;
  1444.         double targetD = INF;
  1445.         double d;
  1446.  
  1447.         for (int i = 0; i < snafflesFE; ++i) {
  1448.             Snaffle *snaffle = snaffles[i];
  1449.  
  1450.             if (!snaffle->dead) {
  1451.                 d = dist2(hisWizard1, snaffle);
  1452.  
  1453.                 if (d < targetD) {
  1454.                     targetD = d;
  1455.                     target = snaffle;
  1456.                 }
  1457.             }
  1458.         }
  1459.  
  1460.         if (target) {
  1461.             hisWizard1->thrust(150.0, target, sqrt(targetD));
  1462.         }
  1463.     }
  1464.  
  1465.     if (hisWizard2->snaffle) {
  1466.         hisWizard2->snaffle->thrust(500.0, hisGoal, dist(hisWizard2, hisGoal));
  1467.     } else {
  1468.         Snaffle *target = NULL;
  1469.         double targetD = INF;
  1470.         double d;
  1471.  
  1472.         for (int i = 0; i < snafflesFE; ++i) {
  1473.             Snaffle *snaffle = snaffles[i];
  1474.  
  1475.             if (!snaffle->dead) {
  1476.                 d = dist2(hisWizard2, snaffle);
  1477.  
  1478.                 if (d < targetD) {
  1479.                     targetD = d;
  1480.                     target = snaffle;
  1481.                 }
  1482.             }
  1483.         }
  1484.  
  1485.         if (target) {
  1486.             hisWizard2->thrust(150.0, target, sqrt(targetD));
  1487.         }
  1488.     }
  1489. }
  1490.  
  1491. void simulate(Solution *solution) {
  1492.     energy = 0;
  1493.     depth = 0;
  1494.  
  1495. //    myWizard1->apply(solution, 0, 1);
  1496. //    myWizard2->apply(solution, 0, 2);
  1497. //    myWizard1->apply(solution->);
  1498. //    myWizard2->apply(solution->moves2);
  1499. //    dummies();
  1500.  
  1501. #ifdef DEBUG
  1502.     cerr << "DEBUG 5 : simulate" <<endl;
  1503. #endif
  1504.     play();
  1505.     depth = 1;
  1506.  
  1507.     solution->energy = eval() * 0.1;
  1508.  
  1509.     for (int i = 0; i < DEPTH; ++i) {
  1510. //        myWizard1->apply(solution, i, 1);
  1511. //        myWizard2->apply(solution, i, 2);
  1512.         myWizard1->apply(solution->moves1[i]);
  1513.         myWizard2->apply(solution->moves2[i]);
  1514.         dummies();
  1515.  
  1516.         play();
  1517.         depth += 1;
  1518.     }
  1519.  
  1520.     solution->energy += energy + eval();
  1521.  
  1522.     reset();
  1523. }
  1524.  
  1525. void simulate2(Solution *solution) {
  1526.     doLog = true;
  1527.  
  1528.     cerr << "Solution: " << endl;
  1529.     for (int i = 0; i < DEPTH; ++i) {
  1530.         cerr << ANGLES[solution->moves1[i]] << " " << ANGLES[solution->moves2[i]] << endl;
  1531.     }
  1532.     // TEST WITHOUT SPELLS
  1533. /*    cerr << "Spell 1: " << solution->spellTurn1 << " " << solution->spell1 << " " << solution->spellTarget1->id << endl;
  1534.     cerr << "Spell 2: " << solution->spellTurn2 << " " << solution->spell2 << " " << solution->spellTarget2->id << endl;*/
  1535.  
  1536.     energy = 0;
  1537.     depth = 0;
  1538.  
  1539. //    myWizard1->apply(solution, 0, 1);
  1540. //    myWizard2->apply(solution, 0, 2);
  1541.     myWizard1->apply(solution->moves1[0]);
  1542.     myWizard2->apply(solution->moves2[0]);
  1543.     dummies();
  1544.  
  1545.     play();
  1546.  
  1547.     cerr << "******* State at turn " << depth + 1 << endl;
  1548.     for (int i = 0; i < unitsFE; ++i) {
  1549.         units[i]->print();
  1550.     }
  1551.     depth = 1;
  1552.  
  1553.     solution->energy = eval() * 0.1;
  1554.  
  1555.     for (int i = 0; i < DEPTH; ++i) {
  1556. //        myWizard1->apply(solution, i, 1);
  1557. //        myWizard2->apply(solution, i, 2);
  1558.         myWizard1->apply(solution->moves1[i]);
  1559.         myWizard1->apply(solution->moves2[i]);
  1560.         dummies();
  1561.  
  1562.         play();
  1563.  
  1564.         cerr << "******* State at turn " << depth + 1 << endl;
  1565.         for (int i = 0; i < unitsFE; ++i) {
  1566.             units[i]->print();
  1567.         }
  1568.         depth += 1;
  1569.     }
  1570.  
  1571.     solution->energy += energy + eval();
  1572.  
  1573.     cerr << "Sanity check : " << solution->energy << endl;
  1574.     cerr << "Mana: " << mana << endl;
  1575.     cerr << "My score: " << myScore << endl;
  1576.     cerr << "His score: " << hisScore << endl;
  1577.  
  1578.     reset();
  1579.  
  1580.     doLog = false;
  1581. }
  1582.  
  1583. // ****************************************************************************************
  1584.  
  1585. int main() {
  1586.     fast_srand(42);
  1587.  
  1588.     fake = new Collision();
  1589.     fake->t = 1000.0;
  1590.  
  1591.     for (int i = 0; i < ANGLES_LENGTH; ++i) {
  1592.         cosAngles[i] = cos(ANGLES[i] * TO_RAD);
  1593.         sinAngles[i] = sin(ANGLES[i] * TO_RAD);
  1594.     }
  1595.  
  1596.     cin >> myTeam;
  1597.     cin.ignore();
  1598.     cerr << myTeam << endl;
  1599.  
  1600.     collisionsCache = new Collision *[100];
  1601.     collisions = new Collision *[100];
  1602.     tempCollisions = new Collision *[100];
  1603.  
  1604.     for (int i = 0; i < 100; ++i) {
  1605.         collisionsCache[i] = new Collision();
  1606.     }
  1607.  
  1608.     wizards[0] = new Wizard(0);
  1609.     wizards[1] = new Wizard(0);
  1610.     wizards[2] = new Wizard(1);
  1611.     wizards[3] = new Wizard(1);
  1612.  
  1613.     units[0] = wizards[0];
  1614.     units[1] = wizards[1];
  1615.     units[2] = wizards[2];
  1616.     units[3] = wizards[3];
  1617.  
  1618.     if (!myTeam) {
  1619.         myWizard1 = wizards[0];
  1620.         myWizard2 = wizards[1];
  1621.         hisWizard1 = wizards[2];
  1622.         hisWizard2 = wizards[3];
  1623.         myGoal = new Point(16000, 3750);
  1624.         hisGoal = new Point(0, 3750);
  1625.     } else {
  1626.         myWizard1 = wizards[2];
  1627.         myWizard2 = wizards[3];
  1628.         hisWizard1 = wizards[0];
  1629.         hisWizard2 = wizards[1];
  1630.         myGoal = new Point(0, 3750);
  1631.         hisGoal = new Point(16000, 3750);
  1632.     }
  1633.  
  1634.     mid = new Point(8000, 3750);
  1635.  
  1636.     bludgers[0] = new Bludger();
  1637.     bludgers[1] = new Bludger();
  1638.  
  1639.     units[4] = bludgers[0];
  1640.     units[5] = bludgers[1];
  1641.  
  1642.     poles[0] = new Pole(20, 0, 1750);
  1643.     poles[1] = new Pole(21, 0, 5750);
  1644.     poles[2] = new Pole(22, 16000, 1750);
  1645.     poles[3] = new Pole(23, 16000, 5750);
  1646.  
  1647.     units[6] = poles[0];
  1648.     units[7] = poles[1];
  1649.     units[8] = poles[2];
  1650.     units[9] = poles[3];
  1651.  
  1652.     unitsFE = 10;
  1653.  
  1654.     // TEST WITHOUT SPELLS
  1655. /*    int spellsFE = 0;
  1656.     for (int j = 0; j < 4; ++j)
  1657.         spells[spellsFE++] = wizards[j]->spell;*/
  1658.  
  1659.     Solution *best = new Solution();
  1660.  
  1661.     int oldSnafflesFE;
  1662.  
  1663.     while (1) {
  1664.         int myScore;
  1665.         int myMagic;
  1666.         cin >> myScore >> myMagic; cin.ignore();
  1667.         cerr << myScore << " " << myMagic <<endl;
  1668.  
  1669.         int opponentScore;
  1670.         int opponentMagic;
  1671.         cin >> opponentScore >> opponentMagic; cin.ignore();
  1672.         cerr << opponentScore << " " << opponentMagic <<endl;
  1673.  
  1674.         int entities;
  1675.         cin >> entities;
  1676.         cin.ignore();
  1677.         cerr << entities << endl;
  1678.  
  1679.         start = NOW;
  1680.  
  1681.         int bludgersFE = 0;
  1682.  
  1683.         if (turn) {
  1684.             for (int i = 0; i < 24; ++i) {
  1685.                 Unit *u = unitsById[i];
  1686.  
  1687.                 if (u && u->type == SNAFFLE) {
  1688.                     u->dead = true;
  1689.                     u->carrier = NULL;
  1690.                 }
  1691.             }
  1692.         }
  1693.  
  1694.         for (int i = 0; i < entities; ++i) {
  1695.             int id; // entity identifier
  1696.             string entityType; // "WIZARD", "OPPONENT_WIZARD" or "SNAFFLE" (or "BLUDGER" after first league)
  1697.             int x; // position
  1698.             int y; // position
  1699.             int vx; // velocity
  1700.             int vy; // velocity
  1701.             int state; // 1 if the wizard is holding a Snaffle, 0 otherwise
  1702.             cin >> id >> entityType >> x >> y >> vx >> vy >> state;
  1703.             cin.ignore();
  1704.             cerr << id << " " << entityType << " " << x << " " << y << " " << vx << " " << vy << " " << state <<endl;
  1705.  
  1706.             Unit *unit;
  1707.  
  1708.             if (entityType == "WIZARD" || entityType == "OPPONENT_WIZARD") {
  1709.                 unit = wizards[id];
  1710.             } else if (entityType == "SNAFFLE") {
  1711.                 if (!turn) {
  1712.                     unit = new Snaffle();
  1713.                 } else {
  1714.                     unit = unitsById[id];
  1715.                 }
  1716.  
  1717.                 unit->dead = false;
  1718.                 units[unitsFE++] = unit;
  1719.                 snaffles[snafflesFE++] = (Snaffle *) unit;
  1720.             } else if (entityType == "BLUDGER") {
  1721.                 unit = bludgers[bludgersFE++];
  1722.             }
  1723.  
  1724.             unit->update(id, x, y, vx, vy, state);
  1725.             // unit->update(id, y, x, vy, vx, state);
  1726.         }
  1727.  
  1728.         if (turn == 0) {
  1729.             victory = (snafflesFE / 2) + 1;
  1730.  
  1731.             for (int i = 0; i < unitsFE; ++i) {
  1732.                 unitsById[units[i]->id] = units[i];
  1733.             }
  1734.         }
  1735.  
  1736.         // Mise à jour des carriers et des snaffles
  1737.         for (int i = 0; i < 4; ++i) {
  1738.             wizards[i]->updateSnaffle();
  1739.         }
  1740.  
  1741.         // Mise à jour du score
  1742.         if (turn && oldSnafflesFE != snafflesFE) {
  1743.             for (int i = 0; i < 24; ++i) {
  1744.                 Unit *u = unitsById[i];
  1745.  
  1746.                 if (u && u->type == SNAFFLE && u->dead) {
  1747.                     if (!myTeam) {
  1748.                         if (u->x > 8000) {
  1749.                             myScore += 1;
  1750.                         } else {
  1751.                             hisScore += 1;
  1752.                         }
  1753.                     } else {
  1754.                         if (u->x > 8000) {
  1755.                             hisScore += 1;
  1756.                         } else {
  1757.                             myScore += 1;
  1758.                         }
  1759.                     }
  1760.  
  1761.                     delete u;
  1762.                     unitsById[i] = NULL;
  1763.                 }
  1764.             }
  1765.         }
  1766.  
  1767.         // TEST WITHOUT SPELLS
  1768. /*
  1769.         // Cibles pour les sorts
  1770.  
  1771.         // Bludgers pour tous les sorts
  1772.         spellTargets[0] = bludgers[0];
  1773.         spellTargets[1] = bludgers[1];
  1774.         spellTargetsFE = 2;
  1775.  
  1776.         // Wizards ennemis pour wingardium
  1777.         if (!myTeam) {
  1778.             spellTargets[spellTargetsFE++] = wizards[2];
  1779.             spellTargets[spellTargetsFE++] = wizards[3];
  1780.         } else {
  1781.             spellTargets[spellTargetsFE++] = wizards[0];
  1782.             spellTargets[spellTargetsFE++] = wizards[1];
  1783.         }
  1784.  
  1785.         // Snaffles pour tous les sorts sauf obliviate
  1786.         for (int j = 0; j < snafflesFE; ++j)
  1787.             spellTargets[spellTargetsFE++] = snaffles[j];
  1788. */
  1789.         for (int i = 0; i < unitsFE; i++) {
  1790.             units[i]->save();
  1791.             smana = mana;
  1792.             smyScore = myScore;
  1793.             shisScore = hisScore;
  1794.         }
  1795.  
  1796.  
  1797. /*        for (int i = 0; i < 4; i++) {
  1798.             if (spells[i]->target != NULL) {
  1799.                 spells[i]->print();
  1800.                 spells[i]->reloadTarget();
  1801.                 spells[i]->save();
  1802.             }
  1803.             else
  1804.                 cerr << "Wizard #" << i << ": no target defined for spell Windardium!! " <<endl;
  1805.         }*/
  1806.  
  1807.  
  1808. #ifndef PROD
  1809.         if (turn) {
  1810.             for (int i = 0; i < unitsFE; i++) {
  1811.                 units[i]->compare();
  1812.             }
  1813.         }
  1814.         cerr << "DEBUG 1 " <<endl;
  1815. #endif
  1816.  
  1817. #ifndef PROD
  1818.         cerr << "hisScore : " << hisScore << endl;
  1819.         cerr << "victory : " << victory << endl;
  1820. #endif
  1821.  
  1822.         /*cerr << "***** State for this turn " << endl;
  1823.         cerr << "Mana: " << mana << endl;
  1824.         cerr << "My score: " << myScore << endl;
  1825.         cerr << "His score: " << hisScore << endl;
  1826.         for (int i = 0; i < unitsFE; i++) {
  1827.             units[i]->print();
  1828.         }*/
  1829.  
  1830.         // Evolution
  1831.         cerr << "DEBUG 2" << endl;
  1832.  
  1833.         Solution *base;
  1834.         if (turn) {
  1835.             cerr << "DEBUG 3" << best << endl;
  1836.             base = new Solution();
  1837.  
  1838.             for (int j = 1; j < DEPTH; ++j) {
  1839.                 base->moves1[j - 1] = best->moves1[j];
  1840.                 base->moves2[j - 1] = best->moves2[j];
  1841.             }
  1842.             cerr << "DEBUG 2" << best << endl;
  1843.  
  1844.             // TEST WITHOUT SPELLS
  1845. /*
  1846.             base->spellTurn1 = best->spellTurn1;
  1847.             base->spellTarget1 = best->spellTarget1;
  1848.             base->spellTurn2 = best->spellTurn2;
  1849.             base->spellTarget2 = best->spellTarget2;
  1850.  
  1851.             if (!base->spellTurn1) {
  1852.                 base->spellTurn1 = SPELL_DEPTH - 1;
  1853.             } else {
  1854.                 base->spellTurn1 -= 1;
  1855.             }
  1856.  
  1857.             if (!base->spellTurn2) {
  1858.                 base->spellTurn2 = SPELL_DEPTH - 1;
  1859.             } else {
  1860.                 base->spellTurn2 -= 1;
  1861.             }
  1862.  
  1863.             if (base->spellTarget1->dead) {
  1864.                 base->spellTurn1 = SPELL_DEPTH - 1;
  1865.                 base->spellTarget1 = spellTargets[fastRandInt(spellTargetsFE)];
  1866.             }
  1867.  
  1868.             if (base->spellTarget2->dead) {
  1869.                 base->spellTurn2 = SPELL_DEPTH - 1;
  1870.                 base->spellTarget2 = spellTargets[fastRandInt(spellTargetsFE)];
  1871.             }*/
  1872.             cerr << "Solution" << best << endl;
  1873.  
  1874.             delete best;
  1875.         }
  1876.  
  1877.  
  1878.         cerr << "DEBUG 4" << endl;
  1879.  
  1880.         Solution **pool = new Solution *[POOL];
  1881.         Solution **newPool = new Solution *[POOL];
  1882.         Solution **temp;
  1883.         int counter = POOL;
  1884.  
  1885.  
  1886.         best = new Solution();
  1887.         Solution *sol = new Solution();
  1888.         sol->randomize();
  1889.  
  1890.         cerr << "DEBUG 5" << endl;
  1891.  
  1892.         simulate(sol);
  1893.         pool[0] = sol;
  1894.  
  1895.  
  1896.         best->copy(sol);
  1897.  
  1898.         Solution *tempBest = sol;
  1899.  
  1900.         cerr << "DEBUG 6" << endl;
  1901.  
  1902.         // First generation
  1903.         int startI = 1;
  1904.  
  1905.         if (turn) {
  1906.             cerr << "DEBUG 7" << endl;
  1907.             // Populate the POOL with some copy of the previous best one
  1908.             for (int i = startI; i < POOL / 5; ++i) {
  1909.                 Solution *solution = new Solution();
  1910.                 solution->copy(base);
  1911.  
  1912.                 // Add a last one random
  1913.                 solution->moves1[DEPTH - 1] = fastRandInt(ANGLES_LENGTH);
  1914.                 solution->moves2[DEPTH - 1] = fastRandInt(ANGLES_LENGTH);
  1915.  
  1916.                 simulate(solution);
  1917.  
  1918.                 if (solution->energy > tempBest->energy) {
  1919.                     tempBest = solution;
  1920.                 }
  1921.  
  1922.                 pool[i] = solution;
  1923.             }
  1924.  
  1925.             delete base;
  1926.  
  1927.             startI = POOL / 5;
  1928.         }
  1929.  
  1930.         cerr << "DEBUG 8" << endl;
  1931.  
  1932.         for (int i = startI; i < POOL; i++) {
  1933.             Solution *solution = new Solution();
  1934.             solution->randomize();
  1935.  
  1936.             simulate(solution);
  1937.  
  1938.             if (solution->energy > tempBest->energy) {
  1939.                 tempBest = solution;
  1940.             }
  1941.  
  1942.             pool[i] = solution;
  1943.         }
  1944.  
  1945.         cerr << "DEBUG 9" << endl;
  1946.  
  1947.         if (tempBest->energy > best->energy) {
  1948.             best->copy(tempBest);
  1949.         }
  1950.         tempBest = best;
  1951.  
  1952.         double limit = turn ? 0.085 : 0.800;
  1953.  
  1954.         cerr << "DEBUG 10" << endl;
  1955.  
  1956.         for (int i=0; i < DEPTH; i++)
  1957.             cerr << "best moves: (" << best->moves1[i] << ", " << best->moves2[i] << ")" <<endl;
  1958.  
  1959. #ifdef DEBUG
  1960. #define LIMIT counter <= 1000
  1961. #else
  1962. #define LIMIT TIME < limit
  1963. #endif
  1964.  
  1965.         int generation = 1;
  1966.         int bestGeneration = 1;
  1967.  
  1968.         int poolFE;
  1969.         while (LIMIT) {
  1970.             // New generation
  1971.  
  1972.             // Force the actual best with a mutation to be in the pool
  1973.             Solution *solution = new Solution();
  1974.             solution->copy(tempBest);
  1975.             solution->mutate();
  1976.             simulate(solution);
  1977.  
  1978.             // cerr << "DEBUG 11" << endl;
  1979.  
  1980.             if (solution->energy > tempBest->energy) {
  1981.                 tempBest = solution;
  1982.             }
  1983.  
  1984.             newPool[0] = solution;
  1985.  
  1986.             counter += 1;
  1987.  
  1988.             poolFE = 1;
  1989.             while (poolFE < POOL && LIMIT) {
  1990.                 int aIndex = fastRandInt(POOL);
  1991.                 int bIndex;
  1992.  
  1993.                 do {
  1994.                     bIndex = fastRandInt(POOL);
  1995.                 } while (bIndex == aIndex);
  1996.  
  1997.                 int firstIndex = pool[aIndex]->energy > pool[bIndex]->energy ? aIndex : bIndex;
  1998.  
  1999.                 do {
  2000.                     aIndex = fastRandInt(POOL);
  2001.                 } while (aIndex == firstIndex);
  2002.  
  2003.                 do {
  2004.                     bIndex = fastRandInt(POOL);
  2005.                 } while (bIndex == aIndex || bIndex == firstIndex);
  2006.  
  2007.                 int secondIndex = pool[aIndex]->energy > pool[bIndex]->energy ? aIndex : bIndex;
  2008.  
  2009.                 Solution *child = pool[firstIndex]->merge(pool[secondIndex]);
  2010.  
  2011.                 if (!fastRandInt(MUTATION)) {
  2012.                     child->mutate();
  2013.                 }
  2014.  
  2015.                 simulate(child);
  2016.  
  2017.                 if (child->energy > tempBest->energy) {
  2018.                     tempBest = child;
  2019.                 }
  2020.  
  2021.                 newPool[poolFE++] = child;
  2022.  
  2023.                 counter += 1;
  2024.             }
  2025.  
  2026.             // Burn previous generation !!
  2027.             for (int i = 0; i < POOL; i++) {
  2028.                 delete pool[i];
  2029.             }
  2030.  
  2031.             temp = pool;
  2032.             pool = newPool;
  2033.             newPool = temp;
  2034.  
  2035.             if (tempBest->energy > best->energy) {
  2036.                 best->copy(tempBest);
  2037.                 bestGeneration = generation;
  2038.             }
  2039.             tempBest = best;
  2040.  
  2041.             generation += 1;
  2042.         }
  2043.  
  2044. #ifndef PROD
  2045.         cerr << "Counter: " << counter << endl;
  2046.         cerr << "Energy: " << best->energy << endl;
  2047.         cerr << "Generation: " << generation << endl;
  2048. #endif
  2049.  
  2050.  
  2051. #ifdef DEBUG
  2052.         // Play a last time for debug
  2053.         simulate(best);
  2054. #endif
  2055.  
  2056.         cerr << "DEBUG 12" << endl;
  2057.  
  2058.         cerr << "best = " << best << endl;
  2059.  
  2060.         // Play a last time to check some infos
  2061. //        myWizard1->apply(best, 0, 1);
  2062. //        myWizard2->apply(best, 0, 2);
  2063.         myWizard1->apply(best->moves1[0]);
  2064.         myWizard2->apply(best->moves2[0]);
  2065.         dummies();
  2066.  
  2067.         play();
  2068.  
  2069.         cerr << "***** State for next turn " << endl;
  2070.         cerr << "Mana: " << mana << endl;
  2071.         cerr << "My score: " << myScore << endl;
  2072.         cerr << "His score: " << hisScore << endl;
  2073.         for (int i = 0; i < unitsFE; i++) {
  2074.             units[i]->print();
  2075.         }
  2076.  
  2077.  
  2078.         smana = mana;
  2079.         bludgers[0]->slast = bludgers[0]->last;
  2080.         bludgers[1]->slast = bludgers[1]->last;
  2081.  
  2082.         // TEST WITHOUT SPELLS
  2083. /*
  2084.         for (int i = 0; i < 4; i++) {
  2085.             spells[i]->save();
  2086.         }
  2087. */
  2088.  
  2089. #ifndef PROD
  2090.         for (int i = 0; i < unitsFE; i++) {
  2091.             units[i]->store();
  2092.         }
  2093. #endif
  2094.  
  2095.         reset();
  2096.  
  2097. #ifdef PROFILE
  2098.         double totalSpent = 0;
  2099.             for (int i = 0; i < DURATIONS_COUNT; i++) {
  2100.                 totalSpent += durations[i];
  2101.             }
  2102.             for (int i = 0; i < DURATIONS_COUNT; i++) {
  2103.                 fprintf(stderr, "Time %3d: %.6fms (%.2f%%)\n", i, durations[i] * 1000.0, durations[i] * 100.0/totalSpent);
  2104.             }
  2105.             fprintf(stderr, "Total: %.6fms (%.6fms per turn)\n", totalSpent * 1000.0, totalSpent * 1000.0/(double)(turn + 1));
  2106. #endif
  2107.  
  2108.         myWizard1->output(best->moves1[0], best->spellTurn1, best->spellTarget1);
  2109.         myWizard2->output(best->moves2[0], best->spellTurn2, best->spellTarget2);
  2110.  
  2111.         // Burn last generation !!
  2112.         for (int i = 0; i < poolFE; i++) {
  2113.             delete pool[i];
  2114.         }
  2115.  
  2116.         delete[] pool;
  2117.         delete[] newPool;
  2118.  
  2119.         turn += 1;
  2120.         unitsFE = 10;
  2121.  
  2122.         oldSnafflesFE = snafflesFE;
  2123.         snafflesFE = 0;
  2124.     }
  2125. }
  2126.  
Add Comment
Please, Sign In to add comment