Example #1
0
// reduces heath for dracula if discoved to be at sea
void reduceHealthIfAtSea (player *currentPlayer) {
    // Boolean to determine if we should deduct HP
    int dropHealth = FALSE;
    
    // DoubleBack, number used if a doubleback is present
    int dB = 0;
    
    // If he is in an unknown sea (hunter view)
    if (currentPlayer->trail[0] == SEA_UNKNOWN) {
        dropHealth = TRUE;
        
    // If the current location is a hide - it can't possibly be
    // to a sea. Hence we test for whether the currentLocation is not
    // a sea
    } else if (currentPlayer->trail[0] != HIDE) {
        switch (currentPlayer->trail[0]) {
            // Set dB to correponding doubleBack number
            case DOUBLE_BACK_1: dB = 1; break;
            case DOUBLE_BACK_2: dB = 2; break;
            case DOUBLE_BACK_3: dB = 3; break;
            case DOUBLE_BACK_4: dB = 4; break;
            case DOUBLE_BACK_5: dB = 5; break;
            default: break;
        }
        if (currentPlayer->trail[dB] != HIDE) {
            // We check again to see if the double back was to
            // a hide. If so - a sea is not possible
            // if it wasn't... well:
            
            if (dB > 0) {
                //printf("\n");
                // If the location was at sea - then drop the health
                
                printf("trail[1] = %d\n", currentPlayer->trail[1]);
                
                if (currentPlayer->trail[dB] == SEA_UNKNOWN) {
                    dropHealth = TRUE;
                } else if (currentPlayer->trail[dB] >= MIN_MAP_LOCATION &&
                           currentPlayer->trail[dB] <= MAX_MAP_LOCATION &&
                           idToType (currentPlayer->trail[dB]) == SEA) {
                    dropHealth = TRUE;
                }
            } else if (currentPlayer->trail[0] >= MIN_MAP_LOCATION &&
                       currentPlayer->trail[0] <= MAX_MAP_LOCATION &&
                       idToType (currentPlayer->trail[0]) == SEA) {
                // the most recently visited location is a sea...
                dropHealth = TRUE;
            }
        }
    }
    
    if (dropHealth) {
        currentPlayer->health -= LIFE_LOSS_SEA;
    }
}
Example #2
0
// Returns the number of direct connections between two nodes
// Also fills the type[] array with the various connection types
// Returns 0 if no direct connection (i.e. not adjacent in graph)
int connections(Map g, LocationID start, LocationID end, TransportID type[])
{
   int numConnections = 0;
    
   assert(g != NULL);
   if (!validPlace(start) || !validPlace(end)) {
        fprintf(stderr, "Map.c: connections(): start location(%d) || end locations(%d) not valid", start, end);
        return numConnections;
   } 

   VList curr = g->connections[start];
   while (curr != NULL) {

      // Check for regular connections
      if (curr->v == end) {
         type[numConnections] = curr->type;
         numConnections++;

      // Check for connections via a common sea
      } else if (idToType(curr->v) == SEA) {
         VList endCurr = g->connections[end];
         while (endCurr != NULL) {
            if (endCurr->v == curr->v) {
               type[numConnections] = curr->type;
               numConnections++;
            }
            endCurr = endCurr->next;
         }
      }
      curr = curr->next;
   }
   return numConnections;
}
Example #3
0
// Creates a new GameView to summarise the current state of the game
GameView newGameView(char *pastPlays, PlayerMessage messages[])
{
    assert(pastPlays != NULL);
    assert(messages != NULL);

    GameView g = malloc(sizeof(struct gameView));

    assert(g != NULL);

    g->pastPlays = malloc(sizeof(char) * MAX_PAST_PLAYS_LENGTH);
    int indexAt = 0;

    // Initialise the hunters
    int i;
    for(i = 0; i < NUM_PLAYERS-1; i++) {
        g->players[i].health = GAME_START_HUNTER_LIFE_POINTS;
        g->players[i].position = NOWHERE;
    }

    // initialise dracula
    g->players[PLAYER_DRACULA].health = GAME_START_BLOOD_POINTS;
    g->players[PLAYER_DRACULA].position = NOWHERE;

    // initialise turn and score
    g->turns = 0;
    g->score = GAME_START_SCORE;

    // initialise the trails
    for(i = 0; i < TRAIL_SIZE; i++) {
        g->trail[i] = NOWHERE;
    }

    // make a copy of past plays
    strncpy(g->pastPlays, pastPlays, MAX_PAST_PLAYS_LENGTH);
    
    // process the plays
    while(pastPlays[indexAt] != '\0') {
//        D("Play to process here is ");
//        int x;
//        for(x = 0; x < CHARS_PER_PLAY; x++) {
//            D("%c",pastPlays[indexAt+x]);
//        }
//        D("\n");
        
        // copy message
        // current turn index [0-based] is g->turns
        // first, allocate space for the string
        g->messages[g->turns] = 
            (char *)(malloc(sizeof(char)*MAX_MESSAGE_LENGTH));

        assert(g->messages[g->turns] != NULL);
        assert(messages[g->turns] != NULL);

        // copy string, using strncpy for safety
        strncpy(g->messages[g->turns], messages[g->turns], MAX_MESSAGE_LENGTH);

        // get the abbreviation for the new location
        char abbrev[3];
        abbrev[0] = pastPlays[indexAt+1];
        abbrev[1] = pastPlays[indexAt+2];

        // add a NUL terminator for good measure
        abbrev[2] = '\0';

        // try to get the place id of the current place
        LocationID placeID = abbrevToID(abbrev);

        // work out if dracula or a hunter
        if(pastPlays[indexAt] == 'D') {
            // This player is dracula
            // We update his position.
            
            int isAtSea;
            int isAtCastle;
            if(placeID != NOWHERE) {
                if(idToType(placeID) == SEA) {
                    isAtSea = TRUE;
                } else {
                    isAtSea = FALSE;
                }
                if(placeID == CASTLE_DRACULA) {
                    isAtCastle = TRUE;
                } else {
                    isAtCastle = FALSE;
                }
                pushOnTrail(g, placeID);
            } else {
                // This is not dracula's string and we do not know where he is
                // And cannot update his position, other than saying if he is
                // on land or at sea.
                // We still need to know if he is at sea
                if(abbrev[0] == 'C') {
                    // He is in some city
                    // That is not castle dracula
                    isAtSea = FALSE;
                    isAtCastle = FALSE;
                    pushOnTrail(g, CITY_UNKNOWN);
                    placeID = CITY_UNKNOWN;
                } else if(abbrev[0] == 'S') {
                    // He is at sea
                    isAtSea = TRUE;
                    isAtCastle = FALSE;
                    pushOnTrail(g, SEA_UNKNOWN);
                    placeID = SEA_UNKNOWN;
                } else if(abbrev[0] == 'T') {
                    // He is at the castle
                    isAtSea = FALSE;
                    isAtCastle = TRUE;
                    pushOnTrail(g, CASTLE_DRACULA);

                    // set placeID to be teleport
                    placeID = TELEPORT;
               } else if(abbrev[0] == 'D') {
                    // He doubled back.
                    // Because of the game's rules, we don't be clever and
                    // instead place only the DOUBLE_BACK_ move type onto the
                    // trail, even though we can (and do) infer the at-sea-ness
                    // and location of dracula
                    int numBack = (int)(abbrev[1]-'0');
                    LocationID newPosition = g->trail[TRAIL_SIZE-numBack];

//                    D("trail:");
//                    for(i=0;i<TRAIL_SIZE;i++) {
//                        D(" %d",g->trail[i]);
//                    }
//                    D("\n");
//                    D("newPosition is %d\n",newPosition);

                    if(newPosition == CITY_UNKNOWN) {
                        isAtSea = FALSE;
                        isAtCastle = FALSE;
                    } else if (newPosition == SEA_UNKNOWN) {
                        isAtSea = TRUE;
                        isAtCastle = FALSE;
                    } else {
                        // We know exactly where dracula is
                        if (idToType(newPosition) == SEA) {
                            isAtSea = TRUE;
                            isAtCastle = FALSE;
                        } else if(newPosition == CASTLE_DRACULA) {
                            isAtSea = FALSE;
                            isAtCastle = TRUE;
                        } else {
                            isAtSea = FALSE;
                            isAtCastle = FALSE;
                        }
                    }
                    pushOnTrail(g, newPosition);

                    // for sake of the getLocation function, we'll set
                    // Dracula's new location to be the TYPE of move as opposed
                    // to the city he's actually at even though we know what
                    // that is
                    placeID = (FIRST_DOUBLE_BACK-MIN_DOUBLE_BACK) + numBack;
                } else if(abbrev[0] == 'H') {
                    // He's HIDING!

                    // push on the most recent location
                    pushOnTrail(g, g->trail[TRAIL_SIZE-1]);

                    // for sake of getLocation, make current location HIDE
                    placeID = HIDE;
                }
            }

            // set Dracula's 'public' location (as returned by getLocation)
            g->players[PLAYER_DRACULA].position = placeID;

            // Now we figure out what exactly dracula does at the new location
            if(isAtSea) {
                g->players[PLAYER_DRACULA].health -= LIFE_LOSS_SEA;
            } else if(isAtCastle) {
                g->players[PLAYER_DRACULA].health += LIFE_GAIN_CASTLE_DRACULA;
            }

            if(pastPlays[indexAt+3] == 'T') {
                // Dracula placed a trap.
                // TODO: Processing on what to do with traps
                // So far, it doesn't seem like we need to do anything
                // Since any encounters of traps are given to us
                // so we don't need to know where these things are
            }
            if(pastPlays[indexAt+4] == 'V') {
                // Dracula placed a young vampire
                // TODO: See the section on traps just above
            }

            // What just left the trail?
            if(pastPlays[indexAt+5] == 'V') {
                // A vampire has matured
                g->score -= SCORE_LOSS_VAMPIRE_MATURES;
            }
        } else {
            // This player is one of the hunters
            PlayerID curHunter;
            switch (pastPlays[indexAt]) {
                case 'G': curHunter = PLAYER_LORD_GODALMING; break;
                case 'S': curHunter = PLAYER_DR_SEWARD; break;
                case 'H': curHunter = PLAYER_VAN_HELSING; break;
                case 'M': curHunter = PLAYER_MINA_HARKER; break;
                default:
                    assert (FALSE && "This is not a valid identifier for a player.");
            }

            LocationID newPosition = abbrevToID(abbrev);

            if(g->players[curHunter].position == ST_JOSEPH_AND_ST_MARYS &&
               g->players[curHunter].health == 0) {
                // Our hunter has grown his legs back now.
                g->players[curHunter].health = GAME_START_HUNTER_LIFE_POINTS;
            }

            // Check if some encounters were made
            int i;

            // only loop while our hunter is alive and kicking
            // (and dracula, of course)
            for(i = 3;i < CHARS_PER_PLAY && 
                      g->players[curHunter].health > 0 &&
                      g->players[PLAYER_DRACULA].health > 0; i++) {
                if(pastPlays[indexAt+i] == 'T') {
                    // Encountered a trap
                    g->players[curHunter].health -= LIFE_LOSS_TRAP_ENCOUNTER;
                } else if(pastPlays[indexAt+i] == 'D') {
                    //D("ENCOUNTERED DRACULA\n");
                    // Encountered Dracula
                    g->players[curHunter].health -= LIFE_LOSS_DRACULA_ENCOUNTER;
                    g->players[PLAYER_DRACULA].health -= LIFE_LOSS_HUNTER_ENCOUNTER;
                }
            }

            // check if our hunter died =(
            if (g->players[curHunter].health <= 0) {
                g->players[curHunter].health = 0;
                g->score -= SCORE_LOSS_HUNTER_HOSPITAL;
                newPosition = ST_JOSEPH_AND_ST_MARYS;
            } else if(newPosition == g->players[curHunter].position) {
                // The hunter rests and regains some health
                // Hunters need a bit of RnR, too!
                g->players[curHunter].health += LIFE_GAIN_REST;

                // cap hunter's health at GAME_START_HUNTER_LIFE_POINTS
                if (g->players[curHunter].health > GAME_START_HUNTER_LIFE_POINTS) {
                    g->players[curHunter].health = GAME_START_HUNTER_LIFE_POINTS;
                }
            }

            // update our hunter's position
            g->players[curHunter].position = newPosition;
        }
        g->turns++;

        // we increment this way just in case we overshoot the NUL terminator
        // at the end of the string
        indexAt += CHARS_PER_PLAY;
        if(pastPlays[indexAt] == PLAY_SEP_CHAR) {
            indexAt++;
        }
    }

    // A little special case to heal the current hunter if they've been 
    // incapacitated last turn.
    int turnPlayer = getCurrentPlayer(g);
    if(g->players[turnPlayer].position == ST_JOSEPH_AND_ST_MARYS &&
       g->players[turnPlayer].health == 0) {
        // The hunter has regrown his legs!
        g->players[turnPlayer].health = GAME_START_HUNTER_LIFE_POINTS;
    }

    // print out messages for teh luls
//    for(i=0;i<g->turns;i++) {
//        D("message for turnplay %d: %s\n",i,g->messages[i]);
//    }
    return g;
}
Example #4
0
// Calculate Dracula's Health
int calculateDraculaHealth (char *pastPlays) {
    //Setup Variables
    assert(pastPlays != NULL);
    int i = 0;  //Counter
    int j = 0;  //Counter
    int pastPlaysLength = strlen(pastPlays);
    char tempLocation[2] = {'0'};
    int tempLocationID = 0;
    int trail[TRAIL_SIZE] = {'0'};

    //Dracula begins with 40 "Blood Points" (health)
    int health = GAME_START_BLOOD_POINTS;

    //Loop through player's turns
    for (j = 0; j < pastPlaysLength; j++) {

        //Keep moving if not the start of a turn
        if (pastPlays[j] != ' ') {
            continue;
        }

        //Loop through the Action phase
        for (i = TRAP_CHAR_OFFSET + 1; i < TRAP_CHAR_OFFSET + 1 + MAX_TRAP_LENGTH; i++) {

            //If a hunter encounters Dracula he loses 10 blood points
            if (pastPlays[j + i] == 'D') {
                health = health - LIFE_LOSS_HUNTER_ENCOUNTER;
                if (health < 0) {
                    return 0;
                }
            }
        }

        //Keep moving if not the player in question
        if (pastPlays[j + 1] != 'D') {
            continue;
        }        

        //Dracula regains 10 blood points if he is in Castle Dracula at the end of his turn
        if (pastPlays[j + 1 + LOCATION_CHAR_OFFSET] == 'D' && pastPlays[j + 1 + LOCATION_CHAR_OFFSET - 1] == 'C') {
            if (health < 0) {
                return 0;
            }
            health = health + LIFE_GAIN_CASTLE_DRACULA;
        }

        //Determine Dracula's location
        //Store location initials temporarily
        tempLocation[1] = pastPlays[j + 1 + LOCATION_CHAR_OFFSET];
        tempLocation[0] = pastPlays[j + 1 + LOCATION_CHAR_OFFSET - 1];  
        //Obtain useful LocationID
        tempLocationID = abbrevToID(tempLocation);

        //Case if tempLocation is not a place
        if (strncmp(tempLocation, "C?", 2) == 0) {
            tempLocationID = CITY_UNKNOWN;
        } else if (strncmp(tempLocation, "S?", 2) == 0) {
            tempLocationID = SEA_UNKNOWN;
        } else if (strncmp(tempLocation, "HI", 2) == 0) {
            tempLocationID = HIDE;
        } else if (strncmp(tempLocation, "D1", 2) == 0) {
            tempLocationID = DOUBLE_BACK_1;
        } else if (strncmp(tempLocation, "D2", 2) == 0) {
            tempLocationID = DOUBLE_BACK_2;
        } else if (strncmp(tempLocation, "D3", 2) == 0) {
            tempLocationID = DOUBLE_BACK_3;
        } else if (strncmp(tempLocation, "D4", 2) == 0) {
            tempLocationID = DOUBLE_BACK_4;
        } else if (strncmp(tempLocation, "D5", 2) == 0) {
            tempLocationID = DOUBLE_BACK_5;
        } else if (strncmp(tempLocation, "TP", 2) == 0) {
            tempLocationID = TELEPORT;
        }

        //Dracula loses 2 blood points if he is at sea at the end of his turn
        if (idToType(tempLocationID) == SEA || tempLocationID == SEA_UNKNOWN) {
            health = health - LIFE_LOSS_SEA;
            if (health < 0) {
                return 0;
            }
        //Case if Dracula hid while at sea
        } else if (tempLocationID == HIDE && idToType(trail[1]) == SEA) {
            health = health - LIFE_LOSS_SEA;
            if (health < 0) {
                return 0;
            }
        //Case if Dracula Doubled-Back to sea
        } else if (tempLocationID == DOUBLE_BACK_1 && (idToType(trail[1]) == SEA || trail[1] == SEA_UNKNOWN)) {
            health = health - LIFE_LOSS_SEA;
            if (health < 0) {
                return 0;
            }
        } else if (tempLocationID == DOUBLE_BACK_2 && (idToType(trail[2]) == SEA || trail[2] == SEA_UNKNOWN)) {
            health = health - LIFE_LOSS_SEA;
            if (health < 0) {
                return 0;
            }
        } else if (tempLocationID == DOUBLE_BACK_3 && (idToType(trail[3]) == SEA || trail[3] == SEA_UNKNOWN)) {
            health = health - LIFE_LOSS_SEA;
            if (health < 0) {
                return 0;
            }
        } else if (tempLocationID == DOUBLE_BACK_4 && (idToType(trail[4]) == SEA || trail[4] == SEA_UNKNOWN)) {
            health = health - LIFE_LOSS_SEA;
            if (health < 0) {
                return 0;
            }
        } else if (tempLocationID == DOUBLE_BACK_5 && (idToType(trail[5]) == SEA || trail[5] == SEA_UNKNOWN)) {
            health = health - LIFE_LOSS_SEA;
            if (health < 0) {
                return 0;
            }
        }

    }

    /*
    printf("this is gameView.c speaking\n");
    printf("Dracula's health is: %d\n", health);
    */

    return health;
    
}
// What are my (Dracula's) possible next moves (locations)
//
// * connectedLocations Conditions:
//
// connectedLocations() returns an array of LocationID that represent
//   all locations that are connected to the given LocationID.
// road, rail and sea are connections should only be considered
//   if the road, rail, sea parameters are TRUE.
// The size of the array is stored in the variable pointed to by numLocations
// The array can be in any order but must contain unique entries
// Your function must take into account the round and player id for rail travel
// Your function must take into account that Dracula can't move to
//   the hospital or travel by rail but need not take into account Dracula's trail
// The destination 'from' should be included in the array
//
// FREE THIS ARRAY IN THE AI
//
// This function only returns a list of locations where duckula can go
// This does not include HIDE or DOUBLE_BACK. Will need to account for
// this somewhere.. somehow
LocationID *whereCanIgo(DracView currentView, int *numLocations,
                        int road, int sea) {

// whereCanIgo() returns an array of LocationIDs giving
//   all locations that Dracula could reach in his next move
// road and/or sea connections should only be considered
//   if the road and/or sea parameters are TRUE.
// The size of the array is stored in the variable pointed to by numLocations
// The array can be in any order but must contain unique entries
// Should not include the hospital nor any locations only reachable by rail
// The current location should be included in the array
// The set of possible locations must be consistent with the rules on Dracula's
//   movement (e.g. can't MOVE to a location currently in his trail)

   LocationID *locations;
   LocationID trail[TRAIL_SIZE];
   LocationID myLocation;
   int i;
   int j;
   int rail;

   rail = 0;
   myLocation = whereIs(currentView, PLAYER_DRACULA);
   // printf("in DV.c; whereCanIGo: myLocation: %d (%s)\n", myLocation, idToAbbrev(myLocation));

   // printf("here0 connectedLocations(%p, %d, %d, %d, %d, %d, %d, %d)\n", currentView->gv, *numLocations, whereIs(currentView, PLAYER_DRACULA), PLAYER_DRACULA, giveMeTheRound(currentView), road, rail, sea);
//   fprintf(stderr,"from %d, round %d\n", whereIs(currentView,PLAYER_DRACULA),giveMeTheRound(currentView));

   locations = connectedLocations(currentView->gv, numLocations, 
                  myLocation, PLAYER_DRACULA, 
                  giveMeTheRound(currentView), road, rail, sea);

   //fprintf(stderr, "in DV.c: connLocs: \n");
   //for (i = 0; i < *numLocations; i++) {
   //   fprintf(stderr, "\tlocations[%d]: %d (%s)\n", i, locations[i], idToAbbrev(locations[i]));
   //}

   getHistory(currentView->gv, PLAYER_DRACULA, trail);

   // check locations aren't in the trail except for trail[0] (current location)
   for (i = 0; i < *numLocations; i++) {
      // printf("in DV.c: locations[%d] = %d (%s)\n", i, locations[i], idToAbbrev(locations[i]));
      for (j = 0; j < TRAIL_SIZE; j++) {
         
         if (locations[i] == myLocation && idToType(myLocation) == SEA) {
            // I'm currently at sea. Remove currently location
            locations[i] = -1;

            int h;

            // shuffle the locations one index to the 'left'
            for (h = i; h < *numLocations; h++) {
               if ((h+1) < *numLocations) {
                  locations[h] = locations[h+1];
               }
            }
            *numLocations -= 1;

         } else if (locations[i] == trail[j] && locations[i] != UNKNOWN_LOCATION && j != 0) {
            // this location is in the trail, remove it
            // printf("in DV.c: locations[%d] (%d : %s) == trail[%d] (%d : %s)\n", i, locations[i], idToAbbrev(locations[i]), j, trail[j], idToAbbrev(trail[j]));
            locations[i] = -1;
            // printf("\tupdated locations[%d] -> %d\n", i, locations[i]);

            int h;

            // shuffle the locations one index to the 'left'
            for (h = i; h < *numLocations; h++) {
               if ((h+1) < *numLocations) {
                  locations[h] = locations[h+1];
               }
            }

            *numLocations -= 1;
         }
      }
   }

   //fprintf(stderr, "new locs: \n");
   //for (i = 0; i < *numLocations; i++) {
   //       fprintf(stderr, "\tin DV.c: locations[%d] (%d : %s)\n", i, locations[i], idToAbbrev(locations[i]));
   //}

   return locations;
}
// Find out what minions are placed at the specified location
void whatsThere(DracView currentView, LocationID where,
                   int *numTraps, int *numVamps) {
   
   DracView dv;
   int count;
   LocationID trail[TRAIL_SIZE] = { -1 };
   LocationID whereType;
   int index;
   int round;
   int trapSetRound;

   dv = currentView;
   count = 0;
   whereType = idToType(where);
   *numTraps = 0;
   *numVamps = 0;
   index = dv->pastPlaysIndex[PLAYER_DRACULA];
   round = getLastRound(dv, PLAYER_DRACULA);
   trapSetRound = -1;

   // printf("whatsThere: round is: %d, currRound: %d\n", round, getRound(dv->gv));

   /* 
    * 1. Get minions placed by Drac
    *       1a. Get Drac's trail
    *       1b. if city is in the trail: increment for any traps/vamps
    *
    * 2. If traps found: 
    *       2a. get each hunter's trail
    *       2b. check if city is in hunter's trail, AND if traps/vamps
    *             have been encountered
    *       2c. if traps/vamps have been encountered, decrement them
    */ 


   // 1. Get minions placed by Drac

   // 'where' restrictions:
   //    - not in the sea,
   //    - is a valid city number,
   //    - not the hospital

   if (whereType != SEA && validPlace(where) && 
                  where != ST_JOSEPH_AND_ST_MARYS) {

      // 1a.
      getHistory(dv->gv, PLAYER_DRACULA, trail);

      
      // 1b. Store the traps set by Drac within that city, if applicable

      // if 'where' is within the trail
      while (count < TRAIL_SIZE) {
         // Starting at the latest round, check if the city the user 
         // wants to check is in drac's trail. 
         // If so, increment if any traps or vamps are there and note
         // which round in which they were set by Drac

         if (trail[count] == where) {

            // index+3 and index+4: the indices where
            //             dracula's encounters will be stored

            if (dv->past[((round - count) * ROUND_LENGTH) + (index + MINION_ONE)] == 'T') {
               *numTraps += 1;
               //printf("yep0: loc[%c%c], round: %d, count: %d\n",dv->past[((round-count) * ROUND_LENGTH) + index+1], dv->past[((round-count) * ROUND_LENGTH) + index+2], round, count);
            } else if (dv->past[((round - count) * ROUND_LENGTH) + (index + MINION_ONE)] == 'V') {
               *numVamps += 1;
            }

            if (dv->past[((round - count) * ROUND_LENGTH) + (index + MINION_TWO)] == 'T') {
               *numTraps += 1;
            } else if (dv->past[((round - count) * ROUND_LENGTH) + (index + MINION_TWO)] == 'V') {
               *numVamps += 1;
            }

            // break out of the loop since 'where' can only be 
            // in the trail once
            trapSetRound = round - count;
            count = TRAIL_SIZE;
         }

         count += 1;
      }
   }

   //printf("found drac's: at %s, traps: %d, vamps: %d\n", idToName(where), *numTraps, *numVamps);


   // 2. If traps found

   // Traps have been found at the given city.
   // Check to see if any hunters have visited that city since,
   // hence encountering and disabling that trap/vamp
   if (trapSetRound != -1 && *numTraps > 0 && *numVamps > 0) {
      int hunter;
      int index;

      hunter = 0;

      // go through all hunter's (NUM_PLAYERS-1) trails**
      // if a hunter has visited the 'where' city, and has
      // encountered a trap/vamp, then decrement trap/vamp
      //
      // **since drac's and hunter's giveMeTheTrails are out of sync,
      // go through the pastPlays string
      // Will need to do that anyway because we need to check the string
      // for T&V encounters
      while (hunter < NUM_PLAYERS-1) {
         index = dv->pastPlaysIndex[hunter];
         round = getLastRound(dv, hunter);
         

         for (count = 0; count < TRAIL_SIZE; count++) {
            if (getRoundLocation(dv, round, hunter) == where) {
               if (dv->past[(round * ROUND_LENGTH) + (index + MINION_ONE)] == 'T') {
                  *numTraps -= 1;
               } else if (dv->past[(round * ROUND_LENGTH) + (index + MINION_ONE)] == 'V') {
                  *numTraps -= 1;
               }

               if (dv->past[(round * ROUND_LENGTH) + (index + MINION_TWO)] == 'T') {
                  *numTraps -= 1;
               } else if (dv->past[(round * ROUND_LENGTH) + (index + MINION_TWO)] == 'V') {
                  *numTraps -= 1;
               }
            }

            round -= 1;
         }
         
         hunter += 1;
      }
   }

   // printf("where: %s (%d), numTraps: %d, numVamps: %d\n", idToName(where), where, *numTraps, *numVamps);
}
Example #7
0
void decideDraculaMove(DracView gameState)
{
    int round = giveMeTheRound(gameState);

    if (round == 0) {
        registerBestPlay("GA","");
    } else if (round == 1){
		registerBestPlay("CD","");
	} else if (round == 2){
		registerBestPlay("KL","");
	} else if (round == 3){
		registerBestPlay("D1","");
    } else if (round == 4){
        registerBestPlay("HI","");
    } else if (round == 5){
        registerBestPlay("TP","");
    } else if (round == 6){
        registerBestPlay("TP","");
	} else {   

   
    // Populate dracTrail with last 6 moves made
    int *dracTrail = calloc(sizeof(int),6);
    giveMeTheTrail(gameState, 4, dracTrail);
    
    // === PREDETERMINE HIDE AND DOUBLE BACK ===
    // Determine if hide has been used in trail. 
    // Returns HIDING = 0 if you can't hide, and 1 if you can.
    int hideCount = 0;
    int HIDING = 0;
    int reference0 = 0;
        
    while(hideCount < 6){
        if(dracTrail[hideCount] == 102){
            hideCount++; reference0++;
        } else hideCount++; 
    }
    if (reference0 == 0) HIDING = 1;
    
    // Can't hide at sea
    if (idToType(whereIs(gameState,4)) == SEA) { printf("At sea\n"); HIDING = 0; }
    
    // Determine if double back has been used in trail. 
    // Returns BACK = 0 if you can't hide, and 1 if you can.
    int backCount = 0;
    int BACK = 0;
    int reference1 = 0;
        
    while(backCount < 6){
        if(dracTrail[backCount] == 103){
            backCount++; reference1++;
        } else backCount++; 
    }
    if (reference1 == 0) BACK = 1;
    
       // === FIND LEGAL CONNECTED LAND AND WATER CONNECTIONS === //
    
                        // == BASIC MOVES == //
    
                            // = LAND = //
        
    // Populate landArray with possible connected LAND 
    // locations from current location
	int numLocations;
    int *landArray = whereCanIgo(gameState,&numLocations,1, 0);
    int landLength = numLocations;
    
    // Works out if we have already gone through a location in our
    // trail.
    // Each location in dracTrail is compared to every
    // location in landArray. 
    // If they're the same, that entry in landArray is changed
    // to -1, meaning we cannot move there, and landLength shortened.
    int count = 0;
    int x = 0;
        
    while(x < numLocations){
        while(count < 6){
            if(dracTrail[count] == landArray[x]){
                landArray[x] = -1;
                count = 8;
                landLength--;
            }else count++;
        }
        x++;
        count = 0;
    }
    
    // Make array as big as possible LAND moves for us is.
    int *landMoves = calloc(sizeof(int),landLength);
    
    // Little loop to transfer possible LAND moves into the new array
    int a = 0; int b = 0;
    while(a < numLocations){
        if(landArray[a] != -1){
            landMoves[b] = landArray[a];
            a++;
            b++;
        } else a++;
    }
    
    printf("%d land length\n", landLength);
    
    // Register first available move (just for safety)
    registerBestPlay(idToAbbrev(landMoves[0]),"1");
    
                            // = WATER = //
        
    // Populate waterArray with possible connected WATER 
    // locations from current location
    int waterLocations;
    int *waterArray = whereCanIgo(gameState,&waterLocations,0,1);
    int waterLength = waterLocations;
        
    // Works out if we have already gone through a location in our
    // trail.
    // Each location in dracTrail is compared to every
    // location in waterArray. 
    // If they're the same, that entry in waterArray is changed
    // to -1, meaning we cannot move there, and waterLength shortened.
    count = 0; x = 0;
        
    while(x < waterLocations){
        while(count < 6){
            if(dracTrail[count] == waterArray[x]){
                waterArray[x] = -1;
                count = 8;
                waterLength--;
            } else count++;
        }
        x++;
        count = 0;
    }
    // Make array as big as possible WATER moves for us is.
    int *waterMoves = calloc(sizeof(int),waterLength);
    
    // Little loop to transfer possible WATER moves into the new array
    a = 0; b = 0;
    while(a < waterLocations){
        if(waterArray[a] != -1){
            waterMoves[b] = waterArray[a];
            a++;
            b++;
        } else a++;
    }
    
                        // = REGISTER BASIC MOVE = //
        
    // Register first available move (just for safety)
    registerBestPlay(idToAbbrev(landMoves[0]),"1");
    
    // Check if no LAND move has been registered. If it hasn't, register
    // basic water move.
    if (landLength == 0) registerBestPlay(idToAbbrev(waterMoves[0]),"2");
    
    // Check if no basic LAND or WATER move has been registered. If not,
    // hide OR double back.
    if ((landLength == 0) && (waterLength == 0)) {
        if (HIDING == 1) {
            registerBestPlay("HI","3");
        } else if ((HIDING == 0) && (BACK == 1)) {
            registerBestPlay("D1","4");
        } else registerBestPlay("TP", "5");
    }
    
                            // == COMPLEX MOVES == //
    
    // Populate the hunter arrays with the possible moves that they can make
    // - both LAND and WATER
    int *hunter0Moves; int *hunter1Moves;
    int *hunter2Moves; int *hunter3Moves;
        
    int hunter0Locations; int hunter1Locations;
    int hunter2Locations; int hunter3Locations;
        
    hunter0Moves = whereCanTheyGo(gameState,&hunter0Locations,0,TRUE,TRUE,TRUE);
    hunter1Moves = whereCanTheyGo(gameState,&hunter1Locations,1,TRUE,TRUE,TRUE);
    hunter2Moves = whereCanTheyGo(gameState,&hunter2Locations,2,TRUE,TRUE,TRUE);
    hunter3Moves = whereCanTheyGo(gameState,&hunter3Locations,3,TRUE,TRUE,TRUE);
        
    // Attempting to determine the next move by working out
    // where we have been, where we can go, and if the hunters
    // can also go there in their next move, makes us safer!

    int hunter0Count = 0; int hunter1Count = 0;
    int hunter2Count = 0; int hunter3Count = 0; int dracCount = 0;
    int safeLength = landLength; int ref = 0;
        
    // Checking whether the possible LAND moves for Dracula
    // are possible LAND moves for the hunters
    // Note: we do not follow this check for water moves because...
    // WE DON'T CARE ABOUT MATCHING WATER MOVES!
    
    // This works by changing entries in the landMoves to -1
    // when there is a risk their move will be the same as our move
    while(dracCount < landLength){
        while(hunter0Count < hunter0Locations){
            if(hunter0Moves[hunter0Count] == landMoves[dracCount]){
            	landMoves[dracCount] = -1;                    
				dracCount++;
                hunter0Count = hunter0Locations; hunter1Count = hunter1Locations;
                hunter2Count = hunter2Locations; hunter3Count = hunter3Locations;
			    safeLength--;
            }else hunter0Count++;
        }
        while(hunter1Count < hunter1Locations){
            if(hunter1Moves[hunter1Count] == landMoves[dracCount]){
	        	landMoves[dracCount] = -1;                    
                dracCount++;
                hunter1Count = hunter1Locations; hunter2Count = hunter2Locations;
                hunter3Count = hunter3Locations;

			    safeLength--;
            }else hunter1Count++;
        }
        while(hunter2Count < hunter2Locations){
            if(hunter2Moves[hunter2Count] == landMoves[dracCount]){
	        	landMoves[dracCount] = -1;                 
                dracCount++;
                hunter2Count = hunter2Locations; hunter3Count = hunter3Locations;
				safeLength--;
                }else hunter2Count++;
            }
        while(hunter3Count < hunter3Locations){
            if(hunter3Moves[hunter3Count] == landMoves[dracCount]){
		        landMoves[dracCount] = -1;                
                dracCount++;
                hunter3Count = hunter3Locations;
				safeLength--;
            }else hunter3Count++;
        }
        //reset the counters, and if the dracCount hasn't already been incremented during the movement,
        hunter0Count = 0; hunter1Count = 0; hunter2Count = 0; hunter3Count = 0;
        if(dracCount == ref){
	    	dracCount++;
        }
        ref++;
    }
    
    // After changing the move list to the -1s, we must create a new array
    // of possible safe moves we can make.
    
    // Make array as big as possible SAFE LAND moves for us is.
    int *safeMoves = calloc(sizeof(int), safeLength);
    
    // Little loop to transfer possible SAFE LAND moves into the new array
    a = 0; b = 0;
    while(a < landLength){
        if(landMoves[a] != -1){
            safeMoves[b] = landMoves[a];
            a++;
            b++;
        } else a++;
    }
        printf("Number of Safe Moves: %d\n",safeLength);
        printf("Number of Water Moves: %d\n",waterLength);
                    // == REGISTER A SAFE MOVE == //
    if (safeLength > 0) registerBestPlay(idToAbbrev(safeMoves[0]),"7");
    
                        // == SMART MOVES == //
    if (safeLength == 0){
        // If greater than 20 health, move towards them anyway
        // (make a safe move next round if available)
        if((howHealthyIs(gameState,4) > 20) && (waterLength > 0)) {
                registerBestPlay(idToAbbrev(waterMoves[0]),"8");
        // If less than 20, try hiding or double backing.
        } else {
            if(HIDING == 1) {
                registerBestPlay("HI","9");
            } else if ((HIDING == 0) && (BACK == 1)) {
                registerBestPlay("D1","10");
            }
        }
    }
    
                        // == LAST RESORT MOVES == //
    // No moves available, TP 
    if ((landLength == 0) && (waterLength == 0)) {
        if (HIDING == 1) {
            registerBestPlay("HI","11");
        } else if ((HIDING == 0) && (BACK == 1)) {
            registerBestPlay("D1","12");
        } else registerBestPlay("TP", "13");
    }
    
    }

}
Example #8
0
DracView newDracView(char *pastPlays, PlayerMessage messages[])
{
    //REPLACE THIS WITH YOUR OWN IMPLEMENTATION
    DracView dracView = malloc(sizeof(struct dracView));

    int j,i=0;
    int player=0;
    Playersave currentstate;    
    
    //initialise struct
    dracView->hello = 42;   
    dracView->gameround = 0;   
    dracView->gameturn = 0;
    dracView->playerturn = 0;
    dracView->score = GAME_START_SCORE ;

    dracView->traps = 0;
    dracView->vamps = 0;

    //initialise array of traps and vamps
    for( i=0; i<NUM_MAP_LOCATIONS ;i++){
      dracView->vampsarray[i] = 0;
      dracView->trapsarray[i] = 0;
    }
    
    //initialise hunters 1-4
    for( i=0; i<PLAYER_DRACULA ; i++){
    
      //create struct
      
      dracView->playerstate[i] = malloc(sizeof(struct PlayerSave));
      //quick access variable
      currentstate = dracView->playerstate[i];
      
      //set player number
      currentstate->playernumber = i;
      
      //set player health to 9
      currentstate->health = GAME_START_HUNTER_LIFE_POINTS;
      
      //set player starting position (nowhere)
      currentstate->current = UNKNOWN_LOCATION;
      
      //fill trail with nowheres
      for( j=0; j<TRAIL_SIZE ; j++){
        currentstate->trail[j] = NOWHERE;
      }
    }
    
    //initialise Dracula
    if(1){
      //player Dracula
      i = PLAYER_DRACULA  ;
      //create struct
      dracView->playerstate[i] = malloc(sizeof(struct PlayerSave));
      //quick access variable
      currentstate = dracView->playerstate[i];
      
      //set player number
      currentstate->playernumber = i;
      
      //set player health to 40
      currentstate->health = GAME_START_BLOOD_POINTS;
      
      //set player starting position (nowhere)
      currentstate->current = UNKNOWN_LOCATION;    
    
      //fill trail with nowheres
      for( j=0; j<TRAIL_SIZE ; j++){
        currentstate->trail[j] = NOWHERE;
      }      
    }
    

    
    //ACTUALLY READING THE STRING
    //reinitialise searching variables
    i = 0;

    //continue if still things is past plays string.
    while( (strlen( pastPlays ) > i) && ((pastPlays[i-1] != '\0')||i==0) ){    
    
      //increment game turn, round
      dracView->gameturn++;
      if(dracView->gameturn == PLAYER_DRACULA+1){
        dracView->gameturn = 0;
        dracView->gameround++;
      }
    
      //player quick variable
      player = dracView->playerturn;   
    
      //easy access pointer
      currentstate = dracView->playerstate[player];
 
      
      //hunterwrite
      //hunterwrite
      if( player < PLAYER_DRACULA ){ 
        
        //check if player stayed in city to heal
        if( (currentstate->current == abbrevToID( pastPlays+i+1 )) && (idToType(currentstate->current) == LAND) ){
          currentstate->health += LIFE_GAIN_REST ;
          //hunter health cannot exceed starting health
          if( currentstate->health > GAME_START_HUNTER_LIFE_POINTS){
            currentstate->health = GAME_START_HUNTER_LIFE_POINTS;
          }
        }
        
        //update locations for player
        currentstate->current = abbrevToID( pastPlays+i+1 );
        
        //check if player is at a hospital
        if( currentstate->current == ST_JOSEPH_AND_ST_MARYS){
          currentstate->health = GAME_START_HUNTER_LIFE_POINTS;
        }
        
        
        
        //fix trail array 
        for( j=TRAIL_SIZE; j>1 ; j--){
          currentstate->trail[j-1] = currentstate->trail[j-2];
        }
        currentstate->trail[0] = currentstate->current;
        
  
        //check remainder of string
        for( j=3 ; pastPlays[i+j] != '.'; j++){
          //different occurrences
          switch( pastPlays[i+j] ){
            //check if trap encountered        
            case 'T':{ 
              //update health
              dracView->trapsarray[currentstate->current]--;
              dracView->traps--;
              currentstate->health -= LIFE_LOSS_TRAP_ENCOUNTER;
              break;
            }
            //check if immature vamp encountered          
            case 'V':{
              //update vamps
              dracView->vampsarray[currentstate->current]--;
              dracView->vamps--;
              break;
            }
            //check if Dracula encountered          
            case 'D':{
              //update health -> hunter                
              currentstate->health -= LIFE_LOSS_DRACULA_ENCOUNTER;
              //update health -> Dracula           
              dracView->playerstate[PLAYER_DRACULA]->health -= LIFE_LOSS_HUNTER_ENCOUNTER;
              break;
            }
          }
          
          //RULECHECK: what happens if hunter goes into a city with drac, but dies to a trap before encounter?
          //check if hunter is dead
          if( currentstate->health < 0 ){
            dracView->score -= SCORE_LOSS_HUNTER_HOSPITAL;
            currentstate->health = GAME_START_HUNTER_LIFE_POINTS;
            currentstate->current = ST_JOSEPH_AND_ST_MARYS;
          }
        }
      }
      
      
      
      //draculawrite
      //draculawrite
      else if( player == PLAYER_DRACULA) { 
      
        //check if drac stayed in castle to heal
        if( (currentstate->current == abbrevToID( pastPlays+i+1 )) && ( currentstate->current == CASTLE_DRACULA) ){
          currentstate->health += LIFE_GAIN_CASTLE_DRACULA;
          //Drac health can exceed 40
        }
    
        //update locations for dracula
        switch( pastPlays[i+1] ){
          //C?
          case 'C': currentstate->current = CITY_UNKNOWN; break;
          //S?
          case 'S': currentstate->current = SEA_UNKNOWN; break;
          //HI
          case 'H': currentstate->current = HIDE; break;
          //TP
          case 'T': currentstate->current = TELEPORT; break;   
          //Dn
          case 'D':{
            //which double back?
            switch( pastPlays[i+2] ){
              case '1': currentstate->current = DOUBLE_BACK_1; break;
              case '2': currentstate->current = DOUBLE_BACK_2; break;
              case '3': currentstate->current = DOUBLE_BACK_3; break;
              case '4': currentstate->current = DOUBLE_BACK_4; break;
              case '5': currentstate->current = DOUBLE_BACK_5; break;
            }
            break;
          }
          //XX proper city coordinates
          default: currentstate->current = abbrevToID( pastPlays+i+1 ); break;
        }
        
        
        //fix trail array 
        LocationID fallenofftrail = currentstate->trail[TRAIL_SIZE-1];
        for( j=TRAIL_SIZE; j>1 ; j--){
          currentstate->trail[j-1] = currentstate->trail[j-2];
        }
        currentstate->trail[0] = currentstate->current;



        //if 'other' locations (hunterview)
        
          //check if at sea
          //HUNTERVIEW
          if( currentstate->current == SEA_UNKNOWN ){
            //update health
            currentstate->health -= LIFE_LOSS_SEA;
          }
          //DRACVIEW
          else if( currentstate->current >= 0 && currentstate->current <= 70 ){
            if( idToType( currentstate->current ) == SEA ){
              currentstate->health -= LIFE_LOSS_SEA;
            }
          }
          
          //check if doublebacked to sea
          if( pastPlays[i+1] == 'D' ){

            //verify double back location from trail array is not sea

            //HUNTERVIEW
            if( currentstate->trail[(pastPlays[i+2]-'0')] == SEA_UNKNOWN ){

              currentstate->health -= LIFE_LOSS_SEA;
            }
            
            //DRACVIEW
            else if( (currentstate->trail[(pastPlays[i+2]-'0')]) >= 0 && (currentstate->trail[(pastPlays[i+2]-'0')]) <= 70 ){
              if( idToType(currentstate->trail[(pastPlays[i+2]-'0')]) == SEA ){

                currentstate->health -= LIFE_LOSS_SEA;
              }
            }
          }
       


        

        
        //update score due to dracula turn
        dracView->score -= SCORE_LOSS_DRACULA_TURN;
        
        //check if trap placed
        if( pastPlays[i+3] == 'T' ){
          //update traps
          if(dracView->trapsarray[currentstate->current] < 3){
            dracView->trapsarray[currentstate->current]++;
            dracView->traps++;
          }
        }
          
        //check if immature vamp placed
        if( pastPlays[i+4] == 'V' ){
          //update vamps
          dracView->vampsarray[currentstate->current]++;
          dracView->vamps++;
        }
        
        //check if trap died
        if( pastPlays[i+5] == 'M' ){
          //update traps
          dracView->traps -= dracView->vampsarray[fallenofftrail];
          dracView->vampsarray[fallenofftrail] = 0;
        }
        
        //check if vamp matures
        if( pastPlays[i+6] == 'V' ){
          //update vamps
          dracView->vampsarray[currentstate->current]--;
          dracView->vamps--;
          dracView->score -= SCORE_LOSS_VAMPIRE_MATURES;
        }
        
      }
      
      //nowrite
      else; 
      

      
      //determine which player will be acting in the next turn
      switch( pastPlays[i] ){
        case 'G': player = 1; break;
        case 'S': player = 2; break;
        case 'H': player = 3; break;
        case 'M': player = 4; break;
        case 'D': player = 0; break;
        default: player = 0xDEADBEEF; break;
      }
      dracView->playerturn = player;
      

      //move into next play
      i += 8;
    }
   
    return dracView;
}
Example #9
0
// What are the specified player's next possible moves
LocationID *whereCanTheyGo(DracView currentView, int *numLocations,
                           PlayerID player, int road, int rail, int sea)
{

  assert(currentView != NULL);
  assert(player >= PLAYER_LORD_GODALMING && player <= PLAYER_DRACULA);
  assert(numLocations != NULL);
  
  LocationID from = currentView->playerstate[player]->current;
  assert(from >= ALICANTE && from < NUM_MAP_LOCATIONS);
  
  Round round = currentView->gameturn;
  assert(round >= 0 && round <= 366);
 
  Map europe = newMap();
  LocationID locations[NUM_MAP_LOCATIONS];
  int i,j=0;
  //USE AN ARRAY TO INDICATE PATHING TO EVERY DESTINATION
  //0 -> cannot reach, 1 -> reachable
  for ( i=0; i<NUM_MAP_LOCATIONS; i++ ) {
    locations[i] = 0;
  }
  
  
  //The reachability will mark on the array 
  if ( road ) {
    reachability(europe, from, ROAD, ONEPATH, locations);
  }
  
  if ( rail && player != PLAYER_DRACULA) {
    //Dracula can't travel by rail
    int roundmod = (round+player) % 4;
    reachability(europe, from, RAIL, roundmod, locations);
  }

  if (sea) {
    reachability(europe, from, BOAT, ONEPATH, locations);
  }

  
  //PATH FIXING FOR DRACULA
  if ( player == PLAYER_DRACULA ) {
  
    //Dracula can't move to hospital, this is a incorrect path.
    locations[ST_JOSEPH_AND_ST_MARYS] = 0;
  
    //checks if Dracula is allowed to hide
    
    //check for hide in trail
    while( i<TRAIL_SIZE ){
      if( currentView->playerstate[PLAYER_DRACULA]->trail[i] == HIDE ){
        locations[from] = 0;
      }
    }
    
    //check if at sea
    if( idToType(from) == SEA ); locations[from] = 0;
    
  }
  
  //place reachable locations into our return array
  j = 0;
  
  LocationID *reachable = malloc(sizeof (int)*NUM_MAP_LOCATIONS);
  
  //place corresponding cities (e.g. ALICANTE, ROME, MARSEILLES) into 'result'
  for (i=0; i<NUM_MAP_LOCATIONS; i++) {
    
    if ( locations[i] ) {
      reachable[j] = i;
      j++;
    }
  }
  
  *numLocations = j;

  
  destroyMap(europe);
  return reachable;
}
Example #10
0
// Creates a new GameView to summarise the current state of the game
GameView newGameView(char *pastPlays, PlayerMessage messages[])
{
    //REPLACE THIS WITH YOUR OWN IMPLEMENTATION
    GameView gameView = malloc(sizeof(struct gameView));

    //Extract information from the pastPlays
    //how many characters are there in pastPlays
    int numberOfChars = 0;
    while(pastPlays[numberOfChars] != 0){
        numberOfChars++;
    }

    //Initialise the roundCounter
    if(numberOfChars == 0){
        gameView->roundCounter = 0;
    }else gameView->roundCounter = (int)numberOfChars/40 + 1;
    printf("numberOfChars is %d roundCounter is %d\n",numberOfChars,gameView->roundCounter);

    //Initialise the turn
    //whoseTurn has to be passed to getCurrentPlayer()
    gameView->whoseTurn = (numberOfChars+1)/8;

    //Initialise the game points
    gameView->gamePoints = GAME_START_SCORE;
    //gamepoints decreases by one every time dracula's turn has been finished
    gameView->gamePoints -= (int)(numberOfChars+1)/ 40;
    //gamepoints decreases by 13 when vampire is mature(six round after dracula place the immature vampire)
    if(numberOfChars+1 > 520){
        int dracVampire = 517;
        while(pastPlays[dracVampire] != 'V' && dracVampire < numberOfChars){
            dracVampire += 40;
        }
        int vampireDead = 0;
        for(int a = dracVampire + 6; a < dracVampire + 40 * 6; a += 8){
            int b = dracVampire;
            while(pastPlays[b] != '.' && ((a-3)/8 % 5) != 4){
                if(pastPlays[b] == 'V') vampireDead = 1;
                b++;
            }
            //six rounds
            if(!vampireDead){
                gameView->gamePoints -= SCORE_LOSS_VAMPIRE_MATURES; 
            }
        }
    }

    //Initialise the blood and life points
    int a = 0;
    int b = 0;

    gameView->blood[PLAYER_LORD_GODALMING] = GAME_START_HUNTER_LIFE_POINTS;
    gameView->blood[PLAYER_DR_SEWARD] = GAME_START_HUNTER_LIFE_POINTS;
    gameView->blood[PLAYER_VAN_HELSING] = GAME_START_HUNTER_LIFE_POINTS;
    gameView->blood[PLAYER_MINA_HARKER] = GAME_START_HUNTER_LIFE_POINTS;
    gameView->blood[PLAYER_DRACULA] = GAME_START_BLOOD_POINTS; 

    //change of hunters' health
    for(a = 3; a < numberOfChars; a += 8){
        b = a;
        while(pastPlays[b] != '.' && ((a-3)/8 % 5) != 4){
            if(pastPlays[b] == 'T'){
                gameView->blood[(a-3)/8 % 5] -= LIFE_LOSS_TRAP_ENCOUNTER;
                if(gameView->blood[(a-3)/8 % 5] < 0) gameView->blood[(a-3)/8 % 5] = GAME_START_HUNTER_LIFE_POINTS;  
            }
            if(pastPlays[b] == 'D') {
                gameView->blood[(a-3)/8 % 5] -= LIFE_LOSS_DRACULA_ENCOUNTER;
                gameView->blood[PLAYER_DRACULA] -= LIFE_LOSS_HUNTER_ENCOUNTER;
            }
            b++;
        }
    }
    //change of dracula's blood
    //dracula hate water
    for(a = 33; a < numberOfChars; a += 40){
        b = a;
        char message[3];
        message[0] = pastPlays[a];
        message[1] = pastPlays[a+1];
        message[2] = 0;
        if((message[0] == 'C' && message[1] == '?')
            || (message[0] == 'H' && message[1] == 'I')
            || (message[0] == 'T' && message[1] == 'P')){
            break;
        }else if(abbrevToID(message) >= MIN_MAP_LOCATION && abbrevToID(message) <= MAX_MAP_LOCATION){
            if(idToType(abbrevToID(message)) == SEA) {
                gameView->blood[PLAYER_DRACULA] -= 2;
            }
        }else if(message[0] == 'S' && message[1] == '?'){
            gameView->blood[PLAYER_DRACULA] -= 2;   
        }else if(message[1] >= '1' && message[1] <= '5'){
            message[0] = pastPlays[b - 40 * (message[1] - 48)];
            message[1] = pastPlays[b - 40 * (message[1] - 48) + 1];
            if(message[0] == 'S' && message[1] == '?'){
                gameView->blood[PLAYER_DRACULA] -= 2;
                break;
            }else if(idToType(abbrevToID(message)) == SEA) gameView->blood[PLAYER_DRACULA] -= 2;
        }
    }


    //Initialise the location
    if(numberOfChars == 0){
        gameView->location[PLAYER_LORD_GODALMING] = UNKNOWN_LOCATION;
        gameView->location[PLAYER_DR_SEWARD] = UNKNOWN_LOCATION;
        gameView->location[PLAYER_VAN_HELSING] = UNKNOWN_LOCATION;
        gameView->location[PLAYER_MINA_HARKER] = UNKNOWN_LOCATION;
        gameView->location[PLAYER_DRACULA] = UNKNOWN_LOCATION;
    }else {
        int first = 0;
        if(numberOfChars < 32) {
            first = 1;
            int a = (39 - numberOfChars)/8;
            int b = 0;
            while (b < a){
                gameView->location[4-b] = UNKNOWN_LOCATION;
                b++;
            }
        } else{
            for(first = numberOfChars - 38;first < numberOfChars; first += 8){
                char message[3];
                message[0] = pastPlays[first];
                message[1] = pastPlays[first+1];
                message[2] = 0;
                printf("%s\n",message);
                if((first-1)/8 % 5 == 4){
                    if(message[1] == '?'){
                        switch(message[0]){
                            case 'C': gameView->location[PLAYER_DRACULA] = CITY_UNKNOWN; break;
                            case 'S': gameView->location[PLAYER_DRACULA] = SEA_UNKNOWN; break;
                        }
                    }else if(message[0] == 'H' && message[1] == 'I'){
                        gameView->location[PLAYER_DRACULA] = HIDE;
                    }else if(message[1] >= '1' && message[1] <= '5'){
                        gameView->location[PLAYER_DRACULA] = DOUBLE_BACK_1 + message[1] - 49;
                    }else if(message[0] == 'T' && message[1] == 'P'){
                        gameView->location[PLAYER_DRACULA] = TELEPORT;
                        gameView->blood[PLAYER_DRACULA] += LIFE_GAIN_CASTLE_DRACULA;
                    } 
                    else{
                        gameView->location[PLAYER_DRACULA] = abbrevToID(message);
                        if(gameView->location[PLAYER_DRACULA] == CASTLE_DRACULA){
                            gameView->blood[PLAYER_DRACULA] += LIFE_GAIN_CASTLE_DRACULA;
                        }
                    }
                }else{
                    gameView->location[((first-1)/8) % 5] = abbrevToID(message);
                    if (gameView->location[((first-1)/8) % 5] == ST_JOSEPH_AND_ST_MARYS){
                        gameView->blood[((first-1)/8) % 5] = GAME_START_HUNTER_LIFE_POINTS;
                        gameView->gamePoints -= SCORE_LOSS_HUNTER_HOSPITAL;
                    }
                    if (gameView->roundCounter >= 2){
                        message[0] = pastPlays[first - 40];
                        message[1] = pastPlays[first - 39];
                        if(abbrevToID(message) == gameView->location[(first-1)/8 % 5]){
                            gameView->blood[(first-1)/8 % 5] += LIFE_GAIN_REST;
                            if(gameView->blood[(first-1)/8 % 5] > 9){
                                gameView->blood[(first-1)/8 % 5] = GAME_START_HUNTER_LIFE_POINTS;
                            }
                        }
                    }
                }
            }
        }
    }
    
    //initialising the trail
    a = 0;
    b = 0;
    int counter = 0;
    int totalNumberPlayers = 0;
    for (a = numberOfChars - 6; a > 0; a -= 8){
        int currentPlayer = 0;
        for(b = a ; b > 0; b -= 40){
            currentPlayer = (b-1)/8 % 5;
            char message[3];
            message[0] = pastPlays[b];
            message[1] = pastPlays[b+1];
            message[2] = 0;
            if((b-1)/8 % 5 == PLAYER_DRACULA){
                if(message[1] == '?'){
                    switch(message[0]){
                        case 'C': gameView->trail[PLAYER_DRACULA][counter] = CITY_UNKNOWN; break;
                        case 'S': gameView->trail[PLAYER_DRACULA][counter] = SEA_UNKNOWN; break;
                    }
                }else if (message[0] == 'H' && message[1] == 'I'){
                    gameView->trail[PLAYER_DRACULA][counter] = HIDE;
                }else if (message[1] >= '1' && message[1] <= '5'){
                    gameView->trail[PLAYER_DRACULA][counter] = DOUBLE_BACK_1 + message[1] - 49;
                }else if(message[0] == 'T' && message[1] == 'P'){
                    gameView->trail[PLAYER_DRACULA][counter] = TELEPORT;
                }else gameView->trail[PLAYER_DRACULA][counter] = abbrevToID(message); 
            }else gameView->trail[currentPlayer][counter] = abbrevToID(message);
            counter++;
            if(counter == 6) break;
        }
        while(counter < 6){
            gameView->trail[currentPlayer][counter] = UNKNOWN_LOCATION;
            counter++;
        }
        counter = 0;
        totalNumberPlayers++;
        if(totalNumberPlayers > 4) break;
    }

    return gameView;
}