diff --git a/travail_de_groupe/jeu_appren_par_renfo/Res/racket.png b/travail_de_groupe/jeu_appren_par_renfo/Res/racket.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c54b73d27e8ef725f32fa8bb27f8e725e2f4e1c
Binary files /dev/null and b/travail_de_groupe/jeu_appren_par_renfo/Res/racket.png differ
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/ball.c b/travail_de_groupe/jeu_appren_par_renfo/src/ball.c
index 87576c507bd66dad3d335b8efe69eb2cfdcfb4ff..4de5849e2c5c1fbf890b1372003632e90f2f4e30 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/ball.c
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/ball.c
@@ -7,13 +7,12 @@ void initBall()
 {
     ball.x = 5 * BLOCK_SIZE;
     ball.y = 5 * BLOCK_SIZE;
-    ball.z = player.h/BLOCK_SIZE;
+    ball.z = player.h / BLOCK_SIZE;
     ball.h = 0.5 * BLOCK_SIZE;
-    ball.w = 0.5 * BLOCK_SIZE;    
+    ball.w = 0.5 * BLOCK_SIZE;
     ball.isHit = 0;
     ball.angle = -pi;
     ball.speed = 0;
-
 }
 //ball_t ball;
 int trajectoireAntoine[NUMBERPOINT_TRAJEC][2];
@@ -127,3 +126,22 @@ void calculTrajectoireAntoine2(int xd, int yd, int xf, int yf, int xt, int yt)
     trajectoireAntoine[NUMBERPOINT_TRAJEC - 1][0] = xt;
     trajectoireAntoine[NUMBERPOINT_TRAJEC - 1][1] = yt;
 }
+
+void updateBall()
+{
+    ball.x = ball.x + ball.speed * cos(ball.angle);
+    ball.y = ball.y + ball.speed * sin(ball.angle);
+    if (ball.isHit)
+    {
+        // landingPoint est déjà / BLOCK_SIZE de base
+        ball.z = lagrangeInterpolation(ball.x / BLOCK_SIZE, lastHitPoint[0] / BLOCK_SIZE, lastHitPoint[1] / BLOCK_SIZE, 15, 2 * player.h / BLOCK_SIZE, landingPoint[0], 0);
+    }
+
+    if ((int)ball.z == 0)
+    {
+        ball.x = 0;
+        ball.y = 0;
+        ball.z = 0;
+        ball.speed = 0;
+    }
+}
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/ball.h b/travail_de_groupe/jeu_appren_par_renfo/src/ball.h
index 393bd56723adcbadb1f1381290f64c89a1dbfc90..fb82d4cd05dee4c0e096475de3cb6de1bcec3882 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/ball.h
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/ball.h
@@ -13,6 +13,9 @@
 
 #define NUMBERPOINT_TRAJEC 50
 
+#define PLAYER 0
+#define AI 1
+
 typedef enum
 {
     false, true
@@ -29,6 +32,7 @@ typedef struct ball
     int isHit;
     float angle;
     int speed;
+    int isTravelingTo;
 } ball_t;
 
 extern ball_t ball;
