Because of a weird task requirement, folders are not allowed

Who tf came up with this limitation? Seriously...
This commit is contained in:
Martin Prokoph
2025-02-01 19:05:56 +01:00
parent d8ae57eb3e
commit 693c389e3f
25 changed files with 66 additions and 59 deletions

View File

@@ -1 +1,2 @@
g++ -std=c++23 -Wall ./src/main.cpp -o ./build/testCompiled && ./build/testCompiled mkdir build
g++ -std=c++23 -Wall ./main.cpp -o ./build/testCompiled && ./build/testCompiled

View File

@@ -1,2 +1,2 @@
# Adventura # Adventura by Martin Prokoph
Simple terminal game made in 24 hours Simple terminal game created for the GdP module at HTWK Leipzig

View File

@@ -1,4 +1,4 @@
Führe das Programm mit dem Argument --test aus r einen automatisierten Test, führe das Programm mit dem Argument --test aus
asdddddddddddddddwwwwwwddddddwwwwdddd asdddddddddddddddwwwwwwddddddwwwwdddd
aaaaaaassssssddddssssdddddddddddwwwwwddddddwwwwdddddddddddddddddddd aaaaaaassssssddddssssdddddddddddwwwwwddddddwwwwdddddddddddddddddddd

View File

@@ -37,13 +37,15 @@ string readInput(string feedback) {
* This is used to progress through the worlds in the correct order. * This is used to progress through the worlds in the correct order.
* *
* @param dir The directory to get the file names from * @param dir The directory to get the file names from
* @param extension The file extension to filter by
* @return A list of all file names in the specified directory, sorted alphabetically. * @return A list of all file names in the specified directory, sorted alphabetically.
*/ */
vector<string> getOrderedFileNames(string dir) { vector<string> getOrderedFileNames(string dir, string extension) {
vector<string> worlds; vector<string> worlds;
// Iterate over all files in the worlds directory // This used to be so elegant and iterate over all files in the worlds directory,
// but because of the weird restriction with no folders being allowed, we just filter the files based on their extension.
for (auto & entry : std::filesystem::directory_iterator(dir)) { for (auto & entry : std::filesystem::directory_iterator(dir)) {
worlds.push_back(entry.path()); if (static_cast<string>(entry.path()).ends_with(extension)) worlds.push_back(entry.path());
} }
// We use this to sort the worlds alphabetically, so that the game progresses in the correct order. // We use this to sort the worlds alphabetically, so that the game progresses in the correct order.
std::sort( worlds.begin(), worlds.end(), [](string a, string b) { std::sort( worlds.begin(), worlds.end(), [](string a, string b) {

View File

@@ -15,7 +15,6 @@ using std::cout;
using std::endl; using std::endl;
bool startWorld(string worldFile); bool startWorld(string worldFile);
vector<string> getOrderedFileNames(string dir);
bool testMode = false; bool testMode = false;
unsigned int worldIndex = 2; unsigned int worldIndex = 2;
@@ -40,27 +39,27 @@ int main(int argc, char *argv[]) {
if (!startWorld("./worlds/" + string(argv[i+1]))) if (!startWorld("./worlds/" + string(argv[i+1])))
return 0; // Load only the specified world return 0; // Load only the specified world
else else
printFile("./screens/completed_single_level.txt", Color::BRIGHT_GREEN); printFile("./completed_single_level.screen.txt", Color::BRIGHT_GREEN);
return 0; return 0;
} }
} }
if (!testMode) { if (!testMode) {
printFile("./screens/help.txt", Color::BRIGHT_BLUE); // Print help screen printFile("./help.screen.txt", Color::BRIGHT_BLUE); // Print help screen
return 0; return 0;
} }
} }
if (!testMode) { if (!testMode) {
printFile("./screens/start.txt", Color::BRIGHT_YELLOW); printFile("./start.screen.txt", Color::BRIGHT_YELLOW);
waitForInput(); waitForInput();
printGuide(); printGuide();
waitForInput(); waitForInput();
} }
// Load every world in order // Load every world in order
for (const auto & world : getOrderedFileNames("./worlds")) for (const auto & world : getOrderedFileNames("./", ".world.txt"))
if (!startWorld(world)) return 0; if (!startWorld(world)) return 0;
// Print the victory screen once all levels have been completed // Print the victory screen once all levels have been completed
printFile("./screens/victory.txt", Color::BRIGHT_GREEN); printFile("./victory.screen.txt", Color::BRIGHT_GREEN);
return 0; return 0;
} }
@@ -82,6 +81,6 @@ bool startWorld(string worldFile) {
inputLoop(player, world, testMode, worldIndex); inputLoop(player, world, testMode, worldIndex);
worldIndex++; worldIndex++;
if (!player.isAlive()) printFile("./screens/death.txt", Color::BRIGHT_RED); if (!player.isAlive()) printFile("./death.screen.txt", Color::BRIGHT_RED);
return player.hasReachedGoal(); return player.hasReachedGoal();
} }

