Advertisement
zynamo

gameview.c

Jan 21st, 2018
372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.42 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////
  2. // COMP2521 18x1 ... the Fury of Dracula
  3. // GameView.c: GameView ADT implementation
  4. //
  5. // 2014-07-01   v1.0    Team Dracula <cs2521@cse.unsw.edu.au>
  6. // 2017-12-01   v1.1    Team Dracula <cs2521@cse.unsw.edu.au>
  7.  
  8. #include <assert.h>
  9. #include <err.h>
  10. #include <stdbool.h>
  11. #include <stdlib.h>
  12. #include <sysexits.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <stdbool.h>
  17.  
  18. #include "Game.h"
  19. #include "GameView.h"
  20. #include "Globals.h"
  21. #include "Map.h"
  22.  
  23. #define LINE_LEN 40
  24. #define PLAY_LEN 8
  25. static char playerToChar(PlayerID player);
  26.  
  27. struct gameView {
  28.     Round roundNumber;
  29.     int currPlayer;
  30.     int currScore;
  31.    
  32.     int godLife;
  33.     int drsLife;
  34.     int vanLife;
  35.     int minLife;
  36.     int draLife;
  37.    
  38.     int godLoca;
  39.     int drsLoca;
  40.     int vanLoca;
  41.     int minLoca;
  42.     int draLoca;
  43.    
  44.     char *pastP;
  45.    
  46.     Map dracMap;   
  47. };
  48. static char playerToChar(PlayerID player);
  49. static void pushToTrail(LocationID trail[TRAIL_SIZE], LocationID location);
  50. static int latestPlay(GameView gv);
  51.  
  52. static int pastPlaysLength(GameView gv){
  53.     char *string = gv->pastP;
  54.     int i;
  55.     for (i = 0; string[i] != '\0'; i++);
  56.     return i;
  57. }
  58.  
  59. // Creates a new GameView to summarise the current state of the game
  60. GameView
  61. newGameView (char *pastPlays, PlayerMessage messages[])
  62. {
  63.     GameView new = malloc (sizeof *new);
  64.     if (new == NULL) err (EX_OSERR, "couldn't allocate GameView");
  65.    
  66.     new->pastP = pastPlays;
  67.        
  68.     new->godLife = GAME_START_HUNTER_LIFE_POINTS;
  69.     new->drsLife = GAME_START_HUNTER_LIFE_POINTS;
  70.     new->vanLife = GAME_START_HUNTER_LIFE_POINTS;
  71.     new->minLife = GAME_START_HUNTER_LIFE_POINTS;
  72.     new->draLife = GAME_START_BLOOD_POINTS;
  73.    
  74.     new->godLoca = UNKNOWN_LOCATION;
  75.     new->drsLoca = UNKNOWN_LOCATION;
  76.     new->vanLoca = UNKNOWN_LOCATION;
  77.     new->minLoca = UNKNOWN_LOCATION;
  78.     new->draLoca = UNKNOWN_LOCATION;
  79.    
  80.     new->roundNumber = 0;
  81.     new->currPlayer = 0;
  82.     new->currScore = GAME_START_SCORE;
  83.     new->dracMap = newMap();
  84.        
  85.     return new;
  86. }
  87.  
  88. // Frees all memory previously allocated for the GameView toBeDeleted
  89. void
  90. disposeGameView (GameView toBeDeleted)
  91. {
  92.  
  93.     disposeMap(toBeDeleted->dracMap);
  94.     free (toBeDeleted);
  95. }
  96.  
  97. //// Functions to return simple information about the current state of the game
  98.  
  99. // Get the current round
  100. Round
  101. getRound (GameView gv)
  102. {
  103.     if (strcmp(gv->pastP, "\0") == 0) return 0;
  104.     int roundCount = 0;
  105.     for (int i = 0; gv->pastP[i] != '\0'; i++){
  106.         if (i % (LINE_LEN-1) == 0){
  107.             roundCount++;
  108.         }      
  109.     }
  110.     gv->roundNumber = roundCount;      
  111.     return roundCount;
  112. }
  113.  
  114. // Get the id of current player - ie whose turn is it?
  115. PlayerID
  116. getCurrentPlayer (GameView gv)
  117. {  
  118.     int pastPlaysLen = pastPlaysLength(gv), currPlayer = 0;
  119.     for (int i = 0; i < pastPlaysLen; i++){
  120.         if (i % 8 == 0){
  121.             currPlayer++;
  122.             if (currPlayer > 4){
  123.                 currPlayer = 0;
  124.             }
  125.         }
  126.     }
  127.     return currPlayer;
  128. }
  129.  
  130. // Get the current score
  131. int getScore (GameView gv)
  132. {
  133.     {
  134.         if (strcmp(gv->pastP, "\0") == 0){
  135.             return GAME_START_SCORE;
  136.         }
  137.         int result = GAME_START_SCORE;
  138.         int turnInt = 0;
  139.         int i = 0;
  140.         int vampCount = 0;
  141.         int vampTimer = 0;//once it reaches 6 vamp falls off trail
  142.        
  143.         int maxLength = pastPlaysLength(gv);//just added.
  144.         maxLength -= PLAY_LEN;
  145.        
  146.         while(i <= maxLength){
  147.            
  148.             if(gv->pastP[i] == 'G'){
  149.                 turnInt++;
  150.             } else if(gv->pastP[i] == 'S'){
  151.                 turnInt++;
  152.             } else if(gv->pastP[i] == 'H'){
  153.                 turnInt++;
  154.             } else if(gv->pastP[i] == 'M'){
  155.                 turnInt++;
  156.             } else {
  157.                 turnInt++;
  158.                 //checking for vampires
  159.                 if(gv->pastP[i+5] == 'V') vampCount++;
  160.                 if(vampCount > 0) vampTimer++;
  161.             }
  162.            
  163.             if(turnInt % 5 == 0){
  164.                 result -= SCORE_LOSS_DRACULA_TURN;
  165.             } else {//not Draculas turn
  166.                 if(gv->pastP[i+1] == 'J' && gv->pastP[i+2] == 'M'){
  167.                     result -= SCORE_LOSS_HUNTER_HOSPITAL;//hunter taken to hospital
  168.                 }
  169.             }
  170.             if(vampTimer > TRAIL_SIZE) result -= SCORE_LOSS_VAMPIRE_MATURES;
  171.             i++;
  172.         }
  173.         gv->currScore = result;
  174.         return gv->currScore;
  175.     }
  176. }
  177.  
  178.  
  179. // Get the current health points for a given player
  180. int
  181. getHealth (GameView gv, PlayerID player)
  182. {
  183.     int turnCount = 0;
  184.     int i = 3;
  185.     int playerAdd = 0;
  186.     int playerHealth = 0;
  187.     if (player == PLAYER_LORD_GODALMING) {
  188.         playerAdd = 3;
  189.         playerHealth = gv->godLife;
  190.     }
  191.     else if (player == PLAYER_DR_SEWARD){
  192.         playerAdd = 11;
  193.         playerHealth = gv->drsLife;
  194.     }
  195.     else if (player == PLAYER_VAN_HELSING){
  196.         playerAdd = 19;
  197.         playerHealth = gv->vanLife;
  198.     }
  199.     else if (player == PLAYER_MINA_HARKER){
  200.         playerAdd = 27;
  201.         playerHealth = gv->minLife;
  202.     }
  203.     else if (player == PLAYER_DRACULA){
  204.         playerAdd = 3;
  205.         playerHealth = gv->draLife;
  206.     }
  207.        
  208.     if (player != PLAYER_DRACULA) {
  209.     char loca[2] = {0};
  210.         while ((playerAdd + i) < pastPlaysLength(gv)){
  211.             loca[0] = gv->pastP[playerAdd-2];
  212.             loca[1] = gv->pastP[playerAdd-1];
  213.             while (i < 5){
  214.                 if (gv->pastP[playerAdd+i] == 'D'){
  215.                     playerHealth = playerHealth - 4;
  216.                 }
  217.                 if (gv->pastP[playerAdd+i] == 'T'){
  218.                     playerHealth = playerHealth - 2;
  219.                 }
  220.                 if (playerHealth == 0){
  221.                     playerHealth = 9;
  222.                 }
  223.                 if (turnCount > 1 && loca[0] == gv->pastP[playerAdd-LINE_LEN-2] && loca[1] == gv->pastP[playerAdd-LINE_LEN-2]){
  224.                     playerHealth = playerHealth + 3;
  225.                 }
  226.                 i++;
  227.             }
  228.             turnCount++;
  229.             playerAdd = playerAdd+LINE_LEN;
  230.             i = 0;
  231.         }
  232.         return playerHealth;
  233.     }
  234.    
  235.     else if (player == PLAYER_DRACULA){
  236.         int i = 0;
  237.         char *string = gv->pastP;
  238.         while ((playerAdd + i) < pastPlaysLength(gv)){
  239.             while (i < 5){
  240.                 if (string[playerAdd + i] == 'D'){
  241.                     playerHealth = playerHealth - 10;
  242.                 }
  243.                 i++;
  244.             }
  245.             i = 0;
  246.             playerAdd = playerAdd+8;
  247.             turnCount++;   
  248.         }
  249.         int m = 33;
  250.         char loca[2] = {0};
  251.         int prevLocaSea = 0;
  252.        
  253.         while (m < pastPlaysLength(gv)){
  254.             loca[0] = gv->pastP[m];
  255.             loca[1] = gv->pastP[m+1];
  256.             char *b = loca;
  257.             PlaceType z = UNKNOWN;
  258.             LocationID y = abbrevToID(b);
  259.             if (validPlace(y))  z = idToType(y);
  260.                
  261.             if (loca[0] == 'S' && loca[1] == '?'){
  262.                 playerHealth = playerHealth - 2;
  263.                 prevLocaSea = 1;
  264.             }else if (z == SEA){
  265.                 playerHealth = playerHealth - 2;
  266.                 prevLocaSea = 1;
  267.             }else if (loca[0] == 'D' && (loca[1] >= 1)){
  268.                 if (prevLocaSea == 1) playerHealth = playerHealth - 2;
  269.             }else if (loca[0] == 'C' && loca[1] == 'D'){
  270.                 playerHealth = playerHealth+10;
  271.                 if (playerHealth > 40)  playerHealth = GAME_START_BLOOD_POINTS;
  272.             }else{
  273.                 prevLocaSea = 0;
  274.             }
  275.                
  276.             m = m+LINE_LEN;
  277.         }
  278.            
  279.    
  280.         return playerHealth;
  281.     }
  282.  
  283.     return 0;
  284. }
  285.  
  286. // Get the current location id of a given player
  287. LocationID
  288. getLocation (GameView gv, PlayerID player)
  289. {
  290.     int lastPlay = latestPlay(gv);
  291.     char tempPlayer = playerToChar(player);
  292.     char locaID[2];
  293.     strcpy(locaID, "");
  294.    
  295.     if (getRound(gv) == 0) return UNKNOWN_LOCATION;
  296.    
  297.     while(lastPlay >= 0 && (gv->pastP[lastPlay] != tempPlayer)){
  298.         lastPlay = lastPlay - PLAY_LEN;
  299.     }
  300.     if (lastPlay >= 0){
  301.         locaID[0] = gv->pastP[lastPlay+1];
  302.         locaID[1] = gv->pastP[lastPlay+2];
  303.     }
  304.    
  305.     char *b = locaID;
  306.     LocationID m = abbrevToID(b);
  307.     if (player == PLAYER_DRACULA){
  308.         if (validPlace(m))  {
  309.             return m;
  310.         }
  311.         if (locaID[0] == 'C' && locaID[1] == '?') return CITY_UNKNOWN;
  312.         if (locaID[0] == 'S' && locaID[1] == '?') return SEA_UNKNOWN;
  313.         if (locaID[0] == 'H' && locaID[1] == 'I') return HIDE;
  314.         if (locaID[0] == 'D' && locaID[1] == '1') return DOUBLE_BACK_1;
  315.         if (locaID[0] == 'D' && locaID[1] == '2') return DOUBLE_BACK_2;
  316.         if (locaID[0] == 'D' && locaID[1] == '3') return DOUBLE_BACK_3;
  317.         if (locaID[0] == 'D' && locaID[1] == '4') return DOUBLE_BACK_4;
  318.         if (locaID[0] == 'D' && locaID[1] == '5') return DOUBLE_BACK_5;
  319.         if (locaID[0] == 'T' && locaID[1] == 'P') return TELEPORT;
  320.         else return UNKNOWN_LOCATION;
  321.     }
  322.     return m;  
  323. }
  324.  
  325. //// Functions that return information about the history of the game
  326.  
  327. // Fills the trail array with the location ids of the last 6 turns
  328.  
  329. void
  330. getHistory (GameView gv, PlayerID player, LocationID trail[TRAIL_SIZE])
  331. {
  332.     //fill trail with -1 to begin with
  333.     for(int j = 0; j < TRAIL_SIZE; j++){
  334.         trail[j] = UNKNOWN_LOCATION;
  335.     }
  336.    
  337.     //find latest play index in pastP
  338.     int lastPlay = latestPlay(gv);
  339.     char tempPlayer = playerToChar(player);
  340.    
  341.     //lastPlay = lastPlay-6;
  342.    
  343.     //find latest play of our current player
  344.     while(gv->pastP[lastPlay] != tempPlayer){
  345.         lastPlay = lastPlay - PLAY_LEN;
  346.     }//index should now be at specified player
  347.    
  348.     //Dracula case:---------------
  349.     if(player == PLAYER_DRACULA){
  350.         int count = 0;
  351.         while(count < TRAIL_SIZE){
  352.                
  353.             if(lastPlay <= 0){//fills in rest of trail with unknown loc
  354.                 count = TRAIL_SIZE;//exit while loop
  355.             } else {
  356.                 char tempLoc[2];//temporary location
  357.                 tempLoc[0] = gv->pastP[lastPlay+1];
  358.                 tempLoc[1] = gv->pastP[lastPlay+2];
  359.  
  360.                 LocationID trailAdd;
  361.                
  362.                 if(tempLoc[0]=='C' && tempLoc[1]=='?'){//if unknown city location
  363.                     trailAdd = CITY_UNKNOWN;
  364.                 } else if(tempLoc[0]=='S' && tempLoc[1]=='?'){//if unknown sea location
  365.                     trailAdd = SEA_UNKNOWN;
  366.                 } else if(tempLoc[0]=='H' && tempLoc[1]=='I'){//if hide move
  367.                     trailAdd = HIDE;
  368.                 } else if(tempLoc[0]=='T' && tempLoc[1]=='P'){//if teleport move
  369.                     trailAdd = TELEPORT;
  370.                 }
  371.                 else if(tempLoc[0]=='D' && tempLoc[1]=='1'){ //all below are doubleback
  372.                     trailAdd = DOUBLE_BACK_1;
  373.                 } else if(tempLoc[0]=='D' && tempLoc[1]=='2'){
  374.                     trailAdd = DOUBLE_BACK_2;
  375.                 } else if(tempLoc[0]=='D' && tempLoc[1]=='3'){
  376.                     trailAdd = DOUBLE_BACK_3;
  377.                 } else if(tempLoc[0]=='D' && tempLoc[1]=='4'){
  378.                     trailAdd = DOUBLE_BACK_4;
  379.                 } else if(tempLoc[0]=='D' && tempLoc[1]=='5'){
  380.                     trailAdd = DOUBLE_BACK_5;
  381.                 }
  382.            
  383.                 else {//known location
  384.                     trailAdd = abbrevToID(tempLoc);
  385.                 }
  386.                
  387.                 pushToTrail(trail, trailAdd);//add to trail
  388.                 lastPlay = lastPlay - LINE_LEN;
  389.                 count++;
  390.             }
  391.         }//--------------
  392.     } else {
  393.         //hunter case:
  394.            
  395.         //now we fill in the trail, finally.
  396.         int countr = 0;
  397.         while(countr < TRAIL_SIZE){
  398.  
  399.             if(lastPlay < 0){
  400.                 countr = TRAIL_SIZE;
  401.             } else {
  402.            
  403.                 char currLoc[2];//current location
  404.                 //extract location abbreviation
  405.                 currLoc[0] = gv->pastP[lastPlay+1];
  406.                 currLoc[1] = gv->pastP[lastPlay+2];
  407.            
  408.                 //turn location abbreviation to locationID using places.c
  409.                 LocationID currLocation = abbrevToID(currLoc);
  410.            
  411.                 //finally, add locationID to trail
  412.                 pushToTrail(trail, currLocation);
  413.                
  414.                 lastPlay = lastPlay - LINE_LEN;//go back to the previous round
  415.                 countr++;//will only go to 6 to ensure trail is at most last 6 plays.
  416.             }
  417.         }
  418.         //after all of this the trail array should be updated for
  419.         //whichever player was parsed into the function.
  420.     }
  421. }
  422.  
  423.  
  424. //// Functions that query the map to find information about connectivity
  425.  
  426. // Returns an array of LocationIDs for all directly connected locations
  427.  
  428. LocationID *
  429. connectedLocations (GameView gv, int *numLocations,
  430.     LocationID from, PlayerID player, Round round,
  431.     bool road, bool rail, bool sea)
  432. {
  433.  
  434.     LocationID *b;
  435.     b = locationsConnected(gv->dracMap, from, 100, road, rail, sea);
  436.     int i = 0;
  437.     int connCount = numberOfConnections(gv->dracMap, from, road, rail, sea);
  438.     while (i < connCount){
  439.         i++;
  440.     }
  441.     *numLocations = connCount;
  442.    
  443.     return b;
  444. }
  445.  
  446. static void pushToTrail(LocationID trail[TRAIL_SIZE], LocationID location){
  447.     assert(trail != NULL);
  448.     int i = 0;
  449.     while(i < TRAIL_SIZE){
  450.         if(trail[i] == UNKNOWN_LOCATION){
  451.             trail[i] = location;
  452.             i = TRAIL_SIZE;
  453.         } else {
  454.             i++;
  455.         }
  456.     }
  457. }
  458. static int latestPlay(GameView gv){
  459.     int i = pastPlaysLength(gv);
  460.     i -= (PLAY_LEN - 1);
  461.     return i;
  462. }
  463. static char playerToChar(PlayerID player){//helper function
  464.  
  465.     char playerChar;
  466.     if(player == PLAYER_DRACULA){
  467.         playerChar = 'D';
  468.     } else if (player == PLAYER_LORD_GODALMING){
  469.         playerChar = 'G';
  470.     } else if (player == PLAYER_DR_SEWARD){
  471.         playerChar = 'S';
  472.     } else if (player == PLAYER_VAN_HELSING){
  473.         playerChar = 'H';
  474.     } else /*player == PLAYER_MINA_HARKER*/{
  475.         playerChar = 'M';
  476.     }
  477.     return playerChar;
  478. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement