Advertisement
PIBogdanov

The Labyrinth

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