diff --git a/image_tagger.c b/image_tagger.c
index 0c4ae13629c34fd8c294ad72361aae76e9738e69..79e4e301f14971386ccb7c187ed0f96515499657 100644
--- a/image_tagger.c
+++ b/image_tagger.c
@@ -25,11 +25,25 @@
 static char const * const HTTP_200_FORMAT = "HTTP/1.1 200 OK\r\n\
 Content-Type: text/html\r\n\
 Content-Length: %ld\r\n\r\n";
+static char const * const HTTP_200_COOKIE = "HTTP/1.1 200 OK\r\n\
+Content-Type: text/html\r\n\
+Content-Length: %ld\r\n\
+Set-Cookie: player=%s\r\n\
+Set-Cookie: nameLength=%d\r\n\r\n";
 static char const * const HTTP_400 = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n";
 static int const HTTP_400_LENGTH = 47;
 static char const * const HTTP_404 = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
 static int const HTTP_404_LENGTH = 45;
+//static char const * const SET_COOKIE = ;
+static char* const PAGE_1 = "1_intro.html";
+static char* const PAGE_2 = "2_start.html";
+static char* const PAGE_3 = "3_first_turn.html";
+static char* const PAGE_4 = "4_accepted.html";
+static char* const PAGE_5 = "5_discarded.html";
+static char* const PAGE_6 = "6_endgame.html";
+static char* const PAGE_7 = "7_gameover.html";
 
+/*
 static char* P1_NAME;
 static char* P2_NAME;
 static int P1_GAME_STATE = 0;
@@ -38,23 +52,38 @@ static char* KEYWORD_LIST_P1[100];
 static char* KEYWORD_LIST_P2[100];
 static int NUM_KEYWORD_P1 = 0;
 static int NUM_KEYWORD_P2 = 0;
-
-static char* PAGE_1 = "1_intro.html";
-static char* PAGE_2 = "2_start.html";
-static char* PAGE_3 = "3_first_turn.html";
-static char* PAGE_4 = "4_accepted.html";
-static char* PAGE_5 = "5_discarded.html";
-static char* PAGE_6 = "6_endgame.html";
-static char* PAGE_7 = "7_gameover.html";
+*/
 
 // represents the types of method
-typedef enum
-{
+typedef enum {
     GET,
     POST,
     UNKNOWN
 } METHOD;
 
+typedef enum {
+	WELCOME,
+	WAITING,
+	READY,
+	COMPLETED,
+	GAMEOVER
+} GAMESTATE;
+
+struct Player {
+	char* name;
+	int nameLength;
+	int playerNum;
+	GAMESTATE gameState;
+	char* keywordList[100];
+	int numKeywords;
+};
+
+static struct Player player1;
+static struct Player player2;
+//player1.playerNum = 1;
+//player2.playerNum = 2;
+
+
 static char* getURL(char* curr) {
 	char* url;
 	if (strncmp(curr, "1_intro.html ", 13) == 0 || strncmp(curr, " HTTP/1.1", 9) == 0)
@@ -63,7 +92,7 @@ static char* getURL(char* curr) {
     } else if(strncmp(curr, "2_start.html ", 13) == 0)
     {
         url = PAGE_2;
-    } else if(strncmp(curr, "3_first_turn.html ", 18) == 0 || strncmp(curr, "?start=Start ", 13) == 0)
+    } else if(strncmp(curr, "3_first_turn.html ", 18) == 0 || strstr(curr, "?start=Start ") != NULL)
     {
         url = PAGE_3;
     } else if(strncmp(curr, "4_accepted.html ", 16) == 0)
@@ -79,7 +108,7 @@ static char* getURL(char* curr) {
     {
         url = PAGE_7;
     } else {
-		url = " ";
+		url = NULL;
 	}
 	return url;
 }
@@ -88,32 +117,106 @@ static bool addKeyword(char * keyword, int playerNum) {
 	int i = 0;
 	bool match = false;
 	if(playerNum == 1) {
-		while(KEYWORD_LIST_P2[i] != NULL) {
-			if((strcmp(KEYWORD_LIST_P2[i], keyword)) == 0) {
+		while(player2.keywordList[i] != NULL) {
+			if((strcmp(player2.keywordList[i], keyword)) == 0) {
 				match = true;
 			}
 			i++;
 		}
-		KEYWORD_LIST_P1[NUM_KEYWORD_P1] = keyword;
-		NUM_KEYWORD_P1++;
+		if((player1.keywordList[player1.numKeywords] = malloc(strlen(keyword)*sizeof(char))) == NULL) {
+			printf("malloc error");
+			exit(0);
+		}
+		memcpy(player1.keywordList[player1.numKeywords],keyword,strlen(keyword));
+		player1.numKeywords++;
 	} else {
-		while(KEYWORD_LIST_P1[i] != NULL) {
-			if((strcmp(KEYWORD_LIST_P1[i], keyword)) == 0) {
+		while(player1.keywordList[i] != NULL) {
+			if((strcmp(player1.keywordList[i], keyword)) == 0) {
 				match = true;
 			}
 			i++;
 		}
-		KEYWORD_LIST_P2[NUM_KEYWORD_P2] = keyword;
-		NUM_KEYWORD_P2++;
+		if((player2.keywordList[player2.numKeywords] = malloc(strlen(keyword)*sizeof(char))) == NULL) {
+			printf("malloc error");
+			exit(0);
+		}
+		memcpy(player2.keywordList[player2.numKeywords],keyword,strlen(keyword));
+		player2.numKeywords++;
 	}
 	return match;
 }
 
-static bool getRequest(int sockfd, char* buff, char* url, int n) {
-	// get the size of the file
-    struct stat st;
-    stat(url, &st);
-    n = sprintf(buff, HTTP_200_FORMAT, st.st_size);
+static struct Player* checkCookie(char* buff) {
+	char * cookie;
+	if((cookie = strstr(buff,"player=")) != NULL) {
+		if(strncmp(cookie+7,player1.name,player1.nameLength) == 0) {
+			return &player1;
+		} else if(strncmp(cookie+7,player2.name,player2.nameLength) == 0) {
+			return &player2;
+		} else if(player1.name == NULL) {
+			char* length = strstr(buff,"nameLength=");
+			player1.nameLength = atoi(length+11);
+			if((player1.name = malloc(player1.nameLength*sizeof(char))) == NULL) {
+					printf("malloc error");
+					return false;
+				}
+			memcpy(player1.name,cookie+7,player1.nameLength);
+			return &player1;
+		} else if(player2.name == NULL) {
+			char* length = strstr(buff,"nameLength=");
+			player1.nameLength = atoi(length+11);
+			if((player2.name = malloc(player2.nameLength*sizeof(char))) == NULL) {
+					printf("malloc error");
+					return false;
+				}
+			memcpy(player2.name,cookie+7,player2.nameLength);
+			return &player2;
+		}
+	}
+	return NULL;
+}
+
+static bool sendResponse(int sockfd, char* file, char* post) {
+	char buff[2049];
+	int n;
+	
+	if(file == NULL) {
+		if (write(sockfd, HTTP_404, HTTP_404_LENGTH) < 0){
+			perror("write");
+			return false;
+		}
+		return true;
+	} else {
+		struct stat st;
+		stat(file, &st);
+		if(post != NULL && (strncmp(post,"user=",5)) == 0) {
+			if(player1.name == NULL) {
+				char* temp = post+5;
+				if((player1.name = malloc(strlen(temp)*sizeof(char))) == NULL) {
+					printf("malloc error");
+					return false;
+				}
+				memcpy(player1.name,temp,strlen(temp));
+				player1.nameLength = strlen(player1.name);
+				player1.gameState = WAITING;
+				n = sprintf(buff, HTTP_200_COOKIE, st.st_size, player1.name, player1.nameLength);
+			} else if (player2.name == NULL) {
+				char* temp = post+5;
+				if((player2.name = malloc(strlen(temp)*sizeof(char))) == NULL) {
+					printf("malloc error");
+					return false;
+				}
+				memcpy(player2.name,temp,strlen(temp));
+				player2.nameLength = strlen(player2.name);
+				player2.gameState = WAITING;
+				n = sprintf(buff, HTTP_200_COOKIE, st.st_size, player2.name, player2.nameLength);
+			} else {
+				n = sprintf(buff, HTTP_200_FORMAT, st.st_size);
+			}
+		} else {
+			n = sprintf(buff, HTTP_200_FORMAT, st.st_size);
+		}
+	}
     // send the header first
     if (write(sockfd, buff, n) < 0)
     {
@@ -121,7 +224,7 @@ static bool getRequest(int sockfd, char* buff, char* url, int n) {
         return false;
     }
     // send the file
-    int filefd = open(url, O_RDONLY);
+    int filefd = open(file, O_RDONLY);
     do
     {
         n = sendfile(sockfd, filefd, NULL, 2048);
@@ -137,62 +240,65 @@ static bool getRequest(int sockfd, char* buff, char* url, int n) {
 	return true;
 }
 
+static bool getRequest(int sockfd, char* buff, char* url, int n) {
+	
+	struct Player* player = checkCookie(buff);
+	
+	if(url != NULL && player != NULL) {
+		if (strcmp(url,PAGE_1) == 0) {
+			url = PAGE_2;
+		}
+		if (strcmp(url,PAGE_3) == 0 || strcmp(url,PAGE_6) == 0) {
+			player->gameState = READY;
+		}
+	}
+	
+	sendResponse(sockfd,url,NULL);
+	return true;
+}
+
 static bool postRequest(int sockfd, char* buff, char* url, int n) {
 	char* post;
 	char* file;
 	
 	if((post = strstr(buff,"user=")) != NULL) {
-		if(P1_GAME_STATE == 0) {
-			P1_NAME = post + 5;
-			P1_GAME_STATE++;
-		} else if (P2_GAME_STATE == 0) {
-			P2_NAME = post + 5;
-			P2_GAME_STATE++;
-		}
 		file = PAGE_2;
 	} else if((post = strstr(buff,"keyword=")) != NULL) {
-		if(P1_GAME_STATE == P2_GAME_STATE && P1_GAME_STATE == 2) {
-			if(addKeyword(post+8,1)) {
+		if(player1.gameState == player2.gameState && player1.gameState == READY) {
+			struct Player* player = checkCookie(buff);
+			if(addKeyword(post+8,player->playerNum)) {
 				file = PAGE_6;
+				player1.gameState = COMPLETED;
+				player2.gameState = COMPLETED;
 			} else {
 				file = PAGE_4;
 			}
+			printf("P1 keywords: \n");
+			for(int i = 0; i < player1.numKeywords; i++) {
+				printf("%s\n",player1.keywordList[i]);
+			}
+			printf("P2 keywords: \n");
+			for(int i = 0; i < player2.numKeywords; i++) {
+				printf("%s\n",player2.keywordList[i]);
+			}
 		} else {
 			file = PAGE_5;
 		}
-	} else if((post = strstr(buff,"quit=Quit")) != NULL) {
+	} else if (player1.gameState == COMPLETED || player2.gameState == COMPLETED) {
+		file = PAGE_6;
+	} else if((post = strstr(buff,"quit=Quit")) != NULL || player1.gameState == GAMEOVER) {
 		file = PAGE_7;
+		player1.gameState = GAMEOVER;
+	} else {
+		file = NULL;
 	}
-	printf("post = %s and file = %s\n", post, file);
 	
-	struct stat st;
-    stat(file, &st);
-    n = sprintf(buff, HTTP_200_FORMAT, st.st_size);
-    // send the header first
-    if (write(sockfd, buff, n) < 0)
-    {
-        perror("write");
-        return false;
-    }
-    // send the file
-    int filefd = open(file, O_RDONLY);
-    do
-    {
-        n = sendfile(sockfd, filefd, NULL, 2048);
-    }
-    while (n > 0);
-    if (n < 0)
-    {
-        perror("sendfile");
-        close(filefd);
-        return false;
-    }
-    close(filefd);
+	sendResponse(sockfd,file,post);
+	
 	return true;
 }
 
-static bool handle_http_request(int sockfd)
-{
+static bool handle_http_request(int sockfd) {
     // try to read the request
     char buff[2049];
 	char * url;
@@ -205,10 +311,9 @@ static bool handle_http_request(int sockfd)
             printf("socket %d close the connection\n", sockfd);
         return false;
     }
-
+	printf("%s\n", buff);
     // terminate the string
     buff[n] = 0;
-	printf("%s\n", buff);
     char * curr = buff;
 
     // parse the method
@@ -235,42 +340,26 @@ static bool handle_http_request(int sockfd)
     // assume the only valid request URI is "/" but it can be modified to accept more files
 	}
 	
-    if (*curr != '\0') 
-	{
-		url = getURL(curr);
-		if(strcmp(url," ") == 0) {
-			perror("read");
+	url = getURL(curr);
+	if (method == GET) {
+		if(getRequest(sockfd,buff,url,n) == false) {
 			return false;
 		}
-        if (method == GET)
-        {
-            if(getRequest(sockfd,buff,url,n) == false) {
-				return false;
-			}
-        }
-        else if (method == POST)
-        {
-            if(postRequest(sockfd,buff,url,n) == false) {
-				return false;
-			}
-        }
-        else
-            // never used, just for completeness
-            fprintf(stderr, "no other methods supported");
-    // send 404
-    } 
-	else if (write(sockfd, HTTP_404, HTTP_404_LENGTH) < 0) {
-        perror("write");
-        return false;
-    }
-
+	} else if (method == POST) {
+		if(postRequest(sockfd,buff,url,n) == false) {
+			return false;
+		}
+	} else {
+	    // never used, just for completeness
+		fprintf(stderr, "no other methods supported");
+	}
+	
     return true;
 }
 
 
 
-int main(int argc, char * argv[])
-{
+int main(int argc, char * argv[]) {
     if (argc < 3)
     {
         fprintf(stderr, "usage: %s ip port\n", argv[0]);
@@ -320,7 +409,14 @@ int main(int argc, char * argv[])
 	
 	char str[INET_ADDRSTRLEN];
 	printf("image_tagger server is now running at IP: %s on port %d\n", inet_ntop(AF_INET, &serv_addr.sin_addr, str, INET_ADDRSTRLEN), ntohs(serv_addr.sin_port));
-
+	
+	player1.gameState = WELCOME;
+	player2.gameState = WELCOME;
+	player1.numKeywords = 0;
+	player2.numKeywords = 0;
+	player1.playerNum = 1;
+	player2.playerNum = 2;
+	
     while (1)
     {
         // monitor file descriptors
@@ -371,4 +467,4 @@ int main(int argc, char * argv[])
     }
 
     return 0;
-}
+}
\ No newline at end of file