Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
 Аватар для kcalbCube
15 / 13 / 4
Регистрация: 16.08.2018
Сообщений: 125

Оцените простенькую игру

16.08.2018, 07:17. Показов 814. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Написал небольшую игру,
Суть в том что бы угадать число.
Я старался хорошо закомментировать код и сделать его наиболее читабельным на моём уровне.
Желательно конструктивная критика моего кода.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "stdafx.h" //При тесте можете убрать эту строку если у вас не Visual Studio
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <windows.h> //для функции Print()
#include <string> //для функции Print()
 
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Инициализирую цветной текст изпользуя windows.h
 
int Random(int min, int max) //Функция генерации случайных чисел в нужном диапозоне
{
    static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);
    return static_cast<int>(rand() * fraction * (max - min + 1) + min);
}
 
using std::string; //Облегчаю кодинг
using std::cout;
using std::cin;
 
 
void print(string text, int clr, int bgclr) //Функция удобной печати цветного текста
{
    SetConsoleTextAttribute(hConsole, (WORD)((bgclr << 4) | clr)); //Изменение цвета печати инструкции 'cout'
    
    cout << text; //Вывожу локальную переменную text
}
void printnum(int text, int clr, int bgclr) //Функция удобной печати чисел в цвете
{
    SetConsoleTextAttribute(hConsole, (WORD)((bgclr << 4) | clr)); //Изменение цвета печати инструкции 'cout'
 
    cout << text;
}
bool Cin(int num) //Инициализация функции проверки инструкции 'cin',
{
    if ((!num < 0) || !(num >= 100)) //Если число меньше 0 или больше 100 то выдаём false
        return true;
    else
        return false;
}
int main()
{
    setlocale(LC_ALL, "rus"); //Русский язык для вывода
 
Restart: //Перезагрузка игры
 
    int num{ Random(1,100) }; //num - Случайное число. Я изпользую Visual Studio, поэтому сразу же присваиваю переменной случайное число
    
    int bufer{};
 
    num = Random(1, 100); // Случайное число
    int tryguess{}; //Число для cin
 
    int guess{ 1 }; //Кол-во Попыток
 
    srand(static_cast<unsigned int>(time(0))); // Изпользую системные часы для инициализации ГПСЧ
 
    print("Давайте поиграем! Я сгенерировало число. У вас есть 7 попыток что-бы угадать число!", 14, 0);
    cout << '\n'; //Не обращайте внимания на эту строку
Restart_nf:
    print("Вариант ", 10, 0);
    printnum(guess, 10, 0);
    print("#: ", 10, 0);
    cout << '\n';
    ReCin: //На случай если пользователь ввёл неправильное число
    cin >> tryguess;
    guess++;
    bool work{ Cin(tryguess) }; //Проверка, правильно ли это число.
    if (guess <= 7)
    {
        if (work)
        {
 
            if (tryguess == num) //Если число верное
            {
                print("Вы выйграли!", 10, 0);
                print("Хотите поиграть ещё?(1/0)", 10, 0);
                cin >> bufer;
                switch (bufer)
                {
                case 1:
                {
                    system("cls"); //Очищаю консоль
                    goto Restart; //Перезагружаю игру
                }
                case 0:
                    exit(0);
                }
            }
            else
            {
                if (tryguess > num) //Если число слишком большое
                {
                    print("Число слишком большое", 4, 0);
                    cout << '\n';
                    goto Restart_nf;
                }
                else
                    if (tryguess < num) //Если число слишком маленькое
                    {
                        print("Число слишком маленькое", 4, 0);
                        cout << '\n';
                        goto Restart_nf;
                    }
            }
        }
        else
            goto ReCin;
    }
    else
    {
        print("Вы проиграли!", 4, 0);
        system("pause");
        system("cls");
        goto Restart;
    }
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.08.2018, 07:17
Ответы с готовыми решениями:

Оцените консольную игру, где символ убивает себе подобных
Игра примитивная, в консоли, ходит символ убивает в текстовом режиме циферки. Управление: движение - стрелочками s - магазин i -...

Написать простенькую 2д игру но не знаю с чего начать
я студент заканчиваю 2 курс института захотелось написать простенькую 2д игру но не знаю с чего начать. Есть базовые знания с++ такие как...

Как создать простенькую игру для Windows Phone
Здравствуйте. У меня есть Microsoft Visual C# 2008 Express Edition,как с помощью него можно создать игру для Windows Phone? Например...

6
2 / 2 / 0
Регистрация: 27.03.2017
Сообщений: 14
16.08.2018, 09:14
особо не смотрел, но при каждом запуске у тебя будет одно и то же превдослучайное число, нужно инициализировать генератор с помощью
C++
1
2
    // Используем текущее время как начальное значение для генератора случайных чисел
    std::srand(unsigned(std::time(0)));
В с++ goto не используют. Попробуй заменить на while и for
0
 Аватар для kcalbCube
15 / 13 / 4
Регистрация: 16.08.2018
Сообщений: 125
16.08.2018, 09:48  [ТС]
Хммм, я Программист-самоучка, объясни почему goto не следует изпользовать?
И да, Я тестировал, числа случайные...
0
2 / 2 / 0
Регистрация: 27.03.2017
Сообщений: 14
16.08.2018, 09:54
я не заметил в коде srand, прошу прощения.

goto в c++ не используют, потому что это ухудшает читаемость кода (Спагетти-код)
0
 Аватар для kcalbCube
15 / 13 / 4
Регистрация: 16.08.2018
Сообщений: 125
16.08.2018, 10:05  [ТС]
Про спаггети-код я слышал, я его избегаю, но в этом случае когда всё(кроме очевидного) закомментировано и когда код относительно небольшой, спаггети-кода вроде не получаеться.
Тоесть можно легко понять что goto Restart; Перезагружает игру и goto Restart_nf; Переводит игру на следующий этап.
Да, Я согласен что это можно было сделать с циклами.
Но мне захотелось попытаться при несовсем правильных инструкциях сделать нормально читаемый код.
0
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
17.08.2018, 01:08
kcalbCube, мой вариант. Надеюсь, что-то новое найдёшь для себя.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
#include <random>
#include <chrono>
#include <windows.h>
 
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Инициализирую цветной текст изпользуя windows.h
 
int Random(int min, int max) //Функция генерации случайных чисел в нужном диапозоне
{
    std::uniform_int_distribution distribution(min, max);
    std::minstd_rand0 generator (
        static_cast<unsigned>(
        #ifdef NDEBUG
            std::chrono::system_clock::now().time_since_epoch().count()
        #else
            0
        #endif
        )
    );
    
    return distribution(generator);
}
 
template <class T>
void ColorPrint(T const& printable, int text_color, int background_color)
{
    SetConsoleTextAttribute(hConsole, (WORD)((background_color << 4) | text_color));
    std::cout << printable;
}
 
bool IsNumberInRange(int num)
{
    // !num < 0 // (!num) == false // (0 < 0) == false // Не знаешь приоритеты.
    // (!num < 0) || !(num >= 100)  // Громоздко. Не понятно без комментария,
                                    // что это проверка на вхождение в диапазон.
                                    // К тому же, скорее всего, с ошибкой.
    return 0 <= num && num <= 100;
}
 
//  0, если ответ не отличается от ожидаемого;
// -1, если ответ отличается от ожидаемого в меньшую сторону;
//  1, если ответ отличается от ожидаемого в большую сторону.
int CheckAnswer(int answer, int expected) {
    return answer - expected;
}
 
bool MainGameLoop() {
    int rand_number = Random(1, 100), current_attempt = 0;
    
    ColorPrint(
        "Давайте поиграем! "
        "Я сгенерировало число. "
        "У вас есть 7 попыток что-бы угадать число!\n",
        14,
        0
    );
    
    int user_answer = 0;
    
    while(true) {
        ++current_attempt;
        if(current_attempt > 7) {
            ColorPrint("Вы проиграли!\n", 4, 0);
            system("pause && cls");
            return true;
        }
        
        ColorPrint("Попытка #" + std::to_string(current_attempt) + ": ", 10, 0);
        
        std::cin >> user_answer;
        if(!IsNumberInRange(user_answer)) {
            continue;
        }
        
        int result = CheckAnswer(user_answer, rand_number);
        if(result == 0) {
            ColorPrint("Вы выйграли! ", 10, 0);
            while(true) {
                ColorPrint("Хотите поиграть ещё? (1/0): ", 10, 0);
                int user_choice = -1;
                std::cin >> user_choice;
                if(user_choice == 1 || user_choice == 0) {
                    return user_choice == 1;
                }
                ColorPrint("Некорректный ответ.\n", 10, 0);
            }
        
        } else if(result < 0) {
            ColorPrint("Число слишком маленькое.", 4, 0);
        } else {
            ColorPrint("Число слишком большое.", 4, 0);
        }
        
        std::cout << std::endl;
    }
}
 
int main() {
    setlocale(LC_ALL, "rus");
    srand(static_cast<unsigned int>(time(0)));
    
    while(MainGameLoop())
        ;
    
    return 0;
}


Такое ощущение, что goto использовалось примерно с такими мыслями:
Ох, а вот тут надо бы предусмотреть кое-что. Вернусь-ка назад, если случилось что-то страшное
Один из критериев написания хорошей программы - знание что за программа должна быть написана.
Знать примеры входных данных. Всегда помнить, что нужно проверять внешнюю информацию.

Имена переменных должны максимально быть приближены к цели их создания и к месту их применения.

Зачем применять всюду универсальную инициализацию,
если это не библиотечный, не шаблонный и даже не код с классами и их сложным конструированием?

Каждый этап алгоритма нужно стараться отделить от остальных этапов.
Проверка ввода на вхождение введённого числа в установленный диапазон.
Это можно обособить отдельно от непосредственно игры - зачем делать спагетти?

Не по теме:

Рис лучше



Чем меньше вложенность конструкций - тем лучше. Может, слышал про 80 символов на строку?
Меньше вложенность - больше поместится в эти 80 символов. Конечно, если делать отступы.

Насколько я понял, суть игры - бинарный поиск числа.
Зачем сразу ограничивать пользовательский ввод в диапазоне 0-100 без всяких пояснений?
Если только это не часть плана.

Привыкание к использованию exit() и goto может дорого аукнуться, когда будут работать несколько потоков,
которые захватывают ресурсы системными блокировками, не считая спагеттификации.

Постфиксный и префиксный инкременты - не одно и то же.
Любой инструмент нужно использовать по назначению.
Нет нужды использовать результат работы инструмента - зачем его использовать?

Я привык использовать using только там, где без него не обойтись.
Например, using namespace std::chrono_literals.
Без этого невозможно будет создать объект длительности (12ms, скажем).
Захламлять пространство имён - это чуть ли не худшая привычка, которая может развиться.
Мы же всё-таки в плюсах - тут масса инструментов, чтобы избежать коллизий имён, в отличии от C.
Поправьте, если я ошибаюсь.


P.S. Интересно услышать комментарии и на мой вариант
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
17.08.2018, 04:27
Цитата Сообщение от kcalbCube Посмотреть сообщение
Хммм, я Программист-самоучка, объясни почему goto не следует изпользовать?
1) Бытует мнение что квалификация программиста обратно пропорциональна количеству goto в его коде.
2) В 99% случаев можно обойтись без goto. Так что в этих самых 99% случаях использование goto - зашквар.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.08.2018, 04:27
Помогаю со студенческими работами здесь

Оцените игру
оцените пожалуйста игру и сделайте вердикт program pbnd; uses crt; var ...

Оцените игру-шутер
uses graphabc,events,Timers; type massiv=array of integer; var x1,y1,x2,y2:massiv; x:array of integer; y:array of integer; ...

Оцените написанную игру
Добрый день, написал игру - сетевые шахматы между игроками. Выложил на github, было бы круто узнать что скажут хорошие программисты,...

Оцените игру ShotGun
Вот, собственно, моя игра! Конечно не очень красиво, но этож бэйсик... Хотелось бы услышать мнение людей, которые посмотрят код программы ...

Оцените консольную игру
Консольная игра, летает самолетик, убивает всякие бяки. Управление: движение - стрелочки стрельба - пробел магазин - 1 вкл./выкл....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru