Browse Source

added checker

Iman Anwarzai 1 year ago
parent
commit
0609ab8836
7 changed files with 266 additions and 9 deletions
  1. BIN
      .DS_Store
  2. 6 6
      Makefile
  3. BIN
      boggle
  4. 155 0
      dictionaryChecker.c
  5. 86 1
      game_server.c
  6. 1 1
      game_server.h
  7. 18 1
      players.c

BIN
.DS_Store


+ 6 - 6
Makefile

@@ -3,14 +3,14 @@ CFLAGS+= -DPORT=\$(PORT)
 
 all: boggle
 
-game_server.o: utils.h game_server.h
+game_server.o: game_server.h
 	gcc -g -Wall -Werror -std=gnu99 -c game_server.c -o game_server.o
-game.o: utils.h game_server.h
-	gcc -g -Wall -Werror -std=gnu99 -c game.c -o game.o
+dictionaryChecker.o: game_server.h
+	gcc -g -Wall -Werror -std=gnu99 -c dictionaryChecker.c -o dictionaryChecker.o
 players.o: game_server.h
 	gcc -g -Wall -Werror -std=gnu99 -c players.c -o players.o
-boggle: game_server.o game.o players.o
-	gcc -g -Wall -Werror -std=gnu99 -o boggle game_server.o game.o players.o
-	rm game_server.o game.o players.o
+boggle: game_server.o dictionaryChecker.o players.o
+	gcc -g -Wall -Werror -std=gnu99 -o boggle game_server.o dictionaryChecker.o players.o
+	rm game_server.o dictionaryChecker.o players.o
 clean:
 	rm boggle

BIN
boggle


+ 155 - 0
dictionaryChecker.c

