diff --git a/http-server.c b/http-server.c
index 63c567c599ffc765c9f938bea587a0fe431c26ca..cc94a64c671964c28349de26822e954889466575 100644
--- a/http-server.c
+++ b/http-server.c
@@ -180,27 +180,34 @@ static bool handle_http_request(int sockfd, User_list* users)
             if(strncmp(req->body, "keyword=", 8)  == 0){
                 printf("strncmp with keywoprds is successful");
                 printf("the numer of users is %d\n", users->n_users);
-                // for(int i=0; i < users->n_users; i++){
-                //     printf("USER ID %d", users->users[i]->id);
-                //     if(users->users[i]->status == READY){
-                //         printf("is ready\n");
-                //     }
-                //     if(users->users[i]->status == WAIT){
-                //         printf("is wait\n");
-                //     }
-                //     if(users->users[i]->status == QUIT){
-                //         printf("is quit\n");
-                //     }
-                // }
-                if(players_ready(users)){
-                    post_request(buff,sockfd, "5_discarded.html");
+                for(int i=0; i < users->n_users; i++){
+                    printf("USER ID %d", users->users[i]->id);
+                    if(users->users[i]->status == READY){
+                        printf("is ready\n");
+                    }
+                    if(users->users[i]->status == WAIT){
+                        printf("is wait\n");
+                    }
+                    if(users->users[i]->status == QUIT){
+                        printf("is quit\n");
+                    }
+                }
+                if(player_won(users)){
+                    post_request(buff,sockfd, "6_endgame.html");
                 }
                 else if(should_player_quit(users)){
                     change_player_status(sockfd,users, QUIT);
                     post_request(buff,sockfd, "7_gameover.html");
                 }
+                else if(!players_ready(users)){
+                    post_request(buff,sockfd, "5_discarded.html");
+                }
                 else{
-                    add_keyword(sockfd, users, req->body);
+                    char* keyword = add_keyword(sockfd, users, req->body);
+                    if(has_match_ended(users, keyword)){
+                        change_player_status(sockfd, users, COMPLETE);
+                        post_request(buff,sockfd, "6_endgame.html");
+                    }
                     post_request(buff,sockfd, "4_accepted.html"); 
                 }
             }
@@ -234,7 +241,9 @@ static bool handle_http_request(int sockfd, User_list* users)
             // player_session(buff, sockfd, "1_welcome.html", resp_string);
             // free(resp_string);
             // free(resp); 
-           get_request(buff,sockfd, "1_welcome.html");
+            User* new_player = new_user(sockfd);
+            add_user(new_player, users);
+            get_request(buff,sockfd, "1_welcome.html");
         }
         else
             // never used, just for completeness
@@ -298,6 +307,7 @@ int main(int argc, char * argv[])
     FD_SET(sockfd, &masterfds);
     // record the maximum socket number
     int maxfd = sockfd;
+    User_list* users = initialise_player_list();
     while (1)
     {
         // monitor file descriptors
@@ -307,7 +317,6 @@ int main(int argc, char * argv[])
             perror("select");
             exit(EXIT_FAILURE);
         }
-        User_list* users = initialise_player_list();
         // loop all possible descriptor
         for (int i = 0; i <= maxfd; ++i){
             // determine if the current file descriptor is active
@@ -331,9 +340,10 @@ int main(int argc, char * argv[])
                         
                         // print out the IP and the socket number
                         char ip[INET_ADDRSTRLEN];
-                        User* new_player = new_user(sockfd);
-                        add_user(new_player, users);
-                        printf("THE NUMBER OF USERS IS %d\n", users->n_users);
+                        // User* new_player = new_user(sockfd);
+                        // add_user(new_player, users);
+                        //printf(" %d \n", users->n_users);
+                        // printf("THE NUMBER OF USERS IS %d\n", users->n_users);
                         printf(
                             "new connection from %s on socket %d\n",
                             // convert to human readable string
@@ -350,7 +360,7 @@ int main(int argc, char * argv[])
                 }
             }
         }
-        free(users);
     }
+    free(users);
     return 0;
 }
diff --git a/http-server.o b/http-server.o
index ce050eae728c5840758ba35cf9fd718b08cf3c24..3d4e54ea3933ba1e16e3ffec12faf81eedaec92c 100644
Binary files a/http-server.o and b/http-server.o differ
diff --git a/image_tagger b/image_tagger
index 058f8c6173d82bfd8264946dc1acfcf47c65e547..c5f4ddd9065e0c88e97564fe4817076b4524bea3 100644
Binary files a/image_tagger and b/image_tagger differ
diff --git a/user.c b/user.c
index 89a79637d5be4d000edb22a2cf79e8d90d135425..eb243485d79614f766ff53c05643f224d7042389 100644
--- a/user.c
+++ b/user.c
@@ -38,7 +38,7 @@ void resize_keywords(User* user, char* keyword){
 }
 
 
-void add_keyword(int id, User_list* users, char* query){
+char* add_keyword(int id, User_list* users, char* query){
     const char s[2] = "&";
     char * curr = query;
     char * token;
@@ -50,6 +50,7 @@ void add_keyword(int id, User_list* users, char* query){
             resize_keywords(users->users[i], token);
         }
     }
+    return token;
 }
 
 void add_user(User* user, User_list* users){
@@ -97,4 +98,43 @@ void change_player_status(int user_id, User_list* users, STATUS status){
             users->users[i]->status = status;
         }
     }
+}
+
+bool keyword_match(User* user, char* keyword){
+    for(int i=0; user->n_keywords;i++){
+        if(strcmp(keyword, user->keywords[i]) == 0){
+            return true;
+        }
+    }
+    return false;
+}
+
+void reset_players(User_list *users){
+    for(int i=0; i< users->n_users;i++){
+        users->users[i]->n_keywords = 0;
+        users->users[i]->n_capacity = 5;
+        free(users->users[i]->keywords);
+        users->users[i]->keywords = malloc(sizeof(char*)*users->users[i]->n_capacity);
+    }
+}
+
+bool has_match_ended(User_list* users, char* keyword){
+    for(int i=0; i< users->n_users;i++){
+        if(users->users[i]->status == READY){
+            if(keyword_match(users->users[i], keyword)){
+                reset_players(users);
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool player_won(User_list *users){
+    for(int i=0; i < users->n_users; i++){
+        if (users->users[i]->status == COMPLETE){
+            return true;
+        }
+    }
+    return false;
 }
\ No newline at end of file
diff --git a/user.h b/user.h
index 81ce36ff438ba10ff84db178c9993bcbfc6b37e9..938e19e33b5efa836a2bb668e707ee4172c7ea78 100644
--- a/user.h
+++ b/user.h
@@ -3,7 +3,8 @@ typedef enum
 {
     READY,
     WAIT,
-    QUIT
+    QUIT,
+    COMPLETE
 } STATUS;
 
 
@@ -27,7 +28,7 @@ User_list* initialise_player_list();
 
 void resize_keywords(User* user, char* keyword);
 
-void add_keyword(int id, User_list* users, char* query);
+char* add_keyword(int id, User_list* users, char* query);
 
 void add_user(User* user, User_list* users);
 
@@ -39,4 +40,12 @@ bool should_player_quit(User_list* users);
 
 bool players_ready(User_list* users);
 
-void change_player_status(int user_id, User_list* users, STATUS status);
\ No newline at end of file
+void change_player_status(int user_id, User_list* users, STATUS status);
+
+bool keyword_match(User* user, char* keyword);
+
+void reset_players(User_list *users);
+
+bool has_match_ended(User_list* users, char* keyword);
+
+bool player_won(User_list *users);
\ No newline at end of file
diff --git a/user.o b/user.o
index 4561529bef21b14459e05815a19a720799bf6d0f..35ee1ecfde6262849be0e31584002bda610d4000 100644
Binary files a/user.o and b/user.o differ