# libmaze library
## Team: Group 9 - Invalid Pointer
Members: Samiha Datta, Mer Anderson, Sabrina Jain
GitHub usernames: samihadatta, meranderson, sabrinajain747
Date: March 9th, 2020
## Overview
The `libmaze` library holds useful data structures created to make the algorithm run. It contains the following modules:
* `avatar` (represents an avatar moving through maze)
* `avatar_info` (the information passed to each `avatar` thread)
* `message` (handles the reading and writing of messages to and from the server)
* `pointlib` (useful functions related to the `XYPos` structure)
* `coordinate` (doubly-linked list node)
* `discovered` (doubly-linked list manipulator)
* `move_algorithm` (methods that determine the optimal next move for each avatar)
## Implementation Strategy
#### `avatar`
``` c
void *run_avatar (void *info);
```
* The `run_avatar` method called for each avatar's thread; essentially the "main" function for each thread. Calls algorithm to determine moves and calls relevant graphicsmethods to update the ASCII GUI.
#### `avatar_info`
```c
typedef struct avatar_info { ... } avatar_info_t
avatar_info_t *new_avatar_info (int id, uint32_t n_avatars, uint32_t difficulty, int comm_sock, uint32_t maze_port, char *log_file, uint32_t maze_width, uint32_t maze_height);
void avatar_info_delete (avatar_info_t *info);
```
* `avatar_info_t` is a structure that holds information about maze/documentation that's passed to each avatar's thread which includes the avatar id, number of avatars in the maze, maze difficulty, socket number for the socket over with communication is occuring, the identifier for the used maze port, string for the log file, exit status of the thread, width of the maze, and height of the maze
* `new_avatar_info` creates a new avatar_info structure, initializing each of its attributes to the provided values (attributes described above).
* `avatar_info_delete` deletes the avatar_info struct
#### `message`
```c
AM_Message new_AM_message (int comm_sock);
AM_Message new_INIT_message (uint32_t n_avatars, uint32_t difficulty);
void send_INIT_message (AM_Message message, int comm_sock);
AM_Message new_READY_message (uint32_t id);
void send_READY_message (AM_Message message, int comm_sock);
void send_MOVE_message(int comm_sock, uint32_t id, uint32_t direction);
```
* `new_AM_message` reads in and create a new message from the server (client has specific message constructors).
* `new_INIT_message` constructs a new AM_INIT message for client.
* `send_INIT_message` sends AM_INIT messsage to server through provided socket.
* `new_READY_message` constructs a new AM_READY message
* `send_READY_message` sends AM_READY message to server through provided socket.
* `send_MOVE_message` sends AM_MOVE messsage to server through provided socket with provided id (of the avatar) and direction (of the move).
#### `pointlib`
```c
XYPos point_new(uint32_t x, uint32_t y);
char *string_from_point(XYPos point);
XYPos point_from_string(char *string_pt);
bool points_are_equal(XYPos pt1, XYPos pt2);
int get_move_direction(XYPos pt1, XYPos pt2);
bool point_is_null_equivalent(XYPos pt);
XYPos point_null_equivalent();
int get_num_digits(uint32_t num);
char *ivl_from_point(XYPos point, int last_move);
```
* `point_new` returns a new XYPos structure with the provided x and y coordinates.
* `string_from_point`, when given an XYPos struct, it returns its string representation (in char* form) as follows, point: (x,y) --> string: x y
* `point_from_string` when given a string representation of a point, returns the corresponding XYPos struct (i.e. an XYPos struct with the provided x and y values) as follows, string: x y --> Point: (x,y)
* `points_are_equal` is an equality checker for the XYPos struct. If the two provided XYPos structures have the same X and Y values, returns true; else (or if either are NULL) returns false.
* `get_move_direction` returns the direction of the move from XYPos pt1 to XYPos pt2. Directions are defined in `amazing.h`.
* `point_is_null_equivalent` returns true if the point is equal to the null equivalent and false if not.
* `point_null_equivalent` returns a null equivalent of the point (each coordinate at max value, which the maze will never reach itself).
* `get_num_digits` provided a uint32_t number, returns the number of digits it encompasses.
* `ivl_from_point` invalid hashtable representation of point (used in algorithm).
#### `coordinate`
```c
typedef struct coordinate coordinate_t;
coordinate_t *coordinate_new(Avatar *move, int turn_number);
XYPos coordinate_getPos(coordinate_t *coordinate);
int coordinate_getTurnNumber(coordinate_t *coordinate);
int coordinate_getID(coordinate_t *coordinate);
coordinate_t *coordinate_getPrevious(coordinate_t *coordinate);
coordinate_t *coordinate_getNext(coordinate_t *coordinate);
bool coordinate_getFollow(coordinate_t *coordinate);
bool coordinate_getMatch(coordinate_t *coordinate);
void coordinate_setNext(coordinate_t *base, coordinate_t *new_next);
void coordinate_setPrevious(coordinate_t *new_next, coordinate_t *to_be_previous);
void coordinate_setFollow(coordinate_t *coordinate, bool follow);
void coordinate_setMatch(coordinate_t *coordinate, bool match);
bool coordinates_areEqual(coordinate_t *c1, coordinate_t *c2);
void coordinate_print(coordinate_t *coordinate, FILE *fp);
void coordinate_delete(coordinate_t *coordinate);
```
* `coordinate_new` creates and returns a new coordinate_t structure (or NULL if error)
* `coordinate_getPos` when provided a coordinate, returns the XYPos associated with the coordinate's move and NULL if the coordinate's avatar is NULL.
* `coordinate_getTurnNumber` returns provided coordinate's turn number and -1 if the coordinate is NULL.
* `coordinate_getID` returns provided coordinate's id and -1 if the coordinate is NULL.
* `coordinate_getPrevious` returns the provided coordinate's previous coordinate and NULL if the coordinate is NULL.
* `coordinate_getNext` returns the provided coordinate's next coordinate and NULL if the coordinate is NULL.
* `coordinate_getFollow` returns the found_follow boolean associated with the provided coordinate.
* `coordinate_getMatch` returns the found_match boolean associated with the provided coordinate.
* `coordinate_setNext` sets the first coordinate's next coordinate pointer to the second coordinate if the first coordinate is not NULL.
* `coordinate_setPrevious` sets the first coordinate's previous coordinate pointer to the second coordinate if the first coordinate is not NULL.
* `coordinate_setFollow` sets the provided coordinate's found_follow attribute to the provided boolean.
* `coordinate_setMatch` sets the provided coordinate's found_match attribute to the provided boolean.
* `coordinates_areEqual` checks if the two coordinates are equal (via points_are_equal in pointlib.c). Returns true if the coordinates are equal (as defined above, i.e. in accordance with the pointlib) and false otherwise including NULL cases).
* `coordinate_print` prints a representation of the current coordinate in the following format:
* `coordinate {point -> [XYPos string], id -> [id integer], turn: [turn number]}`
* `coordinate_delete` deletes the provided coordinate.
#### `discovered`
```c
typedef struct discovered discovered_t;
coordinate_t *discovered_getHead(discovered_t *discovered);
discovered_t *discovered_new(void);
void discovered_add(discovered_t *discovered, Avatar *move, int turn_number);
void discovered_delete(discovered_t *discovered);
void discovered_print(discovered_t *discovered, FILE *fp);
coordinate_t *discovered_getCorrespondingCoordinate(discovered_t *discovered, Avatar *move);
```
* `discovered_getHead` when provided a non-NULL discovered struct, returns its head (a coordinate_t struct). In the event of a NULL provided struct, returns NULL.
* `discovered_new` creates a discovered struct with a head initialized to NULL; in the case of failure, returns NULL.
* `discovered_add` adds new point (information given through provided Avatar and turn number) to list of discovered coordinates. Only adds if the new point is different from the most recent point.
* `discovered_delete` deletes the provided discovered structure.
* `discovered_print` prints the provided discovered structure coordinate by coordinate.
* `discovered_getCorrespondingCoordinate` given a discovered list and an Avatar, returns the coordinate that contains the point corresponding to the avatar or NULL if the point doesn't exist in the discovered struct or any of the inputs are NULL.
#### `move_algorithm`
```c
int get_move(hashtable_t *htdisc_heads, hashtable_t *htpoints_all, hashtable_t *my_invalid_ht, int avatarid, int last_attempt, int n_avatars);
XYPos get_adj_point(XYPos start, uint32_t direction);
```
* `get_move` is the function that executes algorithm functionality. It accepts a hashtable of the heads of the linked list of discovered points for each avatar, a hashtable of all the discovered points, a hashtable of all the invalid points, the current avatar id, the last attempted move by that avatar, and the total number of avatars.
* `get_adj_point` takes in an `XYPos` and a direction and returns the `XYPos` point coordinates if the avatar was to move in that direction.
## Compilation
To build, run `make`.
To clean up, run `make clean`.