@@ -0,0 +1,155 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "game_server.h"
+#include <ctype.h>
+#define MAX_LINE 100
+#define BIG_HASH_SIZE 20000
+#define SMALL_HASH_SIZE 100
+
+typedef struct d_node {
+	char* key;
+    struct d_node *next;
+}DNode;
+
+char *copystr(const char *s) { /* make a duplicate of s */
+        char *p;
+        int len = strlen(s);
+
+        p = (char *) malloc(len+1); /* +1 for í\0í */
+        if (p != NULL)
+                strncpy(p, s, len);
+        p[len] = '\0';
+
+        return p;
+}
+//form hash value for string s
+////this produces a starting value in the dictionary array
+unsigned hash(const char *s) {
+	unsigned hashval;
+	for (hashval = 0; *s != '\0'; s++)
+		hashval = *s + 31 * hashval;
+	return hashval ;
+}
+//Performs search for a key in the hashtable.
+////if the string s is in the dictionary, it is in the list of blocks 
+////beginning in array entry hash(s).
+////if lookup finds entry for s, it returns a pointer to the node
+////if not - it returns NULL
+DNode * lookup (DNode ** dictionary, int hash_size, const char *key) {
+	DNode * np;
+	unsigned int hashval = hash(key);
+	for (np = dictionary [hashval % hash_size]; np !=NULL; np = np->next)
+		if (strcmp (key, np->key) == 0)
+			return np; //found
+	return NULL; //not found
+}
+//insert uses lookup to detemine whether key is already in the dictionary
+////if not, a new entry is created
+DNode * insert (DNode ** dictionary, int hash_size,  const char * key) {
+	unsigned int hashval;
+	DNode *np;
+
+	if ((np = lookup (dictionary, hash_size, key)) == NULL ) { //
+		np = (DNode *) malloc (sizeof (*np));
+
+		if (np == NULL || (np->key = copystr (key)) == NULL)
+			return NULL;
+
+		hashval = hash (key) % hash_size;
+		//now links itself on top of array entry
+		np->next = dictionary [hashval];
+		dictionary [hashval] = np;
+		}
+	return np;
+}
+void free_dictionary (DNode ** dictionary, int hash_size) {
+	int i;
+	for (i=0; i<hash_size; i++) { //iterate over hash array
+		if (dictionary [i]!=NULL) { //if there is an entry at position i
+			DNode *head = dictionary[i]; //find the head of the linked list
+			DNode *current = head;
+			while (current != NULL) {
+				DNode * temp = current;
+				current = current->next;
+                if (temp->key !=NULL)
+                    free (temp->key);
+				free (temp);
+			}
+			dictionary[i] = NULL;  //BUG fix
+		}
+	}
+}
+
+int isInDictionary(char * word) {
+	//int i;
+	FILE *input_FP;
+	char line [MAX_LINE];
+	char * file_name;
+	DNode* result;
+	static DNode* big_dictionary [BIG_HASH_SIZE];
+//	static DNode* small_dictionary[SMALL_HASH_SIZE];
+	
+//
+//	if (argc < 2) {
+//		fprintf (stderr, "test_dictionary <dictionary file name>\n");
+//		return 1;
+//	}
+	file_name = "wordlist.txt";
+
+	if(!(input_FP = fopen ( file_name , "r" )))    {
+        fprintf(stderr,"Could not open file \"%s\" for reading dictionary words\n", file_name);
+        return 1;
+    }
+	while( fgets (line, MAX_LINE, input_FP)!=NULL ) {
+		line[strcspn(line, "\r\n")] = '\0';  //trim new line characters
+		insert (big_dictionary, BIG_HASH_SIZE, line);
+	}	
+	fclose (input_FP);
+
+	result = lookup (big_dictionary, BIG_HASH_SIZE, word);
+	if (result != NULL) 
+		return 1;
+	else
+		return 0;
+	
+	/*result = lookup (big_dictionary, BIG_HASH_SIZE, "MACAC");
+	if (result != NULL) 
+		printf ("<MACAC> is in the dictionary\n");
+	else
+		printf ("<MACAC> not found\n");
+*/
+	free_dictionary(big_dictionary, BIG_HASH_SIZE);
+
+/*	printf ("\n new game session: 1\n");
+	//now testing small dictionary - twice - with cleanup
+	char key[] = "arc";
+	capitalize(key);
+	for (i =0; i< 5; i++) {
+		
+		result = lookup (small_dictionary, SMALL_HASH_SIZE, key);
+		if (result == NULL) {
+			insert (small_dictionary, SMALL_HASH_SIZE, key);
+			printf ("Successfully inserted %s in session 1\n", key);
+		}
+		else
+			printf ("%s has been already used in session 1\n", key);
+	}
+		
+	free_dictionary(small_dictionary, SMALL_HASH_SIZE);
+
+	printf ("\n new game session: 2\n");	
+	for (i =0; i< 5; i++) {
+		result = lookup (small_dictionary, SMALL_HASH_SIZE, key);
+		if (result == NULL){
+			insert (small_dictionary, SMALL_HASH_SIZE, key);
+			printf ("Successfully inserted %s in session 2\n", key);
+		}
+		else
+			printf ("%s has been already used in session 2\n", key);
+	}
+		
+	free_dictionary(small_dictionary, SMALL_HASH_SIZE);
+*/
+	return -10000;
+}

+ 86 - 1
game_server.c

@@ -1,3 +1,5 @@
+#include <ctype.h>
+#include <unistd.h>
 #define _GNU_SOURCE 
 
 #include "game_server.h"
@@ -29,6 +31,67 @@ char dice[16][6] = {
   {'P', 'A', 'C', 'E', 'M', 'D'}
 };
 