@@ -40,9 +44,12 @@ typedef struct point{
 //extern ball_t ball;
 extern int trajectoireAntoine[NUMBERPOINT_TRAJEC][2];
 
+void initBall();
+float defineAngle(int, int, int, int);
+void updateBall();
 point_t  initCanon (point_t canon);
 point_t initDropPoint (point_t dropPoint);
-float defineAngleF(int, int, int, int);
+float defineAngleF(int canonX, int canonY, int xDropPoint, int yDropPoint);
 float defineAngleH(int xCanon, int xDropPoint);
 
 float lagrangeInterpolation(float, int, int, int, int, int, int);
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/ennemy.c b/travail_de_groupe/jeu_appren_par_renfo/src/ennemy.c
new file mode 100644
index 0000000000000000000000000000000000000000..a44030c15c8406b19c363524eb36be5b2e76f271
--- /dev/null
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/ennemy.c
@@ -0,0 +1,55 @@
+#include "player.h"
+
+int angleF;
+int angleH;
+int ennemyZone;
+int canonZone;
+int action;
+
+void initEnnemy()
+{
+    ennemy.h = 2 * BLOCK_SIZE;
+    ennemy.w = 2 * BLOCK_SIZE;
+    ennemy.x = 25 * BLOCK_SIZE;
+    ennemy.y = 5 * BLOCK_SIZE;
+    ennemy.angle = -pi;
+    ennemy.speed = MOVEMENT_SPEED;
+}
+
+void manageEnnemyMovement()
+{
+    if (ball.isTravelingTo == AI){
+        angleF = defineAngleF(lastHitPoint[0], lastHitPoint[1], landingPoint[0], landingPoint[1]);
+        angleF = converterIntoAngleF(angleF);
+        angleH = defineAngleH(lastHitPoint[0], landingPoint[0]);
+        angleH = converterIntoAngleH(angleH);
+        ennemyZone = convertIntoZone(ennemy.x, ennemy.y);
+        canonZone = convertIntoZone(lastHitPoint[0], lastHitPoint[1]);
+        action = takeAction(ennemy.x, ennemy.y, Q, canonZone, angleH, angleF, 0);
+        switch (action)
+        {
+            case BACK:
+                ennemy.x += MOVEMENT_SPEED;
+                break;
+
+            case FOWARD:
+                ennemy.x -= MOVEMENT_SPEED;
+                break;
+
+            case UP:
+                ennemy.y -= MOVEMENT_SPEED;
+                break;
+
+            case DOWN:
+                ennemy.y += MOVEMENT_SPEED;
+                break;
+            
+            default:
+                break;
+        }
+    }
+}
+
+void manageEnnemy(){
+    manageEnnemyMovement();
+}
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/ennemy.h b/travail_de_groupe/jeu_appren_par_renfo/src/ennemy.h
new file mode 100644
index 0000000000000000000000000000000000000000..660453be677e92987bb34dee561e04e36fa87d61
--- /dev/null
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/ennemy.h
@@ -0,0 +1,16 @@
+#ifndef ENNEMY_H
+#define ENNEMY_H
+
+#include "player.h"
+#include "map.h"
+#include "render.h"
+#include "ball.h"
+#include "qlearn.h"
+
+
+
+
+void initEnnemy();
+void manageEnnemy();
+
+#endif
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.c b/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.c
index b014b4c107a7abe2e10af291b4b57ef39ba727c1..e5299afa87faae35dcc1eb97927c6f1d1d686861 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.c
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.c
@@ -53,6 +53,7 @@ void gestGame()
             break;
 
         case SDL_MOUSEMOTION:
+            // mouvement de caméra
             if (event.motion.xrel > 0)
             {
                 player.angle += 0.01;
@@ -104,6 +105,16 @@ void gestGame()
                 Keys[1] = 1;
                 continue;
 
+            case SDLK_h:
+                if (showHub == 0)
+                {
+                    showHub = 1;
+                }
+                else
+                {
+                    showHub = 0;
+                }
+
             default:
                 break;
             }
@@ -134,10 +145,12 @@ void gestGame()
         case SDL_MOUSEBUTTONDOWN:
             if (event.button.button == SDL_BUTTON_LEFT)
             {
-                if (player.isHitting){
+                if (player.isHitting)
+                {
                     player.isHitting = 0;
                 }
-                else {
+                else
+                {
                     player.isHitting = 1;
                 }
             }
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.h b/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.h
index 9256d7dd965c715db4fa68367bbcd0e589793475..3546dba53048f3d5fc2e00ee3e7de16814ab680f 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.h
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/gest_event.h
@@ -1,7 +1,6 @@
 #ifndef _GEST_EVENT_H_
 #define _GEST_EVENT_H_
 
-
 #include "main.h"
 #include "render.h"
 
@@ -12,4 +11,4 @@ extern int Keys[NB_KEYS];
 void *EventLoop(void *arg);
 void initKeys();
 
-#endif 
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/main.c b/travail_de_groupe/jeu_appren_par_renfo/src/main.c
index fc78b9bfa87cf68d1270b0e98a7b362870ba6407..1e1570e9e5c0e13907cc3127c15bad4181cc64e6 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/main.c
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/main.c
@@ -2,10 +2,10 @@
 
 int running;
 int game_state;
-
-
+float ***** Q;
 int main(){ 
-    float ***** Q = allocateAndInitiateQ();
+    Q = allocateAndInitiateQ();
+    readQFromFile(Q);
     int i= 10;
     
     srand ( time(NULL));
@@ -22,4 +22,6 @@ int main(){
     
     // mainLoop();
 
-} 
\ No newline at end of file
+
+    mainLoop();
+}
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/main.h b/travail_de_groupe/jeu_appren_par_renfo/src/main.h
index 8b5b70cd140f103f3ec088ee075443341bcfc151..3edf7a052106c8b26d9598a54cc73d7894fec362 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/main.h
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/main.h
@@ -1,7 +1,6 @@
 #ifndef _MAIN_HEADER_
 #define _MAIN_HEADER_
 
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -14,17 +13,18 @@
 
 #include <pthread.h>
 
-#include "render.h"
 #include "gest_event.h"
+#include "player.h"
+#include "ennemy.h"
 #include "map.h"
 #include "qlearn.h"
-
+#include "render.h"
 
 #define MENU 0
 #define GAME 1
 
 extern int running;
 extern int game_state;
+extern float ***** Q;
 
-
-#endif 
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/map.c b/travail_de_groupe/jeu_appren_par_renfo/src/map.c
index 97e1d63b3ea8ff94e670af0deee711c18007500b..ac663274cf65c3bbbf5c287e6d5cac86e3c1a486 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/map.c
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/map.c
@@ -2,27 +2,32 @@
 
 int map[MAP_HEIGHT][MAP_WIDTH];
 
-
-void readMapFromFile(char *file_name){
+void readMapFromFile(char *file_name)
+{
     FILE *file = fopen(file_name, "r");
-    if (file == NULL){
+    if (file == NULL)
+    {
         printf("Couldn't open map file.");
         exit(EXIT_FAILURE);
     }
     int i, j;
-    for (i = 0; i < MAP_HEIGHT ; i++){
-        for (j = 0; j < MAP_WIDTH; j++){
+    for (i = 0; i < MAP_HEIGHT; i++)
+    {
+        for (j = 0; j < MAP_WIDTH; j++)
+        {
             fscanf(file, "%d", &map[i][j]);
         }
     }
     fclose(file);
 }
 
-
-void printMap(){
+void printMap()
+{
     int i, j;
-    for (i = 0; i < MAP_HEIGHT; i++){
-        for (j = 0; j < MAP_WIDTH; j++){
+    for (i = 0; i < MAP_HEIGHT; i++)
+    {
+        for (j = 0; j < MAP_WIDTH; j++)
+        {
             printf("%d ", map[i][j]);
         }
         printf("\n");
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/map.h b/travail_de_groupe/jeu_appren_par_renfo/src/map.h
index e39b4457df85bbffcce3cc937c3a2a35f2a98c46..20248bf32b3782ecbdce1d8c4407e0eba8ce9d40 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/map.h
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/map.h
@@ -1,13 +1,15 @@
 #ifndef MAP_HEADER_
 #define MAP_HEADER_
 
-#include "main.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
+//#include "main.h"
 
 #define MAP_WIDTH 31
 #define MAP_HEIGHT 11
 
-
 extern int map[MAP_HEIGHT][MAP_WIDTH];
 
 void readMapFromFile(char *file_name);
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/player.c b/travail_de_groupe/jeu_appren_par_renfo/src/player.c
index 4122ff22f59a621d5df8965bf95c52451154525b..38c4aaef56752fa8cdef19b3163d9ea8dac7fa0a 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/player.c
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/player.c
@@ -35,10 +35,10 @@ int *generateLandingPoint(int rxWall)
     int *landingPoint = malloc(sizeof(int) * 2);
     srand(time(NULL));
 
-    int randomPointX = MAP_WIDTH/2 + 1 + rand()%(rxWall/BLOCK_SIZE - (MAP_WIDTH/2));
+    int randomPointX = MAP_WIDTH / 2 + 1 + rand() % (rxWall / BLOCK_SIZE - (MAP_WIDTH / 2));
     int randomPointY = -1;
 
-    landingPoint[0] = randomPointX ;
+    landingPoint[0] = randomPointX;
     landingPoint[1] = randomPointY / BLOCK_SIZE;
     landingPointIsFind = 1;
 
@@ -72,16 +72,16 @@ void hitBall()
         float distanceNet;
         if (player.isHitting)
         {
-        castSingleRay(player.angle, &distanceWall, &distanceNet, &rxWall, &ryWall, &rxNet, &ryNet);
-            // printf("hit\n");
-            if (rxWall > MAP_WIDTH/2)
+            castSingleRay(player.angle, &distanceWall, &distanceNet, &rxWall, &ryWall, &rxNet, &ryNet);
+            if (rxWall > MAP_WIDTH / 2)
             {
-                
+
                 freeIntList(lastHitPoint);
                 lastHitPoint = allocLastHitPoint();
 
-                //cherche et trouve point de chute, UNE SEULE FOIS!
-                if(landingPointIsFind == 0){
+                // cherche et trouve point de chute, UNE SEULE FOIS!
+                if (landingPointIsFind == 0)
+                {
                     freeIntList(landingPoint);
                     landingPoint = generateLandingPoint(rxWall);
                     printf("landing point: x=%d; y=%d\n", landingPoint[0], landingPoint[1]);
@@ -94,47 +94,12 @@ void hitBall()
                 ball.speed = 2 * HIT_FORCE;
                 ball.z = player.h;
                 ball.isHit = 1;
+                ball.isTravelingTo = AI;
             }
-            // printf("valid hit\n");
-        }
-        else
-        {
-            // printf("unvalid hit\n");
         }
     }
-    //}
 }
 
-void updateBall()
-{
-    ball.x = ball.x + ball.speed * cos(ball.angle);
-    ball.y = ball.y + ball.speed * sin(ball.angle);
-    if (ball.isHit)
-    {
-        // landingPoint est déjà / BLOCK_SIZE de base
-        ball.z = lagrangeInterpolation(ball.x / BLOCK_SIZE, lastHitPoint[0] / BLOCK_SIZE, lastHitPoint[1] / BLOCK_SIZE, 15, 2 * player.h / BLOCK_SIZE, landingPoint[0], 0);
-        if (ball.z > 0)
-        {
-            /*printf("param. lagrange : xp=%f, xd=%d, yd=%d, xf=%d, yf=%d, xt=%d, yt=%d\n",
-                   ball.x / BLOCK_SIZE,
-                   lastHitPoint[0] / BLOCK_SIZE,
-                   lastHitPoint[1] / BLOCK_SIZE,
-                   15,
-                   2 * player.h / BLOCK_SIZE,
-                   landingPoint[0],
-                   0);
-            printf("ballZ: %f\n", ball.z);*/
-        }
-    }
-
-    if ((int)ball.z == 0)
-    {
-        ball.x = 0;
-        ball.y = 0;
-        ball.z = 0;
-        ball.speed = 0;
-    }
-}
 
 void manageMovement()
 {
@@ -144,9 +109,10 @@ void manageMovement()
     // d : keys[3] : droite
     float x_increment = (Keys[0] - Keys[2]) * player.deltax + (Keys[3] - Keys[1]) * sin(player.angle);
     float y_increment = (Keys[0] - Keys[2]) * player.deltay + (Keys[1] - Keys[3]) * cos(player.angle);
-    float newpos_x = (player.x + x_increment) / BLOCK_SIZE;
-    float newpos_y = (player.y + y_increment) / BLOCK_SIZE;
-    if (newpos_x >= 0 && newpos_x < MAP_WIDTH && newpos_y >= 0 && newpos_y < MAP_HEIGHT)
+    float newpos_x = (player.x + x_increment * MOVEMENT_SPEED) / BLOCK_SIZE;
+    float newpos_y = (player.y + y_increment * MOVEMENT_SPEED) / BLOCK_SIZE;
+    int widthColli = player.w / (3 * BLOCK_SIZE);
+    if (newpos_x > widthColli && newpos_x < MAP_WIDTH - widthColli && newpos_y > widthColli && newpos_y < MAP_HEIGHT - widthColli)
     {
         if (map[(int)newpos_y][(int)newpos_x] != 1)
         {
@@ -160,5 +126,4 @@ void managePlayer()
 {
     manageMovement();
     hitBall();
-    updateBall();
 }
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/player.h b/travail_de_groupe/jeu_appren_par_renfo/src/player.h
index ebe9a2dbf350d550cbf6316a206180b2c86ce997..af0ca971a4fb605ec00e9cf372f9232ed12df0d7 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/player.h
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/player.h
@@ -11,10 +11,11 @@
 #define ENTITIES_RIGHT 3
 
 #define HIT_RANGE 2
-#define HIT_FORCE 20
+#define HIT_FORCE 10
+#define MOVEMENT_SPEED 10
 
-#define MOVEMENT_SPEED 20
-typedef struct player{
+typedef struct player
+{
     float x;
     float y;
     float z;
@@ -36,6 +37,9 @@ typedef struct player{
 
 extern player_t player;
 extern player_t ennemy;
+extern int *landingPoint;
+extern int *lastHitPoint;
+extern int landingPointIsFind;
 
 void initPlayer();
 void managePlayer();
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.c b/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.c
index 5f67460c97b9d913378d99fdd1fa4ef6c9a07e3f..4fea238ffaafef9c61755db7614697a864769ba4 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.c
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.c
@@ -110,6 +110,23 @@ void writeQ(float *****Q){
     fclose(fp);
 }
 
+void readQFromFile(float *****Q){
+    int i, j, k, l, m ;
+    FILE * fp = fopen("q.txt", "r");
+    for(i = 0; i < NUMBER_ZONE_RECEIVER; i++){
+        for(j = 0; j < NUMBER_ZONE_SHOOTER; j++){
+            for(k = 0; k < 3; k++){
+                for(l= 0; l < 5; l++){
+                    for(m= 0; m <5; m++){
+                         fscanf(fp, "%f ", &Q[i][j][k][l][m]);
+                    }
+                }
+            }
+        }
+    }
+    fclose(fp);
+}
+
 
 int argmax(float * arr){
     int i;
@@ -408,63 +425,4 @@ void traningAgent ( int numberRun, int numberStep, float *****Q) {// pour avoir
         numberRun--; 
     }
     freeStack(stack); 
-
-
-
-
-
-
-
-
-    //     printf("%d %d %d %d \n",dropZone, canonZone,zoneAngleH,zoneAngleF);
-    //     printf("%d %d  \n",agent->x, agent->y);
-
-    //     for (i=0; i<numberStep-1;i++){ 
-    //         action = takeAction(agent->x,agent->y,Q,canonZone,zoneAngleH,zoneAngleF,greedy); 
-    //         agentZone = convertIntoZone(agent->x, agent->y); 
-    //         line.receiverZone=agentZone; 
-    //         line.shooterZone =canonZone; 
-    //         line.angleHZone= zoneAngleH; 
-    //         line.angleFZone= zoneAngleF; 
-    //         line.action= action;
-    //         line.reward= reward ; 
-    //         actionStack(stack,line);
-    //         moveAgent(agent, action);
-
-    //     }
-    //     action = takeAction(agent->x, agent->y,Q,canonZone,zoneAngleH,zoneAngleF,greedy); 
-    //     agentZone = convertIntoZone(agent->x, agent->y); 
-       
-    //     line.receiverZone=agentZone; 
-    //     line.shooterZone =canonZone; 
-    //     line.angleHZone= zoneAngleH; 
-    //     line.angleFZone= zoneAngleF; 
-    //     line.action= action;
-    //     line.reward = 0; 
-    //    // actionStack(stack,line);
-    //     moveAgent(agent, action);
-    //      if (agentZone==dropZone){ 
-    //                reward=1; 
-    //             }
-    //             else{reward= 0;}
-        
-
-    //     Q[line.receiverZone][line.shooterZone][line.angleHZone][line.angleFZone][line.action] +=  
-    //                 + LEARN_RATE* ( reward - Q[line.receiverZone][line.shooterZone][line.angleHZone][line.angleFZone][line.action] );
-       
-    //     while (!emptyStack(stack)){
-    //         maxAction= argmax(Q[line.receiverZone][line.shooterZone][line.angleHZone][line.angleFZone]);
-    //         reward=line.reward;
-    //         line=unStack(stack);
-
-    //         Q[line.receiverZone][line.shooterZone][line.angleHZone][line.angleFZone][line.action] +=  
-    //                 + LEARN_RATE* ( reward +  DISCOUNT*Q[line.receiverZone][line.shooterZone][line.angleHZone][line.angleFZone][maxAction]
-    //                 - Q[line.receiverZone][line.shooterZone][line.angleHZone][line.angleFZone][line.action] );
-    //     }  
-    //     numberRun--; 
-    //     greedy=greedy-1/((float)numberRun);
-
-    //     if ( numberRun%1000000==1){printf (" %d \n  ", numberRun);} 
-    // } 
-    // freeStack(stack);
 } 
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.h b/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.h
index 60fe308715821fa9a24e68b723829f1d0e5b9c93..0de0a4563b67d2f222de7c891a38abf29ee24654 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.h
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/qlearn.h
@@ -63,7 +63,7 @@ int convertIntoZone(int ,int y);
 int convertIntoZoneCanon(int xCanon,int yCanon);
 int converterIntoAngleF(float);
 int converterIntoAngleH(float);
-int takeAction(int ,int , float ***** , int , int, int, float );
+int takeAction(int xAgent, int yAgent, float ***** Q, int canonZone, int angleHZone, int angleFZone, float eps);
 int setReward(int , int , int );
 stack_t* initStack (int nbelt);
 int emptyStack (stack_t *stack);
@@ -72,4 +72,5 @@ void actionStack(stack_t *stack, line_t line);
 line_t unStack(stack_t *stack);
 void freeStack(stack_t *stack);
 void traningAgent( int numberRun, int numberStep, float *****Q);
+void readQFromFile(float *****Q);
 #endif
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/render.c b/travail_de_groupe/jeu_appren_par_renfo/src/render.c
index 14eebf743f7f0b2a6149d372b2259850ba6bd21a..02e079b78af567065ebabd7ad487b8261ff451de 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/render.c
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/render.c
@@ -10,6 +10,9 @@ SDL_Rect destRect;
 SDL_Rect rect;
 SDL_Rect sky;
 SDL_Rect ground;
+SDL_Rect racket;
+
+int showHub = 0;
 
 SDL_Texture *netTexture;
 SDL_Texture *netEdgeLeftTexture;
@@ -19,6 +22,7 @@ SDL_Texture *playerTexture;
 SDL_Texture *ballTexture;
 SDL_Texture *skyTexture;
 SDL_Texture *groundTexture;
+SDL_Texture *racketTexture;
 
 int **rays;
 int raysListLength = 0;
@@ -49,7 +53,6 @@ void freeRayInfoList(rayInfo_t *rayInfoHead)
     rayInfo_t *rayInfo = rayInfoHead->next;
     while (rayInfo != NULL)
     {
-        // printf("freeing : %p\n", rayInfo);
         rayInfo_t *next = rayInfo->next;
         free(rayInfo);
         rayInfo = next;
@@ -125,7 +128,7 @@ void createWindow()
 
     SDL_GetCurrentDisplayMode(0, &screenDimension);
 
-    window = SDL_CreateWindow("Mat Le King", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screenDimension.w, screenDimension.h, SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP);
+    window = SDL_CreateWindow("Mat Le Tennisman", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screenDimension.w, screenDimension.h, SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP);
 
     if (window == NULL)
     {
@@ -151,6 +154,16 @@ void createWindow()
 
 void endSDL()
 {
+    SDL_DestroyTexture(netTexture);
+    SDL_DestroyTexture(netEdgeLeftTexture);
+    SDL_DestroyTexture(netEdgeRightTexture);
+    SDL_DestroyTexture(crowdTexture);
+    SDL_DestroyTexture(playerTexture);
+    SDL_DestroyTexture(ballTexture);
+    SDL_DestroyTexture(skyTexture);
+    SDL_DestroyTexture(groundTexture);
+    SDL_DestroyTexture(racketTexture);
+
     SDL_DestroyWindow(window);
     SDL_DestroyRenderer(renderer);
     TTF_CloseFont(RobotoFont);
@@ -181,16 +194,18 @@ void drawRayColumn(rayInfo_t *rayInfo)
     if (rayInfo->isTransparent)
     {
         rect.h *= 1.2;
-        // rect.y -= rect.h/3;
-        if (map[rayInfo->ry/BLOCK_SIZE][rayInfo->rx/BLOCK_SIZE] == 3){
+        if (map[rayInfo->ry / BLOCK_SIZE][rayInfo->rx / BLOCK_SIZE] == 3)
+        {
             SDL_RenderCopy(renderer, netEdgeLeftTexture, &destRect, &rect);
         }
-        
-        if (map[rayInfo->ry/BLOCK_SIZE][rayInfo->rx/BLOCK_SIZE] == 4){
+
+        if (map[rayInfo->ry / BLOCK_SIZE][rayInfo->rx / BLOCK_SIZE] == 4)
+        {
             SDL_RenderCopy(renderer, netEdgeRightTexture, &destRect, &rect);
         }
 
-        else {
+        else
+        {
             SDL_RenderCopy(renderer, netTexture, &destRect, &rect);
         }
     }
@@ -208,11 +223,11 @@ void drawRayColumn(rayInfo_t *rayInfo)
     }
 }
 
-void drawVerticalWalls(){
+void drawVerticalWalls()
+{
     rayInfo_t *current = raysListHead.next;
     while (current != NULL)
     {
-        // printf("%p\n", current);
         if (current->direction && !current->isTransparent)
         {
             drawRayColumn(current);
@@ -221,11 +236,11 @@ void drawVerticalWalls(){
     }
 }
 
-void drawVerticalNet(){
+void drawVerticalNet()
+{
     rayInfo_t *current = raysListHead.next;
     while (current != NULL)
     {
-        // printf("%p\n", current);
         if (current->direction && current->isTransparent)
         {
             drawRayColumn(current);
@@ -239,7 +254,6 @@ void drawHorizentalWalls()
     rayInfo_t *current = raysListHead.next;
     while (current != NULL)
     {
-        // printf("%p\n", current);
         if (!current->direction)
         {
             drawRayColumn(current);
@@ -248,6 +262,202 @@ void drawHorizentalWalls()
     }
 }
 
+void castSingleRay(float angle, float *distanceWall, float *distanceNet, int *returnXWall, int *returnYWall, int *returnXNet, int *returnYNet)
+{
+    // ray casting variables
+    int mx, my, dof;
+    double rx, ry, rx2, ry2, xo, yo, distT2;
+    double ra;
+    mx = 0;
+    my = 0;
+    raysListHead.next = NULL;
+    ra = angle;
+    if (ra < 0)
+        ra -= 2 * pi;
+    if (ra > 2 * pi)
+        ra -= 2 * pi;
+    // check horizontal rays
+    int foundSolidWallH = 0;
+    dof = 0;
+    float disH, hx = player.x, hy = player.y, hx2 = player.x, hy2 = player.y;
+    float aTan = -1 / tan(ra);
+    if (ra > pi)
+    { // looking up
+        ry = (((int)player.y >> 6) << 6) - 0.0001;
+        rx = (player.y - ry) * aTan + player.x;
+        yo = -BLOCK_SIZE;
+        xo = -yo * aTan;
+    }
+    if (ra < pi)
+    { // looking down
+        ry = (((int)player.y >> 6) << 6) + BLOCK_SIZE;
+        rx = (player.y - ry) * aTan + player.x;
+        yo = BLOCK_SIZE;
+        xo = -yo * aTan;
+    }
+    if (ra == pi)
+    {
+        ry = player.y;
+        rx = player.x;
+        dof = DOF;
+    }
+    while (dof < DOF)
+    {
+        mx = (int)rx >> 6;
+        my = (int)ry >> 6;
+        if (mx >= 0 && mx < MAP_WIDTH && my >= 0 && my < MAP_HEIGHT)
+        {
+            if (map[my][mx] == 1)
+            {
+                hx = rx;
+                hy = ry;
+                disH = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
+                dof = DOF;
+                foundSolidWallH = 1;
+            }
+            else
+            {
+                hx2 = rx;
+                hy2 = ry;
+                dof++;
+                rx += xo;
+                ry += yo;
+            }
+        }
+        else
+        {
+            rx += xo;
+            ry += yo;
+            dof++;
+        }
+    }
+
+    // check vertical rays
+    dof = 0;
+    float disV = 100000, disV2 = 100000, vx = player.x, vy = player.y, vx2, vy2;
+    float nTan = -tan(ra);
+    if (ra > pi / 2 && ra < 3 * pi / 2)
+    { // looking left
+        rx = (((int)player.x >> 6) << 6) - 0.0001;
+        ry = player.y + (player.x - rx) * nTan;
+        xo = -BLOCK_SIZE;
+        yo = -xo * nTan;
+    }
+    if (ra < pi / 2 || ra > 3 * pi / 2)
+    { // looking right
+        rx = (((int)player.x >> 6) << 6) + BLOCK_SIZE;
+        ry = player.y + (player.x - rx) * nTan;
+        xo = BLOCK_SIZE;
+        yo = -xo * nTan;
+    }
+    if (ra == pi || ra == 0)
+    {
+        ry = player.y;
+        rx = player.x;
+        dof = DOF;
+    }
+    int foundSolidWallV = 0;
+    int foundTransparentWallV = 0;
+    while (dof < DOF)
+    {
+        mx = (int)rx >> 6;
+        my = (int)ry >> 6;
+        if (mx >= 0 && mx < MAP_WIDTH && my >= 0 && my < MAP_HEIGHT && map[my][mx])
+        {
+            if (map[my][mx] == 1)
+            {
+                vx = rx;
+                vy = ry;
+                disV = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
+                foundSolidWallV = 1;
+                dof = DOF;
+            }
+            else
+            {
+                vx2 = rx;
+                vy2 = ry;
+                disV2 = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
+                foundTransparentWallV = 1;
+                dof++;
+                rx += xo;
+                ry += yo;
+            }
+        }
+        else
+        {
+            rx += xo;
+            ry += yo;
+            dof++;
+        }
+    }
+
+    if (foundTransparentWallV)
+    {
+        if (disH < disV2)
+        {
+            rx = hx2;
+            ry = hy2;
+            distT2 = disV2;
+        }
+        else
+        {
+            rx = vx2;
+            ry = vy2;
+        }
+        if (foundSolidWallV)
+        {
+            if (disH < disV)
+            {
+                rx2 = hx;
+                ry2 = hy;
+                distT2 = disH;
+            }
+            else
+            {
+                rx2 = vx;
+                ry2 = vy;
+                distT2 = disV;
+            }
+        }
+        if (foundSolidWallH)
+        {
+            if (disH < disV)
+            {
+                rx2 = hx;
+                ry2 = hy;
+                distT2 = disH;
+            }
+            else
+            {
+                rx2 = vx;
+                ry2 = vy;
+                distT2 = disV;
+            }
+        }
+    }
+    else
+    {
+        if (disH < disV)
+        {
+            rx = hx;
+            ry = hy;
+        }
+        else
+        {
+            rx = vx;
+            ry = vy;
+        }
+    }
+
+    *returnXWall = (int)rx2;
+    *returnYWall = (int)ry2;
+    *distanceWall = distT2;
+
+    *returnXNet = (int)rx;
+    *returnYNet = (int)ry2;
+    *distanceNet = (int)distT2;
+}
+
 void castRays(int map[][MAP_WIDTH])
 {
     // ray casting variables
@@ -268,7 +478,6 @@ void castRays(int map[][MAP_WIDTH])
     for (r = 0; r < NB_RAYS; r++)
     {
         // check horizontal rays
-        // int foundTransparentWallH = 0;
         int foundSolidWallH = 0;
         dof = 0;
         float disH = 100000, disH2 = 100000, hx = player.x, hy = player.y, hx2 = player.x, hy2 = player.y;
@@ -312,7 +521,6 @@ void castRays(int map[][MAP_WIDTH])
                     hx2 = rx;
                     hy2 = ry;
                     disH2 = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
-                    // foundTransparentWallH = 1;
                     dof++;
                     rx += xo;
                     ry += yo;
@@ -326,8 +534,6 @@ void castRays(int map[][MAP_WIDTH])
             }
         }
 
-        // printf("hx %f hy %f\n", hx, hy);
-
         // check vertical rays
         dof = 0;
         float disV = 100000, disV2 = 100000, vx = player.x, vy = player.y, vx2, vy2;
@@ -446,7 +652,6 @@ void castRays(int map[][MAP_WIDTH])
                 }
             }
         }
-
         else
         {
             if (disH < disV)
@@ -489,24 +694,7 @@ void castRays(int map[][MAP_WIDTH])
                 addRayInfoToList(&raysListHead, column);
             }
         }
-        // draw the ray in the minimap
-        if (r == 0)
-        {
-            // printf("%d %d\n", (int)rx, (int)ry);
-            ray1[0] = (int)rx;
-            ray1[1] = (int)ry;
-            // printf("ray1 %d %d\n", ray1[0], ray1[1]);
-            // printf("ray2 %d %d\n", ray2[0], ray2[1]);
-        }
-        if (r == NB_RAYS - 1)
-        {
-            // printf("%d %d\n", (int)rx, (int)ry);
-            ray2[0] = (int)rx;
-            ray2[1] = (int)ry;
-            // printf("ray1 %d %d\n", ray1[0]/BLOCK_SIZE, ray1[1]/BLOCK_SIZE);
-            /// printf("ray2 %d %d\n", ray2[0]/BLOCK_SIZE, ray2[1]/BLOCK_SIZE);
-        }
-        // printf("raylistlength %d\n", raysListLength);
+
         addRayToList(rx, ry);
         addRayToList(rx2, ry2);
     }
@@ -515,19 +703,11 @@ void castRays(int map[][MAP_WIDTH])
 void drawEnnemy()
 {
     float ennemyAngle = atan2((ennemy.y + ennemy.w / 2) - (player.y + player.w / 2), (ennemy.x + ennemy.w / 2) - (player.x + player.w / 2));
-    // if (ennemyAngle < 0) ennemyAngle += 2*pi;
-    // if (ennemyAngle > 2*pi) ennemyAngle -= 2*pi;
     float ennemyDistance = sqrt((ennemy.x - player.x) * (ennemy.x - player.x) + (ennemy.y - player.y) * (ennemy.y - player.y)) * BLOCK_SIZE;
-    float ennemyBaseWidth = BLOCK_SIZE;
-    float ennemyDistanceX = ennemyDistance * cos(ennemyAngle - player.angle) * BLOCK_SIZE;
-    float ennemyDistanceY = ennemyDistance * fabs(sin(ennemyAngle - player.angle)) * BLOCK_SIZE;
-    float scaledEnnemyWidth = ennemyBaseWidth / sqrt(3);
     int ennemyWidth = 50;
     int ennemyHeight = 200;
     float angleMin = player.angle - (FOV_ANGLE * DR) / 2;
-    // if (angleMin > 2*pi) angleMin -= 2*pi;
     float angleMax = player.angle + (FOV_ANGLE * DR) / 2;
-    // if (angleMax < 0) angleMax += 2*pi;
     if (angleMin < 0)
     {
         angleMin += 2 * pi;
@@ -537,22 +717,14 @@ void drawEnnemy()
     {
         angleMax -= 2 * pi;
         angleMin -= 2 * pi;
-        // ballAngle -= 2*pi;
     }
     if (angleMax > 0 && angleMin > 0 && ennemyAngle < 0)
     {
         ennemyAngle += 2 * pi;
     }
 
-    // printf("ennemy angle: %f player angle: %f\n", ennemyAngle * RD, player.angle * RD);
-    // printf("limit angles: %f %f\n", angleMin * RD, angleMax * RD);
-    // printf("%f %f\n", ennemyAngle, player.angle - (FOV_ANGLE)/2 * DR);
-    // printf("%f\n", player.angle * RD);
-
     if (ennemyAngle >= angleMin && ennemyAngle <= angleMax)
     {
-        // printf("player angle %f\n", player.angle * RD);
-        // printf("ennemy angle %f\n", ennemyAngle * RD);
         rect.x = screenDimension.w / 2 + (screenDimension.w * tan(ennemyAngle - player.angle)) * sqrt(3) * 0.5;
         rect.w = (ennemyWidth * screenDimension.w) / (ennemyDistance / BLOCK_SIZE);
         rect.h = (ennemyHeight * screenDimension.h) / (ennemyDistance / BLOCK_SIZE);
@@ -568,8 +740,6 @@ void drawEnnemy()
         if (angleSum < 0)
             angleSum += 2 * pi;
 
-        // printf("sum: %f\n", angleSum * RD);
-
         if (angleSum > 5 * pi / 3 && angleSum <= pi / 3)
         {
             destRect.x = 2 * destRect.w;
@@ -586,261 +756,26 @@ void drawEnnemy()
         {
             destRect.x = 1 * destRect.w;
         }
-        // printf("%d %d %d %d\n", rect.x, rect.y, rect.w, rect.h);
         SDL_RenderCopy(renderer, playerTexture, &destRect, &rect);
     }
 }
 
-void castSingleRay(float angle, float *distanceWall, float *distanceNet, int *returnXWall, int *returnYWall, int *returnXNet, int *returnYNet)
-{
-    // ray casting variables
-    float htexture, htexture2;
-    int r, mx, my, dof;
-    double rx, ry, rx2, ry2, xo, yo, distT, distT2;
-    double ra;
-    mx = 0;
-    my = 0;
-    raysListHead.next = NULL;
-    ra = angle;
-    if (ra < 0)
-        ra -= 2 * pi;
-    if (ra > 2 * pi)
-        ra -= 2 * pi;
-    // check horizontal rays
-    // int foundTransparentWallH = 0;
-    int foundSolidWallH = 0;
-    dof = 0;
-    float disH = 100000, disH2 = 100000, hx = player.x, hy = player.y, hx2 = player.x, hy2 = player.y;
-    float aTan = -1 / tan(ra);
-    if (ra > pi)
-    { // looking up
-        ry = (((int)player.y >> 6) << 6) - 0.0001;
-        rx = (player.y - ry) * aTan + player.x;
-        yo = -BLOCK_SIZE;
-        xo = -yo * aTan;
-    }
-    if (ra < pi)
-    { // looking down
-        ry = (((int)player.y >> 6) << 6) + BLOCK_SIZE;
-        rx = (player.y - ry) * aTan + player.x;
-        yo = BLOCK_SIZE;
-        xo = -yo * aTan;
-    }
-    if (ra == pi)
-    {
-        ry = player.y;
-        rx = player.x;
-        dof = DOF;
-    }
-    while (dof < DOF)
-    {
-        mx = (int)rx >> 6;
-        my = (int)ry >> 6;
-        if (mx >= 0 && mx < MAP_WIDTH && my >= 0 && my < MAP_HEIGHT)
-        {
-            if (map[my][mx] == 1)
-            {
-                hx = rx;
-                hy = ry;
-                disH = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
-                dof = DOF;
-                foundSolidWallH = 1;
-            }
-            else
-            {
-                hx2 = rx;
-                hy2 = ry;
-                disH2 = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
-                // foundTransparentWallH = 1;
-                dof++;
-                rx += xo;
-                ry += yo;
-            }
-        }
-        else
-        {
-            rx += xo;
-            ry += yo;
-            dof++;
-        }
-    }
-
-    // printf("hx %f hy %f\n", hx, hy);
-
-    // check vertical rays
-    dof = 0;
-    float disV = 100000, disV2 = 100000, vx = player.x, vy = player.y, vx2, vy2;
-    float nTan = -tan(ra);
-    if (ra > pi / 2 && ra < 3 * pi / 2)
-    { // looking left
-        rx = (((int)player.x >> 6) << 6) - 0.0001;
-        ry = player.y + (player.x - rx) * nTan;
-        xo = -BLOCK_SIZE;
-        yo = -xo * nTan;
-    }
-    if (ra < pi / 2 || ra > 3 * pi / 2)
-    { // looking right
-        rx = (((int)player.x >> 6) << 6) + BLOCK_SIZE;
-        ry = player.y + (player.x - rx) * nTan;
-        xo = BLOCK_SIZE;
-        yo = -xo * nTan;
-    }
-    if (ra == pi || ra == 0)
-    {
-        ry = player.y;
-        rx = player.x;
-        dof = DOF;
-    }
-    int foundSolidWallV = 0;
-    int foundTransparentWallV = 0;
-    while (dof < DOF)
-    {
-        mx = (int)rx >> 6;
-        my = (int)ry >> 6;
-        if (mx >= 0 && mx < MAP_WIDTH && my >= 0 && my < MAP_HEIGHT && map[my][mx])
-        {
-            if (map[my][mx] == 1)
-            {
-                vx = rx;
-                vy = ry;
-                disV = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
-                foundSolidWallV = 1;
-                dof = DOF;
-            }
-            else
-            {
-                vx2 = rx;
-                vy2 = ry;
-                disV2 = sqrt((rx - player.x) * (rx - player.x) + (ry - player.y) * (ry - player.y));
-                foundTransparentWallV = 1;
-                dof++;
-                rx += xo;
-                ry += yo;
-            }
-        }
-        else
-        {
-            rx += xo;
-            ry += yo;
-            dof++;
-        }
-    }
-
-    int direction, direction2;
-
-    if (foundTransparentWallV)
-    {
-        if (disH < disV2)
-        {
-            rx = hx2;
-            ry = hy2;
-            distT = disH2;
-            distT2 = disV2;
-            direction = 0;
-            htexture = (int)(rx) % BLOCK_SIZE;
-        }
-        else
-        {
-            rx = vx2;
-            ry = vy2;
-            distT = disV2;
-            direction = 1;
-            htexture = (int)(ry) % BLOCK_SIZE;
-        }
-        if (foundSolidWallV)
-        {
-            if (disH < disV)
-            {
-                rx2 = hx;
-                ry2 = hy;
-                distT2 = disH;
-                direction2 = 0;
-                htexture2 = (int)(rx2) % BLOCK_SIZE;
-            }
-            else
-            {
-                rx2 = vx;
-                ry2 = vy;
-                distT2 = disV;
-                direction2 = 1;
-                htexture2 = (int)(ry2) % BLOCK_SIZE;
-            }
-        }
-        if (foundSolidWallH)
-        {
-            if (disH < disV)
-            {
-                rx2 = hx;
-                ry2 = hy;
-                distT2 = disH;
-                direction2 = 0;
-                htexture2 = (int)(rx2) % BLOCK_SIZE;
-            }
-            else
-            {
-                rx2 = vx;
-                ry2 = vy;
-                distT2 = disV;
-                direction2 = 1;
-                htexture2 = (int)(ry2) % BLOCK_SIZE;
-            }
-        }
-    }
-
-    else
-    {
-        if (disH < disV)
-        {
-            rx = hx;
-            ry = hy;
-            distT = disH;
-            direction = 0;
-            htexture = (int)(rx) % BLOCK_SIZE;
-        }
-        else
-        {
-            rx = vx;
-            ry = vy;
-            distT = disV;
-            direction = 1;
-            htexture = (int)(ry) % BLOCK_SIZE;
-        }
-    }
-
-    *returnXWall = (int)rx2;
-    *returnYWall = (int)ry2;
-    *distanceWall = distT2;
-    
-    *returnXNet = (int)rx;
-    *returnYNet = (int)ry2;
-    *distanceNet = (int)distT2;
-
-}
 
 int isAngleInRange(float angle, float min, float max)
 {
-
     return ((angle >= min && angle <= max)) || ((angle >= max && angle <= min));
 }
 
 void drawBall()
 {
     float ballAngle = atan2(ball.y - player.y, ball.x - player.x);
-    // if (ballAngle < 0) ballAngle += 2*pi;
-    // if (ballAngle > 2*pi) ballAngle -= 2*pi;
     float ballDistance = sqrt((ball.x - player.x) * (ball.x - player.x) + (ball.y - player.y) * (ball.y - player.y)) * BLOCK_SIZE;
-    float ballBaseWidth = BLOCK_SIZE / 2;
     float ballDistanceX = ballDistance * cos(ballAngle - player.angle);
-    float ballDistanceY = ballDistance * fabs(sin(ballAngle - player.angle));
-    float ballDistanceZ = (ball.z - player.h);
     float ballViewAngle = atan2(ball.z * BLOCK_SIZE, ballDistanceX);
-    float scaledBallWidth = ballBaseWidth / sqrt(3);
     int ballWidth = 25;
     int ballHeight = 25;
     float angleMin = player.angle - (FOV_ANGLE * DR) / 2;
-    // if (angleMin > 2*pi) angleMin -= 2*pi;
     float angleMax = player.angle + (FOV_ANGLE * DR) / 2;
-    // if (angleMax < 0) angleMax += 2*pi;
     if (angleMin < 0)
     {
         angleMin += 2 * pi;
@@ -850,45 +785,34 @@ void drawBall()
     {
         angleMax -= 2 * pi;
         angleMin -= 2 * pi;
-        // ballAngle -= 2*pi;
     }
     if (angleMax > 0 && angleMin > 0 && ballAngle < 0)
     {
         ballAngle += 2 * pi;
     }
 
-    char str[10];
-    int drawBallY = (3 * screenDimension.h / 4 + player.viewAngle) - rect.h / 5 + player.h / BLOCK_SIZE - tan(ballViewAngle) * ballDistance;
-    sprintf(str, "%d", drawBallY);
-    drawString(str, screenDimension.w - 300, 100, 100, 50, 255, 255, 255, 255);
-
-    // if (angleMax > 2*pi) angleMax -= 2*pi;
-    // printf("is playing in range %d\n", isAngleInRange(ballAngle, angleMin, angleMax));
-    // printf("ball angle: %f player angle: %f\n", ballAngle * RD, player.angle * RD);
-    // printf("limit angles: %f %f\n", angleMin * RD, angleMax * RD);
     if (ballAngle >= angleMin && ballAngle <= angleMax)
     {
         rect.x = screenDimension.w / 2 + (screenDimension.w * tan(ballAngle - player.angle)) * sqrt(3) * 0.5;
-        rect.w = (ballWidth * screenDimension.w) / (ballDistance / BLOCK_SIZE);
-        rect.h = (ballHeight * screenDimension.h) / (ballDistance / BLOCK_SIZE);
-        rect.y = (3 * screenDimension.h / 4 + player.viewAngle) - sqrt(3) * tan(ballViewAngle) * ballDistance;
-        // printf("%d %d %d %d\n", rect.x, rect.y, rect.w, rect.h);
+        rect.w = (ballWidth * screenDimension.w) / (2 * ballDistance / BLOCK_SIZE);
+        rect.h = (ballHeight * screenDimension.h) / (2 * ballDistance / BLOCK_SIZE);
+        rect.y = (3 * screenDimension.h / 4 + player.viewAngle) - 2 * tan(ballViewAngle) * ballDistance;
 
         destRect.x = 32 * (SDL_GetTicks() / 150 % 4);
         destRect.y = 0;
         destRect.w = 32;
         destRect.h = 32;
-        // printf("%d %d %d %d\n", rect.x, rect.y, rect.w, rect.h);
+
         SDL_RenderCopy(renderer, ballTexture, &destRect, &rect);
     }
 }
 
 void drawSkyAndGround()
 {
-    destRect.x = ((int)( (player.angle+pi) * RD + player.x/BLOCK_SIZE));
+    destRect.x = ((int)((player.angle + pi) * RD + player.x / BLOCK_SIZE));
     destRect.y = 0;
     destRect.w = 100;
-    destRect.h = 128/2;
+    destRect.h = 128 / 2;
 
     rect.x = 0;
     rect.y = screenDimension.h / 2 + player.viewAngle;
@@ -906,6 +830,11 @@ void drawSkyAndGround()
     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
 }
 
+void drawRacket()
+{
+    // todo
+}
+
 void drawMap2D(int map[][MAP_WIDTH])
 {
     int i, j;
@@ -913,37 +842,77 @@ void drawMap2D(int map[][MAP_WIDTH])
     rect.h = CELL_SIZE;
     rect.x = 0;
     rect.y = 0;
+    // draw ray
     SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
     for (i = 0; i < raysListLength; i++)
     {
         SDL_RenderDrawLine(renderer, player.x * CELL_SIZE / BLOCK_SIZE, player.y * CELL_SIZE / BLOCK_SIZE, rays[i][0] * CELL_SIZE / BLOCK_SIZE, rays[i][1] * CELL_SIZE / BLOCK_SIZE);
     }
+    // draw map
     for (i = 0; i < MAP_HEIGHT; i++)
     {
         for (j = 0; j < MAP_WIDTH; j++)
         {
             switch (map[i][j])
             {
+            // bords du terrain
             case 1:
                 SDL_SetRenderDrawColor(renderer, 5, 255, 255, 255);
                 SDL_RenderFillRect(renderer, &rect);
                 break;
-
+            // filet du milieu
             case 2:
                 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 100);
                 SDL_RenderFillRect(renderer, &rect);
                 break;
-            }
-            if ((i == player.x / BLOCK_SIZE && j == player.y / BLOCK_SIZE) || (i == ennemy.x / BLOCK_SIZE && j == ennemy.y / BLOCK_SIZE))
-            {
-                SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
+
+            // extremites du filet gauche et droit
+            case 3:
+                SDL_SetRenderDrawColor(renderer, 255, 255, 255, 100);
+                SDL_RenderFillRect(renderer, &rect);
+                break;
+            case 4:
+                SDL_SetRenderDrawColor(renderer, 255, 255, 255, 100);
                 SDL_RenderFillRect(renderer, &rect);
+                break;
             }
             rect.x += CELL_SIZE;
         }
         rect.y += CELL_SIZE;
         rect.x = 0;
     }
+
+    // draw player
+    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
+    rect.x = (player.x * CELL_SIZE) / BLOCK_SIZE - CELL_SIZE/2;
+    rect.y = (player.y * CELL_SIZE) / BLOCK_SIZE - CELL_SIZE/2;
+    SDL_RenderFillRect(renderer, &rect);
+
+    // draw ennemi
+    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
+    rect.x = (ennemy.x * CELL_SIZE) / BLOCK_SIZE - CELL_SIZE/2;
+    rect.y = (ennemy.y * CELL_SIZE) / BLOCK_SIZE - CELL_SIZE/2;
+    SDL_RenderFillRect(renderer, &rect);
+
+    //draw landing point
+    if(landingPointIsFind == 1){
+        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
+        rect.x = landingPoint[0] * CELL_SIZE;
+        rect.y = CELL_SIZE;
+        rect.h = (MAP_HEIGHT-2) * CELL_SIZE;
+        rect.w = 3;
+        SDL_RenderFillRect(renderer, &rect);
+        // reset taille cellule
+        rect.h = CELL_SIZE;
+        rect.w = CELL_SIZE;
+    }
+
+    // draw ball
+    SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
+    rect.x = (ball.x * CELL_SIZE) / BLOCK_SIZE - CELL_SIZE/2;
+    rect.y = (ball.y * CELL_SIZE) / BLOCK_SIZE - CELL_SIZE/2;
+    SDL_RenderFillRect(renderer, &rect);
+
     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
 }
 
@@ -1010,29 +979,43 @@ void drawInfosBall()
     drawString(str_ballZ, screenDimension.w - 120, 300, 100, 50, 255, 255, 255, 255);
 }
 
+void drawHub()
+{
+    drawInfosPlayer();
+    drawInfosBall();
+}
+
 void drawGame()
 {
     SDL_RenderClear(renderer);
     drawSkyAndGround();
     castRays(map);
-    if (ball.x < MAP_WIDTH * BLOCK_SIZE/2){
+    if (ball.x < MAP_WIDTH * BLOCK_SIZE / 2)
+    {
         drawVerticalWalls();
         drawEnnemy();
         drawHorizentalWalls();
         drawVerticalNet();
         drawBall();
     }
-    else {
+    else
+    {
         drawVerticalWalls();
         drawEnnemy();
         drawHorizentalWalls();
+        // todo bonus : draw point de chute de la balle
         drawBall();
         drawVerticalNet();
     }
     drawMap2D(map);
+    drawRacket();
     drawFPS();
-    drawInfosPlayer();
-    drawInfosBall();
+    // affiche le hub
+    if (showHub)
+    {
+        drawHub();
+    }
+
     SDL_RenderPresent(renderer);
 }
 
@@ -1049,6 +1032,7 @@ void mainLoop()
     netEdgeRightTexture = loadTexture("Res/netRight.png");
     skyTexture = loadTexture("Res/sky.png");
     groundTexture = loadTexture("Res/ground.png");
+    racketTexture = loadTexture("Res/racket.png");
 
     ray1 = malloc(sizeof(int) * 2);
     ray2 = malloc(sizeof(int) * 2);
@@ -1070,7 +1054,6 @@ void mainLoop()
         delta = (a - b);
         if (delta > 1000 / FPS_TO_GET)
         {
-            // printf("fps: %f\n", 1000/delta);
             fps = 1000 / delta;
             b = a;
             switch (game_state)
@@ -1081,6 +1064,8 @@ void mainLoop()
             case GAME:
                 drawGame();
                 managePlayer();
+                manageEnnemy();
+                updateBall();
                 break;
             }
         }
@@ -1090,6 +1075,5 @@ void mainLoop()
             usleep(1000 * (1000 / FPS_TO_GET - delta));
         }
     }
-
     endSDL();
 }
\ No newline at end of file
diff --git a/travail_de_groupe/jeu_appren_par_renfo/src/render.h b/travail_de_groupe/jeu_appren_par_renfo/src/render.h
index 0cad8e4b7ddbb53e0948b57d1f59d679aaac9eed..f6a2215409ecd55ef5310278554c9b07bea55bbe 100644
--- a/travail_de_groupe/jeu_appren_par_renfo/src/render.h
+++ b/travail_de_groupe/jeu_appren_par_renfo/src/render.h
@@ -8,7 +8,7 @@
 
 #define FPS_TO_GET 60
 #define CELL_SIZE 10
- 
+
 #define DOF 100
 #define BLOCK_SIZE 64
 #define DR 0.0174533
@@ -18,27 +18,31 @@
 #define NB_RAYS (screenDimension.w)
 #define ANGLE_INC ((DR * FOV_ANGLE) / NB_RAYS)
 
-typedef struct rayInfo{
+typedef struct rayInfo
+{
     float ra;
     float distT;
     int r;
     int isTransparent;
-    int direction; 
+    int direction;
     float htexture;
     int rx;
     int ry;
-    struct rayInfo * next;
+    struct rayInfo *next;
 } rayInfo_t;
 
 extern SDL_Window *window;
 extern SDL_Renderer *renderer;
 extern SDL_DisplayMode screenDimension;
 
-extern int * ray1;
-extern int * ray2;
+extern int *ray1;
+extern int *ray2;
+
+extern int showHub;
 
 void castSingleRay(float angle, float *distanceWall, float *distanceNet, int *returnXWall, int *returnYWall, int *returnXNet, int *returnYNet);
 void drawString(char *str, int x, int y, int w, int h, int r, int g, int b, int a);
 void mainLoop();
+void drawHub();
 
-#endif 
\ No newline at end of file
+#endif
\ No newline at end of file