Browse Source

Added the code of people participating the original competition.

The file name is the name of the competitor. The sources can be found here:
https://web.archive.org/web/20071101002722/http://www.prologin.org/archives/2001/finale/
Godzil 2 years ago
parent
commit
429078c389

+ 295 - 0
data/clients/antoine_jacquet.c

@@ -0,0 +1,295 @@
+#include "prolo.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+
+/* Quelques constantes... */
+
+#define pi M_PI
+#define sqr(x) ((x)*(x))
+#define MAX 300
+#define RAYON_MIN 1
+#define OUVERTURE_DEPART pi/4
+#define DEFENSE_DISTANCE 5
+#define DEFENSE_OUVERTURE 5
+#define ATTAQUE_DISTANCE 1
+#define ATTAQUE_OUVERTURE 0.01
+#define GRATUIT_FREQ 10/10
+#define GRATUIT_OUVERTURE 0.5
+#define AIDE_TIMELIMIT 10000
+#define AIDE_NBLIMIT 1
+#define AIDE_OUVERTURE (2*r4d2_get_speed()+1)
+
+
+
+/* Variables globales */
+
+struct
+{
+    int team;
+    float x,y;
+    float angle,ouverture;
+} akx[MAX];
+
+struct
+{
+    float x,y,r;
+} vise;
+
+int capturing[MAX];
+
+int nation;
+
+
+
+/* Player_Init */
+
+void player_init(int team_id, int nb_team)
+{
+    int i;
+
+    nation=team_id;
+    printf("version 2\n");
+    printf("je suis %d\n",nation);
+    printf("akx_see_power : %f\n",akx_get_see_power());
+
+    for (i=0;i<MAX;i++)
+    {
+        akx[i].ouverture=OUVERTURE_DEPART;
+        akx[i].team=-1;
+        capturing[i]=-1;
+    }
+
+    return;
+}
+
+
+
+/* Player_New_Turn */
+
+void player_new_turn(int turn_number)
+{
+    int i,j,best_akx,best_r4d2;
+    float best,dist;
+
+    /* Mise a jour de la table locale des AnaKronoX */
+    for (i=0;i<MAX;i++) if (akx_get_team(i)!=-1)
+    {
+        if (akx[i].team==-1)
+        {
+            printf("akx %d trouve\n",i);
+            akx[i].x=akx_get_pos_x(i);
+            akx[i].y=akx_get_pos_y(i);
+            akx[i].team=akx_get_team(i);
+        }
+        if (akx[i].team!=akx_get_team(i))
+        {
+            printf("akx %d a change de team\n",i);
+            akx[i].team=akx_get_team(i);
+        }
+        if ((akx[i].x!=akx_get_pos_x(i)) || (akx[i].y!=akx_get_pos_y(i)))
+        {
+            printf("akx %d a bouge\n",i);
+            akx[i].x=akx_get_pos_x(i);
+            akx[i].y=akx_get_pos_y(i);
+        }
+    }
+
+    /* S'il ne reste que peu de r4d2 ou qu'on approche de la fin de partie, on defend le plus possible un des r4d2 restants */
+    if ((turn_counter()>=AIDE_TIMELIMIT) || (map_count_my_r4d2()<=AIDE_NBLIMIT))
+        for (i=0;i<MAX;i++) if (r4d2_get_team(i)==nation)
+        {
+            printf("AIDE r4d2 %d\n",i);
+            vise.x=r4d2_get_pos_x(i);
+            vise.y=r4d2_get_pos_y(i);
+            vise.r=AIDE_OUVERTURE;
+            return;
+        }
+
+    /* Recherche du r4d2 ennemi le plus proche d'un de mes AnaKronoX */
+    best=10000;
+    for (i=0;i<MAX;i++) if (((akx_get_team(i)==nation)||(akx_get_team(i))==0) && ((j=map_get_nearest_r4d2_plot(akx_get_pos_x(i),akx_get_pos_y(i),-nation))!=-1))
+    {
+        dist=sqrt(sqr(akx_get_pos_x(i)-r4d2_get_pos_x(j))
+                +sqr(akx_get_pos_y(i)-r4d2_get_pos_y(j)));
+        if (dist<best)
+        {
+            best=dist;
+            best_akx=i;
+            best_r4d2=j;
+        }
+    }
+
+    /* S'il y a un r4d2 ennemi tres proche d'un de mes AnaKronoX (surement en train de convertir donc surement imobile, on le vise tres serre */
+    if (best<ATTAQUE_DISTANCE)
+    {
+        printf("ATTAQUE %d\n",best_r4d2);
+        vise.x=r4d2_get_pos_x(best_r4d2);
+        vise.y=r4d2_get_pos_y(best_r4d2);
+        vise.r=ATTAQUE_OUVERTURE;
+        return;
+    }
+
+    /* S'il y a un r4d2 ennemi assez proche d'un des mes AnaKronoX, on le gene faisant un defense de zone autour de l'AnaKronoX */
+    if (best<DEFENSE_DISTANCE)
+    {
+        printf("DEFENSE %d\n",best_akx);
+        vise.x=akx_get_pos_x(best_akx);
+        vise.y=akx_get_pos_y(best_akx);
+        vise.r=DEFENSE_OUVERTURE;
+        return;
+    }
+
+    /* On tente une attaque "gratuite" sur un r4d2 ennemi de temps en temps */
+    if (map_random()<GRATUIT_FREQ)
+        for (i=0;i<MAX;i++) if ((r4d2_get_team(i)!=-1) && (r4d2_get_team(i)!=nation))
+        {
+            vise.x=r4d2_get_pos_x(i);
+            vise.y=r4d2_get_pos_y(i);
+            vise.r=GRATUIT_OUVERTURE;
+            return;
+        }
+
+    /* Sinon on ne vise rien de special (on fera du scanning) */
+    vise.r=-1;
+    return;
+}
+
+
+
+/* Player_AKX_Turn */
+
+void player_akx_turn(int akx_id)
+{
+    float rayon,ouverture,tcos,tsin;
+
+    /* Si on n'a plus de r4d2, on fait une defense de zone tres concentree, en bougeant une fois sur 3 */
+    if (map_count_my_r4d2()==0)
+    {
+        /* J'utilise l'angle comme boolean pour alterner deplacement/defense */
+        if (akx[akx_id].angle<2)
+        {
+            akx[akx_id].angle++;
+            vise.x=akx_get_pos_x(akx_id);
+            vise.y=akx_get_pos_y(akx_id);
+            vise.r=RAYON_MIN;
+        }
+        else
+        {
+            akx[akx_id].angle=0;
+            akx_move(akx_id,1,1);
+            return;
+        }
+    }
+
+    /* Si on a une directive de visee, on l'execute */
+    if (vise.r!=-1)
+    {
+        rayon=sqrt(sqr(akx_get_pos_x(akx_id)-vise.x)
+                +sqr(akx_get_pos_y(akx_id)-vise.y));
+        /* Si la distance entre l'AnaKronoX et sa cible est trop faible, on fait une defense circulaire */
+        if (rayon<RAYON_MIN)
+            akx_pulse(akx_id,akx_get_pos_x(akx_id)+RAYON_MIN,akx_get_pos_y(akx_id),2*pi);
+        /* Sinon on vise la cible avec l'ouverture demandee, en centrant au maximum */
+        else
+        {
+            tcos=(vise.x-akx_get_pos_x(akx_id))/rayon;
+            tsin=(vise.y-akx_get_pos_y(akx_id))/rayon;
+            ouverture=2*atan(vise.r/rayon);
+            akx_pulse(akx_id,vise.x+tcos*vise.r,vise.y+tsin*vise.r,ouverture);
+        }
+        return;
+    }
+
+    /* Sinon on scanne la carte pour trouver de nouveaux objectifs */
+    rayon=sqrt(2*akx_get_power()/(akx_get_see_power()*akx[akx_id].ouverture));
+    rayon--;
+    akx_pulse(akx_id,akx_get_pos_x(akx_id)+cos(akx[akx_id].angle)*rayon,akx_get_pos_y(akx_id)+sin(akx[akx_id].angle)*rayon,akx[akx_id].ouverture);
+
+    /* Calcul du prochain scan : on evite de scanner en dehors de la carte */
+    do
+    {
+        akx[akx_id].angle+=akx[akx_id].ouverture;
+        while (akx[akx_id].angle>=2*pi) akx[akx_id].angle-=2*pi;
+        /* Si on a fait un tour complet, on scanne plus serre et plus loin */
+        if ((akx[akx_id].angle>=0) && (akx[akx_id].angle<akx[akx_id].ouverture))
+        {
+            akx[akx_id].angle=0;
+            /* Si on scanne deja un rayon plus grand que la map, on repart sur un petit scan */
+            if ((rayon>=map_get_size_x()) && (rayon>=map_get_size_y())) akx[akx_id].ouverture=OUVERTURE_DEPART;
+            else akx[akx_id].ouverture=akx[akx_id].ouverture/2;
+        }
+        rayon=sqrt(2*akx_get_power()/(akx_get_see_power()*akx[akx_id].ouverture));
+    }
+    while ((akx_get_pos_x(akx_id)+cos(akx[akx_id].angle)*rayon<-1) ||
+    (akx_get_pos_x(akx_id)+cos(akx[akx_id].angle)*rayon>map_get_size_x()+1) ||
+    (akx_get_pos_y(akx_id)+sin(akx[akx_id].angle)*rayon<-1) ||
+    (akx_get_pos_y(akx_id)+sin(akx[akx_id].angle)*rayon>map_get_size_y()+1));
+
+    return;
+}
+
+
+
+int being_captured(int akx_id)
+/* Retourne 1 si l'AnaKronoX passe en parametre est deja en cours de capture */
+{
+    int i;
+    for (i=0;i<MAX;i++) if (capturing[i]==akx_id) return(1);
+    return(0);
+}
+
+int choose_nearest_akx_plot(int x, int y)
+/* Retourne l'AnaKronoX le plus proche du point (x,y) et qui n'est pas deja en cours de capture */
+{
+    float dist,best=10000;
+    int id=-1,i;
+
+    for (i=0;i<MAX;i++) if ((akx[i].team!=-1) && (akx[i].team!=nation) && (!being_captured(i)))
+    {
+        dist=sqrt(sqr(akx_get_pos_x(i)-x)+sqr(akx_get_pos_y(i)-y));
+        if (dist<best)
+        {
+            best=dist;
+            id=i;
+        }
+    }
+    return(id);
+}
+
+
+/* Player_R4D2_Turn */
+
+void player_r4d2_turn(int r4d2_id)
+{
+    int i;
+
+    if (akx_get_team(capturing[r4d2_id])==nation)
+    {
+        printf("%d -/-> %d\n",r4d2_id,capturing[r4d2_id]);
+        capturing[r4d2_id]=-1;
+    }
+
+    if (capturing[r4d2_id]==-1)
+    {
+        if ((i=choose_nearest_akx_plot(r4d2_get_pos_x(r4d2_id),r4d2_get_pos_y(r4d2_id)))==-1)
+            r4d2_move(r4d2_id,map_get_size_x()/2,map_get_size_y()/2);
+        else
+        {
+            r4d2_move(r4d2_id,akx[i].x,akx[i].y);
+            capturing[r4d2_id]=i;
+            printf("%d ---> %d\n",r4d2_id,i);
+        }
+    }
+    else
+        if (sqrt(sqr(r4d2_get_pos_x(r4d2_id)-akx[capturing[r4d2_id]].x)+
+        sqr(r4d2_get_pos_y(r4d2_id)-akx[capturing[r4d2_id]].y))<1)
+            r4d2_take_akx(r4d2_id,capturing[r4d2_id]);
+        else
+            r4d2_move(r4d2_id,akx[capturing[r4d2_id]].x,akx[capturing[r4d2_id]].y);
+        return;
+}
+
+

+ 302 - 0
data/clients/frederic_jacquot.c

@@ -0,0 +1,302 @@
+#include <iostream.h>
+#include <math.h>
+#include <stdlib.h>
+#include "prolo.hh"
+
+struct coords
+        {
+    float x,y;
+    int target;
+        };
+
+
+double distance (float x1, float y1, float x2, float y2)
+// Distance entre deux points, merci pythagore
+{
+    return sqrt(pow(x2-x1,2)+pow(y2-y1,2));
+}
+
+
+bool trouve(int id, coords tab[100])
+// l'unite visee est elle deja convoitee par un r4d2 ?
+{
+    int a;
+    for(a=0;a<100;a++)
+    {
+        if (id==tab[a].target)
+            return true;
+    }
+    return false;
+}
+
+
+const float PI=3.1418; // et des poussieres
+int myteam;
+
+
+// angles de tir
+float angles[100];
+int dirsens[100];
+
+// ID r4d2 vise
+int targetone=-1;
+
+// ou vont mes r4d2 ?
+coords lemming[100];
+
+//
+// Player Init
+//
+
+void	player_init(int team_id)
+{
+    myteam=team_id;
+
+    for(int a=0;a<100;a++)
+    {
+        lemming[a].x=-1;
+        lemming[a].y=-1;
+
+        angles[a]=PI/12;
+        // pqs encore pointe
+        dirsens[a]=1;
+    }
+    return;
+}
+
+
+//
+// Player New Turn
+//
+
+void	player_new_turn(int turn_number)
+{
+    // et oui, rien
+    return;
+}
+
+
+//
+// Player Akx Turn
+//
+
+void	player_akx_turn(int akx_id)
+{
+    float xdanger;
+    float ydanger;
+    int r4d2_proche;
+
+
+    //reperage r4d2 adverse
+    r4d2_proche = map_get_nearest_r4d2(akx_id,0-myteam);
+    xdanger = r4d2_get_pos_x(r4d2_proche);
+    ydanger = r4d2_get_pos_y(r4d2_proche);
+
+    // Si je detecte un r4d2 ennemi a moins de 30
+    if (xdanger!=-1 && distance(akx_get_pos_x(akx_id),
+                                akx_get_pos_y(akx_id),
+                                r4d2_get_pos_x(r4d2_proche),
+                                r4d2_get_pos_y(r4d2_proche))<50)
+    {
+        // il devient nouvelle cible principale
+        targetone=r4d2_proche;
+        akx_pulse(akx_id,r4d2_get_pos_x(targetone),
+                  r4d2_get_pos_y(targetone),0.01);
+        if (r4d2_get_pos_x(targetone)==-1)
+        {
+            cout << "Cible detruite!\n";
+            targetone=-1;
+        }
+    }
+    else
+        // pqs d'ennemi proche
+        {
+        //tous les 4 tours - Big Pulse
+        if (turn_counter()%4==0)
+        {
+            //DeepPulse
+            akx_pulse(akx_id,akx_get_pos_x(akx_id)+20,
+                      akx_get_pos_y(akx_id)+20,2*PI);
+            if (turn_counter()%8==0) targetone=-1;
+        }
+        else
+            //pqs de deepPulse
+            {
+            if (targetone!=-1)
+                //une cible etait lockee
+                {
+                akx_pulse(akx_id,r4d2_get_pos_x(targetone),
+                          r4d2_get_pos_y(targetone),0.01);
+                if (r4d2_get_pos_x(targetone)==-1)
+                    //Plus de cible
+                    {
+                    cout << "Cible detruite!\n";
+                    targetone=-1;
+                    }
+                }
+            // Pqs de cible lockee
+            else
+            {
+                //PULSE Rotatif
+
+                bool haut=false;
+                bool bas=false;
+                bool gauche=false;
+                bool droite=false;
+
+                if (akx_get_pos_x(akx_id)==0) gauche=true;
+                if (akx_get_pos_y(akx_id)==0) haut=true;
+                if (akx_get_pos_x(akx_id)==map_get_size_x()) droite=true;
+                if (akx_get_pos_y(akx_id)==map_get_size_y()) bas=true;
+
+
+                //coins
+                if (haut && gauche &&
+                (angles[akx_id]>PI/2-0.2 ) )
+                    angles[akx_id]=PI/12;
+
+                if (haut && droite &&
+                (angles[akx_id]>PI-0.2 || angles[akx_id]<PI/2) )
+                    angles[akx_id]=PI/2+PI/12;
+
+                if (bas && droite &&
+                (angles[akx_id]>3*PI/2-0.2 || angles[akx_id]<PI) )
+                    angles[akx_id]=PI+PI/12;
+
+                if (bas && gauche &&
+                (angles[akx_id]>2*PI-0.2 || angles[akx_id]<3*PI/2) )
+                    angles[akx_id]=3*PI/2+PI/12;
+
+                //bords
+                if (haut && !gauche && !droite &&
+                angles[akx_id]>PI-0.2 )
+                    angles[akx_id]=0+PI/12;
+
+                if (bas && !droite && !gauche &&
+                (angles[akx_id]>2*PI-0.2 || angles[akx_id]<PI) )
+                    angles[akx_id]=PI+PI/12;
+
+                if (droite && !bas && !haut &&
+                (angles[akx_id]>3*PI/2-0.2 || angles[akx_id]<PI/2) )
+                    angles[akx_id]=PI/2+PI/12;
+
+                if (gauche && !bas && !haut &&
+                (angles[akx_id]>2*PI-0.2 ) )
+                    angles[akx_id]=0+PI/12;
+
+                if (gauche && !bas && !haut &&
+                angles[akx_id]>PI/2-0.2 && angles[akx_id]<3*PI/2 )
+                    angles[akx_id]=3*PI/2+PI/12;
+
+
+                akx_pulse(akx_id,
+                          akx_get_pos_x(akx_id)+cos(angles[akx_id])*40,
+                          akx_get_pos_y(akx_id)+sin(angles[akx_id])*40,PI/6+0.1);
+
+                angles[akx_id]+=PI/6*dirsens[akx_id];
+            }
+            }
+        }
+    return;
+}
+
+
+//
+// r4d2 Turn
+//
+
+void	player_r4d2_turn(int r4d2_id)
+{
+    int akx_proche;
+    float xakx;
+    float yakx;
+
+    int r4d2_proche;
+    float xr4,yr4;
+
+    // locate hostile akx
+    akx_proche = map_get_nearest_akx(r4d2_id,0-myteam);
+    xakx = akx_get_pos_x(akx_proche);
+    yakx = akx_get_pos_y(akx_proche);
+    // locate hostile r4d2
+    r4d2_proche = map_get_nearest_r4d2(r4d2_id,0-myteam);
+    xr4 = r4d2_get_pos_x(r4d2_proche);
+    yr4 = r4d2_get_pos_y(r4d2_proche);
+
+
+
+
+    // je suis immobile et j'ai repere un r4d2 proche
+    if (r4d2_get_status(r4d2_id)==0 && xr4!=-1 &&
+    distance(r4d2_get_pos_x(r4d2_id),r4d2_get_pos_y(r4d2_id),
+             xr4,yr4)<1)
+        //cqpture r4d2 -rare -
+        {
+        cout<< "Tentative capture d'un R4D2!\n";
+        r4d2_take_r4d2(r4d2_id,r4d2_proche);
+        }
+
+    else
+    {
+
+        // je suis immobile ou en mouvement et j'ai repere un akx
+        if (r4d2_get_status(r4d2_id)==0 && xakx!=-1)
+        {
+            if (lemming[r4d2_id].x==-1)
+                // je suis ne suis pas en mission
+                {
+                //qqn est deja sur le coup
+                if (trouve(akx_proche,lemming))
+                {
+                    if(rand()%4==1)
+                        //on force le deplacement une fois sur 4
+                        {
+                        lemming[r4d2_id].x=xakx;
+                        lemming[r4d2_id].y=yakx;
+                        lemming[r4d2_id].target= akx_proche;
+                        }
+                    else
+                        //qqn est sur le coup, et je nai pas le droit
+                        //donc j'attends calmement
+                        {
+                        // r4d2_boire_un_cafe(r4d2_id);
+                        }
+                }
+                else
+                    // personne sur le coup
+                    {
+                    lemming[r4d2_id].x=xakx;
+                    lemming[r4d2_id].y=yakx;
+                    lemming[r4d2_id].target= akx_proche;
+                    r4d2_move (r4d2_id, lemming[r4d2_id].x, lemming[r4d2_id].y);
+                    }
+
+                }
+            else
+                // je suis deja en mission, je m'y tiens
+                {
+                r4d2_move (r4d2_id, lemming[r4d2_id].x, lemming[r4d2_id].y);
+                }
+        }
+    }
+    // akx adversqire tout proche
+    if ( distance(r4d2_get_pos_x(r4d2_id),
+                  r4d2_get_pos_y(r4d2_id),lemming[r4d2_id].x,
+                  lemming[r4d2_id].y)<1 && r4d2_get_status(r4d2_id)!=2 )
+    {
+        // je verif que je ne veux pas capturer un truc a moi
+        if(akx_get_team(lemming[r4d2_id].target)!=myteam)
+        {
+            r4d2_take_akx(r4d2_id, lemming[r4d2_id].target);
+            cout << "Tentative de capture d'un akx!\n";
+        }
+
+        lemming[r4d2_id].x=-1;
+    }
+
+
+    return;
+}
+
+
+