+int exists = 0;
+void isaword_helper(char arr[4][4], int ** passed, int i, int j, char * str, char * goal){
+        passed[i][j] = 1;
+        str[strlen(str)] = arr[i][j];
+        if(strcmp(str, goal) == 0){
+                exists = 1;
+		            return;
+        }
+        for (int r = i-1; r <= i+1 && r < 4; r++)
+                for (int c = j-1; c <= j+1 && c < 4; c++)
+                        if (r >=0 && c >=0 && !passed[r][c])
+                                if(goal[strlen(str)] == arr[r][c])
+                                        isaword_helper(arr, passed, r, c, str, goal);
+        str[strlen(str) - 1] = '\0';
+        passed[i][j] = 0;
+}
+int isaword(char arr[4][4], char * goal){
+        int ** temp = malloc(sizeof(int*) * 4);
+        for(int i = 0; i < 4; i ++)
+                temp[i] = malloc(sizeof(int) * 4);
+        for(int x = 0; x < 4; x++)
+                for(int y = 0; y < 4; y++)
+                          temp[x][y] = 0;
+
+        char * string = calloc(1, 1024);
+        for(int i = 0; i < 4; i++)
+                for(int j = 0; j < 4; j++)
+                        isaword_helper(arr, temp, i, j, string, goal);
+        for(int i = 0; i < 4; i++)
+		free(temp[i]);
+	free(temp);
+        free(string);
+        return exists;
+
+}
+
+void capitalize(char* s){
+   int i = 0;
+   while(s[i]) {
+          unsigned char c = (unsigned char ) s[i];
+      s[i] = toupper(c);
+      i++;
+   }
+}
+
+int wordval(char * s){
+        if(strlen(s) == 3)
+                return 1;
+        if(strlen(s) == 4)
+                return 1;
+        if(strlen(s) == 5)
+                return 2;
+        if(strlen(s) == 6)
+                return 3;
+        if(strlen(s) == 7)
+                return 5;
+        if(strlen(s) >= 8)
+                return 11;
+        return 0;
+}
+
 void generate_board(){
 	srand(time(0));
 	int filled[16];
@@ -233,6 +296,10 @@ void remove_client(int fd){
 		}
 		curr = curr->next;
 	}
+	if(curr->fd == fd){
+		client_list = NULL;
+		return;
+	}
 	
 			
 
@@ -393,7 +460,25 @@ int do_command(struct client * p, int cmd_argc, char **cmd_argv) {
     		sendclient(p, "\r\n");
   	}	
     }else {
-        sendclient(p, "Incorrect syntax\r\n");
+	char * word = cmd_argv[0];
+	if(isaword(board, word)){
+		if(isInDictionary(word)){
+				Player *player = find_player(p->name, player_list);
+				char str [BUFFER_SIZE - 10];
+				capitalize(word);
+				int score = wordval(word);
+				player->total_score+=score;
+        			if (score > player->max_score)
+            				player->max_score = score;
+        			sprintf (str, "added score %d for player %s\r\n", score, p->name);
+        			sendclient(p, str);
+			}
+		else
+			sendclient(p, "Word is not in dictionary");			
+	}
+	else{ 
+        	sendclient(p, "Word is not in board\r\n");
+	}
     }
     return 0;
 }

+ 1 - 1
game_server.h

@@ -107,5 +107,5 @@ int do_command(struct client * p, int cmd_argc, char **cmd_argv);
 
 int find_network_newline(char *buf, int inbuf);
 //void generate_board();
-
+int isInDictionary(char * word);
 #endif

+ 18 - 1
players.c

@@ -10,8 +10,25 @@
  */
 int create_player(const char *name, Player **player_ptr_add) {
 	if(find_player(name, *player_ptr_add))
-		return 1;   	
+		return 1; 
 	Player * p = calloc(1, sizeof(Player));
+	if(strlen(name) > MAX_NAME){
+		strncpy(p->name, name, MAX_NAME - 1);
+		p->total_score = 0;
+        	p->max_score = 0;
+        	p->total_games = 0;
+        	p->next = NULL;
+        	Player * curr = *player_ptr_add;
+        	if(curr == NULL){
+                	*player_ptr_add = p;
+                return 0;
+        }
+        while(curr->next)
+                curr = curr->next;
+        curr->next = p;
+		return 2;  	
+	}
+	//Player * p = calloc(1, sizeof(Player));
 	strcpy(p->name, name);
 	p->total_score = 0;
 	p->max_score = 0;