// 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; } }
// 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; }
// 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; }
// 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); }
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"); } } }
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; }
// 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; }
// 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; }