Advertisement
PIBogdanov

The Labyrinth

Feb 23rd, 2023
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.11 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&, int, int);
  49.  
  50. void playerMove(string**);
  51.  
  52. void display(string**, int, int, int, string);
  53.  
  54. void loadMap(string, int, string);
  55.  
  56. void loadCustomMapFromTheFolder();
  57.  
  58. void createACustomMap();
  59.  
  60. void rowsAndColumnsChoice(int, int);
  61.  
  62. void startAndEndChoice(int, int);
  63.  
  64. int setWallsCountChoice(int);
  65.  
  66. int filesInFolderCount(string);
  67.  
  68. void levels(string);
  69.  
  70. void CoutCentered(string);
  71.  
  72. void CoutCenteredWithoutNewLine(string);
  73.  
  74. int GetConsoleWidth();
  75.  
  76. void SetVolume(int);
  77.  
  78. void ShowConsoleCursor(bool showFlag);
  79.  
  80. int main()
  81. {
  82.     system("color 04");
  83.  
  84.     HWND hWnd = GetConsoleWindow(); // Get the console window handle
  85.  
  86.     ShowWindow(hWnd, SW_MAXIMIZE); // Maximize the window
  87.  
  88.     HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  89.  
  90.     CONSOLE_FONT_INFOEX fontInfo{};
  91.  
  92.     fontInfo.cbSize = sizeof(fontInfo);
  93.  
  94.     GetCurrentConsoleFontEx(consoleHandle, FALSE, &fontInfo);
  95.  
  96.     fontInfo.dwFontSize.X += 2; // Increase the font width
  97.  
  98.     fontInfo.dwFontSize.Y += 2; // Increase the font height
  99.  
  100.     SetCurrentConsoleFontEx(consoleHandle, FALSE, &fontInfo);
  101.  
  102.     ShowConsoleCursor(false);
  103.  
  104.     PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  105.  
  106.     // Set audio volume to 25%
  107.     SetVolume(0xFFFF / 4);
  108.  
  109.     mainMenu();
  110.  
  111.     return 0;
  112. }
  113.  
  114. typedef void(*menuOptions)();
  115.  
  116. menuOptions mainMenuOptions[] = { gameStart, customGame, gameControls, gameCredits, customMapInformation, exitProgram };
  117.  
  118. int mainMenu()
  119. {
  120.     string menu[] = { "Start Game", "Create a Custom Game", "Controls", "Credits", "How to create a custom map?", "Exit"};
  121.  
  122.     size_t pointer = 0;
  123.  
  124.     bool lastUpKeyState = false;
  125.  
  126.     bool lastDownKeyState = false;
  127.  
  128.     bool lastReturnKeyState = false;
  129.  
  130.     bool arrowVisible = true;
  131.  
  132.     while (true)
  133.     {
  134.         system("cls");
  135.  
  136.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  137.  
  138.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  139.  
  140.         CoutCentered("The Labyrinth");
  141.  
  142.         cout << "\n" << "\n";
  143.  
  144.         CoutCentered("Main Menu");
  145.  
  146.         cout << "\n";
  147.  
  148.         for (size_t i = 0; i < size(menu); i++)
  149.         {
  150.             if (i == pointer)
  151.             {
  152.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  153.  
  154.                 if (arrowVisible)
  155.                 {
  156.                     CoutCentered("-> " + menu[i]);
  157.  
  158.                     arrowVisible = false;
  159.                 }
  160.  
  161.                 else
  162.                 {
  163.                     CoutCentered("    ");
  164.  
  165.                     arrowVisible = true;
  166.                 }
  167.             }
  168.  
  169.             else
  170.             {
  171.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  172.  
  173.                 CoutCentered(menu[i]);
  174.             }
  175.         }
  176.  
  177.         bool upKeyState = GetAsyncKeyState(VK_UP);
  178.  
  179.         if ( (upKeyState) && !(lastUpKeyState) )
  180.         {
  181.             pointer -= 1;
  182.  
  183.             if (pointer == -1)
  184.             {
  185.                 pointer = size(menu) - 1; // FROM pointer = 4
  186.             }
  187.         }
  188.  
  189.         lastUpKeyState = upKeyState;
  190.  
  191.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  192.  
  193.         if ( (downKeyState) && !(lastDownKeyState) )
  194.         {
  195.             pointer += 1;
  196.  
  197.             if (pointer == size(menu)) // FROM pointer = 5
  198.             {
  199.                 pointer = 0;
  200.             }
  201.         }
  202.  
  203.         lastDownKeyState = downKeyState;
  204.  
  205.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  206.  
  207.         if ( (returnKeyState) && !(lastReturnKeyState) )
  208.         {
  209.             mainMenuOptions[pointer]();
  210.         }
  211.  
  212.         lastReturnKeyState = returnKeyState;
  213.  
  214.         this_thread::sleep_for(chrono::milliseconds(200));
  215.     }
  216. }
  217.  
  218. void gameStart()
  219. {
  220.     difficultyMenu();
  221. }
  222.  
  223. void customGame()
  224. {
  225.     customGameMenu();
  226. }
  227.  
  228. void gameControls()
  229. {
  230.     system("cls");
  231.  
  232.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  233.  
  234.     CoutCentered("  --------------CONTROLS---------------");
  235.     CoutCentered("  |                                   |");
  236.     CoutCentered("  |                                   |");
  237.     CoutCentered("  |   ^ --> Up Arrow to move up       |");
  238.     CoutCentered("  |   < --> Left Arrow to move left   |");
  239.     CoutCentered("  |   > --> Right Arrow to move right |");
  240.     CoutCentered("  |   v --> Down Arrow to move down   |");
  241.     CoutCentered("  |                                   |");
  242.     CoutCentered("  |   Enter / Return --> Enter        |");
  243.     CoutCentered("  |   Escape --> Back                 |");
  244.     CoutCentered("  |                                   |");
  245.     CoutCentered("  |                                   |");
  246.     CoutCentered("  -------------------------------------");
  247.  
  248.     while (true)
  249.     {
  250.         backToMenu();
  251.     }
  252. }
  253.  
  254. void gameCredits()
  255. {
  256.     system("cls");
  257.  
  258.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  259.  
  260.     CoutCentered("Thanks for playing!");
  261.    
  262.     cout << "\n";
  263.  
  264.     CoutCentered("Creator: Petar Bogdanov");
  265.  
  266.     CoutCentered("The people who helped me with this project: eng. Stoyan Filipov and eng. Monika Gencheva");
  267.    
  268.     cout << "\n";
  269.  
  270.     CoutCentered("Press \"ESCAPE\" to go back to the Main Menu");
  271.  
  272.     while (true)
  273.     {
  274.         backToMenu();
  275.     }
  276. }
  277.  
  278. void customMapInformation()
  279. {
  280.     system("cls");
  281.  
  282.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  283.  
  284.     CoutCentered("To create a custom map you need to:");
  285.  
  286.     cout << "\n";
  287.  
  288.     CoutCentered("1. Create a file with the .txt extension.  ");
  289.  
  290.     CoutCentered("2. Visualize your map inside the .txt file.");
  291.  
  292.     CoutCentered("3. Put the file in the \"custom\" subfolder.");
  293.  
  294.     cout << "\n";
  295.  
  296.     CoutCentered("NOTE: DO NOT DO PART 3 IF YOU HAVE CREATED THE FILE ALREADY THERE!");
  297.    
  298.     cout << "\n" << "\n";
  299.  
  300.     CoutCentered("Press \"ESCAPE\" to go back to the Main Menu");
  301.  
  302.     while (true)
  303.     {
  304.         backToMenu();
  305.     }
  306. }
  307.  
  308. void exitProgram()
  309. {
  310.     exit(0);
  311. }
  312.  
  313. menuOptions customMenuOptions[] = { loadCustomMapFromTheFolder, createACustomMap };
  314.  
  315. int customGameMenu()
  316. {
  317.     string menu[] = { "Play on already created custom map placed in the subfolder", "Create a Custom Map" };
  318.  
  319.     size_t pointer = 0;
  320.  
  321.     bool lastUpKeyState = false;
  322.  
  323.     bool lastDownKeyState = false;
  324.  
  325.     bool lastReturnKeyState = false;
  326.  
  327.     bool arrowVisible = true;
  328.  
  329.     while (true)
  330.     {
  331.         system("cls");
  332.  
  333.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  334.  
  335.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  336.  
  337.         CoutCentered("Type of a custom map");
  338.  
  339.         cout << "\n" << "\n";
  340.  
  341.         for (size_t i = 0; i < size(menu); i++)
  342.         {
  343.             if (i == pointer)
  344.             {
  345.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  346.  
  347.                 if (arrowVisible)
  348.                 {
  349.                     CoutCentered("-> " + menu[i]);
  350.  
  351.                     arrowVisible = false;
  352.                 }
  353.  
  354.                 else
  355.                 {
  356.                     CoutCentered("    ");
  357.  
  358.                     arrowVisible = true;
  359.                 }
  360.             }
  361.  
  362.             else
  363.             {
  364.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  365.  
  366.                 CoutCentered(menu[i]);
  367.             }
  368.         }
  369.  
  370.         bool upKeyState = GetAsyncKeyState(VK_UP);
  371.  
  372.         if ( (upKeyState) && !(lastUpKeyState) )
  373.         {
  374.             pointer -= 1;
  375.  
  376.             if (pointer == -1)
  377.             {
  378.                 pointer = size(menu) - 1;
  379.             }
  380.         }
  381.  
  382.         lastUpKeyState = upKeyState;
  383.  
  384.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  385.  
  386.         if ( (downKeyState) && !(lastDownKeyState) )
  387.         {
  388.             pointer += 1;
  389.  
  390.             if (pointer == size(menu))
  391.             {
  392.                 pointer = 0;
  393.             }
  394.         }
  395.  
  396.         lastDownKeyState = downKeyState;
  397.  
  398.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  399.  
  400.         if ( (returnKeyState) && !(lastReturnKeyState) )
  401.         {
  402.             customMenuOptions[pointer]();
  403.         }
  404.  
  405.         lastReturnKeyState = returnKeyState;
  406.        
  407.         backToMenu();
  408.  
  409.         this_thread::sleep_for(chrono::milliseconds(200));
  410.     }
  411. }
  412.  
  413. menuOptions difficultyMenuOptions[] = { easyDifficulty, normalDifficulty, hardDifficulty };
  414.  
  415. int difficultyMenu()
  416. {
  417.     string difficulty[] = { "Easy", "Normal", "Hard" };
  418.  
  419.     size_t pointer = 0;
  420.  
  421.     bool lastUpKeyState = false;
  422.  
  423.     bool lastDownKeyState = false;
  424.  
  425.     bool lastReturnKeyState = false;
  426.  
  427.     bool arrowVisible = true;
  428.  
  429.     while (true)
  430.     {
  431.         system("cls");
  432.  
  433.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  434.  
  435.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  436.  
  437.         CoutCentered("Choose difficulty");
  438.  
  439.         cout << "\n" << "\n";
  440.  
  441.         for (size_t i = 0; i < size(difficulty); i++)
  442.         {
  443.             if (i == pointer)
  444.             {
  445.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  446.  
  447.                 if (arrowVisible)
  448.                 {
  449.                     CoutCentered("-> " + difficulty[i]);
  450.  
  451.                     arrowVisible = false;
  452.                 }
  453.  
  454.                 else
  455.                 {
  456.                     CoutCentered("    ");
  457.  
  458.                     arrowVisible = true;
  459.                 }
  460.             }
  461.  
  462.             else
  463.             {
  464.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  465.  
  466.                 CoutCentered(difficulty[i]);
  467.             }
  468.         }
  469.  
  470.         bool upKeyState = GetAsyncKeyState(VK_UP);
  471.  
  472.         if ( (upKeyState) && !(lastUpKeyState) )
  473.         {
  474.             pointer -= 1;
  475.  
  476.             if (pointer == -1)
  477.             {
  478.                 pointer = size(difficulty) - 1;
  479.             }
  480.         }
  481.  
  482.         lastUpKeyState = upKeyState;
  483.  
  484.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  485.  
  486.         if ( (downKeyState) && !(lastDownKeyState) )
  487.         {
  488.             pointer += 1;
  489.  
  490.             if (pointer == size(difficulty))
  491.             {
  492.                 pointer = 0;
  493.             }
  494.         }
  495.  
  496.         lastDownKeyState = downKeyState;
  497.  
  498.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  499.  
  500.         if ( (returnKeyState) && !(lastReturnKeyState) )
  501.         {
  502.             difficultyMenuOptions[pointer]();
  503.         }
  504.  
  505.         lastReturnKeyState = returnKeyState;
  506.  
  507.         backToMenu();
  508.  
  509.         this_thread::sleep_for(chrono::milliseconds(200));
  510.     }
  511. }
  512.  
  513. void easyDifficulty()
  514. {
  515.     levels("easy");
  516. }
  517.  
  518. void normalDifficulty()
  519. {
  520.     levels("normal");
  521. }
  522.  
  523. void hardDifficulty()
  524. {
  525.     levels("hard");
  526. }
  527.  
  528. void backToMenu()
  529. {
  530.     if (GetAsyncKeyState(VK_ESCAPE))
  531.     {
  532.         mainMenu();
  533.     }
  534. }
  535.  
  536. void characterMove(string** labyrinth, size_t& x, size_t& y, int dx, int dy)
  537. {
  538.     if (labyrinth[x + dx][y + dy] == "S" || labyrinth[x + dx][y + dy] == " " || labyrinth[x + dx][y + dy] == "E")
  539.     {
  540.         x += dx;
  541.  
  542.         y += dy;
  543.     }
  544. }
  545.  
  546. void playerMove(string** labyrinth)
  547. {
  548.     //char key = _getch();
  549.  
  550.     //if (key == 72) // The ASCII CODE FOR THE UP ARROW KEY
  551.     //{
  552.     //    characterMove(labyrinth, playerX, playerY, -1, 0);
  553.     //}
  554.  
  555.     //else if (key == 75) // The ASCII CODE FOR THE LEFT ARROW KEY
  556.     //{
  557.     //    characterMove(labyrinth, playerX, playerY, 0, -1);
  558.     //}
  559.  
  560.     //else if (key == 80) // The ASCII CODE FOR THE DOWN ARROW KEY
  561.     //{
  562.     //    characterMove(labyrinth, playerX, playerY, 1, 0);
  563.     //}
  564.  
  565.     //else if (key == 77) // The ASCII CODE FOR THE RIGHT ARROW KEY
  566.     //{
  567.     //    characterMove(labyrinth, playerX, playerY, 0, 1);
  568.     //}
  569.  
  570.     // Using the GetAsyncKeyState function from the Windows.h header performs better than using the ASCII code's for the buttons from the conio.h header
  571.  
  572.     bool upKeyState = GetAsyncKeyState(VK_UP);
  573.  
  574.     bool leftKeyState = GetAsyncKeyState(VK_LEFT);
  575.  
  576.     bool downKeyState = GetAsyncKeyState(VK_DOWN);
  577.  
  578.     bool rightKeyState = GetAsyncKeyState(VK_RIGHT);
  579.  
  580.     if (upKeyState)
  581.     {
  582.         characterMove(labyrinth, playerX, playerY, -1, 0);
  583.     }
  584.  
  585.     else if (leftKeyState)
  586.     {
  587.         characterMove(labyrinth, playerX, playerY, 0, -1);
  588.     }
  589.  
  590.     else if (downKeyState)
  591.     {
  592.         characterMove(labyrinth, playerX, playerY, 1, 0);
  593.     }
  594.  
  595.     else if (rightKeyState)
  596.     {
  597.         characterMove(labyrinth, playerX, playerY, 0, 1);
  598.     }
  599. }
  600.  
  601. void display(string** labyrinth, int rowsCount, int columnsCount, int level, string levelType)
  602. {
  603.     string player = "O";
  604.  
  605.     bool breakAfterRender = false;
  606.  
  607.     while (true)
  608.     {
  609.         system("cls");
  610.  
  611.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  612.  
  613.         // Center the game screen
  614.  
  615.         int consoleWidth = GetConsoleWidth();
  616.  
  617.         int screenLeftMargin = (consoleWidth - columnsCount) / 2;
  618.  
  619.         CoutCentered("Difficulty: " + levelType);
  620.  
  621.         if ( (levelType == "easy") || (levelType == "normal") || (levelType == "hard") )
  622.         {
  623.             CoutCentered("Level: " + to_string(level) + " / " + to_string(filesInFolderCount(levelType)));
  624.  
  625.             cout << "\n" << "\n";
  626.         }
  627.  
  628.         else
  629.         {
  630.             cout << "\n";
  631.         }
  632.  
  633.         int colour = rand() % 15 + 1;
  634.  
  635.         for (size_t i = 0; i < rowsCount; i++)
  636.         {
  637.             cout << setw(screenLeftMargin); // Center each row
  638.  
  639.             for (size_t j = 0; j < columnsCount; j++)
  640.             {
  641.                 if ( (i == playerX) && (j == playerY) )
  642.                 {
  643.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colour);
  644.  
  645.                     cout << player;
  646.  
  647.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
  648.                 }
  649.  
  650.                 else
  651.                 {
  652.                     cout << labyrinth[i][j];
  653.                 }
  654.             }
  655.  
  656.             cout << "\n";
  657.         }
  658.  
  659.         if (breakAfterRender)
  660.         {
  661.             cout << "\n" << "\n";
  662.  
  663.             CoutCentered("Congratulations! You have reached the end of the level!");
  664.  
  665.             cout << "\n" << "\n";
  666.  
  667.             CoutCentered("Press \"ENTER\" to continue");
  668.  
  669.             cout << "\n";
  670.  
  671.             while (true)
  672.             {
  673.                 if (GetAsyncKeyState(VK_RETURN))
  674.                 {
  675.                     break;
  676.                 }
  677.             }
  678.  
  679.             break;
  680.         }
  681.  
  682.         labyrinth[playerX][playerY] = " ";
  683.  
  684.         playerMove(labyrinth);
  685.  
  686.         if (labyrinth[playerX][playerY] == "E")
  687.         {
  688.             breakAfterRender = true;
  689.         }
  690.  
  691.         labyrinth[playerX][playerY] = player;
  692.  
  693.         // Pause sound
  694.         if (GetAsyncKeyState(VK_ESCAPE))
  695.         {
  696.             system("cls");
  697.  
  698.             cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  699.  
  700.             CoutCentered("Paused");
  701.  
  702.             while (true)
  703.             {
  704.                 if (GetAsyncKeyState(VK_ESCAPE))
  705.                 {
  706.                     break;
  707.                 }
  708.             }
  709.         }
  710.  
  711.         this_thread::sleep_for(chrono::milliseconds(64));
  712.     }
  713. }
  714.  
  715. void loadMap(string fileName, int level, string levelType)
  716. {
  717.     int rowsCount = 1;
  718.  
  719.     int columnsCount = 0;
  720.  
  721.     int startAt = 0;
  722.  
  723.     int endAt = 0;
  724.  
  725.     ifstream mapFile;
  726.     mapFile.open(fileName);
  727.  
  728.     if (mapFile.is_open())
  729.     {
  730.         char currentSymbol;
  731.  
  732.         while (mapFile)
  733.         {
  734.             currentSymbol = mapFile.get();
  735.  
  736.             if (currentSymbol == '\n')
  737.             {
  738.                 rowsCount++;
  739.             }
  740.  
  741.             else if ( (currentSymbol != '\n') && (rowsCount == 1) )
  742.             {
  743.                 columnsCount++;
  744.             }
  745.  
  746.             else if (currentSymbol == 'S')
  747.             {
  748.                 startAt = rowsCount - 1;
  749.             }
  750.  
  751.             else if (currentSymbol == 'E')
  752.             {
  753.                 endAt = rowsCount - 1;
  754.             }
  755.         }
  756.     }
  757.  
  758.     else
  759.     {
  760.         CoutCentered("Error: Unable to open file " + fileName);
  761.        
  762.         cout << "\n";
  763.  
  764.         CoutCentered("Press \"ESCAPE\" to go back to the Main Menu");
  765.  
  766.         while (true)
  767.         {
  768.             backToMenu();
  769.         }
  770.     }
  771.  
  772.     mapFile.close();
  773.  
  774.     // Dynamically allocating row space in the heap
  775.     string** labyrinth = new string * [rowsCount];
  776.  
  777.     // Dynamically allocating column space in the heap
  778.     for (size_t i = 0; i < rowsCount; i++)
  779.     {
  780.         labyrinth[i] = new string[columnsCount];
  781.     }
  782.  
  783.     int currentRow = 0;
  784.  
  785.     int currentColumn = 0;
  786.  
  787.     mapFile.open(fileName);
  788.  
  789.     if (mapFile.is_open())
  790.     {
  791.         char currentSymbol;
  792.  
  793.         while (mapFile.get(currentSymbol))
  794.         {
  795.             if ( (currentRow < rowsCount) && (currentColumn < columnsCount) )
  796.             {
  797.                 labyrinth[currentRow][currentColumn] = currentSymbol;
  798.             }
  799.  
  800.             if (currentSymbol == '\n')
  801.             {
  802.                 currentRow++;
  803.  
  804.                 currentColumn = 0;
  805.             }
  806.  
  807.             else
  808.             {
  809.                 currentColumn++;
  810.             }
  811.         }
  812.     }
  813.  
  814.     mapFile.close();
  815.  
  816.     for (size_t i = 0; i < rowsCount; i++)
  817.     {
  818.         for (size_t j = 0; j < columnsCount; j++)
  819.         {
  820.             if (labyrinth[i][j] == "S")
  821.             {
  822.                 playerX = i;
  823.  
  824.                 playerY = j;
  825.             }
  826.         }
  827.     }
  828.  
  829.     // Displaying the labyrinth
  830.     display(labyrinth, rowsCount, columnsCount, level, levelType);
  831.  
  832.     // Free up the space after the use of the array
  833.     for (size_t i = 0; i < rowsCount; i++)
  834.     {
  835.         delete[] labyrinth[i];
  836.     }
  837.  
  838.     delete[] labyrinth;
  839. }
  840.  
  841. void loadCustomMapFromTheFolder()
  842. {
  843.     size_t fileCount = filesInFolderCount("custom");
  844.  
  845.     string* menu = new string[fileCount];
  846.  
  847.     WIN32_FIND_DATA findData;
  848.  
  849.     HANDLE hFind;
  850.  
  851.     string folderPath = "maps/custom/";
  852.  
  853.     wstring wideFolderPath(folderPath.begin(), folderPath.end());
  854.     wideFolderPath += L"*";
  855.  
  856.     hFind = FindFirstFile(wideFolderPath.c_str(), &findData);
  857.  
  858.     if (hFind != INVALID_HANDLE_VALUE)
  859.     {
  860.         char narrowString[MAX_PATH];
  861.  
  862.         string* newData;
  863.  
  864.         int counter = 0;
  865.  
  866.         while (FindNextFile(hFind, &findData) != 0)
  867.         {
  868.             WideCharToMultiByte(CP_ACP, 0, findData.cFileName, -1, narrowString, MAX_PATH, NULL, NULL);
  869.  
  870.             if (strcmp(narrowString, ".") != 0 && strcmp(narrowString, "..") != 0)
  871.             {
  872.                 if (counter == fileCount)
  873.                 {
  874.                     newData = new string[fileCount + 2];
  875.  
  876.                     for (size_t i = 0; i < counter; i++)
  877.                     {
  878.                         newData[i] = menu[i];
  879.                     }
  880.  
  881.                     delete[] menu;
  882.  
  883.                     menu = newData;
  884.                 }
  885.  
  886.                 menu[counter] = narrowString;
  887.  
  888.                 counter++;
  889.             }
  890.         }
  891.  
  892.         FindClose(hFind);
  893.     }
  894.  
  895.     size_t pointer = 0;
  896.  
  897.     bool lastUpKeyState = false;
  898.  
  899.     bool lastDownKeyState = false;
  900.  
  901.     bool lastReturnKeyState = false;
  902.  
  903.     bool arrowVisible = true;
  904.  
  905.     while (true)
  906.     {
  907.         system("cls");
  908.  
  909.         cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  910.  
  911.         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  912.  
  913.         CoutCentered("There are " + to_string(fileCount) + " files in the subfolder called \"custom\".");
  914.  
  915.         cout << "\n";
  916.  
  917.         CoutCentered("Select a Custom Map");
  918.  
  919.         cout << "\n";
  920.  
  921.         for (size_t i = 0; i < fileCount; i++)
  922.         {
  923.             if (i == pointer)
  924.             {
  925.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  926.  
  927.                 if (arrowVisible)
  928.                 {
  929.                     CoutCentered("-> " + menu[i]);
  930.  
  931.                     arrowVisible = false;
  932.                 }
  933.  
  934.                 else
  935.                 {
  936.                     CoutCentered("    ");
  937.  
  938.                     arrowVisible = true;
  939.                 }
  940.             }
  941.  
  942.             else
  943.             {
  944.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  945.  
  946.                 CoutCentered(menu[i]);
  947.             }
  948.         }
  949.  
  950.         bool upKeyState = GetAsyncKeyState(VK_UP);
  951.  
  952.         if ( (upKeyState) && !(lastUpKeyState) )
  953.         {
  954.             pointer -= 1;
  955.  
  956.             if (pointer == -1)
  957.             {
  958.                 pointer = fileCount - 1;
  959.             }
  960.         }
  961.  
  962.         lastUpKeyState = upKeyState;
  963.  
  964.         bool downKeyState = GetAsyncKeyState(VK_DOWN);
  965.  
  966.         if ( (downKeyState) && !(lastDownKeyState) )
  967.         {
  968.             pointer += 1;
  969.  
  970.             if (pointer == fileCount)
  971.             {
  972.                 pointer = 0;
  973.             }
  974.         }
  975.  
  976.         lastDownKeyState = downKeyState;
  977.  
  978.         bool returnKeyState = GetAsyncKeyState(VK_RETURN);
  979.  
  980.         if ( (returnKeyState) && !(lastReturnKeyState) )
  981.         {
  982.             // Play sound
  983.             PlaySound(TEXT("river.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  984.  
  985.             // Set audio volume to 25%
  986.             SetVolume(0xFFFF / 4);
  987.  
  988.             string mapFile = "maps/custom/" + menu[pointer];
  989.  
  990.             // Opening the text file
  991.             loadMap(mapFile, 0, "custom");
  992.  
  993.             PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  994.  
  995.             // Set audio volume to 25%
  996.             SetVolume(0xFFFF / 4);
  997.  
  998.             mainMenu();
  999.         }
  1000.  
  1001.         lastReturnKeyState = returnKeyState;
  1002.        
  1003.         if (GetAsyncKeyState(VK_ESCAPE))
  1004.         {
  1005.             customGameMenu();
  1006.         }
  1007.  
  1008.         this_thread::sleep_for(chrono::milliseconds(200));
  1009.     }
  1010.  
  1011.     delete[] menu;
  1012. }
  1013.  
  1014. void createACustomMap()
  1015. {
  1016.     system("cls");
  1017.  
  1018.     system("color 04");
  1019.  
  1020.     cin.ignore();
  1021.  
  1022.     cin.get();
  1023.  
  1024.     // TO DO: Rows and Colums
  1025.     // At least 4
  1026.    
  1027.     int rows = 0;
  1028.  
  1029.     int columns = 0;
  1030.  
  1031.     rowsAndColumnsChoice(rows, columns);
  1032.  
  1033.     system("cls");
  1034.  
  1035.     // TO DO: Start and End
  1036.  
  1037.     int start = 0;
  1038.    
  1039.     int end = 0;
  1040.  
  1041.     startAndEndChoice(start, end);
  1042.  
  1043.     system("cls");
  1044.  
  1045.     int wallsCount = 0;
  1046.  
  1047.     setWallsCountChoice(wallsCount);
  1048.  
  1049.     system("cls");
  1050.  
  1051.     // TO DO: Visualize the labyrinth with the specific rows and colums and start and end and cover the board with the "#" symbol.
  1052.     // Display a message with the walls count. Then ask the user if he wants to set the walls inside the board or if he wants the game to set them for him
  1053.    
  1054.     // TO DO: Create the labyrinth
  1055.      
  1056.     // TO DO: Display the board
  1057.     // TO DO: Place inside the labyrinth numbers
  1058.     // TO DO: Display the board
  1059.     // TO DO: Do you want to save map in a _time stamp.txt file and what name
  1060. }
  1061.  
  1062. void rowsAndColumnsChoice(int rows, int columns)
  1063. {
  1064.     system("cls");
  1065.  
  1066.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1067.  
  1068.     CoutCentered("Do you want to set your own rows and columns or do you want the game to set them for you?");
  1069.     CoutCentered("The possible answers are \"myself\" for you to set them yourself or \"random\" for the game to set them for you.");
  1070.     CoutCenteredWithoutNewLine("Your answer is: ");
  1071.  
  1072.     string choice;
  1073.     getline(cin >> ws, choice);
  1074.  
  1075.     for (size_t i = 0; i < choice.length(); i++)
  1076.     {
  1077.         choice[i] = tolower(choice[i]);
  1078.     }
  1079.  
  1080.     if (choice == "myself")
  1081.     {
  1082.  
  1083.     }
  1084.  
  1085.     else if (choice == "random")
  1086.     {
  1087.  
  1088.     }
  1089.  
  1090.     else
  1091.     {
  1092.         CoutCentered("Invalid choice");
  1093.  
  1094.         return rowsAndColumnsChoice(rows, columns);
  1095.     }
  1096. }
  1097.  
  1098. void startAndEndChoice(int start, int end)
  1099. {
  1100.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1101.  
  1102.     CoutCentered("Do you want to set your own start and end or you do want the game to set them for you?");
  1103.     CoutCentered("The possible answers are \"myself\" for you to set them yourself or \"random\" for the game to set them for you.");
  1104.     CoutCenteredWithoutNewLine("Your answer is: ");
  1105.  
  1106.     string choice;
  1107.     getline(cin >> ws, choice);
  1108.  
  1109.     for (size_t i = 0; i < choice.length(); i++)
  1110.     {
  1111.         choice[i] = tolower(choice[i]);
  1112.     }
  1113.    
  1114.     if (choice == "myself")
  1115.     {
  1116.  
  1117.     }
  1118.    
  1119.     else if (choice == "random")
  1120.     {
  1121.  
  1122.     }
  1123.    
  1124.     else
  1125.     {
  1126.         CoutCentered("Invalid choice");
  1127.  
  1128.         return startAndEndChoice(start, end);
  1129.     }
  1130. }
  1131.  
  1132. int setWallsCountChoice(int wallsCount)
  1133. {
  1134.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1135.  
  1136.     CoutCentered("Do you want to set your number of walls or do you want the game to set them for you?");
  1137.     CoutCentered("The possible answers are \"myself\" for you to set them yourself or \"random\" for the game to set them for you.");
  1138.     CoutCenteredWithoutNewLine("Your answer is: ");
  1139.  
  1140.     string choice;
  1141.     getline(cin >> ws, choice);
  1142.  
  1143.     for (size_t i = 0; i < choice.length(); i++)
  1144.     {
  1145.         choice[i] = tolower(choice[i]);
  1146.     }
  1147.  
  1148.     if (choice == "myself")
  1149.     {
  1150.  
  1151.     }
  1152.  
  1153.     else if (choice == "random")
  1154.     {
  1155.  
  1156.     }
  1157.  
  1158.     else
  1159.     {
  1160.         CoutCentered("Invalid choice");
  1161.  
  1162.         return setWallsCountChoice(wallsCount);
  1163.     }
  1164.  
  1165.     return wallsCount;
  1166. }
  1167.  
  1168. int filesInFolderCount(string levelType)
  1169. {
  1170.     int fileCount = 0;
  1171.  
  1172.     string folderPath = "maps/" + levelType + "/";
  1173.  
  1174.     // Get the first file in the folder
  1175.     WIN32_FIND_DATAA findFileData;
  1176.  
  1177.     HANDLE hFind = FindFirstFileA((folderPath + "*").c_str(), &findFileData);
  1178.  
  1179.     // Iterate through the files in the folder
  1180.     if (hFind != INVALID_HANDLE_VALUE)
  1181.     {
  1182.         while (true)
  1183.         {
  1184.             // Check if the current file is a regular file
  1185.             if ( (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 )
  1186.             {
  1187.                 fileCount++;
  1188.             }
  1189.  
  1190.             if ( !(FindNextFileA(hFind, &findFileData)) )
  1191.             {
  1192.                 break;
  1193.             }
  1194.         }
  1195.  
  1196.         // Clean up
  1197.         FindClose(hFind);
  1198.     }
  1199.  
  1200.     return fileCount;
  1201. }
  1202.  
  1203. void levels(string levelType)
  1204. {
  1205.     // Play sound
  1206.     PlaySound(TEXT("river.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1207.  
  1208.     // Set audio volume to 25%
  1209.     SetVolume(0xFFFF / 4);
  1210.  
  1211.     int level = 1;
  1212.  
  1213.     if ( (levelType != "easy") && (levelType != "normal") && (levelType != "hard") )
  1214.     {
  1215.         system("cls");
  1216.  
  1217.         CoutCentered("Invalid level type!");
  1218.  
  1219.         return;
  1220.     }
  1221.  
  1222.     string mapFile;
  1223.  
  1224.     while (level <= filesInFolderCount(levelType))
  1225.     {
  1226.         system("cls");
  1227.  
  1228.         mapFile = "maps/" + levelType + "/map_" + to_string(level) + ".txt";
  1229.  
  1230.         // Opening the text file
  1231.         loadMap(mapFile, level, levelType);
  1232.  
  1233.         level++;
  1234.     }
  1235.  
  1236.     system("cls");
  1237.  
  1238.     cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  1239.  
  1240.     CoutCentered("Congratulations! You have finished the game!");
  1241.  
  1242.     cout << "\n";
  1243.  
  1244.     CoutCentered("Press \"ENTER\" to continue");
  1245.  
  1246.     while (true)
  1247.     {
  1248.         if (GetAsyncKeyState(VK_RETURN))
  1249.         {
  1250.             break;
  1251.         }
  1252.     }
  1253.  
  1254.     PlaySound(TEXT("running_home_to_you.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
  1255.  
  1256.     // Set audio volume to 25%
  1257.     SetVolume(0xFFFF / 4);
  1258.  
  1259.     gameCredits();
  1260. }
  1261.  
  1262. void CoutCentered(string text)
  1263. {
  1264.     // This function will center the text within the console window.
  1265.  
  1266.     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Get the console handle.
  1267.  
  1268.     CONSOLE_SCREEN_BUFFER_INFO screenInfo;
  1269.  
  1270.     GetConsoleScreenBufferInfo(hConsole, &screenInfo); // Get the console screen buffer info.
  1271.  
  1272.     int consoleWidth = screenInfo.dwSize.X;
  1273.  
  1274.     int textWidth = static_cast<int>(text.length());
  1275.  
  1276.     int leftMargin = (consoleWidth - textWidth) / 2;
  1277.  
  1278.     for (size_t i = 0; i < leftMargin; i++)
  1279.     {
  1280.         cout << " ";
  1281.     }
  1282.  
  1283.     cout << text << "\n";
  1284. }
  1285.  
  1286. void CoutCenteredWithoutNewLine(string text)
  1287. {
  1288.     // This function will center the text within the console window.
  1289.  
  1290.     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Get the console handle.
  1291.  
  1292.     CONSOLE_SCREEN_BUFFER_INFO screenInfo;
  1293.  
  1294.     GetConsoleScreenBufferInfo(hConsole, &screenInfo); // Get the console screen buffer info.
  1295.  
  1296.     int consoleWidth = screenInfo.dwSize.X;
  1297.  
  1298.     int textWidth = static_cast<int>(text.length());
  1299.  
  1300.     int leftMargin = (consoleWidth - textWidth) / 2;
  1301.  
  1302.     for (size_t i = 0; i < leftMargin; i++)
  1303.     {
  1304.         cout << " ";
  1305.     }
  1306.  
  1307.     cout << text;
  1308. }
  1309.  
  1310. int GetConsoleWidth()
  1311. {
  1312.     CONSOLE_SCREEN_BUFFER_INFO csbi;
  1313.  
  1314.     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
  1315.  
  1316.     int columns = csbi.srWindow.Right - csbi.srWindow.Left + 2;
  1317.  
  1318.     return columns;
  1319. }
  1320.  
  1321. // Sets the audio volume
  1322. void SetVolume(int volume)
  1323. {
  1324.     DWORD newVolume = ((DWORD)volume << 16) | (DWORD)volume;
  1325.  
  1326.     waveOutSetVolume(NULL, newVolume);
  1327. }
  1328.  
  1329. void ShowConsoleCursor(bool showFlag)
  1330. {
  1331.     HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
  1332.  
  1333.     CONSOLE_CURSOR_INFO cursorInfo;
  1334.  
  1335.     GetConsoleCursorInfo(out, &cursorInfo);
  1336.  
  1337.     cursorInfo.bVisible = showFlag; // SET THE CURSOR VISIBILITY
  1338.  
  1339.     SetConsoleCursorInfo(out, &cursorInfo);
  1340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement