Untitled
unknown
plain_text
2 years ago
10 kB
3
Indexable
#include <iostream> #include <fstream> #include <string> #include "logic.h" using std::cout, std::endl, std::ifstream, std::string; /** * TODO: Student implement this function * Load representation of the dungeon level from file into the 2D map. * Calls createMap to allocate the 2D array. * @param fileName File name of dungeon level. * @param maxRow Number of rows in the dungeon table (aka height). * @param maxCol Number of columns in the dungeon table (aka width). * @param player Player object by reference to set starting position. * @return pointer to 2D dynamic array representation of dungeon map with player's location., or nullptr if loading fails for any reason * @updates maxRow, maxCol, player */ char** loadLevel(const string& fileName, int& maxRow, int& maxCol, Player& player) { std::ifstream file(fileName); if (!file) { std::cerr << "Error loading level: " << fileName << std::endl; return nullptr; } // Read the dimensions of the level from the file file >> maxRow >> maxCol; // Allocate memory for the map char** map = createMap(maxRow, maxCol); // Read the map from the file for (int i = 0; i < maxRow; ++i) { for (int j = 0; j < maxCol; ++j) { file >> map[i][j]; if (map[i][j] == TILE_PLAYER) { player.row = i; player.col = j; } } } // Update the player's initial position to 'o' map[player.row][player.col] = TILE_PLAYER; return map; } /** * TODO: Student implement this function * Translate the character direction input by the user into row or column change. * That is, updates the nextRow or nextCol according to the player's movement direction. * @param input Character input by the user which translates to a direction. * @param nextRow Player's next row on the dungeon map (up/down). * @param nextCol Player's next column on dungeon map (left/right). * @updates nextRow, nextCol */ void getDirection(char input, int& nextRow, int& nextCol) { switch (input) { case MOVE_UP: nextRow = -1; nextCol = 0; break; case MOVE_DOWN: nextRow = 1; nextCol = 0; break; case MOVE_LEFT: nextRow = 0; nextCol = -1; break; case MOVE_RIGHT: nextRow = 0; nextCol = 1; break; default: break; } } /** * TODO: [suggested] Student implement this function * Allocate the 2D map array. * Initialize each cell to TILE_OPEN. * @param maxRow Number of rows in the dungeon table (aka height). * @param maxCol Number of columns in the dungeon table (aka width). * @return 2D map array for the dungeon level, holds char type. */ char** createMap(int maxRow, int maxCol) { char** map = new char*[maxRow]; for(int i = 0; i < maxRow; ++i) map[i] = new char[maxCol]; for(int i = 0; i < maxRow; ++i) for(int j = 0; j < maxCol; ++j) map[i][j] = TILE_OPEN; return map; } /** * TODO: Student implement this function * Deallocates the 2D map array. * @param map Dungeon map. * @param maxRow Number of rows in the dungeon table (aka height). * @return None * @update map, maxRow */ void deleteMap(char**& map, int& maxRow) { for (int i = 0; i < maxRow; ++i) { delete[] map[i]; } delete[] map; } /** * TODO: Student implement this function * Resize the 2D map by doubling both dimensions. * Copy the current map contents to the right, diagonal down, and below. * Do not duplicate the player, and remember to avoid memory leaks! * You can use the STATUS constants defined in logic.h to help! * @param map Dungeon map. * @param maxRow Number of rows in the dungeon table (aka height), to be doubled. * @param maxCol Number of columns in the dungeon table (aka width), to be doubled. * @return pointer to a dynamically-allocated 2D array (map) that has twice as many columns and rows in size. * @update maxRow, maxCol */ char** resizeMap(char** map, int& maxRow, int& maxCol) { int newMaxRow = maxRow * 2; int newMaxCol = maxCol * 2; char** newMap = new char*[newMaxRow]; for (int i = 0; i < newMaxRow; ++i) { newMap[i] = new char[newMaxCol]; } // Initialize new map with empty spaces for (int i = 0; i < newMaxRow; ++i) { for (int j = 0; j < newMaxCol; ++j) { newMap[i][j] = TILE_OPEN; } } // Copy old map into new map for (int i = 0; i < maxRow; ++i) { for (int j = 0; j < maxCol; ++j) { newMap[i * 2][j * 2] = map[i][j]; } } // Delete old map for (int i = 0; i < maxRow; ++i) { delete[] map[i]; } delete[] map; maxRow = newMaxRow; maxCol = newMaxCol; return newMap; } /** * TODO: Student implement this function * Checks if the player can move in the specified direction and performs the move if so. * Cannot move out of bounds or onto TILE_PILLAR or TILE_MONSTER. * Cannot move onto TILE_EXIT without at least one treasure. * If TILE_TREASURE, increment treasure by 1. * Remember to update the map tile that the player moves onto and return the appropriate status. * You can use the STATUS constants defined in logic.h to help! * @param map Dungeon map. * @param maxRow Number of rows in the dungeon table (aka height). * @param maxCol Number of columns in the dungeon table (aka width). * @param player Player object to by reference to see current location. * @param nextRow Player's next row on the dungeon map (up/down). * @param nextCol Player's next column on dungeon map (left/right). * @return Player's movement status after updating player's position. * @update map contents, player */ int doPlayerMove(char** map, int maxRow, int maxCol, Player& player, int nextRow, int nextCol) { char nextPosition = map[nextRow][nextCol]; // Check if the next position is an empty space, a door, or a treasure if (nextPosition == TILE_OPEN || nextPosition == TILE_DOOR || nextPosition == TILE_TREASURE) { // Update the player's position map[player.row][player.col] = TILE_OPEN; player.row = nextRow; player.col = nextCol; map[player.row][player.col] = TILE_PLAYER; // Check if the next position is a treasure if (nextPosition == TILE_TREASURE) { player.treasure++; return STATUS_TREASURE; } // Check if the next position is a door if (nextPosition == TILE_DOOR) { // Check if the player has at least one treasure to exit if (player.treasure > 0) { return STATUS_LEAVE; } else { // Player cannot exit without treasures return STATUS_STAY; } } // Player moved to an empty space return STATUS_MOVE; } // Invalid move: player hit a wall or encountered a monster return STATUS_STAY; } /** * TODO: Student implement this function * Update monster locations: * We check up, down, left, right from the current player position. * If we see an obstacle, there is no line of sight in that direction, and the monster does not move. * If we see a monster before an obstacle, the monster moves one tile toward the player. * We should update the map as the monster moves. * At the end, we check if a monster has moved onto the player's tile. * @param map Dungeon map. * @param maxRow Number of rows in the dungeon table (aka height). * @param maxCol Number of columns in the dungeon table (aka width). * @param player Player object by reference for current location. * @return Boolean value indicating player status: true if monster reaches the player, false if not. * @update map contents */ bool doMonsterAttack(char** map, int maxRow, int maxCol, const Player& player) { char** tempMap = createMap(maxRow, maxCol); for (int i = 0; i < maxRow; ++i) { for (int j = 0; j < maxCol; ++j) { tempMap[i][j] = map[i][j]; } } // Update monster locations for (int i = 0; i < maxRow; ++i) { for (int j = 0; j < maxCol; ++j) { if (tempMap[i][j] == TILE_MONSTER) { // Move monsters one tile toward the player int rowDiff = player.row - i; int colDiff = player.col - j; if (abs(rowDiff) >= abs(colDiff)) { // Move vertically tempMap[i][j] = TILE_OPEN; i += (rowDiff > 0) ? 1 : -1; tempMap[i][j] = TILE_MONSTER; } else { // Move horizontally tempMap[i][j] = TILE_OPEN; j += (colDiff > 0) ? 1 : -1; tempMap[i][j] = TILE_MONSTER; } // Check if monster has reached the player's tile if (i == player.row && j == player.col) { deleteMap(tempMap, maxRow); return true; // Player is caught by a monster } } } } // Update the original map with the new monster positions for (int i = 0; i < maxRow; ++i) { for (int j = 0; j < maxCol; ++j) { map[i][j] = tempMap[i][j]; } } // Clean up the temporary map deleteMap(tempMap, maxRow); return false; // Player is not caught by a monster }
Editor is loading...