1. C++ / Говнокод #27141

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    #include <iostream>
    #include <ctime>
    #include <random>
    #include <windows.h>
    #include <cstdint>                             // Для int8_t;
    #include <string>   
    #include <string_view> 
    #include <array>                               
    #include <iomanip>                           // setw();
    
    using namespace std;
    
    const array <string, 94> arr = { "олицетворение", "патология", "субтропики", "лекарь", "предосторожность", "монархист",
            "социум", "клякса", "борщевик", "лемур", "старьевщик", "марсельеза", "послушание", "прикол", "шифровка", "фантом", "субмарина",
            "гладиолус", "сообщество", "гениальность", "трансформация", "пальпация", "усушка", "благополучие", "капелла", "недоумение",
            "траверс", "проныра", "полоскание", "побережье", "закись", "кровопиец", "сыродел", "продвижение", "совместимость", "двойственность",
            "сабботаж", "рассылка", "куратор", "прорицание", "синтез", "негодяй", "паралич", "тяжелоатлет", "освободитель", "кунжут",
            "мордобой", "ностальгия", "хлорофилл", "первооткрыватель", "гипотенуза", "шкатулка", "психиатр", "маэстро", "прыть",
            "пустомеля", "здравоохранение", "алиментщик", "параметр", "аннотация", "пудинг", "прыжок", "пневматика", "штырь", "фасовщик",
            "совместитель", "свиновод", "яйцеварка", "зверобой", "тундра", "вогнутость", "рикошет", "компромисс", "фоторепортер",
            "кордебалет", "нумизмат", "гипербола", "желтизна", "брезент", "ботфорты", "гостинец", "символист", "акустика", "психика",
            "удивление", "уховертка", "снежинка", "меценат", "атомоход", "контрабас", "брюква", "миловидность", "спринтер", "пунктир" };
    
    int randNumber(int min, int max)
    {
        random_device rd;  //Will be used to obtain a seed for the random number engine
        mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
        uniform_int_distribution<int> distrib(min, max);
        return distrib(gen);
    }
    
    string_view randString()
    {
        return (string_view)arr[randNumber(0, arr.size())];
    }
    
    void printGuessedChar(string_view input, string_view randWord)
    {
        for (int i = 0; i < randWord.size(); ++i)
        {
            for (int j = 0; j < input.size(); ++j)
            {
                if (randWord[i] == input[j])
                {
                    cout << randWord[i];
                    break;
                }
            }
            cout << '*';
        }
        cout << endl;
    }
    
    int randNumber(int min, int max)
    {
        random_device rd;  //Will be used to obtain a seed for the random number engine
        mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
        uniform_int_distribution<int> distrib(min, max);
        return distrib(gen);
    }
    
    void theGame()
    {
        cout << "Добро пожаловать в игру 'Виселица'!" << endl;
        string_view randWord = randString();
        cout << "Компьютер сгенерировал слово" << endl;
        cout << "Слово - ";
        for (int i = 0; i < randWord.size(); ++i)
        {
            cout << '*';
        };
        cout << endl;
        int8_t count = 0;
        string input;
        do
        {
            cout << "У вас " << 6 - count << " попыток угадать слово." << endl << "Введите букву: ";
            if (cin.fail()) // если предыдущее извлечение оказалось неудачным,
            {
                cin.clear(); // то возвращаем cin в 'обычный' режим работы
                cin.ignore(32767, '\n'); // и удаляем значения предыдущего ввода из входного буфера
            }
            cin >> setw(1) >> input[count];
            printGuessedChar(input, randWord);
            ++count;
        } while (count != 6);
    }
    
    int main()
    {
        SetConsoleCP(1251);
        SetConsoleOutputCP(1251);
        srand((unsigned)time(nullptr));
        theGame();
    }

    Заколебался уже с этим кодом. Не получается впихнуть пользовательский ввоз в массив...Первая попытка освоить std::string и std::string_view. Ну и в целом советы по коду приветствуются. Благодарю
    //Давайте напишем популярную игру, которая называется «Виселица».В игре вам нужно угадать слово, которое загадала программа, буква за буквой.
    //Игрок угадывает одну букву за раз и может ошибиться только 6 раз(после этого он проигрывает).
    //Необходимый функционал вашей программы :
    //создайте массив слов(например, поместите туда 40 слов) и рандомным образом выберите 1 слово для угадывания;
    //программа должна выводить длину всего слова и отображать буквы, которые угадал игрок;
    //после каждого неудачного угадывания, программа должна сообщить игроку, сколько у него осталось попыток неверно указать букву, прежде чем он проиграет;
    //если человек указал букву, которую ранее уже угадывал, и она не дублируется в слове, то не наказывайте его, а просто предоставьте возможность угадать букву еще раз.
    //Например, компьютер загадал слово INTERESTING :
    //
    //Добро пожаловать в игру "Виселица"!
    //Слово - _ _ _ _ _ _ _ _ _ _ _
    //Угадайте букву : S
    //Верно - _ _ _ _ _ _ S _ _ _ _
    //Угадайте следующую букву : F
    //Неверно!Такой буквы нет, у вас осталось 5 попыток неверно указать букву!
    //...

    Запостил: radionnazmiev, 30 Ноября 2020

    Комментарии (33) RSS

    • > using namespace std;

      Фу.

      > uniform_int_distribution<int> distrib(min, max);
      > return (string_view)arr[randNumber(0, arr.size())];

      Прога крашится с вероятностью 1/95, или я туплю?

      > cout << '*';

      Хм, звёздочка безусловно выводится, даже если символ угадали?

      > "У вас " << 6 - count << " попыток

      Я бы скобочки въебал, читатель не обязан помнить приоритеты.

      > string input;
      > cin >> setw(1) >> input[count];

      Как это вообще работает.

      > srand((unsigned)time(nullptr));

      Выбрось каку, крестовые генераторы не юзают этот стейт.
      Ответить
    • > (string_view)arr[randNumber(0, arr.size())]
      static_cast<std::string_view>(randNumber (0, arr.size())])
      Ответить
      • Да, но не стыдно с багом копипастить?
        Ответить
        • Про 1/95 уже было упомянуто. Автор уведомлён, так что уже не стыдно.
          Ответить
          • И никто так и не сказал, как правильно прочитать символ.

            Потому что в ёбаном "iostream" это с первого раза никто не напишет.
            Ответить
            • Именно поэтому я за «getchar()».
              Ответить
              • Всё равно \n'ки пропускать.

                З.Ы. Кстати, сможешь что-нибудь сворецировать на основе слов из этого кода?
                Ответить
                • Зачем? Новые строки — тоже символ! Или ты символист и угнетаешь?!
                  #NewLinesMatter

                  > З.Ы. Кстати, сможешь что-нибудь сворецировать на основе слов из этого кода?
                  Хм, если взять какую-нибудь модельку и обрезать по этим словам…
                  Ответить
                • > сможешь что-нибудь сворецировать на основе слов из этого кода?

                  Тоже сначала подумал, что массив слов для каких-то хитрых вореций.
                  Ответить
            • Я хотел напейсать что-то про впетушивание в строку символа перед чтением, поскольку input[count] - доставание ссылки на ничего, и надо сначала обеспечить буфер под чтение, а потом читать.

              input.push_back('*');
              cin >> input[count];

              или
              input.push_back('*');
              cin >> input.back();


              Потому, что сначала надо убедиться, что программа не тронулась умом по части памяти, и уже потом пердолиться с iostream, что я пожелал бы оставить автору как домашнее задание ибо сам не хотел бы в это погружаться.

              Но потом я занялся рабочим вопросом и забыл про ГК.
              Ответить
              • Да проще тогда в отдельный символ прочитать и пушбекнуть его в строку чем так извращаться...
                Ответить
            • > Потому что в ёбаном "iostream" это с первого раза никто не напишет.

              А как правильно? Какие подводные камни?

              Если чо, я госту въебал плюс за «getchar()». Это лютая годнота.
              Ответить
              • Не буду спойлерить, попробуй сам.

                > getchar()

                По-дефолту вроде включена синхронизация буфера между c и c++ стримами, но в общем случае тоже можно ногу отстрелить.
                Ответить
                • >включена
                  а есть пруф?
                  Ответить
                  • Ты что, не читал пункт 29.5.2.5 Стандарта С++?
                    Ответить
                    • Читал, конечно. Но почему-то думал, что надо явно вызвать ``sync_with_stdio``.
                      Я такой невнимательный...
                      Ответить
              • > А как правильно?
                std::string input;
                //Забиваю хуй на обрабаотку ошибок. Лаба же.
                std::cin >> input;
                if ( input.size() > 1 ) {
                    std::cout << 
                R"(Один символ! Один символ, сука, вводить надо! Ты долбоёб? До одного считать не умеешь?
                Какого хуя ты, мудила, эту поебень ввёл? Самый умный, думаешь? Подъебал, думаешь?
                А вот хуй тебе, конина блядская.
                )";
                    while(true) std::cout << "\aСМОТРИТЕ СЮДА Я ЕБУ КОНЕЙ\n"; 
                }
                Ответить
                • Вы все ненормальные что ли?
                  #include <iostream>
                  
                  int main()
                  {
                  	const auto c = std::cin.get();
                  	std::cout << "You said " << static_cast<char>(c) << std::endl;
                  }
                  Ответить
                  • А теперь засунь это в цикл, как в оригинале. (Подсказка, что будет, если у питуха большие пальцы и он введёт две буквы?)
                    Ответить
                    • Я пока не понимаю, какую проблему вы решаете. Буква в буфере застревает? Так удалите ее после первого чтения.
                      Ответить
                      • 1) Прочесть букву
                        2) Убедиться, что лишние буквы неаккуратно введёные питухом не ломают программу.
                        3) Убедиться, что решение к (2) не теряет буквы из потока символов, переправленных из файла или чем то типа myprog < abcdef
                        4) Прочесть пробел
                        5) Прочесть перенос строки
                        Ответить
                        • А обязательно портабельно делать?

                          Я к стыду своему не знаю, как портабельно отключить буфер, чтобы читать сразу, а не после \n.

                          С буфером можно сгородить стейт машину, и фильттровать говно, но это геморно.
                          Ответить
                          • В любом случае придётся городить макросню и/или ifdef'ы. Стандартно isatty ты не сделаешь, отключать буферизацию ввода нужно тоже пирдолясь с ОС-специфичными функциями...

                            В том и дело, что если тебе нужно от ввода что-то иное, чем «последовательности печатных символов, разделённые последовательностями пробельных символов», то проще либо забить на iostream и манипулировать вводом самому, либо читать ввод большими кусками и парсить отдельно.
                            Ответить
                            • Понял.

                              C++ слишком абстрактен, и не предоставляет небуферизированный, низкоуровневый API.

                              Я могу не ебаться с макросней, а просто собрать разные объектные файлы, и прилинковать их на разных ОС же?

                              На позиксе я возьму termios, в досе conio на винде -- Console API и потеку.


                              Читать кусками и парсить отдельно это гиморно. Тогда уж лучше я возьму тулу для генерации лексера какого-то может быть.
                              Ответить
    • >int randNumber(int min, int max)
      >{
      > random_device rd; //Will be used to obtain a seed for the random number engine
      > mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
      > uniform_int_distribution<int> distrib(min, max);
      > return distrib(gen);
      >}

      А может не надо каждый раз для получения случайного числа переинициализировать ГПСЧ новым сидом?

      ttps://stackoverflow.com/questions/29549873/
      Ответить
      • А как же секурность?! Я бы еще и finger-print собрал и им бы инициализировал )))
        Ответить
        • конечно, чем больше раз инициализируешь гспч сидом -- тем секурнее
          Ответить
        • https://bit.ly/3lodTFM
          Ответить
      • Какой багор ))) А мы с Бормандом какие-то скобочки круглые и треугольные смотрели вместо этого.
        Ответить
    • > void printGuessedChar(string_view input, string_view randWord)
      Я бы ещё рекомендовал ради тренировки в архитектурщине эту питушню переделать в
      void printGuessedString(std::string_view input, std::string_view randWord, std::ostream out), чтобы выводить куда угодно
      либо в
      std::string getGuessedString(std::string_view input, std::string_view randWord), чтобы полученную строку использовать где угодно как угодно.
      (std::string или std::string_view или const std::string, или ... на выходе - не знаю, пишу по смыслу, а не по царскому пирфомансу)

      Ну и, как минимум, переименовать в printGuessedString, чтобы читатель кода не охреневал от происходящего.
      Ответить
    • Спасибо всем за советы! Переписал немного..
      https://repl.it/@radionnazmiev/Ravesli#Ravesli_24_H/main.cpp
      Что еще можно улучшить помимо проверки на ввод? Правильные ли переменные я подобрал, string_view правильно ли применил, да и семантику перемещениянужно ли было реализвать где то?
      Ответить

    Добавить комментарий