View File

@@ -6,9 +6,6 @@
#include "blockRegistry.hpp" #include "blockRegistry.hpp"
#include "output.hpp" #include "output.hpp"
bool tryWalk(World& world, Player& player, bool left);
bool tryGoDown(World& world, Player& player);
bool tryGoUp(World& world, Player& player);
void tryPushBlock(BlockPos& blockPos, World& world, bool left); void tryPushBlock(BlockPos& blockPos, World& world, bool left);
void tryBlockGravity(BlockPos& blockPos, World& world); void tryBlockGravity(BlockPos& blockPos, World& world);
@@ -38,41 +35,6 @@ void waitForInput() {
while (!is_in(lastChar, 'w', 'a', 's', 'd')) cin >> lastChar; while (!is_in(lastChar, 'w', 'a', 's', 'd')) cin >> lastChar;
} }
/**
* Processes the player's input and attempts to move the player in the game world
* based on the input character. Supports moving up, left, down, or right
* using the keys 'w', 'a', 's', 'd' as well as their upper-case equivalents (useful in case caps lock is pressed by accident).
*
* @param lastChar The character input representing the player's movement command.
* @param world Reference to the World object representing the game's world.
* @param player Reference to the Player object representing the player's state.
* @return true if the player's position was successfully updated, false otherwise.
*/
bool onInput(char lastChar, World& world, Player& player) {
switch (lastChar) {
case ' ':
case 'w':
case 'W':
return tryGoUp(world, player);
case 'a':
case 'A':
return tryWalk(world, player, true);
case 's':
case 'S':
return tryGoDown(world, player);
case 'd':
case 'D':
return tryWalk(world, player, false);
default: return false;
}
}
/** /**
* Attempts to move the player one block to the left or right. * Attempts to move the player one block to the left or right.
* *
@@ -180,6 +142,40 @@ void tryBlockGravity(BlockPos& playerPos, World& world) {
} }
} }
/**
* Processes the player's input and attempts to move the player in the game world
* based on the input character. Supports moving up, left, down, or right
* using the keys 'w', 'a', 's', 'd' as well as their upper-case equivalents (useful in case caps lock is pressed by accident).
*
* @param lastChar The character input representing the player's movement command.
* @param world Reference to the World object representing the game's world.
* @param player Reference to the Player object representing the player's state.
* @return true if the player's position was successfully updated, false otherwise.
*/
bool onInput(char lastChar, World& world, Player& player) {
switch (lastChar) {
case ' ':
case 'w':
case 'W':
return tryGoUp(world, player);
case 'a':
case 'A':
return tryWalk(world, player, true);
case 's':
case 'S':
return tryGoDown(world, player);
case 'd':
case 'D':
return tryWalk(world, player, false);
default: return false;
}
}
/** /**
* Listens for the player's input and updates the game state accordingly. * Listens for the player's input and updates the game state accordingly.
* If test mode is enabled, reads input from the file TEST.txt instead of the console. * If test mode is enabled, reads input from the file TEST.txt instead of the console.

View File

@@ -43,12 +43,17 @@ public:
move(0, 1); move(0, 1);
} }
else { else {
if (fallLength > 5) alive = false;
fallLength = 0;
playerTexture = REGULAR_PLAYER_TEXTURE; playerTexture = REGULAR_PLAYER_TEXTURE;
if (fallLength > 5) unalive();
fallLength = 0;
} }
if (world.getBlockAt(pos.add(0, 2)).getSettings().isLethal()) alive = false; if (world.getBlockAt(pos.add(0, 2)).getSettings().isLethal()) unalive();
}
void unalive() {
playerTexture = DEAD_PLAYER_TEXTURE;
redraw(world, this->mapToWorldspace());
alive = false;
} }
bool isAlive() { bool isAlive() {
return alive; return alive;
@@ -91,12 +96,16 @@ private:
{' ', 'o', ' '}, {' ', 'o', ' '},
{'/', '|', '\\'}, {'/', '|', '\\'},
{'/', ' ', '\\'} {'/', ' ', '\\'}
} // Player pos is at the center '|' char // Player pos is at the center '|' char
}; }};
const std::array<std::array<char, 3>, 3> FALLING_PLAYER_TEXTURE {{ const std::array<std::array<char, 3>, 3> FALLING_PLAYER_TEXTURE {{
{'\\', 'o', '/'}, {'\\', 'o', '/'},
{' ', '|', ' '}, {' ', '|', ' '},
{'/', ' ', '\\'} {'/', ' ', '\\'}
} // Player pos is at the center '|' char }};
}; const std::array<std::array<char, 3>, 3> DEAD_PLAYER_TEXTURE {{
{' ', ' ', ' '},
{'/', '-', 'X'},
{'/', ' ', '\\'}
}};
}; };