+ 411 - 0
data/clients/jean-didier_febvay.pas

@@ -0,0 +1,411 @@
+program finale_prologin_2001;
+
+function turn_number : integer; external; c ;
+function turn_counter : integer; external; c ;
+
+function time_get_left : integer; external ; c ;
+
+function score_get : integer; external ; c ;
+
+function error_get : integer; external ; c ;
+
+function r4d2_get_team(r4d2_id : integer) : integer; external ; c ;
+function r4d2_get_pos_x(r4d2_id : integer) : single; external ; c ;
+function r4d2_get_pos_y(r4d2_id : integer) : single; external ; c ;
+function r4d2_get_status(r4d2_id : integer) : integer; external ; c ;
+
+function r4d2_get_speed : single; external; c ;
+function r4d2_get_destroy_speed : single; external; c ;
+
+function r4d2_turn_take_r4d2 : integer; external; c ;
+function r4d2_turn_untake_r4d2 : integer; external; c ;
+function r4d2_turn_take_akx : integer; external; c ;
+function r4d2_turn_untake_akx : integer ; external; c ;
+
+function r4d2_move(r4d2_id : integer; dx, dy : single) : boolean; external ; c ;
+function r4d2_take_akx(r4d2_id, target_id : integer) : boolean; external ; c ;
+function r4d2_take_r4d2(r4d2_id, target_id : integer) : boolean; external ; c ;
+
+function akx_get_team(r4d2_id : integer) : integer; external ; c ;
+function akx_get_pos_x(r4d2_id : integer) : single; external ; c ;
+function akx_get_pos_y(r4d2_id : integer) : single; external ; c ;
+function akx_get_status(r4d2_id : integer) : integer; external ; c ;
+
+function akx_pulse_angle(r4d2_id : integer) : single; external ; c ;
+function akx_pulse_destx(r4d2_id : integer) : single; external ; c ;
+function akx_pulse_desty(r4d2_id : integer) : single; external ; c ;
+
+function akx_get_speed : single; external ; c ;
+function akx_get_power : single; external ; c ;
+function akx_get_pulse_coef : single; external ; c ;
+function akx_get_see_power : single; external ; c ;
+
+function akx_move(r4d2_id : integer; dx, dy : single) : boolean; external ; c ;
+function akx_pulse(r4d2_id : integer; dx, dy, angle : single) : boolean; external ; c ;
+function akx_link(r4d2_id, target_id : integer) : boolean; external ; c ;
+
+function map_get_size_x : single; external ; c ;
+function map_get_size_y : single; external; c ;
+function map_get_pulse(team_id : integer; x, y : single) : single; external ; c ;
+function map_get_pulse_id(akx_id : integer; x, y : single) : single; external ; c ;
+function map_count_akx : integer; external ; c ;
+function map_count_r4d2 : integer; external ; c ;
+function map_count_my_akx : integer; external ; c ;
+function map_count_my_r4d2 : integer; external ; c ;
+function map_get_nearest_akx_plot(x, y : single; team_id : integer) : integer; external ; c ;
+function map_get_nearest_r4d2_plot(x, y : single ; team_id : integer) : integer; external ; c ;
+function map_get_nearest_akx(id, team_id : integer) : integer; external ; c ;
+function map_get_nearest_r4d2(id, team_id	: integer ): integer; external ; c ;
+
+			   (* Vous devez coder: *)
+
+(* Variables globales *)
+const Pi = 3.14159265358979323846;
+
+var my_team_id : integer;
+    xmax, ymax : single;
+
+
+
+type tnature  = (tank, robot);
+     t_ami    = record
+		   nature : tnature;
+		   x, y	  : single;
+		   id	  : integer;
+		end;
+     t_ennemi = record
+		   nature : tnature;
+		   x, y	  : single;
+		   id	  : integer;
+		   etat	  : (neutre, disparu, ennemi);
+		end;
+var amis    : array[1..168+21] of t_ami;
+    ennemis : array[1..168*2-21] of t_ennemi;
+    nombre_amis,
+    nombre_ennemis : integer;
+
+(* Ici nous venons de declarer 2 tableaux : amis et ennemis qui vont stocker toutes les infos possibles concernant les robots et les tanks connus. Ce sera la base de donnees du programme. Ensuite, a partir de ces informations, le programme decidera des actions a effectuer. Les unites ne decident donc pas individuellement des actions a effectuer, sauf dans certains cas particuliers. *)
+
+
+(* Les variables qui suivent permettent de definir le mouvement d'un tank scrutant ce qu'il y a autour de lui. *)
+
+var rotation, angle, arc_sup, arc_inf	: array[0..168*2-1] of single;
+    deja_vu, coeff_x, coeff_y, balayage	: array[0..168*2-1] of boolean;
+    sum					: array[0..168*2-1] of integer;
+
+(* Les tableaux suivants permettent de savoir si une unite subit un ordre venant du programme ou est libre de faire ce qu'elle veut' et qui chasse tel ou tel tank ennemi. *)
+
+var occupe   : array[0..168*2-1] of boolean;
+    chasseur : array[0..168*2-1] of integer;
+
+
+(* Le tableau qui suit renvoie l'index d'un ennemi en fonction de son id. *)
+
+var index_ennemis : array[0..168*2-1] of integer;
+
+var concentration : boolean;
+
+
+procedure player_init(team_id : integer) ;
+var i : integer;
+begin
+   (* On recupere le numero d'id attribue a notre team. *)
+   my_team_id := team_id;
+
+   (* Et on enregistre quelques infos utilses dans des variables globales, afin de ne pas avoir a rappeler les fonctions donnant ces infos. *)
+   xmax := map_get_size_x;
+   ymax := map_get_size_y;
+
+   (* Et on initialise ici quelques variables. *)
+   for i := 0 to 168*2-1 do
+   begin
+      deja_vu[i] := false;
+      occupe[i] := false;
+      chasseur[i] := -1;
+      index_ennemis[i] := 0;
+      sum[i] := 0;
+      balayage[i] := false;
+   end;
+   nombre_amis := 0;
+   nombre_ennemis := 0;
+   concentration := false;
+end;
+
+procedure player_new_turn(turn_number : integer) ;
+var i, j, k, found : integer;
+    d, r : single;
+begin
+   (* Recherche les ennemis et construit une base de donnees sur eux. *)
+   for i := 1 to nombre_amis do if amis[i].nature = tank then
+   begin
+      (* Recherche les tanks ennemis. *)
+      k := map_get_nearest_akx(amis[i].id, -my_team_id);
+      if k >= 0 then
+      begin
+         found := 0;
+	 for j := 1 to nombre_ennemis do if ennemis[j].id = k then
+	 begin
+	    found := 1;
+	    with ennemis[j] do
+	    begin
+	       x := akx_get_pos_x(k);
+	       y := akx_get_pos_y(k);
+	       if akx_get_team(k) = 0 then etat := neutre
+	       else etat := ennemi;
+	    end;
+	    break;
+	 end;
+	 if found = 0 then
+	 begin
+	    inc(nombre_ennemis);
+	    index_ennemis[k] := nombre_ennemis;
+	    with ennemis[nombre_ennemis] do
+	    begin
+	       nature := tank;
+	       x := akx_get_pos_x(k);
+	       y := akx_get_pos_y(k);
+	       id := k;
+	       if akx_get_team(k) = 0 then etat := neutre
+	       else etat := ennemi;
+	    end;
+	 end;
+      end;
+
+      (* Recherche les robots ennemis. *)
+      k := map_get_nearest_r4d2(amis[i].id, -my_team_id);
+      if k >= 0 then
+      begin
+         found := 0;
+	 for j := 1 to nombre_ennemis do if ennemis[j].id = k then
+	 begin
+	    found := 1;
+	    with ennemis[j] do
+	    begin
+	       x := r4d2_get_pos_x(k);
+	       y := r4d2_get_pos_y(k);
+	       if r4d2_get_team(k) = 0 then etat := neutre
+	       else etat := ennemi;
+	    end;
+	    break;
+	 end;
+	 if found = 0 then
+	 begin
+	    inc(nombre_ennemis);
+	    index_ennemis[k] := nombre_ennemis;
+	    with ennemis[nombre_ennemis] do
+	    begin
+	       nature := robot;
+	       x := r4d2_get_pos_x(k);
+	       y := r4d2_get_pos_y(k);
+	       id := k;
+	       if r4d2_get_team(k) = 0 then etat := neutre
+	       else etat := ennemi;
+	    end;
+	 end;
+      end;
+
+      (* Si rien de nouveau n'a ete trouve apres un balayage, on diminue le rayon de recherche. C'est une strategie majeure pour mon programme ; en effet, cela me permet d'avoir une assez bonne visibilite. *)
+      if (balayage[amis[i].id]) and (sum[amis[i].id] = 0) then
+	 angle[amis[i].id] := angle[amis[i].id] / 2;
+      if balayage[amis[i].id] then
+      begin
+	 balayage[amis[i].id] := false;
+	 sum[amis[i].id] := 0;
+      end;
+   end;
+
+   (* Ici, le programme va prendre les decisions en fonction des donnees dont il dispose. Notons que la base de donnees n'est remplie qu'apres la fin du second tour. *)
+   if turn_counter > 1 then
+   begin
+
+      (* 1) Les robots attaquent les tanks, a raison de 1 robot par tank. *)
+      for i := 1 to nombre_ennemis do if (ennemis[i].nature = tank) and (ennemis[i].etat <> disparu) then
+      begin
+	 (* Verifie si le tank a prendre n'a pas perdu son chasseur s'il en a un. *)
+	 if chasseur[ennemis[i].id] > -1 then
+	 if (r4d2_get_team(chasseur[ennemis[i].id]) = -1) or
+	    (not occupe[chasseur[ennemis[i].id]]) then chasseur[ennemis[i].id] := -1;
+      	 (* Recherche du robot le plus pres non affecte a une tache. *)
+	 found := 0;
+	 r := 1000000;
+	 for j := 1 to nombre_amis do
+         if (amis[j].nature = robot) and (r4d2_get_status(amis[j].id) = 0) then
+	 begin
+	    d := sqr(ennemis[i].x-amis[j].x) + sqr(ennemis[i].y-amis[j].y);
+	    if d <= 1 then
+	    begin
+	       occupe[amis[j].id] := false;
+	       r4d2_take_akx(amis[j].id, ennemis[i].id);
+	       break;
+	    end;
+	    if (d < r) and (not occupe[amis[j].id]) and (chasseur[ennemis[i].id] = -1) then
+	    begin
+	       r := d;
+	       found := j;
+	    end;
+	 end;
+	 (* S'il existe un tel robot, alors il est envoye vers le tank. *)
+	 if found > 0 then
+	 begin
+	    occupe[amis[found].id] := true;
+	    chasseur[ennemis[i].id] := amis[found].id;
+	    r4d2_move(amis[found].id, ennemis[i].x, ennemis[i].y);
+	 end;
+      end;
+
+      (* 2) Tanks. Tirent de maniere concentree sur les R4D2 arrivant. *)
+      for i := 1 to nombre_amis do if amis[i].nature = tank then occupe[amis[i].id] := false;
+      if not concentration then
+      begin
+         for i := 1 to nombre_ennemis do if (ennemis[i].nature = robot) and (ennemis[i].etat <> disparu) and (r4d2_get_team(ennemis[i].id) <> -1) then
+         begin
+	    for j := 1 to nombre_amis do if amis[j].nature = tank then
+	    begin
+	       akx_pulse(amis[j].id, ennemis[i].x, ennemis[i].y, Pi/25);
+	       occupe[amis[j].id] := true;
+	    end;
+	    concentration := true;
+         end;
+      end else concentration := false;
+   end;
+
+   (* Reinitialise la base de donnees sur les unites amies pour le tour suivant. *)
+   nombre_amis := 0;
+end;
+
+procedure player_akx_turn(akx_id : integer) ;
+var r, x, y : single;
+begin
+(* Initialisation des parametres de rotation *)
+   if not deja_vu[akx_id] then
+   begin
+      x := akx_get_pos_x(akx_id);
+      y := akx_get_pos_y(akx_id);
+      angle[akx_id] := Pi/5;
+      if (x <= xmax/3) and (y <= ymax/3) then
+      begin
+         rotation[akx_id] := 0;
+	 arc_sup[akx_id] := Pi/2;
+	 arc_inf[akx_id] := 0;
+	 coeff_x[akx_id] := false;
+	 coeff_y[akx_id] := false;
+      end
+      else if (x <= xmax/3) and (y >= 2*ymax/3) then
+      begin
+         rotation[akx_id] := 0;
+	 arc_sup[akx_id] := Pi/2;
+	 arc_inf[akx_id] := 0;
+         coeff_x[akx_id] := false;
+	 coeff_y[akx_id] := true;
+      end
+      else if (x >= 2*xmax/3) and (y <= ymax/3) then
+      begin
+         rotation[akx_id] := 0;
+	 arc_sup[akx_id] := Pi/2;
+	 arc_inf[akx_id] := 0;
+         coeff_x[akx_id] := true;
+	 coeff_y[akx_id] := false;
+      end
+      else if (x >= 2*xmax/3) and (y >= 2*ymax/3) then
+      begin
+         rotation[akx_id] := Pi;
+	 arc_sup[akx_id] := 3*Pi/2;
+	 arc_inf[akx_id] := Pi;
+         coeff_x[akx_id] := false;
+	 coeff_y[akx_id] := false;
+      end
+      else if y <= ymax/3 then
+      begin
+	 rotation[akx_id] := 0;
+	 arc_sup[akx_id] := Pi;
+	 arc_inf[akx_id] := 0;
+	 coeff_x[akx_id] := false;
+	 coeff_y[akx_id] := false;
+      end
+      else if y >= 2*ymax/3 then
+      begin
+	 rotation[akx_id] := 0;
+	 arc_sup[akx_id] := Pi;
+	 arc_inf[akx_id] := 0;
+	 coeff_x[akx_id] := false;
+	 coeff_y[akx_id] := true;
+      end
+      else if x <= xmax/3 then
+      begin
+	 rotation[akx_id] := 0;
+	 arc_sup[akx_id] := Pi/2;
+	 arc_inf[akx_id] := -Pi/2;
+	 coeff_x[akx_id] := false;
+	 coeff_y[akx_id] := false;
+      end
+      else if x >= 2*xmax/3 then
+      begin
+	 rotation[akx_id] := 0;
+	 arc_sup[akx_id] := Pi/2;
+	 arc_inf[akx_id] := -Pi/2;
+	 coeff_x[akx_id] := true;
+	 coeff_y[akx_id] := false;
+      end
+      else
+      begin
+	 rotation[akx_id] := 0;
+	 angle[akx_id] := Pi/10;
+	 arc_sup[akx_id] := 2*Pi;
+	 arc_inf[akx_id] := 0;
+         coeff_x[akx_id] := false;
+	 coeff_y[akx_id] := false;
+      end;
+   end;
+   deja_vu[akx_id] := true;
+
+   (* Si le tank est un ennemi qui vient d'etre capture par notre team, alors il signale qu'il n'est plus un ennemi. *)
+   ennemis[index_ennemis[akx_id]].etat := disparu;
+   index_ennemis[akx_id] := 0;
+
+   (* Le tank se declare dans la base de donnees globale. *)
+   inc(nombre_amis);
+   with amis[nombre_amis] do
+   begin
+      nature := tank;
+      x := akx_get_pos_x(akx_id);
+      y := akx_get_pos_y(akx_id);
+      id := akx_id;
+   end;
+
+   (* Le tank, lorsqu'il n'a aucun ordre de la part du programme, pulse autour de lui, selon certains parametres que le programme principal peut modifier a sa guise. *)
+   if not occupe[akx_id] then
+   begin
+      r := sqrt(2*akx_get_power/(angle[akx_id]*akx_get_see_power)-2/angle[akx_id]) - 0.001;
+      x := r * cos(rotation[akx_id]);
+      y := r * sin(rotation[akx_id]);
+      if coeff_x[akx_id] then x := -x;
+      if coeff_y[akx_id] then y := -y;
+      akx_pulse(akx_id, amis[nombre_amis].x+x, amis[nombre_amis].y+y, angle[akx_id]);
+      rotation[akx_id] := rotation[akx_id] + angle[akx_id];
+      if rotation[akx_id] > arc_sup[akx_id] then
+      begin
+	 rotation[akx_id] := arc_inf[akx_id];
+	 balayage[akx_id] := true;
+      end;
+   end;
+end;
+
+procedure player_r4d2_turn(r4d2_id : integer) ;
+begin
+   (* Si le robot est un ennemi qui vient d'etre capture par notre team, alors il signale qu'il n'est plus un ennemi. *)
+   ennemis[index_ennemis[r4d2_id]].etat := disparu;
+   index_ennemis[r4d2_id] := 0;
+
+   (* Le robot se declare dans la base de donnees globale. *)
+   inc(nombre_amis);
+   with amis[nombre_amis] do
+   begin
+      nature := robot;
+      x := r4d2_get_pos_x(r4d2_id);
+      y := r4d2_get_pos_y(r4d2_id);
+      id := r4d2_id;
+   end;
+end;
+
+begin
+end.

+ 178 - 0
data/clients/leo_cacheux.c

@@ -0,0 +1,178 @@
+#include <math.h>
+#include <time.h>
+#include <stdio.h>
+#include <malloc.h>
+#include "prolo.h"
+
+/* Structure pour stocker des coordonnees */
+typedef struct {
+    float x;
+    float y;
+} coord;
+
+
+/* Variables globales */
+coord map_size;
+int nb_akx, nb_r4d2;
+int my_akx, my_r4d2;
+int my_team;
+int change;
+int *dest;
+coord *dest_coord;
+int *units;
+
+
+/* Obtenir les coordonnees d'un r4d2 */
+coord get_r4d2_coord (int id)
+{
+    coord foo;
+    foo.x = r4d2_get_pos_x(id);
+    foo.y = r4d2_get_pos_y(id);
+    return foo;
+}
+
+
+/* Obtenir les coordonnees d'un Anakronox */
+coord get_akx_coord (int id)
+{
+    coord foo;
+    foo.x = akx_get_pos_x(id);
+    foo.y = akx_get_pos_y(id);
+    return foo;
+}
+
+
+/* Calcul de la distance entre deux points */
+float distance (coord a, coord b)
+{
+    return ( sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) ) );
+}
+
+
+void player_init (int team_id)
+{
+    int i;
+
+    map_size.x = map_get_size_x();
+    map_size.y = map_get_size_y();
+
+    nb_akx = map_count_akx();
+    nb_r4d2 = map_count_r4d2();
+
+    my_akx = map_count_my_akx();
+    my_r4d2 = map_count_my_r4d2();
+
+    change=1;
+
+    dest = (int*)malloc(sizeof(int)*nb_r4d2);
+    dest_coord = (coord*)malloc(sizeof(coord)*nb_r4d2);
+    units = (int*)malloc(sizeof(int)*(nb_akx+nb_r4d2));
+
+    for (i=0; i<nb_r4d2; i++)
+    {
+        dest[i] = -1;
+    }
+
+    for (i=0; i<nb_akx+nb_r4d2; i++)
+    {
+        units[i] = 0;
+    }
+}
+
+
+void player_new_turn (int turn_number)
+{
+
+}
+
+
+void player_akx_turn (int akx_id)
+{
+    int r4d2, akx;
+    coord r4d2_coord, akx_coord, my_coord;
+
+    my_team = akx_get_team(akx_id);
+    my_coord = get_akx_coord (akx_id);
+
+    printf ("%i\n",map_get_nearest_r4d2 (akx_id, -my_team));
+    printf ("%i\n",map_get_nearest_akx (akx_id, -my_team));
+
+    if ((r4d2 = map_get_nearest_r4d2 (akx_id, -my_team)) != -1)
+    {
+        change=0;
+        r4d2_coord = get_r4d2_coord (r4d2);
+        akx_pulse (akx_id, r4d2_coord.x, r4d2_coord.y, 0.2);
+        return;
+    }
+
+    if ((akx = map_get_nearest_akx (akx_id, -my_team)) != -1)
+    {
+        change=0;
+        akx_coord = get_akx_coord (akx);
+        akx_pulse (akx_id, akx_coord.x, akx_coord.y, 0.5);
+        return;
+    }
+
+    akx_pulse (akx_id, rand()%(int)map_size.x, rand()%(int)map_size.y, 0.2);
+    return;
+
+}
+
+
+void player_r4d2_turn (int r4d2_id)
+{
+    int savage_r4d2, savage_akx;
+    coord savage_r4d2_coord, savage_akx_coord;
+
+    /*
+    for (i=0; i<nb_r4d2; i++)
+      {
+        if (r4d2_get_team(i)==my_team && dest_coord[i].x==dest_coord[r4d2_id].x &&
+   dest_coord[i].y==dest_coord[r4d2_id].y && dest[i]!=-1 && i!=r4d2_id)
+          {
+            r4d2_move (r4d2_id, rand()%(int)map_size.x, rand()%(int)map_size.y);
+            return;
+          }
+      }
+    */
+
+    if ( (savage_r4d2 = map_get_nearest_r4d2 (r4d2_id, -my_team)) != -1)
+    {
+        units[savage_r4d2] = 1;
+        dest[r4d2_id] = savage_r4d2;
+        savage_r4d2_coord = get_r4d2_coord (savage_r4d2);
+        dest_coord[r4d2_id] = savage_r4d2_coord;
+        if (distance(get_r4d2_coord (r4d2_id), get_r4d2_coord (savage_r4d2)) <= 1)
+        {
+            dest[r4d2_id]=-1;
+            units[savage_r4d2] = 0;
+            change=1;
+            r4d2_take_r4d2 (r4d2_id, savage_r4d2);
+            return;
+        }
+    }
+
+    if ( (savage_akx = map_get_nearest_akx (r4d2_id, 0)) != -1)
+    {
+        units[savage_akx] = 1;
+        dest[r4d2_id] = savage_akx;
+        savage_akx_coord = get_akx_coord (savage_akx);
+        dest_coord[r4d2_id] = savage_akx_coord;
+        if (distance(savage_akx_coord, get_r4d2_coord (r4d2_id) ) <= 1)
+        {
+            units[savage_akx]=0;
+            dest[r4d2_id]=-1;
+            change=1;
+            r4d2_take_akx (r4d2_id, savage_akx);
+            return;
+        }
+    }
+
+    if (r4d2_get_status(r4d2_id) == 0 && dest[r4d2_id]!=-1)
+    {
+        r4d2_move (r4d2_id, dest_coord[r4d2_id].x, dest_coord[r4d2_id].y);
+        return;
+    }
+
+    r4d2_move (r4d2_id, rand()%(int)map_size.x, rand()%(int)map_size.y);
+}