Advertisement
PIBogdanov

The Labyrinth

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