Advertisement
PIBogdanov

The Labyrinth

Apr 24th, 2023
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 48.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4. #include <Windows.h>
  5. #include <conio.h>
  6. #include <ctype.h>
  7. #include <random>
  8. #include <chrono>
  9. #include <thread>
  10. #include <mmsystem.h>
  11.  
  12. #pragma comment(lib, "winmm.lib")
  13.  
  14. using namespace std;
  15.  
  16. size_t playerX = 0;
  17.  
  18. size_t playerY = 0;
  19.  
  20. int mainMenu();
  21.  
  22. void gameStart();
  23.  
  24. void customGame();
  25.  
  26. void gameControls();
  27.  
  28. void gameCredits();
  29.  
  30. void customMapInformation();
  31.  
  32. void exitProgram();
  33.  
  34. int customGameMenu();
  35.  
  36. int difficultyMenu();
  37.  
  38. void easyDifficulty();
  39.  
  40. void normalDifficulty();
  41.  
  42. void hardDifficulty();
  43.  
  44. void backToMenu();
  45.  
  46. void playMusic(wstring&);
  47.  
  48. void characterMove(string**, size_t&, size_t&, size_t, size_t);
  49.  
  50. void playerMove(string**);
  51.  
  52. void display(string**, size_t, size_t, size_t, string);
  53.  
  54. void loadMapFromAFolder(string, size_t, string);
  55.  
  56. void loadMap(string**, size_t, size_t);
  57.  
  58. void loadCustomMapFromTheFolder();
  59.  
  60. void createACustomMap();
  61.  
  62. void rowsAndColumnsChoice(size_t&, size_t&);
  63.  
  64. void rowsAndColumnsSetByThePlayer(size_t&, size_t&);
  65.  
  66. void startAndEndChoice(int&, int&);
  67.  
  68. void startAndEndSetByThePlayer(string**&, size_t&, size_t&, size_t&, size_t&, string&, string&);
  69.  
  70. int setWallsCountChoice(int&);
  71.  
  72. void wallsSetByThePlayerWithoutASetWallsCount(string**&, size_t&, size_t&);
  73.  
  74. void chooseAnAction(string**&, size_t&, size_t&, string&);
  75.  
  76. void saveTheMapConfiguration(string**&, size_t&, size_t&, string&);
  77.  
  78. void displayTheConfiguration(string**, size_t, size_t);
  79.  
  80. void displayTheConfigurationWithCoordinates(string**, size_t, size_t);
  81.  
  82. void displayTheConfigurationWithoutSpaces(string**, size_t, size_t);
  83.  
  84. size_t filesInFolderCount(string);
  85.  
  86. void levels(string);
  87.  
  88. void CoutCentered(string);
  89.  
  90. size_t GetConsoleWidth();
  91.  
  92. void SetVolume(int);
  93.  
  94. void ShowConsoleCursor(bool);
  95.  
  96. int main()
  97. {
  98.     system("color 04");
  99.  
  100.     HWND hWnd = GetConsoleWindow(); // Get the console window handle
  101.  
  102.     ShowWindow(hWnd, SW_MAXIMIZE); // Maximize the window
  103.  
  104.     HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  105.  
  106.     CONSOLE_FONT_INFOEX fontInfo{};
  107.  
  108.     fontInfo.cbSize = sizeof(fontInfo);
  109.  
  110.     GetCurrentConsoleFontEx(consoleHandle, FALSE, &fontInfo);
  111.  
  112.     fontInfo.dwFontSize.X += 2; // Increase the font width
  113.  
  114.     fontInfo.dwFontSize.Y += 2; // Increase the font height
  115.  
  116.     SetCurrentConsoleFontEx(consoleHandle, FALSE, &fontInfo);
  117.  
  118.     ShowConsoleCursor(false);
  119.  
  120.     PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  121.  
  122.     SetVolume(0xFFFF / 4); // Set audio volume to 25%
  123.  
  124.     mainMenu();
  125.  
  126.     return 0;
  127. }
  128.  
  129. typedef void(*menuOptions)();
  130.  
  131. menuOptions mainMenuOptions[] = { gameStart, customGame, gameControls, gameCredits, customMapInformation, exitProgram };
  132.  
  133. int mainMenu()
  134. {
  135.     string menu[] = { "Start Game", "Create a Custom Game", "Controls", "Credits", "How to create a custom map?", "Exit" };
  136.  
  137.     size_t pointer = 0;
  138.  
  139.     bool lastUpKeyState = false;
  140.  
  141.     bool lastDownKeyState = false;
  142.  
  143.     bool lastReturnKeyState = false;
  144.  
  145.     bool arrowVisible = true;
  146.  
  147.     while (true)
  148.     {
  149.         system("cls");
  150.  
  151.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  152.  
  153.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  154.  
  155.         CoutCentered("The Labyrinth\n\n\n");
  156.  
  157.         CoutCentered("Main Menu\n\n");
  158.  
  159.         for (size_t i = 0; i < size(menu); i++)
  160.         {
  161.             if (i == pointer)
  162.             {
  163.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  164.  
  165.                 if (arrowVisible)
  166.                 {
  167.                     CoutCentered("-> " + menu[i] + "\n");
  168.  
  169.                     arrowVisible = false;
  170.                 }
  171.  
  172.                 else
  173.                 {
  174.                     CoutCentered("   \n");
  175.  
  176.                     arrowVisible = true;
  177.                 }
  178.             }
  179.  
  180.             else
  181.             {
  182.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  183.  
  184.                 CoutCentered(menu[i] + "\n");
  185.             }
  186.         }
  187.  
  188.         bool upKeyState = GetAsyncKeyState(VK_UP);
  189.  
  190.         if ( (upKeyState) && !(lastUpKeyState) )
  191.         {
  192.             pointer -= 1;
  193.  
  194.             if (pointer == -1)
  195.             {
  196.                 pointer = size(menu) - 1;
  197.             }
  198.         }
  199.  
  200.         lastUpKeyState = upKeyState;
  201.  
  202.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  203.  
  204.         if ( (downKeyState) && !(lastDownKeyState) )
  205.         {
  206.             pointer += 1;
  207.  
  208.             if (pointer == size(menu))
  209.             {
  210.                 pointer = 0;
  211.             }
  212.         }
  213.  
  214.         lastDownKeyState = downKeyState;
  215.  
  216.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  217.  
  218.         if ( (returnKeyState) && !(lastReturnKeyState) )
  219.         {
  220.             mainMenuOptions[pointer]();
  221.         }
  222.  
  223.         lastReturnKeyState = returnKeyState;
  224.  
  225.         this_thread::sleep_for(chrono::milliseconds(200));
  226.     }
  227. }
  228.  
  229. void gameStart()
  230. {
  231.     difficultyMenu();
  232. }
  233.  
  234. void customGame()
  235. {
  236.     customGameMenu();
  237. }
  238.  
  239. void gameControls()
  240. {
  241.     system("cls");
  242.  
  243.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  244.  
  245.     CoutCentered("  --------------CONTROLS---------------  \n");
  246.     CoutCentered("  |                                   |  \n");
  247.     CoutCentered("  |                                   |  \n");
  248.     CoutCentered("  |   ^ --> Up Arrow to move up       |  \n");
  249.     CoutCentered("  |   < --> Left Arrow to move left   |  \n");
  250.     CoutCentered("  |   > --> Right Arrow to move right |  \n");
  251.     CoutCentered("  |   v --> Down Arrow to move down   |  \n");
  252.     CoutCentered("  |                                   |  \n");
  253.     CoutCentered("  |   Enter / Return --> Enter        |  \n");
  254.     CoutCentered("  |   Escape --> Back                 |  \n");
  255.     CoutCentered("  |                                   |  \n");
  256.     CoutCentered("  |                                   |  \n");
  257.     CoutCentered("  -------------------------------------  \n");
  258.  
  259.     while (true)
  260.     {
  261.         backToMenu();
  262.     }
  263. }
  264.  
  265. void gameCredits()
  266. {
  267.     system("cls");
  268.  
  269.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  270.  
  271.     CoutCentered("Thanks for playing!\n\n");
  272.    
  273.     CoutCentered("Creator: Petar Bogdanov\n\n");
  274.  
  275.     CoutCentered("The man who helped me with this project: eng. Stoyan Filipov\n\n");
  276.  
  277.     CoutCentered("Press \"ESCAPE\" to go back to the Main Menu\n");
  278.  
  279.     while (true)
  280.     {
  281.         backToMenu();
  282.     }
  283. }
  284.  
  285. void customMapInformation()
  286. {
  287.     system("cls");
  288.  
  289.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  290.  
  291.     CoutCentered("To create a custom map you need to:\n\n");
  292.  
  293.     CoutCentered("1. Create a file with the .txt extension.  \n\n");
  294.  
  295.     CoutCentered("2. Visualize your map inside the .txt file.\n\n");
  296.  
  297.     CoutCentered("3. Put the file in the \"custom\" subfolder. \n\n");
  298.  
  299.     CoutCentered("NOTE: DO NOT DO PART 3 IF YOU HAVE CREATED THE FILE ALREADY THERE!\n\n");
  300.  
  301.     CoutCentered("Press \"ESCAPE\" to go back to the Main Menu\n");
  302.  
  303.     while (true)
  304.     {
  305.         backToMenu();
  306.     }
  307. }
  308.  
  309. void exitProgram()
  310. {
  311.     exit(0);
  312. }
  313.  
  314. menuOptions customMenuOptions[] = { loadCustomMapFromTheFolder, createACustomMap };
  315.  
  316. int customGameMenu()
  317. {
  318.     string menu[] = { "Play on already created custom map placed in the subfolder", "Create a Custom Map" };
  319.  
  320.     size_t pointer = 0;
  321.  
  322.     bool lastUpKeyState = false;
  323.  
  324.     bool lastDownKeyState = false;
  325.  
  326.     bool lastReturnKeyState = false;
  327.  
  328.     bool arrowVisible = true;
  329.  
  330.     while (true)
  331.     {
  332.         system("cls");
  333.  
  334.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  335.  
  336.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  337.  
  338.         CoutCentered("Type of a custom map\n\n");
  339.  
  340.         for (size_t i = 0; i < size(menu); i++)
  341.         {
  342.             if (i == pointer)
  343.             {
  344.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  345.  
  346.                 if (arrowVisible)
  347.                 {
  348.                     CoutCentered("-> " + menu[i] + "\n");
  349.  
  350.                     arrowVisible = false;
  351.                 }
  352.  
  353.                 else
  354.                 {
  355.                     CoutCentered("   \n");
  356.  
  357.                     arrowVisible = true;
  358.                 }
  359.             }
  360.  
  361.             else
  362.             {
  363.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  364.  
  365.                 CoutCentered(menu[i] + "\n");
  366.             }
  367.         }
  368.  
  369.         bool upKeyState = GetAsyncKeyState(VK_UP);
  370.  
  371.         if ( (upKeyState) && !(lastUpKeyState) )
  372.         {
  373.             pointer -= 1;
  374.  
  375.             if (pointer == -1)
  376.             {
  377.                 pointer = size(menu) - 1;
  378.             }
  379.         }
  380.  
  381.         lastUpKeyState = upKeyState;
  382.  
  383.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  384.  
  385.         if ( (downKeyState) && !(lastDownKeyState) )
  386.         {
  387.             pointer += 1;
  388.  
  389.             if (pointer == size(menu))
  390.             {
  391.                 pointer = 0;
  392.             }
  393.         }
  394.  
  395.         lastDownKeyState = downKeyState;
  396.  
  397.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  398.  
  399.         if ( (returnKeyState) && !(lastReturnKeyState) )
  400.         {
  401.             customMenuOptions[pointer]();
  402.         }
  403.  
  404.         lastReturnKeyState = returnKeyState;
  405.        
  406.         backToMenu();
  407.  
  408.         this_thread::sleep_for(chrono::milliseconds(200));
  409.     }
  410. }
  411.  
  412. menuOptions difficultyMenuOptions[] = { easyDifficulty, normalDifficulty, hardDifficulty };
  413.  
  414. int difficultyMenu()
  415. {
  416.     string difficulty[] = { "Easy", "Normal", "Hard" };
  417.  
  418.     size_t pointer = 0;
  419.  
  420.     bool lastUpKeyState = false;
  421.  
  422.     bool lastDownKeyState = false;
  423.  
  424.     bool lastReturnKeyState = false;
  425.  
  426.     bool arrowVisible = true;
  427.  
  428.     while (true)
  429.     {
  430.         system("cls");
  431.  
  432.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  433.  
  434.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  435.  
  436.         CoutCentered(" Choose a difficulty\n\n");
  437.  
  438.         for (size_t i = 0; i < size(difficulty); i++)
  439.         {
  440.             if (i == pointer)
  441.             {
  442.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  443.  
  444.                 if (arrowVisible)
  445.                 {
  446.                     CoutCentered("-> " + difficulty[i] + "\n");
  447.  
  448.                     arrowVisible = false;
  449.                 }
  450.  
  451.                 else
  452.                 {
  453.                     CoutCentered("   \n");
  454.  
  455.                     arrowVisible = true;
  456.                 }
  457.             }
  458.  
  459.             else
  460.             {
  461.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  462.  
  463.                 CoutCentered(difficulty[i] + "\n");
  464.             }
  465.         }
  466.  
  467.         bool upKeyState = GetAsyncKeyState(VK_UP);
  468.  
  469.         if ( (upKeyState) && !(lastUpKeyState) )
  470.         {
  471.             pointer -= 1;
  472.  
  473.             if (pointer == -1)
  474.             {
  475.                 pointer = size(difficulty) - 1;
  476.             }
  477.         }
  478.  
  479.         lastUpKeyState = upKeyState;
  480.  
  481.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  482.  
  483.         if ( (downKeyState) && !(lastDownKeyState) )
  484.         {
  485.             pointer += 1;
  486.  
  487.             if (pointer == size(difficulty))
  488.             {
  489.                 pointer = 0;
  490.             }
  491.         }
  492.  
  493.         lastDownKeyState = downKeyState;
  494.  
  495.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  496.  
  497.         if ( (returnKeyState) && !(lastReturnKeyState) )
  498.         {
  499.             difficultyMenuOptions[pointer]();
  500.         }
  501.  
  502.         lastReturnKeyState = returnKeyState;
  503.  
  504.         backToMenu();
  505.  
  506.         this_thread::sleep_for(chrono::milliseconds(200));
  507.     }
  508. }
  509.  
  510. void easyDifficulty()
  511. {
  512.     levels("easy");
  513. }
  514.  
  515. void normalDifficulty()
  516. {
  517.     levels("normal");
  518. }
  519.  
  520. void hardDifficulty()
  521. {
  522.     levels("hard");
  523. }
  524.  
  525. void backToMenu()
  526. {
  527.     if (GetAsyncKeyState(VK_ESCAPE))
  528.     {
  529.         mainMenu();
  530.     }
  531. }
  532.  
  533. void characterMove(string** labyrinth, size_t& x, size_t& y, size_t dx, size_t dy)
  534. {
  535.     if ( (sizeof(labyrinth[x]) > (x + dx)) && ( (labyrinth[x + dx][y + dy] == "S") || (labyrinth[x + dx][y + dy] == " ") || (labyrinth[x + dx][y + dy] == "E") ) )
  536.     {
  537.         x += dx;
  538.  
  539.         y += dy;
  540.     }
  541. }
  542.  
  543. void playerMove(string** labyrinth)
  544. {
  545.     /*
  546.     char key = _getch();
  547.  
  548.     if (key == 72) // The ASCII CODE FOR THE UP ARROW KEY
  549.     {
  550.         characterMove(labyrinth, playerX, playerY, -1, 0);
  551.     }
  552.  
  553.     else if (key == 75) // The ASCII CODE FOR THE LEFT ARROW KEY
  554.     {
  555.         characterMove(labyrinth, playerX, playerY, 0, -1);
  556.     }
  557.  
  558.     else if (key == 80) // The ASCII CODE FOR THE DOWN ARROW KEY
  559.     {
  560.         characterMove(labyrinth, playerX, playerY, 1, 0);
  561.     }
  562.  
  563.     else if (key == 77) // The ASCII CODE FOR THE RIGHT ARROW KEY
  564.     {
  565.         characterMove(labyrinth, playerX, playerY, 0, 1);
  566.     }
  567.     */
  568.  
  569.     // Using the GetAsyncKeyState function from the Windows.h header performs better than using the ASCII codes for the arrow buttons from the conio.h header
  570.  
  571.     bool upKeyState = GetAsyncKeyState(VK_UP);
  572.  
  573.     bool leftKeyState = GetAsyncKeyState(VK_LEFT);
  574.  
  575.     bool downKeyState = GetAsyncKeyState(VK_DOWN);
  576.  
  577.     bool rightKeyState = GetAsyncKeyState(VK_RIGHT);
  578.  
  579.     if (upKeyState)
  580.     {
  581.         characterMove(labyrinth, playerX, playerY, -1, 0);
  582.     }
  583.  
  584.     else if (leftKeyState)
  585.     {
  586.         characterMove(labyrinth, playerX, playerY, 0, -1);
  587.     }
  588.  
  589.     else if (downKeyState)
  590.     {
  591.         characterMove(labyrinth, playerX, playerY, 1, 0);
  592.     }
  593.  
  594.     else if (rightKeyState)
  595.     {
  596.         characterMove(labyrinth, playerX, playerY, 0, 1);
  597.     }
  598. }
  599.  
  600. void display(string** labyrinth, size_t rowsCount, size_t columnsCount, size_t level, string levelType)
  601. {
  602.     string player = "O";
  603.  
  604.     bool breakAfterRender = false;
  605.  
  606.     while (true)
  607.     {
  608.         system("cls");
  609.  
  610.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  611.  
  612.         // Centers the game screen
  613.  
  614.         size_t consoleWidth = GetConsoleWidth();
  615.  
  616.         size_t screenLeftMargin = (consoleWidth - columnsCount) / 2;
  617.  
  618.         CoutCentered(" Difficulty: " + levelType + "\n");
  619.  
  620.         if ( (levelType == "easy") || (levelType == "normal") || (levelType == "hard") )
  621.         {
  622.             CoutCentered("   Level: " + to_string(level) + " / " + to_string(filesInFolderCount(levelType)) + "\n\n\n");
  623.         }
  624.  
  625.         else
  626.         {
  627.             cout << "\n";
  628.         }
  629.  
  630.         int colour = rand() % 15 + 1;
  631.  
  632.         for (size_t i = 0; i < rowsCount; i++)
  633.         {
  634.             cout << setw(screenLeftMargin); // Center each row
  635.  
  636.             for (size_t j = 0; j < columnsCount; j++)
  637.             {
  638.                 if ( (i == playerX) && (j == playerY) )
  639.                 {
  640.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colour);
  641.  
  642.                     cout << player;
  643.  
  644.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
  645.                 }
  646.  
  647.                 else
  648.                 {
  649.                     cout << labyrinth[i][j];
  650.                 }
  651.             }
  652.  
  653.             cout << "\n";
  654.         }
  655.  
  656.         if (breakAfterRender)
  657.         {
  658.             cout << "\n" << "\n";
  659.  
  660.             CoutCentered("Congratulations! You have reached the end of the level!\n\n\n");
  661.  
  662.             CoutCentered("Press \"ENTER\" to continue\n\n");
  663.  
  664.             while (true)
  665.             {
  666.                 if (GetAsyncKeyState(VK_RETURN))
  667.                 {
  668.                     break;
  669.                 }
  670.             }
  671.  
  672.             break;
  673.         }
  674.  
  675.         labyrinth[playerX][playerY] = " ";
  676.  
  677.         playerMove(labyrinth);
  678.  
  679.         if (labyrinth[playerX][playerY] == "E")
  680.         {
  681.             breakAfterRender = true;
  682.         }
  683.  
  684.         labyrinth[playerX][playerY] = player;
  685.  
  686.         // Pauses the game
  687.         if (GetAsyncKeyState(VK_ESCAPE))
  688.         {
  689.             system("cls");
  690.  
  691.             cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  692.  
  693.             CoutCentered("Paused\n");
  694.  
  695.             while (true)
  696.             {
  697.                 if (GetAsyncKeyState(VK_ESCAPE))
  698.                 {
  699.                     break;
  700.                 }
  701.             }
  702.         }
  703.  
  704.         this_thread::sleep_for(chrono::milliseconds(64));
  705.     }
  706. }
  707.  
  708. void loadMapFromAFolder(string fileName, size_t level, string levelType)
  709. {
  710.     size_t rowsCount = 1;
  711.  
  712.     size_t columnsCount = 0;
  713.  
  714.     size_t startAt = 0;
  715.  
  716.     size_t endAt = 0;
  717.  
  718.     ifstream mapFile;
  719.     mapFile.open(fileName);
  720.  
  721.     if (mapFile.is_open())
  722.     {
  723.         char currentSymbol;
  724.  
  725.         while (mapFile)
  726.         {
  727.             currentSymbol = mapFile.get();
  728.  
  729.             if (currentSymbol == '\n')
  730.             {
  731.                 rowsCount++;
  732.             }
  733.  
  734.             else if ( (currentSymbol != '\n') && (rowsCount == 1) )
  735.             {
  736.                 columnsCount++;
  737.             }
  738.  
  739.             else if (currentSymbol == 'S')
  740.             {
  741.                 startAt = rowsCount - 1;
  742.             }
  743.  
  744.             else if (currentSymbol == 'E')
  745.             {
  746.                 endAt = rowsCount - 1;
  747.             }
  748.         }
  749.     }
  750.  
  751.     else
  752.     {
  753.         CoutCentered("Error: Unable to open file " + fileName + ".\n\n");
  754.        
  755.         CoutCentered("Press \"ESCAPE\" to go back to the Main Menu.\n\n");
  756.  
  757.         while (true)
  758.         {
  759.             backToMenu();
  760.         }
  761.     }
  762.  
  763.     mapFile.close();
  764.  
  765.     // Dynamically allocating row space in the heap
  766.     string** labyrinth = new string * [rowsCount];
  767.  
  768.     // Dynamically allocating column space in the heap
  769.     for (size_t i = 0; i < rowsCount; i++)
  770.     {
  771.         labyrinth[i] = new string[columnsCount];
  772.     }
  773.  
  774.     size_t currentRow = 0;
  775.  
  776.     size_t currentColumn = 0;
  777.  
  778.     mapFile.open(fileName);
  779.  
  780.     if (mapFile.is_open())
  781.     {
  782.         char currentSymbol;
  783.  
  784.         while (mapFile.get(currentSymbol))
  785.         {
  786.             if ( (currentRow < rowsCount) && (currentColumn < columnsCount) )
  787.             {
  788.                 labyrinth[currentRow][currentColumn] = currentSymbol;
  789.             }
  790.  
  791.             if (currentSymbol == '\n')
  792.             {
  793.                 currentRow++;
  794.  
  795.                 currentColumn = 0;
  796.             }
  797.  
  798.             else
  799.             {
  800.                 currentColumn++;
  801.             }
  802.         }
  803.     }
  804.  
  805.     mapFile.close();
  806.  
  807.     for (size_t i = 0; i < rowsCount; i++)
  808.     {
  809.         for (size_t j = 0; j < columnsCount; j++)
  810.         {
  811.             if (labyrinth[i][j] == "S")
  812.             {
  813.                 playerX = i;
  814.  
  815.                 playerY = j;
  816.             }
  817.         }
  818.     }
  819.  
  820.     // Displaying the labyrinth
  821.     display(labyrinth, rowsCount, columnsCount, level, levelType);
  822.  
  823.     // Free up the space after the use of the array
  824.     for (size_t i = 0; i < rowsCount; i++)
  825.     {
  826.         delete[] labyrinth[i];
  827.     }
  828.  
  829.     delete[] labyrinth;
  830. }
  831.  
  832. void loadMap(string** labyrinth, size_t rowsCount, size_t columnsCount)
  833. {
  834.     for (size_t i = 0; i < rowsCount; i++)
  835.     {
  836.         for (size_t j = 0; j < columnsCount; j++)
  837.         {
  838.             if (labyrinth[i][j] == "S")
  839.             {
  840.                 playerX = i;
  841.  
  842.                 playerY = j;
  843.             }
  844.         }
  845.     }
  846.  
  847.     // Displaying the labyrinth
  848.     display(labyrinth, rowsCount, columnsCount, size_t(0), "custom");
  849.  
  850.     // Free up the space after the use of the array
  851.     for (size_t i = 0; i < rowsCount; i++)
  852.     {
  853.         delete[] labyrinth[i];
  854.     }
  855.  
  856.     delete[] labyrinth;
  857. }
  858.  
  859. void loadCustomMapFromTheFolder()
  860. {
  861.     size_t fileCount = filesInFolderCount("custom");
  862.  
  863.     string* menu = new string[fileCount];
  864.  
  865.     WIN32_FIND_DATA findData; // Returns information about the directory
  866.  
  867.     HANDLE hFind;
  868.  
  869.     string folderPath = "maps/custom/"; // Folder directory
  870.  
  871.     wstring wideFolderPath(folderPath.begin(), folderPath.end());
  872.  
  873.     wideFolderPath += L"*";
  874.  
  875.     hFind = FindFirstFile(wideFolderPath.c_str(), &findData);
  876.  
  877.     if (hFind != INVALID_HANDLE_VALUE)
  878.     {
  879.         char narrowString[MAX_PATH];
  880.  
  881.         string* newData;
  882.  
  883.         size_t counter = 0;
  884.  
  885.         while (FindNextFile(hFind, &findData) != 0)
  886.         {
  887.             WideCharToMultiByte(CP_ACP, 0, findData.cFileName, -1, narrowString, MAX_PATH, NULL, NULL);
  888.  
  889.             if ( (strcmp(narrowString, ".") != 0) && (strcmp(narrowString, "..") != 0) ) // Find information about . and ..
  890.             {
  891.                 if (counter == fileCount)
  892.                 {
  893.                     newData = new string[fileCount + 2];
  894.  
  895.                     for (size_t i = 0; i < counter; i++)
  896.                     {
  897.                         newData[i] = menu[i];
  898.                     }
  899.  
  900.                     delete[] menu;
  901.  
  902.                     menu = newData;
  903.                 }
  904.  
  905.                 menu[counter] = narrowString;
  906.  
  907.                 counter++;
  908.             }
  909.         }
  910.  
  911.         FindClose(hFind);
  912.     }
  913.  
  914.     size_t pointer = 0;
  915.  
  916.     bool lastUpKeyState = false;
  917.  
  918.     bool lastDownKeyState = false;
  919.  
  920.     bool lastReturnKeyState = false;
  921.  
  922.     bool arrowVisible = true;
  923.  
  924.     while (true)
  925.     {
  926.         system("cls");
  927.  
  928.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  929.  
  930.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  931.  
  932.         CoutCentered("There are " + to_string(fileCount) + " files in the subfolder called \"custom\"\n\n");
  933.  
  934.         CoutCentered("Select a Custom Map\n\n");
  935.  
  936.         for (size_t i = 0; i < fileCount; i++)
  937.         {
  938.             if (i == pointer)
  939.             {
  940.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  941.  
  942.                 if (arrowVisible)
  943.                 {
  944.                     CoutCentered("-> " + menu[i] + "\n");
  945.  
  946.                     arrowVisible = false;
  947.                 }
  948.  
  949.                 else
  950.                 {
  951.                     CoutCentered("   \n");
  952.  
  953.                     arrowVisible = true;
  954.                 }
  955.             }
  956.  
  957.             else
  958.             {
  959.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  960.  
  961.                 CoutCentered(menu[i] + "\n");
  962.             }
  963.         }
  964.  
  965.         bool upKeyState = GetAsyncKeyState(VK_UP);
  966.  
  967.         if ( (upKeyState) && !(lastUpKeyState) )
  968.         {
  969.             pointer -= 1;
  970.  
  971.             if (pointer == -1)
  972.             {
  973.                 pointer = fileCount - 1;
  974.             }
  975.         }
  976.  
  977.         lastUpKeyState = upKeyState;
  978.  
  979.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  980.  
  981.         if ( (downKeyState) && !(lastDownKeyState) )
  982.         {
  983.             pointer += 1;
  984.  
  985.             if (pointer == fileCount)
  986.             {
  987.                 pointer = 0;
  988.             }
  989.         }
  990.  
  991.         lastDownKeyState = downKeyState;
  992.  
  993.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  994.  
  995.         if ( (returnKeyState) && !(lastReturnKeyState) )
  996.         {
  997.             // Play sound
  998.             PlaySound(TEXT("river.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  999.  
  1000.             // Set audio volume to 25%
  1001.             SetVolume(0xFFFF / 4);
  1002.  
  1003.             string mapFile = "maps/custom/" + menu[pointer];
  1004.  
  1005.             // Opening the text file
  1006.             loadMapFromAFolder(mapFile, 0, "custom");
  1007.  
  1008.             PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1009.  
  1010.             // Set audio volume to 25%
  1011.             SetVolume(0xFFFF / 4);
  1012.  
  1013.             mainMenu();
  1014.         }
  1015.  
  1016.         lastReturnKeyState = returnKeyState;
  1017.        
  1018.         if (GetAsyncKeyState(VK_ESCAPE))
  1019.         {
  1020.             customGameMenu();
  1021.         }
  1022.  
  1023.         this_thread::sleep_for(chrono::milliseconds(200));
  1024.     }
  1025.  
  1026.     delete[] menu;
  1027. }
  1028.  
  1029. void createACustomMap()
  1030. {
  1031.     system("cls");
  1032.  
  1033.     system("color 04");
  1034.  
  1035.     cin.ignore();
  1036.  
  1037.     cin.get();
  1038.  
  1039.     size_t rowsCount = 0;
  1040.  
  1041.     size_t columnsCount = 0;
  1042.  
  1043.     // Possible future update
  1044.     // rowsAndColumnsChoice(rowsCount, columnsCount);
  1045.  
  1046.     rowsAndColumnsSetByThePlayer(rowsCount, columnsCount);
  1047.  
  1048.     size_t farRightAngle = rowsCount * 2 + columnsCount * 2 - 4;
  1049.  
  1050.     size_t farLeftAngle = rowsCount * 2 + columnsCount - 3;
  1051.  
  1052.     system("cls");
  1053.  
  1054.     // Dynamically allocating row space in the heap
  1055.     string** labyrinth = new string * [rowsCount];
  1056.  
  1057.     // Dynamically allocating column space in the heap
  1058.     for (size_t i = 0; i < rowsCount; i++)
  1059.     {
  1060.         labyrinth[i] = new string[columnsCount];
  1061.     }
  1062.  
  1063.     size_t count = 1;
  1064.  
  1065.     for (size_t i = 0; i < rowsCount; i++)
  1066.     {
  1067.         for (size_t j = 0; j < columnsCount; j++)
  1068.         {
  1069.             if ( !( (i > 0) && (i < rowsCount - 1) && (j > 0) && (j < columnsCount - 1) ) )
  1070.             {
  1071.                 labyrinth[i][j] = to_string(count);
  1072.  
  1073.                 count++;
  1074.             }
  1075.         }
  1076.     }
  1077.  
  1078.     system("cls");
  1079.  
  1080.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1081.  
  1082.     displayTheConfiguration(labyrinth, rowsCount, columnsCount);
  1083.  
  1084.     string start;
  1085.  
  1086.     string end;
  1087.  
  1088.     // Possible future update
  1089.     // startAndEndChoice(start, end);
  1090.  
  1091.     startAndEndSetByThePlayer(labyrinth, rowsCount, columnsCount, farRightAngle, farLeftAngle, start, end);
  1092.  
  1093.     /*
  1094.     int wallsCount = 0;
  1095.  
  1096.     setWallsCountChoice(wallsCount);
  1097.     */
  1098.  
  1099.     wallsSetByThePlayerWithoutASetWallsCount(labyrinth, rowsCount, columnsCount);
  1100.  
  1101.     string name;
  1102.  
  1103.     chooseAnAction(labyrinth, rowsCount, columnsCount, name);
  1104. }
  1105.  
  1106. // Possible future update
  1107. void rowsAndColumnsChoice(size_t& rowsCount, size_t& columnsCount)
  1108. {
  1109.     system("cls");
  1110.  
  1111.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1112.  
  1113.     CoutCentered("Do you want to set your own rows and columns or do you want the game to set them for you?\n");
  1114.     CoutCentered("The possible answers are \"myself\" for you to set them yourself or \"random\" for the game to set them for you.\n");
  1115.     CoutCentered("Your answer is: ");
  1116.  
  1117.     string choice;
  1118.     getline(cin >> ws, choice);
  1119.  
  1120.     for (size_t i = 0; i < choice.length(); i++)
  1121.     {
  1122.         choice[i] = tolower(choice[i]);
  1123.     }
  1124.  
  1125.     if (choice == "myself")
  1126.     {
  1127.         rowsAndColumnsSetByThePlayer(rowsCount, columnsCount);
  1128.     }
  1129.  
  1130.     else if (choice == "random")
  1131.     {
  1132.         // Possible future update
  1133.     }
  1134.  
  1135.     else
  1136.     {
  1137.         system("cls");
  1138.  
  1139.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1140.  
  1141.         CoutCentered("Invalid choice!\n");
  1142.  
  1143.         this_thread::sleep_for(chrono::milliseconds(800));
  1144.  
  1145.         return rowsAndColumnsChoice(rowsCount, columnsCount);
  1146.     }
  1147. }
  1148.  
  1149. // The player sets the rows and the columns
  1150. void rowsAndColumnsSetByThePlayer(size_t& rowsCount, size_t& columnsCount)
  1151. {
  1152.     system("cls");
  1153.  
  1154.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1155.  
  1156.     // MIN 5
  1157.     // MAX 23
  1158.  
  1159.     CoutCentered("The allowed values are between 5 and 23.\n\n\n");
  1160.  
  1161.     CoutCentered("Enter rows: ");
  1162.     cin >> rowsCount;
  1163.  
  1164.     while ( (rowsCount < 5) || (rowsCount > 23) )
  1165.     {
  1166.         system("cls");
  1167.  
  1168.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1169.  
  1170.         CoutCentered("Invalid choice!\n");
  1171.         CoutCentered("The allowed values are between 5 and 23.\n");
  1172.  
  1173.         CoutCentered("Enter rows: ");
  1174.         cin >> rowsCount;
  1175.     }
  1176.  
  1177.     system("cls");
  1178.  
  1179.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1180.  
  1181.     CoutCentered("The allowed values are between 5 and 23.\n\n\n");
  1182.  
  1183.     CoutCentered("Enter columns: ");
  1184.     cin >> columnsCount;
  1185.  
  1186.     while ( (columnsCount < 5) || (columnsCount > 23) )
  1187.     {
  1188.         system("cls");
  1189.  
  1190.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1191.  
  1192.         CoutCentered("Invalid choice!\n");
  1193.         CoutCentered("The allowed values are between 5 and 23.\n");
  1194.  
  1195.         CoutCentered("Ener columns: ");
  1196.         cin >> columnsCount;
  1197.     }
  1198. }
  1199.  
  1200. // Possible future update
  1201. void startAndEndChoice(int& start, int& end)
  1202. {
  1203.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1204.  
  1205.     CoutCentered("Do you want to set your own start and end or you do want the game to set them for you?\n");
  1206.     CoutCentered("The possible answers are \"myself\" for you to set them yourself or \"random\" for the game to set them for you.\n");
  1207.     CoutCentered("Your answer is: ");
  1208.  
  1209.     string choice;
  1210.     getline(cin >> ws, choice);
  1211.  
  1212.     for (size_t i = 0; i < choice.length(); i++)
  1213.     {
  1214.         choice[i] = tolower(choice[i]);
  1215.     }
  1216.    
  1217.     if (choice == "myself")
  1218.     {
  1219.  
  1220.     }
  1221.    
  1222.     else if (choice == "random")
  1223.     {
  1224.  
  1225.     }
  1226.    
  1227.     else
  1228.     {
  1229.         system("cls");
  1230.  
  1231.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1232.  
  1233.         CoutCentered("Invalid choice!\n");
  1234.  
  1235.         this_thread::sleep_for(chrono::milliseconds(800));
  1236.  
  1237.         return startAndEndChoice(start, end);
  1238.     }
  1239. }
  1240.  
  1241. // The player sets the start and the end
  1242. void startAndEndSetByThePlayer(string**& labyrinth, size_t& rowsCount, size_t& columnsCount, size_t& farRightAngle, size_t& farLeftAngle, string& start, string& end)
  1243. {
  1244.     system("cls");
  1245.  
  1246.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1247.  
  1248.     CoutCentered("The starting point can't be on 1, " + to_string(rowsCount) + ", " + to_string(farLeftAngle) + " and " + to_string(farRightAngle) + ".\n\n\n");
  1249.  
  1250.     displayTheConfiguration(labyrinth, rowsCount, columnsCount);
  1251.  
  1252.     cout << "\n";
  1253.  
  1254.     string startAt;
  1255.     CoutCentered("Choose a starting point: ");
  1256.     cin >> startAt;
  1257.  
  1258.     while ( (stoi(startAt) == 1) || (stoi(startAt) == farRightAngle) || (stoi(startAt) == farLeftAngle) || (stoi(startAt) == columnsCount) )
  1259.     {
  1260.         system("cls");
  1261.  
  1262.         CoutCentered("The starting point can't be on 1, " + to_string(rowsCount) + ", " + to_string(farLeftAngle) + " and " + to_string(farRightAngle) + ".\n\n\n");
  1263.  
  1264.         displayTheConfiguration(labyrinth, rowsCount, columnsCount);
  1265.  
  1266.         cout << "\n";
  1267.  
  1268.         CoutCentered("Choose a starting point: ");
  1269.         cin >> startAt;
  1270.     }
  1271.  
  1272.     for (size_t i = 0; i < rowsCount; i++)
  1273.     {
  1274.         for (size_t j = 0; j < columnsCount; j++)
  1275.         {
  1276.             if (startAt == labyrinth[i][j])
  1277.             {
  1278.                 labyrinth[i][j] = "S";
  1279.             }
  1280.         }
  1281.     }
  1282.  
  1283.     system("cls");
  1284.  
  1285.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1286.  
  1287.     CoutCentered("The ending point can't be on 1, " + to_string(rowsCount) + ", " + to_string(farLeftAngle) + " and " + to_string(farRightAngle) + ".\n\n\n");
  1288.  
  1289.     displayTheConfiguration(labyrinth, rowsCount, columnsCount);
  1290.  
  1291.     cout << "\n";
  1292.  
  1293.     string endAt;
  1294.     CoutCentered("Choose an ending point: ");
  1295.     cin >> endAt;
  1296.  
  1297.     while ( (stoi(endAt) == 1) || (endAt == startAt) || (stoi(endAt) == farRightAngle) || (stoi(endAt) == farLeftAngle) || (stoi(endAt) == columnsCount) )
  1298.     {
  1299.         system("cls");
  1300.  
  1301.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1302.  
  1303.         CoutCentered("The ending point can't be on 1, " + to_string(rowsCount) + ", " + to_string(farLeftAngle) + " and " + to_string(farRightAngle) + ".\n\n\n");
  1304.  
  1305.         displayTheConfiguration(labyrinth, rowsCount, columnsCount);
  1306.  
  1307.         cout << "\n";
  1308.  
  1309.         CoutCentered("Choose an ending point: ");
  1310.         cin >> endAt;
  1311.     }
  1312.  
  1313.     for (size_t i = 0; i < rowsCount; i++)
  1314.     {
  1315.         for (size_t j = 0; j < columnsCount; j++)
  1316.         {
  1317.             if (endAt == labyrinth[i][j])
  1318.             {
  1319.                 labyrinth[i][j] = "E";
  1320.             }
  1321.         }
  1322.     }
  1323. }
  1324.  
  1325. // Possible future update
  1326. int setWallsCountChoice(int& wallsCount)
  1327. {
  1328.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1329.  
  1330.     CoutCentered("Do you want to set your number of walls or do you want the game to set them for you?\n");
  1331.     CoutCentered("The possible answers are \"myself\" for you to set them yourself or \"random\" for the game to set them for you.\n");
  1332.     CoutCentered("Your answer is: ");
  1333.  
  1334.     string choice;
  1335.     getline(cin >> ws, choice);
  1336.  
  1337.     for (size_t i = 0; i < choice.length(); i++)
  1338.     {
  1339.         choice[i] = tolower(choice[i]);
  1340.     }
  1341.  
  1342.     if (choice == "myself")
  1343.     {
  1344.  
  1345.     }
  1346.  
  1347.     else if (choice == "random")
  1348.     {
  1349.  
  1350.     }
  1351.  
  1352.     else
  1353.     {
  1354.         system("cls");
  1355.  
  1356.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1357.  
  1358.         CoutCentered("Invalid choice!\n");
  1359.  
  1360.         this_thread::sleep_for(chrono::milliseconds(800));
  1361.  
  1362.         return setWallsCountChoice(wallsCount);
  1363.     }
  1364.  
  1365.     return wallsCount;
  1366. }
  1367.  
  1368. // The player sets walls in the labyrinth
  1369. void wallsSetByThePlayerWithoutASetWallsCount(string**& labyrinth, size_t& rowsCount, size_t& columnsCount)
  1370. {
  1371.     system("cls");
  1372.  
  1373.     size_t count = 1;
  1374.  
  1375.     for (size_t i = 0; i < rowsCount; i++)
  1376.     {
  1377.         for (size_t j = 0; j < columnsCount; j++)
  1378.         {
  1379.             if ( (labyrinth[i][j] == "S") || (labyrinth[i][j] == "E") )
  1380.             {
  1381.                 continue;
  1382.             }
  1383.  
  1384.             else if ( (i > 0) && (i < rowsCount - 1) && (j > 0) && (j < columnsCount - 1) )
  1385.             {
  1386.                 count++;
  1387.             }
  1388.  
  1389.             else
  1390.             {
  1391.                 labyrinth[i][j] = "#";
  1392.             }
  1393.         }
  1394.     }
  1395.  
  1396.     system("cls");
  1397.  
  1398.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1399.  
  1400.     CoutCentered("You can enter as many walls as you want. When you want to stop entering walls, type \"end\".\n\n\n");
  1401.  
  1402.     displayTheConfigurationWithCoordinates(labyrinth, rowsCount, columnsCount);
  1403.  
  1404.     CoutCentered("Enter a wall (ROWxCOLUMN): ");
  1405.  
  1406.     string currentWall;
  1407.     getline(cin >> ws, currentWall);
  1408.  
  1409.     for (size_t i = 0; i < currentWall.length(); i++)
  1410.     {
  1411.         currentWall[i] = tolower(currentWall[i]);
  1412.     }
  1413.  
  1414.     while (currentWall != "end")
  1415.     {
  1416.         for (size_t i = 0; i < rowsCount; i++)
  1417.         {
  1418.             for (size_t j = 0; j < columnsCount; j++)
  1419.             {
  1420.                 if (currentWall == (to_string(i) + 'x' + to_string(j)))
  1421.                 {
  1422.                     labyrinth[i][j] = "#";
  1423.                 }
  1424.             }
  1425.         }
  1426.  
  1427.         system("cls");
  1428.  
  1429.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1430.  
  1431.         CoutCentered("You can enter as many walls as you want. When you want to stop entering walls, type \"end\".\n\n\n");
  1432.  
  1433.         displayTheConfigurationWithCoordinates(labyrinth, rowsCount, columnsCount);
  1434.  
  1435.         cout << "\n";
  1436.  
  1437.         CoutCentered("Enter a wall (ROWxCOLUMN): ");
  1438.        
  1439.         getline(cin >> ws, currentWall);
  1440.  
  1441.         for (size_t i = 0; i < currentWall.length(); i++)
  1442.         {
  1443.             currentWall[i] = tolower(currentWall[i]);
  1444.         }
  1445.     }
  1446. }
  1447.  
  1448. // The player chooses an action
  1449. void chooseAnAction(string**& labyrinth, size_t& rowsCount, size_t& columnsCount, string& customMapName)
  1450. {
  1451.     system("cls");
  1452.  
  1453.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1454.  
  1455.     displayTheConfigurationWithoutSpaces(labyrinth, rowsCount, columnsCount);
  1456.  
  1457.     cout << "\n" << "\n";
  1458.  
  1459.     CoutCentered("What do you want to do now?\n\n\n");
  1460.  
  1461.     CoutCentered("If you want to save the map and play it, type \"both\".\n\n");
  1462.  
  1463.     CoutCentered("If you want to save the map without playing it, type \"save\".\n\n");
  1464.  
  1465.     CoutCentered("If you want to play the map without saving it, type \"play\".\n\n");
  1466.  
  1467.     CoutCentered("Your answer is: ");
  1468.  
  1469.     string choice;
  1470.     getline(cin >> ws, choice);
  1471.  
  1472.     for (size_t i = 0; i < choice.length(); i++)
  1473.     {
  1474.         choice[i] = tolower(choice[i]);
  1475.     }
  1476.  
  1477.     if (choice == "both")
  1478.     {
  1479.         saveTheMapConfiguration(labyrinth, rowsCount, columnsCount, customMapName);
  1480.  
  1481.         // Play sound
  1482.         PlaySound(TEXT("river.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1483.  
  1484.         // Set audio volume to 25%
  1485.         SetVolume(0xFFFF / 4);
  1486.  
  1487.         loadMapFromAFolder(customMapName, size_t(0), "custom");
  1488.  
  1489.         PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1490.  
  1491.         // Set audio volume to 25%
  1492.         SetVolume(0xFFFF / 4);
  1493.        
  1494.         mainMenu();
  1495.     }
  1496.  
  1497.     else if (choice == "save")
  1498.     {
  1499.         saveTheMapConfiguration(labyrinth, rowsCount, columnsCount, customMapName);
  1500.     }
  1501.  
  1502.     else if (choice == "play")
  1503.     {
  1504.         // Play sound
  1505.         PlaySound(TEXT("river.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1506.  
  1507.         // Set audio volume to 25%
  1508.         SetVolume(0xFFFF / 4);
  1509.  
  1510.         loadMap(labyrinth, rowsCount, columnsCount);
  1511.  
  1512.         PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1513.  
  1514.         // Set audio volume to 25%
  1515.         SetVolume(0xFFFF / 4);
  1516.  
  1517.         mainMenu();
  1518.     }
  1519.  
  1520.     else
  1521.     {
  1522.         system("cls");
  1523.  
  1524.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1525.  
  1526.         CoutCentered("Invalid choice!\n");
  1527.  
  1528.         this_thread::sleep_for(chrono::milliseconds(800));
  1529.  
  1530.         return chooseAnAction(labyrinth, rowsCount, columnsCount, customMapName);
  1531.     }
  1532. }
  1533.  
  1534. // Creates a text file and saves it in the subfolder called "custom"
  1535. void saveTheMapConfiguration(string**& labyrinth, size_t& rowsCount, size_t& columnsCount, string& nameWithTheFolderPath)
  1536. {
  1537.     system("cls");
  1538.  
  1539.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1540.  
  1541.     CoutCentered("Type a name for the text file. The name should contain only lowercase letters.\n");
  1542.     CoutCentered("File's name is: ");
  1543.  
  1544.     string name;
  1545.     getline(cin >> ws, name);
  1546.  
  1547.     for (size_t i = 0; i < name.length(); i++)
  1548.     {
  1549.         name[i] = tolower(name[i]);
  1550.     }
  1551.  
  1552.     time_t currentTime = time(NULL);
  1553.  
  1554.     name += "_" + to_string(currentTime) + ".txt";
  1555.  
  1556.     nameWithTheFolderPath = "maps/custom/" + name;
  1557.  
  1558.     ofstream customMap(nameWithTheFolderPath);
  1559.  
  1560.     for (size_t i = 0; i < rowsCount; i++)
  1561.     {
  1562.         for (size_t j = 0; j < columnsCount; j++)
  1563.         {
  1564.             customMap << labyrinth[i][j];
  1565.         }
  1566.        
  1567.         customMap << "\n";
  1568.     }
  1569.  
  1570.     customMap.close();
  1571. }
  1572.  
  1573. // Displays the labyrinth with spaces between the elements
  1574. void displayTheConfiguration(string** labyrinth, size_t rowsCount, size_t columnsCount)
  1575. {
  1576.     size_t consoleWidth = GetConsoleWidth();
  1577.  
  1578.     size_t screenLeftMargin = (consoleWidth - columnsCount) / 2;
  1579.  
  1580.     string currentElement;
  1581.  
  1582.     size_t currentLength = 0;
  1583.  
  1584.     for (size_t i = 0; i < rowsCount; i++)
  1585.     {
  1586.         cout << setw(screenLeftMargin); // Center each row
  1587.  
  1588.         for (size_t j = 0; j < columnsCount; j++)
  1589.         {
  1590.             currentElement = labyrinth[i][j];
  1591.  
  1592.             currentLength = currentElement.length();
  1593.  
  1594.             if (currentElement.length() < 2)
  1595.             {
  1596.                 currentElement = " " + currentElement;
  1597.             }
  1598.  
  1599.             if (currentElement.length() < 3)
  1600.             {
  1601.                 cout << currentElement + string(3 - currentElement.length(), ' ');
  1602.             }
  1603.  
  1604.             else
  1605.             {
  1606.                 cout << currentElement;
  1607.             }
  1608.         }
  1609.  
  1610.         cout << "\n";
  1611.     }
  1612. }
  1613.  
  1614. // Displays the labyrinth with additional information for rows and columns
  1615. void displayTheConfigurationWithCoordinates(string** labyrinth, size_t rowsCount, size_t columnsCount)
  1616. {
  1617.     size_t consoleWidth = GetConsoleWidth();
  1618.  
  1619.     size_t screenLeftMargin = (consoleWidth - columnsCount) / 2;
  1620.  
  1621.     string currentElement;
  1622.  
  1623.     size_t currentLength = 0;
  1624.  
  1625.     for (size_t i = 0; i < rowsCount; i++)
  1626.     {
  1627.         cout << setw(screenLeftMargin); // Center each row
  1628.  
  1629.         if (i == 0)
  1630.         {
  1631.             for (size_t j = 0; j < columnsCount; j++)
  1632.             {
  1633.                 currentElement = to_string(j);
  1634.  
  1635.                 currentLength = currentElement.length();
  1636.  
  1637.                 if (currentElement.length() < 2)
  1638.                 {
  1639.                     if (j == 0)
  1640.                     {
  1641.                         currentElement = "   " + currentElement + " ";
  1642.                     }
  1643.  
  1644.                     else
  1645.                     {
  1646.                         currentElement = " " + currentElement;
  1647.                     }
  1648.                 }
  1649.  
  1650.                 if (currentElement.length() < 3)
  1651.                 {
  1652.                     cout << currentElement + string(3 - currentElement.length(), ' ');
  1653.                 }
  1654.  
  1655.                 else
  1656.                 {
  1657.                     cout << currentElement;
  1658.                 }
  1659.             }
  1660.  
  1661.             cout << "\n";
  1662.         }
  1663.  
  1664.         cout << setw(screenLeftMargin); // Center each row
  1665.  
  1666.         for (size_t j = 0; j < columnsCount; j++)
  1667.         {
  1668.             currentElement = labyrinth[i][j];
  1669.  
  1670.             currentLength = currentElement.length();
  1671.  
  1672.             if (currentElement.length() < 2)
  1673.             {
  1674.                 if (j == 0)
  1675.                 {
  1676.                     currentElement = " " + to_string(i) + " " + currentElement + " ";
  1677.                 }
  1678.  
  1679.                 else
  1680.                 {
  1681.                     currentElement = " " + currentElement;
  1682.                 }
  1683.             }
  1684.  
  1685.             if (currentElement.length() < 3)
  1686.             {
  1687.                 cout << currentElement + string(3 - currentElement.length(), ' ');
  1688.             }
  1689.  
  1690.             else
  1691.             {
  1692.                 cout << currentElement;
  1693.             }
  1694.         }
  1695.  
  1696.         cout << "\n";
  1697.     }
  1698. }
  1699.  
  1700. // Displays the labyrinth without spaces
  1701. void displayTheConfigurationWithoutSpaces(string** labyrinth, size_t rowsCount, size_t columnsCount)
  1702. {
  1703.     for (size_t i = 0; i < rowsCount; i++)
  1704.     {
  1705.         for (size_t j = 0; j < columnsCount; j++)
  1706.         {
  1707.             if ( (labyrinth[i][j] != "S") && (labyrinth[i][j] != "#") && (labyrinth[i][j] != "E") )
  1708.             {
  1709.                 labyrinth[i][j] = " ";
  1710.             }
  1711.         }
  1712.     }
  1713.  
  1714.     size_t consoleWidth = GetConsoleWidth();
  1715.  
  1716.     size_t screenLeftMargin = (consoleWidth - columnsCount) / 2;
  1717.  
  1718.     for (size_t i = 0; i < rowsCount; i++)
  1719.     {
  1720.         cout << setw(screenLeftMargin); // Center each row
  1721.  
  1722.         for (size_t j = 0; j < columnsCount; j++)
  1723.         {
  1724.             cout << labyrinth[i][j];
  1725.         }
  1726.  
  1727.         cout << "\n";
  1728.     }
  1729. }
  1730.  
  1731. // Returns the count of the text files (maps)
  1732. size_t filesInFolderCount(string levelType)
  1733. {
  1734.     size_t fileCount = 0;
  1735.  
  1736.     string folderPath = "maps/" + levelType + "/";
  1737.  
  1738.     // Get the first file in the folder
  1739.     WIN32_FIND_DATAA findFileData;
  1740.  
  1741.     HANDLE hFind = FindFirstFileA((folderPath + "*").c_str(), &findFileData);
  1742.  
  1743.     // Iterate through the files in the folder
  1744.     if (hFind != INVALID_HANDLE_VALUE)
  1745.     {
  1746.         while (true)
  1747.         {
  1748.             // Check if the current file is a regular file
  1749.             if ( (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 )
  1750.             {
  1751.                 fileCount++;
  1752.             }
  1753.  
  1754.             if (!FindNextFileA(hFind, &findFileData))
  1755.             {
  1756.                 break;
  1757.             }
  1758.         }
  1759.  
  1760.         // Clean up
  1761.         FindClose(hFind);
  1762.     }
  1763.  
  1764.     return fileCount;
  1765. }
  1766.  
  1767. // Information about the current level
  1768. void levels(string levelType)
  1769. {
  1770.     // Play sound
  1771.     PlaySound(TEXT("river.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1772.  
  1773.     // Set audio volume to 25%
  1774.     SetVolume(0xFFFF / 4);
  1775.  
  1776.     size_t level = 1;
  1777.  
  1778.     if ( (levelType != "easy") && (levelType != "normal") && (levelType != "hard") )
  1779.     {
  1780.         system("cls");
  1781.  
  1782.         CoutCentered("Invalid level type!\n");
  1783.  
  1784.         return;
  1785.     }
  1786.  
  1787.     string mapFile;
  1788.  
  1789.     while (level <= filesInFolderCount(levelType))
  1790.     {
  1791.         system("cls");
  1792.  
  1793.         mapFile = "maps/" + levelType + "/map_" + to_string(level) + ".txt";
  1794.  
  1795.         // Opening the text file
  1796.         loadMapFromAFolder(mapFile, level, levelType);
  1797.  
  1798.         level++;
  1799.     }
  1800.  
  1801.     system("cls");
  1802.  
  1803.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1804.  
  1805.     CoutCentered("Congratulations! You have finished the game!\n\n");
  1806.  
  1807.     CoutCentered("Press \"ENTER\" to continue\n");
  1808.  
  1809.     while (true)
  1810.     {
  1811.         if (GetAsyncKeyState(VK_RETURN))
  1812.         {
  1813.             break;
  1814.         }
  1815.     }
  1816.  
  1817.     PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1818.  
  1819.     // Set audio volume to 25%
  1820.     SetVolume(0xFFFF / 4);
  1821.  
  1822.     gameCredits();
  1823. }
  1824.  
  1825. // This function centers the text within the console window.
  1826. void CoutCentered(string text)
  1827. {
  1828.     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Get the console handle.
  1829.  
  1830.     CONSOLE_SCREEN_BUFFER_INFO screenInfo;
  1831.  
  1832.     GetConsoleScreenBufferInfo(hConsole, &screenInfo); // Get the console screen buffer info.
  1833.  
  1834.     size_t consoleWidth = screenInfo.dwSize.X;
  1835.  
  1836.     size_t textWidth = static_cast<size_t>(text.length());
  1837.  
  1838.     size_t leftMargin = (consoleWidth - textWidth) / 2;
  1839.  
  1840.     for (size_t i = 0; i < leftMargin; i++)
  1841.     {
  1842.         cout << " ";
  1843.     }
  1844.  
  1845.     cout << text;
  1846. }
  1847.  
  1848. // Returns the console's width
  1849. size_t GetConsoleWidth()
  1850. {
  1851.     CONSOLE_SCREEN_BUFFER_INFO csbi;
  1852.  
  1853.     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
  1854.  
  1855.     size_t columns = static_cast<size_t>(csbi.srWindow.Right - csbi.srWindow.Left + 2);
  1856.  
  1857.     return columns;
  1858. }
  1859.  
  1860. // Sets the audio volume
  1861. void SetVolume(int volume)
  1862. {
  1863.     DWORD newVolume = ((DWORD)volume << 16) | (DWORD)volume;
  1864.  
  1865.     waveOutSetVolume(NULL, newVolume);
  1866. }
  1867.  
  1868. // Removes the cursor
  1869. void ShowConsoleCursor(bool showFlag)
  1870. {
  1871.     HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
  1872.  
  1873.     CONSOLE_CURSOR_INFO cursorInfo;
  1874.  
  1875.     GetConsoleCursorInfo(out, &cursorInfo);
  1876.  
  1877.     cursorInfo.bVisible = showFlag; // Sets the cursor visability
  1878.  
  1879.     SetConsoleCursorInfo(out, &cursorInfo);
  1880. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement