Advertisement
zynamo

Map.c

Jan 21st, 2018
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.45 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////
  2. // COMP2521 18x1 ... the Fury of Dracula
  3. // Map.c: an implementation of a Map type
  4. // You can change this as much as you want!
  5. //
  6. // 2017-11-30   v1.0    Team Dracula <cs2521@cse.unsw.edu.au>
  7.  
  8. #include <assert.h>
  9. #include <err.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <sysexits.h>
  13. #include <stdbool.h>
  14. #include "Map.h"
  15. #include "Places.h"
  16.  
  17. typedef struct vNode *VList;
  18. struct vNode {
  19.     LocationID  v;    // ALICANTE, etc
  20.     TransportID type; // ROAD, RAIL, BOAT
  21.     VList       next; // link to next node
  22. };
  23.  
  24. struct map {
  25.     int nV; // #vertices
  26.     int nE; // #edges
  27.     VList connections[NUM_MAP_LOCATIONS]; // array of lists
  28. };
  29.  
  30. static void addConnections(Map);
  31. static int checkifAlreadyConnected(int array[], int length, LocationID check);
  32.  
  33. // Create a new empty graph (for a map)
  34. // #Vertices always same as NUM_PLACES
  35. Map
  36. newMap (void)
  37. {
  38.     Map g = malloc (sizeof *g);
  39.     if (g == NULL) err (EX_OSERR, "couldn't allocate Map");
  40.  
  41.     (*g) = (struct map){
  42.         .nV = NUM_MAP_LOCATIONS,
  43.         .nE = 0,
  44.         .connections = { NULL }
  45.     };
  46.  
  47.     addConnections (g);
  48.     return g;
  49. }
  50.  
  51. // Remove an existing graph
  52. void
  53. disposeMap (Map g)
  54. {
  55.     // wait, what?
  56.     if (g == NULL) return;
  57.  
  58.     for (int i = 0; i < g->nV; i++) {
  59.         VList curr = g->connections[i];
  60.         while (curr != NULL) {
  61.             VList next = curr->next;
  62.             free (curr);
  63.             curr = next;
  64.         }
  65.     }
  66.     free (g);
  67. }
  68.  
  69. static VList
  70. insertVList (VList L, LocationID v, TransportID type)
  71. {
  72.     VList new = malloc (sizeof(struct vNode));
  73.     if (new == NULL) err (EX_OSERR, "couldn't allocate vNode");
  74.  
  75.     (*new) = (struct vNode){
  76.         .v = v,
  77.         .type = type,
  78.         .next = L
  79.     };
  80.     return new;
  81. }
  82.  
  83. static int
  84. inVList (VList L, LocationID v, TransportID type)
  85. {
  86.     for (VList cur = L; cur != NULL; cur = cur->next)
  87.         if (cur->v == v && cur->type == type)
  88.             return 1;
  89.  
  90.     return 0;
  91. }
  92.  
  93. // Add a new edge to the Map/Graph
  94. static void
  95. addLink (Map g, LocationID start, LocationID end, TransportID type)
  96. {
  97.     assert (g != NULL);
  98.  
  99.     // don't add edges twice
  100.     if (inVList (g->connections[start], end, type)) return;
  101.  
  102.     g->connections[start] = insertVList(g->connections[start],end,type);
  103.     g->connections[end] = insertVList(g->connections[end],start,type);
  104.     g->nE++;
  105. }
  106.  
  107. static const char *
  108. typeToString (TransportID t)
  109. {
  110.     switch (t) {
  111.     case ROAD: return "road";
  112.     case RAIL: return "rail";
  113.     case BOAT: return "boat";
  114.     default:   return "????";
  115.     }
  116. }
  117.  
  118. // Display content of Map/Graph
  119. void
  120. showMap (Map g)
  121. {
  122.     assert (g != NULL);
  123.  
  124.     printf ("V=%d, E=%d\n", g->nV, g->nE);
  125.     for (int i = 0; i < g->nV; i++)
  126.         for (VList n = g->connections[i]; n != NULL; n = n->next)
  127.             printf ("%s connects to %s by %s\n",
  128.                 idToName (i), idToName (n->v), typeToString (n->type));
  129. }
  130.  
  131. // Return count of nodes
  132. int
  133. numV (Map g)
  134. {
  135.     assert (g != NULL);
  136.     return g->nV;
  137. }
  138.  
  139. // Return count of edges of a particular type
  140. int
  141. numE (Map g, TransportID type)
  142. {
  143.     assert (g != NULL);
  144.     assert (0 <= type && type <= ANY);
  145.  
  146.     int nE = 0;
  147.     for (int i = 0; i < g->nV; i++)
  148.         for (VList n = g->connections[i]; n != NULL; n = n->next)
  149.             if (n->type == type || type == ANY)
  150.                 nE++;
  151.  
  152.     return nE;
  153. }
  154.  
  155. // Add edges to Graph representing map of Europe
  156. static void
  157. addConnections (Map g)
  158. {
  159. #define IS_SENTINEL(x) ((x).v == -1 && (x).w == -1 && (x).t == ANY)
  160.     for (int i = 0; ! IS_SENTINEL (CONNECTIONS[i]); i++)
  161.         addLink (g, CONNECTIONS[i].v, CONNECTIONS[i].w, CONNECTIONS[i].t);
  162. }
  163.  
  164. int connections(Map g, LocationID start, LocationID end, TransportID type[])
  165. {
  166.     int connCount = 0;
  167.     assert(g != NULL);
  168.     VList n = g->connections[start];
  169.    
  170.     while (n != NULL){
  171.         if (n->v == end){
  172.             type[connCount] = n->type;
  173.             connCount++;
  174.         } else if (n->type == BOAT){
  175.             VList m = g->connections[n->v];
  176.             while (m != NULL){
  177.                 if (m->v == end){
  178.                     type[connCount] = n->type;
  179.                     connCount++;
  180.                 }
  181.                 m = m->next;
  182.             }
  183.         }
  184.        
  185.        
  186.         n = n->next;
  187.     }
  188.    return connCount;
  189. }
  190.  
  191. int numberOfConnections(Map g, LocationID start, bool road, bool rail, bool sea)
  192. {
  193.     int connCount = 1;
  194.     assert(g != NULL);
  195.     VList n = g->connections[start];
  196.     int i = 1;
  197.     int arr[50] = {0};
  198.     arr[0] = start;
  199.     while (n != NULL){
  200.         if (((n->type == ROAD) && road == 1) || ((n->type == RAIL) && rail == 1) || ((n->type == BOAT) && sea == 1)){
  201.             if (checkifAlreadyConnected(arr, i, n->v) == 1){
  202.                 connCount++;
  203.                 arr[i] = n->v;
  204.                 i++;
  205.             }
  206.         }
  207.         n = n->next;
  208.        
  209.     }
  210.    return connCount;
  211. }
  212.  
  213. int * locationsConnected (Map g, LocationID start, int arraySize, bool road, bool rail, bool sea){
  214.     assert (g != NULL);
  215.     VList n = g->connections[start];
  216.     int i = 1;
  217.     int *arr = malloc(15*sizeof(int));
  218.     arr[0] = start;
  219.     while (n != NULL){
  220.         if ((checkifAlreadyConnected(arr, i, n->v) == 1) && ((n->type == ROAD && road == 1) || (n->type == RAIL && rail == 1) || (n->type == BOAT && sea == 1))){
  221.             arr[i] = n->v;
  222.             i++;
  223.         }
  224.         n = n->next;
  225.     }
  226.     if (n == NULL){
  227.         arr[i+1] = '\0';
  228.     }
  229.     int *b = arr;
  230.    
  231.     return b;
  232. }
  233. static int checkifAlreadyConnected(int array[], int length, LocationID check){
  234.     int i  = 0;
  235.     while ( i < length){
  236.         if (array[i] == check){
  237.             return 0;
  238.         }
  239.         i++;
  240.     }
  241.     return 1;
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement