Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <Windows.h>
- #include <conio.h>
- #include <ctype.h>
- #include <random>
- #include <chrono>
- #include <thread>
- #include <mmsystem.h>
- #pragma comment(lib, "winmm.lib")
- using namespace std;
- int playerX = 0;
- int playerY = 0;
- int mainMenu();
- void gameStart();
- void customGame();
- void gameControls();
- void gameCredits();
- void customMapInformation();
- void exitProgram();
- int customGameMenu();
- int difficultyMenu();
- void easyDifficulty();
- void normalDifficulty();
- void hardDifficulty();
- void backToMenu();
- void characterMove(string**, int&, int&, int, int);
- void playerMove(string**);
- void display(string**, int, int, int, string);
- void loadMap(string, int, string);
- void loadCustomMapFromTheFolder();
- void createACustomMap();
- void rowsAndColumnsChoice(int, int);
- void startAndEndChoice(int, int);
- int filesInFolderCount(string);
- void levels(string);
- void ShowConsoleCursor(bool showFlag);
- int main()
- {
- system("color 04");
- ShowWindow(GetConsoleWindow(), SW_MAXIMIZE);
- SendMessage(GetConsoleWindow(), WM_SYSKEYDOWN, VK_RETURN, 0x2000000);
- ShowConsoleCursor(false);
- PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC);
- mainMenu();
- return 0;
- }
- typedef void(*menuOptions)();
- menuOptions mainMenuOptions[] = { gameStart, customGame, gameControls, gameCredits, customMapInformation, exitProgram };
- int mainMenu()
- {
- string menu[] = { "Start Game", "Create a Custom Game", "Controls", "Credits", "How to create a custom map?", "Exit"};
- int pointer = 0;
- bool lastUpKeyState = false;
- bool lastDownKeyState = false;
- bool lastReturnKeyState = false;
- bool arrowVisible = true;
- while (true)
- {
- system("cls");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << "The Labyrinth" << "\n" << "\n";
- cout << "Main Menu" << "\n" << "\n";
- for (int i = 0; i < size(menu); i++) // FROM i < 5
- {
- if (i == pointer)
- {
- if (arrowVisible)
- {
- cout << "-> ";
- arrowVisible = false;
- }
- else
- {
- cout << " "; // Prints 4 spaces to cover the previous "-> "
- arrowVisible = true;
- }
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
- cout << menu[i] << "\n";
- }
- else
- {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << menu[i] << "\n";
- }
- }
- bool upKeyState = GetAsyncKeyState(VK_UP);
- if ( (upKeyState) && !(lastUpKeyState) )
- {
- pointer -= 1;
- if (pointer == -1)
- {
- pointer = size(menu) - 1; // FROM pointer = 4
- }
- }
- lastUpKeyState = upKeyState;
- bool downKeyState = GetAsyncKeyState(VK_DOWN);
- if ( (downKeyState) && !(lastDownKeyState) )
- {
- pointer += 1;
- if (pointer == size(menu)) // FROM pointer = 5
- {
- pointer = 0;
- }
- }
- lastDownKeyState = downKeyState;
- bool returnKeyState = GetAsyncKeyState(VK_RETURN);
- if ( (returnKeyState) && !(lastReturnKeyState) )
- {
- mainMenuOptions[pointer]();
- }
- lastReturnKeyState = returnKeyState;
- this_thread::sleep_for(chrono::milliseconds(200));
- }
- }
- void gameStart()
- {
- difficultyMenu();
- }
- void customGame()
- {
- customGameMenu();
- }
- void gameControls()
- {
- system("cls");
- cout << "\n" << "\n";
- cout << " --------------CONTROLS---------------" << "\n";
- cout << " | |" << "\n";
- cout << " | |" << "\n";
- cout << " | ^ --> Up Arrow to move up |" << "\n";
- cout << " | < --> Left Arrow to move left |" << "\n";
- cout << " | > --> Right Arrow to move right |" << "\n";
- cout << " | v --> Down Arrow to move down |" << "\n";
- cout << " | |" << "\n";
- cout << " | Enter / Return --> Enter |" << "\n";
- cout << " | Escape --> Back |" << "\n";
- cout << " | |" << "\n";
- cout << " | |" << "\n";
- cout << " -------------------------------------";
- while (true)
- {
- backToMenu();
- }
- }
- void gameCredits()
- {
- system("cls");
- cout << "Thanks for playing!" << "\n" << "\n";
- cout << "Creator: Petar Bogdanov" << "\n";
- cout << "The people who helped me with this project: eng. Stoyan Filipov and eng. Monika Gencheva" << "\n" << "\n";
- cout << "Press \"ESCAPE\" to go back to the Main Menu";
- while (true)
- {
- backToMenu();
- }
- }
- void customMapInformation()
- {
- system("cls");
- cout << "To create a custom map you need to:" << "\n";
- cout << " 1. Create a .txt file." << "\n";
- cout << " 2. Visualize your map." << "\n";
- cout << " 3. Put the file in the subfolder called \"custom\", if you haven't created it there already." << "\n" << "\n";
- cout << "Press \"ESCAPE\" to go back to the Main Menu";
- while (true)
- {
- backToMenu();
- }
- }
- void exitProgram()
- {
- exit(0);
- }
- menuOptions customMenuOptions[] = { loadCustomMapFromTheFolder, createACustomMap };
- int customGameMenu()
- {
- string menu[] = { "Play on already created custom map placed in the subfolder", "Create a Custom Map" };
- int pointer = 0;
- bool lastUpKeyState = false;
- bool lastDownKeyState = false;
- bool lastReturnKeyState = false;
- bool arrowVisible = true;
- while (true)
- {
- system("cls");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << "Type of a custom map" << "\n" << "\n";
- for (int i = 0; i < size(menu); i++)
- {
- if (i == pointer)
- {
- if (arrowVisible)
- {
- cout << "-> ";
- arrowVisible = false;
- }
- else
- {
- cout << " "; // Prints 4 spaces to cover the previous "-> "
- arrowVisible = true;
- }
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
- cout << menu[i] << "\n";
- }
- else
- {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << menu[i] << "\n";
- }
- }
- bool upKeyState = GetAsyncKeyState(VK_UP);
- if ( (upKeyState) && !(lastUpKeyState) )
- {
- pointer -= 1;
- if (pointer == -1)
- {
- pointer = size(menu) - 1;
- }
- }
- lastUpKeyState = upKeyState;
- bool downKeyState = GetAsyncKeyState(VK_DOWN);
- if ( (downKeyState) && !(lastDownKeyState) )
- {
- pointer += 1;
- if (pointer == size(menu))
- {
- pointer = 0;
- }
- }
- lastDownKeyState = downKeyState;
- bool returnKeyState = GetAsyncKeyState(VK_RETURN);
- if ( (returnKeyState) && !(lastReturnKeyState) )
- {
- customMenuOptions[pointer]();
- }
- lastReturnKeyState = returnKeyState;
- backToMenu();
- this_thread::sleep_for(chrono::milliseconds(200));
- }
- }
- menuOptions difficultyMenuOptions[] = { easyDifficulty, normalDifficulty, hardDifficulty };
- int difficultyMenu()
- {
- string difficulty[] = { "Easy", "Normal", "Hard" };
- int pointer = 0;
- bool lastUpKeyState = false;
- bool lastDownKeyState = false;
- bool lastReturnKeyState = false;
- bool arrowVisible = true;
- while (true)
- {
- system("cls");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << "Choose difficulty" << "\n" << "\n";
- for (int i = 0; i < size(difficulty); i++)
- {
- if (i == pointer)
- {
- if (arrowVisible)
- {
- cout << "-> ";
- arrowVisible = false;
- }
- else
- {
- cout << " "; // Prints 4 spaces to cover the previous "-> "
- arrowVisible = true;
- }
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
- cout << difficulty[i] << "\n";
- }
- else
- {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << difficulty[i] << "\n";
- }
- }
- bool upKeyState = GetAsyncKeyState(VK_UP);
- if ( (upKeyState) && !(lastUpKeyState) )
- {
- pointer -= 1;
- if (pointer == -1)
- {
- pointer = size(difficulty) - 1;
- }
- }
- lastUpKeyState = upKeyState;
- bool downKeyState = GetAsyncKeyState(VK_DOWN);
- if ( (downKeyState) && !(lastDownKeyState) )
- {
- pointer += 1;
- if (pointer == size(difficulty))
- {
- pointer = 0;
- }
- }
- lastDownKeyState = downKeyState;
- bool returnKeyState = GetAsyncKeyState(VK_RETURN);
- if ( (returnKeyState) && !(lastReturnKeyState) )
- {
- difficultyMenuOptions[pointer]();
- }
- lastReturnKeyState = returnKeyState;
- backToMenu();
- this_thread::sleep_for(chrono::milliseconds(200));
- }
- }
- void easyDifficulty()
- {
- levels("easy");
- }
- void normalDifficulty()
- {
- levels("normal");
- }
- void hardDifficulty()
- {
- levels("hard");
- }
- void backToMenu()
- {
- if (GetAsyncKeyState(VK_ESCAPE))
- {
- mainMenu();
- }
- }
- void characterMove(string** labyrinth, int& x, int& y, int dx, int dy)
- {
- if (labyrinth[x + dx][y + dy] == "S" || labyrinth[x + dx][y + dy] == " " || labyrinth[x + dx][y + dy] == "E")
- {
- x += dx;
- y += dy;
- }
- }
- void playerMove(string** labyrinth)
- {
- char key = _getch();
- if (key == 72) // The ASCII CODE FOR THE UP ARROW KEY
- {
- characterMove(labyrinth, playerX, playerY, -1, 0);
- }
- else if (key == 75) // The ASCII CODE FOR THE LEFT ARROW KEY
- {
- characterMove(labyrinth, playerX, playerY, 0, -1);
- }
- else if (key == 80) // The ASCII CODE FOR THE DOWN ARROW KEY
- {
- characterMove(labyrinth, playerX, playerY, 1, 0);
- }
- else if (key == 77) // The ASCII CODE FOR THE RIGHT ARROW KEY
- {
- characterMove(labyrinth, playerX, playerY, 0, 1);
- }
- }
- void display(string** labyrinth, int rowsCount, int columnsCount, int level, string levelType)
- {
- string player = "O";
- bool breakAfterRender = false;
- while (true)
- {
- system("cls");
- cout << "Difficulty: " << levelType << "\n";
- if ( (levelType == "easy") || (levelType == "normal") || (levelType == "hard") )
- {
- cout << "Level: " << level << " / " << filesInFolderCount(levelType) << "\n" << "\n";
- }
- else
- {
- cout << "\n";
- }
- int colour = rand() % 15 + 1;
- for (int i = 0; i < rowsCount; i++)
- {
- for (int j = 0; j < columnsCount; j++)
- {
- if ( (i == playerX) && (j == playerY) )
- {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colour);
- cout << player;
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
- }
- else
- {
- cout << labyrinth[i][j];
- }
- }
- cout << "\n";
- }
- if (breakAfterRender)
- {
- cout << "\n";
- cout << "Congratulations! You have reached the end of the level!" << "\n" << "\n" << "\n";
- cout << "Press \"ENTER\" to continue" << "\n";
- while (true)
- {
- if (_getch() == 13) // The ASCII CODE FOR THE ENTER / RETURN KEY
- {
- break;
- }
- }
- break;
- }
- labyrinth[playerX][playerY] = " ";
- playerMove(labyrinth);
- if (labyrinth[playerX][playerY] == "E")
- {
- breakAfterRender = true;
- }
- labyrinth[playerX][playerY] = player;
- if (GetAsyncKeyState(VK_ESCAPE))
- {
- system("cls");
- cout << "PAUSED";
- while (true)
- {
- if (GetAsyncKeyState(VK_ESCAPE))
- {
- break;
- }
- this_thread::sleep_for(chrono::milliseconds(6));
- }
- }
- this_thread::sleep_for(chrono::milliseconds(24));
- }
- }
- void loadMap(string fileName, int level, string levelType)
- {
- int rowsCount = 1;
- int columnsCount = 0;
- int startAt = 0;
- int endAt = 0;
- ifstream mapFile;
- mapFile.open(fileName);
- if (mapFile.is_open())
- {
- char currentSymbol;
- while (mapFile)
- {
- currentSymbol = mapFile.get();
- if (currentSymbol == '\n')
- {
- rowsCount++;
- }
- else if ( (currentSymbol != '\n') && (rowsCount == 1) )
- {
- columnsCount++;
- }
- else if (currentSymbol == 'S')
- {
- startAt = rowsCount - 1;
- }
- else if (currentSymbol == 'E')
- {
- endAt = rowsCount - 1;
- }
- }
- }
- else
- {
- cout << "Error: Unable to open file " << fileName << "\n" << "\n";
- cout << "Press \"ESCAPE\" to go back to the Main Menu" << "\n";
- while (true)
- {
- backToMenu();
- }
- }
- mapFile.close();
- // Dynamically allocating row space in the heap
- string** labyrinth = new string * [rowsCount];
- // Dynamically allocating column space in the heap
- for (int i = 0; i < rowsCount; i++)
- {
- labyrinth[i] = new string[columnsCount];
- }
- int currentRow = 0;
- int currentColumn = 0;
- mapFile.open(fileName);
- if (mapFile.is_open())
- {
- char currentSymbol;
- while (mapFile.get(currentSymbol))
- {
- if ( (currentRow < rowsCount) && (currentColumn < columnsCount) )
- {
- labyrinth[currentRow][currentColumn] = currentSymbol;
- }
- if (currentSymbol == '\n')
- {
- currentRow++;
- currentColumn = 0;
- }
- else
- {
- currentColumn++;
- }
- }
- }
- mapFile.close();
- for (int i = 0; i < rowsCount; i++)
- {
- for (int j = 0; j < columnsCount; j++)
- {
- if (labyrinth[i][j] == "S")
- {
- playerX = i;
- playerY = j;
- }
- }
- }
- // Displaying the labyrinth
- display(labyrinth, rowsCount, columnsCount, level, levelType);
- // Free up the space after the use of the array
- for (int i = 0; i < rowsCount; i++)
- {
- delete[] labyrinth[i];
- }
- delete[] labyrinth;
- }
- void loadCustomMapFromTheFolder()
- {
- int fileCount = filesInFolderCount("custom");
- string* menu = new string[fileCount];
- WIN32_FIND_DATA findData;
- HANDLE hFind;
- string folderPath = "maps/custom/";
- wstring wideFolderPath(folderPath.begin(), folderPath.end());
- wideFolderPath += L"*";
- hFind = FindFirstFile(wideFolderPath.c_str(), &findData);
- if (hFind != INVALID_HANDLE_VALUE)
- {
- char narrowString[MAX_PATH];
- string* newData;
- int counter = 0;
- while (FindNextFile(hFind, &findData) != 0)
- {
- WideCharToMultiByte(CP_ACP, 0, findData.cFileName, -1, narrowString, MAX_PATH, NULL, NULL);
- if (strcmp(narrowString, ".") != 0 && strcmp(narrowString, "..") != 0)
- {
- if (counter == fileCount)
- {
- newData = new string[fileCount + 2];
- for (int i = 0; i < counter; i++)
- {
- newData[i] = menu[i];
- }
- delete[] menu;
- menu = newData;
- }
- menu[counter] = narrowString;
- counter++;
- }
- }
- FindClose(hFind);
- }
- int pointer = 0;
- bool lastUpKeyState = false;
- bool lastDownKeyState = false;
- bool lastReturnKeyState = false;
- bool arrowVisible = true;
- while (true)
- {
- system("cls");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << "There are " << fileCount << " files in the subfolder called \"custom\"." << "\n" << "\n";
- cout << "Select a Custom Map" << "\n" << "\n";
- for (int i = 0; i < fileCount; i++)
- {
- if (i == pointer)
- {
- if (arrowVisible)
- {
- cout << "-> ";
- arrowVisible = false;
- }
- else
- {
- cout << " "; // Prints 4 spaces to cover the previous "-> "
- arrowVisible = true;
- }
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
- cout << menu[i] << "\n";
- }
- else
- {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- cout << menu[i] << "\n";
- }
- }
- bool upKeyState = GetAsyncKeyState(VK_UP);
- if ( (upKeyState) && !(lastUpKeyState) )
- {
- pointer -= 1;
- if (pointer == -1)
- {
- pointer = fileCount - 1;
- }
- }
- lastUpKeyState = upKeyState;
- bool downKeyState = GetAsyncKeyState(VK_DOWN);
- if ( (downKeyState) && !(lastDownKeyState) )
- {
- pointer += 1;
- if (pointer == fileCount)
- {
- pointer = 0;
- }
- }
- lastDownKeyState = downKeyState;
- bool returnKeyState = GetAsyncKeyState(VK_RETURN);
- if ( (returnKeyState) && !(lastReturnKeyState) )
- {
- string mapFile = "maps/custom/" + menu[pointer];
- // Opening the text file
- loadMap(mapFile, 0, "custom");
- }
- lastReturnKeyState = returnKeyState;
- if (GetAsyncKeyState(VK_ESCAPE))
- {
- customGameMenu();
- }
- this_thread::sleep_for(chrono::milliseconds(200));
- }
- delete[] menu;
- }
- void createACustomMap()
- {
- system("cls");
- system("color 04");
- cin.ignore();
- cin.get();
- // TO DO: Rows and Colums
- // At least 4
- int rows = 0;
- int columns = 0;
- rowsAndColumnsChoice(rows, columns);
- system("cls");
- // TO DO: Start and End
- int start = 0;
- int end = 0;
- startAndEndChoice(start, end);
- system("cls");
- // TO DO: Create the labyrinth
- // TO DO: Display the board
- // TO DO: Place inside the labyrinth numbers
- // TO DO: Display the board
- // TO DO: Do you want to save map in a _time stamp.txt file and what name
- }
- void rowsAndColumnsChoice(int rows, int columns)
- {
- system("cls");
- cout << "Do you want to set your own rows and columns or you want the game to set them for you?" << "\n";
- cout << "The possible answers are \"myself\" for you to set them them yourself or \"random\" for the game to set them for you." << "\n";
- cout << "Your answer is: ";
- string choice;
- getline(cin >> ws, choice);
- for (int i = 0; i < choice.length(); i++)
- {
- choice[i] = tolower(choice[i]);
- }
- if (choice == "myself")
- {
- }
- else if (choice == "random")
- {
- }
- else
- {
- cout << "Invalid choice";
- return rowsAndColumnsChoice(rows, columns);
- }
- }
- void startAndEndChoice(int start, int end)
- {
- cout << "Do you want to set your own start and end or you want the game to set them for you?" << "\n";
- cout << "The possible answers are \"myself\" for you to set them them yourself or \"random\" for the game to set them for you." << "\n";
- cout << "Your answer is: ";
- string choice;
- getline(cin >> ws, choice);
- for (int i = 0; i < choice.length(); i++)
- {
- choice[i] = tolower(choice[i]);
- }
- if (choice == "myself")
- {
- }
- else if (choice == "random")
- {
- }
- else
- {
- cout << "Invalid choice";
- return startAndEndChoice(start, end);
- }
- }
- int filesInFolderCount(string levelType)
- {
- int fileCount = 0;
- string folderPath = "maps/" + levelType + "/";
- // Get the first file in the folder
- WIN32_FIND_DATAA findFileData;
- HANDLE hFind = FindFirstFileA((folderPath + "*").c_str(), &findFileData);
- // Iterate through the files in the folder
- if (hFind != INVALID_HANDLE_VALUE)
- {
- while (true)
- {
- // Check if the current file is a regular file
- if ( (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 )
- {
- fileCount++;
- }
- if ( !(FindNextFileA(hFind, &findFileData)) )
- {
- break;
- }
- }
- // Clean up
- FindClose(hFind);
- }
- return fileCount;
- }
- void levels(string levelType)
- {
- int level = 1;
- if ( (levelType != "easy") && (levelType != "normal") && (levelType != "hard") )
- {
- system("cls");
- cout << "Invalid level type!" << "\n";
- return;
- }
- string mapFile;
- while (level <= filesInFolderCount(levelType))
- {
- system("cls");
- mapFile = "maps/" + levelType + "/map_" + to_string(level) + ".txt";
- // Opening the text file
- loadMap(mapFile, level, levelType);
- level++;
- }
- system("cls");
- cout << "Congratulations! You have finished the game!" << "\n" << "\n";
- cout << "Press \"ENTER\" to continue";
- while (true)
- {
- if (_getch() == 13) // The ASCII CODE FOR THE ENTER / RETURN KEY
- {
- break;
- }
- }
- gameCredits();
- }
- void ShowConsoleCursor(bool showFlag)
- {
- HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_CURSOR_INFO cursorInfo;
- GetConsoleCursorInfo(out, &cursorInfo);
- cursorInfo.bVisible = showFlag; // SET THE CURSOR VISIBILITY
- SetConsoleCursorInfo(out, &cursorInfo);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement