Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10

Винапи с++, суть программы в том, что компьютер угадывает число пользователя. Нужна доработка кода

26.09.2021, 11:11. Показов 2113. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужно написать событие, при которой если пользователь лжет компьютер и всегда нажимает "нет" или "да", то мы видим, что компьютер пишет, к примеру,"Вы обманываете":

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
#include <windows.h>
#include <tchar.h>
#define  APPNAME    _T("LabWork1")
#define  APPCLS     _T("Nuklon")
#define  IDC_SMALL  100
#define  IDC_BIG    101
#define  IDC_ANSWER 102
#define  _creatButton(name, id, x, y) \
CreateWindow(_T("BUTTON"), name, WS_CHILD | BS_USERBUTTON | WS_VISIBLE,\
x, y, 200, 60, hwnd, (HMENU)id, (HINSTANCE)lParam, NULL)
//////////////////////////////////////////////////////////
LRESULT CALLBACK  _wndProc(HWND, UINT, WPARAM, LPARAM);
int   _creatWindow(HINSTANCE, const TCHAR*);
void  _helloDlg(HWND, int, int);
void  _answerCPU(HWND, int, int, char);
/// /////////////////////////////////////////////////////
int  f_n = 1;
int  l_n = 1000;
//////////////////////////////////////////////////////////
int WINAPI  _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int) { return _creatWindow(hInstance, _T("LabWork1. Less or more?"));}
///////////////////////ОКНО//////////////////////
int  _creatWindow(HINSTANCE hInst, const TCHAR* caption) {
    HWND hwnd = NULL;
    MSG  msg = { 0 };
    WNDCLASS ofs = {
          0, _wndProc, 0, 0,  hInst, 0, LoadCursor(NULL, IDC_ARROW),
         (HBRUSH)(COLOR_WINDOW + 2), 0, APPCLS };
    if (!RegisterClass(&ofs))
        return 1;
    hwnd = CreateWindow(APPCLS, caption, WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_DESKTOP,
        NULL, hInst, hInst);
    if (hwnd == NULL) {
        UnregisterClass(APPCLS, hInst);
        return 1;}
    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);}
    return 0;}
////////////////////////////////////////////////////////
LRESULT CALLBACK _wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    static HWND bbig = NULL;
    static HWND bsmall = NULL;
    RECT  rc;
    switch (msg) {
    case WM_CREATE:
        GetClientRect(hwnd, &rc);
        bsmall = _creatButton(_T("МЕНЬШЕ"), IDC_SMALL, rc.right / 10 + 350, rc.bottom / 2 + 30);
        bbig = _creatButton(_T("БОЛЬШЕ"), IDC_BIG, rc.right / 10 + 350, rc.bottom / 2 - 40);
        SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_ANSWER, 0), 0);
        break;
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDC_SMALL:
            _answerCPU(hwnd, f_n, l_n, '<');
            break;
        case IDC_BIG:
            _answerCPU(hwnd, f_n, l_n, '>');
            break;
        case IDC_ANSWER:  
            _helloDlg(hwnd, f_n, l_n);
            _answerCPU(hwnd, f_n, l_n, 0);
            break;
        }
        break;
    case WM_DESTROY:
        DestroyWindow(bsmall);
        DestroyWindow(bbig);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);}
    return 0;}
////////////////////НАЧАЛО/////////////////////////////////
void  _helloDlg(HWND hwnd, int f, int l) {
    TCHAR buf[64];
    wsprintf(buf, _T("Для начала игры задумайте число от %d до %d"), f, l);
    MessageBox(hwnd, buf, APPNAME, MB_OK | MB_ICONINFORMATION);
}
///////////////////////////////////////////////////////
void  _answerCPU(HWND hwnd, int _f, int _l, char ch) {
    static int f = _f;
    static int l = _l;
    static int num = 0;
    TCHAR buf[64];
    int   id;
 
    switch (ch) {
    case '<':  // МЕНЬШЕ
        l = num;
        break;
    case '>':  // БОЛЬШЕ
        f = num + 1;
        break;
    }
    num = (f + l) / 2; 
 
    wsprintf(buf, _T("Загаданным числом является %d. Да/Нет?"), num);
    id = MessageBox(hwnd, buf, APPNAME, MB_YESNO | MB_ICONQUESTION);
    if (id != IDYES)
        return;
    
 
    wsprintf(buf, _T("Получилось! Ваше число %d"), num);
 
    id = MessageBox(hwnd, buf, APPNAME, MB_OKCANCEL | MB_ICONINFORMATION);
    if (id == IDCANCEL) 
        SendMessage(hwnd, WM_DESTROY, 0, 0);
    else { 
        f = _f;
        l = _l;
        SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_ANSWER, 0), 0);
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.09.2021, 11:11
Ответы с готовыми решениями:

Компьютер угадывает число
Здравствуйте. Задание: Человек загадывает целое число, а компьютер его угадывает. Понятно, что он будет использоваться бинарный поиск. ...

Компьютер угадывает число
Пользователь загадывает число от 1 до 100 и компьютер пытается угадать. На каждую попытку компьютера пользователь отвечает, больше (h)...

Компьютер угадывает число
Пользователь “загадывает” число oт 1 дo Х-1, а компьютер должен его отгадать. Подсчитать количество неправильных попыток угадывания. x =...

19
 Аватар для Nishen
1358 / 856 / 366
Регистрация: 26.02.2015
Сообщений: 3,814
26.09.2021, 11:56
Можешь яснее описать то, что нужно сделать?
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
26.09.2021, 12:08  [ТС]
В программе числа больше, но пример будет следующим в пределах 1 до 10:
Компьютер: Ваше число 5?
Пользователь: Нет
К: Больше или меньше?
П: Больше (Меньше)
По ответам пользователя доходит до верхнего (10) или нижнего (1) числа. НО! Компьютер продолжает спрашивать, к примеру,: "Ваше число 1?". Пользователь задумал постоянно отвечать, что число не то. И ТУТ! Программа должна после такой попытки пользователя "подурачиться" вывести: "Ты обманываешь", "Вы точно загадали число?"
0
 Аватар для Morgot
336 / 129 / 18
Регистрация: 26.12.2010
Сообщений: 501
26.09.2021, 16:24
Цитата Сообщение от Devochka123 Посмотреть сообщение
Пользователь задумал постоянно отвечать, что число не то. И ТУТ! Программа должна после такой попытки пользователя "подурачиться" вывести: "Ты обманываешь", "Вы точно загадали число?"
Вы хотите реализовать ИИ в 10 строках винапи? Или когда именно компьютер должен спрашивать такое, после второго-третьего (какого?) "нет"?
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
26.09.2021, 18:02  [ТС]
Когда дошло до верхней (как в примере, 10) или нижней (1) границе, то после 3 попытки пользователя, который вовсе не загадывал число, а хочет проверить, что будет если отвечать постоянно НЕТ, выводить текст "Вы точно загадали число?"
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
27.09.2021, 01:21
Цитата Сообщение от Devochka123 Посмотреть сообщение
Когда дошло до верхней (как в примере, 10) или нижней (1) границе,
В норме процесс поиска числа вовсе не обязан дойти до какой-то из границ, так как он должен сходиться к задуманному числу. А вопрос нужно задавать, когда l и f уже "сошлись в точку", а пользователь в ответ на предложение ему единственно возможно числа ответил "Нет".

Но есть нюанс: логика в функции _answerCPU() такова, что независимо от ответов пользователя выбор следующего претендента всегда идёт вниз, к нулю. Поэтому есть немалый риск, что даже при правильных ответах программа число не найдёт.
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
27.09.2021, 01:42  [ТС]
Пробовала сделать условия, но они лишь сбивают счет либо не влияют
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
27.09.2021, 01:59
Судя по:
Цитата Сообщение от Devochka123 Посмотреть сообщение
num = (f + l) / 2;
задумывалось сделать поиск дихотомией. Но вот это обнуление num в самом начале:
Цитата Сообщение от Devochka123 Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
10
11
12
static int f = _f;
static int l = _l;
static int num = 0;
switch (ch) {
    case '<': // МЕНЬШЕ
        l = num;
        break;
    case '>': // БОЛЬШЕ
        f = num + 1;
        break;
}
num = (f + l) / 2;
портит всю идею.
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
27.09.2021, 02:07  [ТС]
В изучении не дошла до таких строчек кода: static int num = 0; Не совсем понимаю
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
27.09.2021, 02:14
А кто всю эту женскую логику в _answerCPU() придумывал и писал? Не Вы?

Или по другому зайдём: что такое метод половинного деления (дихотомия) и как он работает - знаете?
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
27.09.2021, 02:20  [ТС]
У меня проще вариант был, но не такой действенный как предполагался. Половинное деление только было видно в литературе, дихотомия пока не встречалась. Была идея рандомом число искать, будет ли им легче реализовать? По результату моих попыток внедрить, получается, что я неправильно поняла, что за B и как программе не выдавать ошибку при следующем выражении [B]num
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
27.09.2021, 02:28
Цитата Сообщение от Devochka123 Посмотреть сообщение
Половинное деление только было видно в литературе, дихотомия пока не встречалась.
Это одно и то же.

Цитата Сообщение от Devochka123 Посмотреть сообщение
Была идея рандомом число искать, будет ли им легче реализовать?
В C/C++ - однозначно нет, потому что нужно же как-то хранить уже сделанные и отвергнутые предположения и при выборе нового сверяться с ними, чтобы не повторяться, а эти языки удобных средств для этого не дают.
И в любом языке - это менее эффективно.

Цитата Сообщение от Devochka123 Посмотреть сообщение
По результату моих попыток внедрить, получается, что я неправильно поняла, что за B и как программе не выдавать ошибку
Для начала пробуйте здесь сформулировать (словами) алгоритм поиска задуманного числа методом половинного деления.
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
27.09.2021, 02:47  [ТС]
Я понимаю этот метод следующим образом: начинается с наших границ (1 и 1000), число делится на половину и так мы сокращаем этот интервал, в зависимости от ответа пользователя (больше/меньше), число 500 станет нижней/верхней границей и так далее. Когда дело доходит до конечного числа, то программа спросит оно ли, ЗДЕСЬ ЖЕ проблема, что оно не уведомляет пользователя, что все числа уже перебраны, иначе пользователь уже нажал бы Да. И в другие классы бы пошел "сигнал" о том, что поиск удался
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
27.09.2021, 04:00
Цитата Сообщение от Devochka123 Посмотреть сообщение
Я понимаю этот метод следующим образом: начинается с наших границ (1 и 1000), число делится на половину и так мы сокращаем этот интервал, в зависимости от ответа пользователя (больше/меньше), число 500 станет нижней/верхней границей и так далее.
Всё правильно. В первом сообщении в коде f - текущее значение нижней границы, l - текущее значение верхней границы. Их середина num = (f + l) / 2 показывается пользователю. если он говорит, что не угадали, то в зависимости от его ответа про больше-меньше ему на следующем круге предлагается или середина отрезка от f до num, или середина отрезка от num до l (вычисляемая с учётом того, что это целочисленная математика, т.е. если результат деления не целый, то он преобразуется в целое число путём отбрасывания того, что стоит после запятой).

Цитата Сообщение от Devochka123 Посмотреть сообщение
Когда дело доходит до конечного числа, то программа спросит оно ли, ЗДЕСЬ ЖЕ проблема, что оно не уведомляет пользователя, что все числа уже перебраны, иначе пользователь уже нажал бы Да.
А представьте, что по ходу игры отрезок сократился до [1..4], и попробуйте с карандашом и бумагой проиграть дальнейший ход событий в Вашей программе в зависимости от ответов пользователя, который всегда говорит "Нет" (даже когда ему показывают единственно возможное число). Вы увидите, что в конце-концов неизбежно получите ответ "Нет" в ситуации, когда num == l и f == l. Это и будет критерием того, что пора показывать окошко "Вы обманываете".
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
27.09.2021, 23:46  [ТС]
Да, я поняла о чем вы. Такая попытка была, но у меня сбился подсчет и последовательность вывода окон

Добавлено через 34 секунды
Пыталась при помощи if. Может он неудачен для винапи и в данном коде?
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
28.09.2021, 02:02
Цитата Сообщение от Devochka123 Посмотреть сообщение
Такая попытка была, но у меня сбился подсчет и последовательность вывода окон
А ничего и не нужно подсчитывать. Сейчас интерфейс программы, насколько я понимаю, такой: есть главное окно, в котором имеются только кнопки "МЕНЬШЕ"-"БОЛЬШЕ"; перед ним выскакивает окошко сообщения с числом-кандидатом и двумя кнопками: "Да"-"Нет." После нажатия на "Да" программа громко радуется и закрывается, а после нажатия на "Нет" сообщение исчезает и перед глазами пользователя остаётся окно, в котором кнопки "МЕНЬШЕ"-"БОЛЬШЕ" и ничего больше. (Для чего эти кнопки предназначены, поди догадайся.) После нажатия на любую из этих кнопок опять появляется сообщение с новым кандидатом, и всё повторяется.

А что нужно делать после показа сообщения "Вы обманываете"? Закрыть программу? Ладно, смотрим. Код функции _answerCPU() начинается с:
Цитата Сообщение от Devochka123 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
switch (ch) {
case '<':  // МЕНЬШЕ
    l = num;
    break;
case '>':  // БОЛЬШЕ
    f = num + 1;
    break;
}
Допустим, пользователь стабильно врёт, мы уже добрались до последнего возможного кандидата, показали его, получили ответ "Нет", закрыли сообщение, вывалились из _answerCPU() в цикл обработки сообщений окна и теперь ждём нажатия на какую-нибудь большую кнопку, уже зная, что в данном случае любой ответ - ложь.
Пользователь нажимает кнопку, программа попадает в ветку case WM_COMMAND:, оттуда вызывается _answerCPU(), а нам уже безразлично, что он там нажал, мы просто перед switch (ch) вставляем проверку:
C++
1
2
3
4
5
6
if (f == l) {
    MessageBox(hwnd, "Вы обманываете", APPNAME, MB_OK | MB_ICONEXCLAMATION);
    SendMessage(hwnd, WM_DESTROY, 0, 0);
}
switch (ch) {
...
Здесь даже значением num можно не интересоваться, потому что если при вызове _answerCPU() значения переменных f и l равны, то и num заведомо равна тому же.

"По-моему, так".

Добавлено через 31 минуту
Цитата Сообщение от Devochka123 Посмотреть сообщение
Пыталась при помощи if. Может он неудачен для винапи и в данном коде?
WinAPI - это просто набор функций. Функции эти с точки зрения языка программирования ничем не отличаются от любых других функций и поэтому совместимы с любыми языковыми конструкциями.
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
28.09.2021, 09:41  [ТС]
Спасибо вышло, только в скрине ниже возникает необработанное исключение
Миниатюры
Винапи с++, суть программы в том, что компьютер угадывает число пользователя. Нужна доработка кода  
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
28.09.2021, 10:06
В какой момент (после какого действия) возникает?
0
0 / 0 / 0
Регистрация: 04.05.2020
Сообщений: 10
28.09.2021, 10:10  [ТС]
После того, как в образованном окне мы нажимаем ОК или крестик (закрыть окошко), то постоянно мигает большое окно
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
28.09.2021, 11:19
Чукча не писатель на C/C++ и даже читатель только по складам (лишь с третьего раза вспомнил, что такое "static int f"), поэтому "с листа" сообразить, что происходит, не могу, а машина с компилятором (и, главное, отладчиком) C++ мне сейчас недоступна и когда станет доступна неизвестно (всем отделом ждём этого события).

Попробуйте с помощью Spy++ посмотреть, какие события (за исключением мышиных) валятся в главное окно программы во время его мигания.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.09.2021, 11:19
Помогаю со студенческими работами здесь

Написать программу, в которой задается число, а компьютер его угадывает
помогите пожалуйста, написать программу, в которой я задаю число, а компьютер угадывает это число. количество попыток ограничено ?

Компьютер угадывает число. Задача решена, как считаете? (вектор и цикл)
Компьютер должен угадать задуманное пользователем число с 7-ми попыток. Хотел написать с использованием циклов, а не просто перебором...

Суть проблемы в том, что график не появляется
суть проблемы в том, что график не появляется и пишет, что &quot;значение должно быть скалярной или матричной&quot; ...

Напишите программу "Угадай число", но здесь компьютер угадывает ваше число
Напишите программу &quot;Угадай число&quot;, но здесь компьютер угадывает ваше число. Желательно, чтобы в выводе писали, сколько попыток потратил...

"Угадай Число", где угадывает компьютер
Привет, у меня проблема. По идее, все предельно просто и поиск загаданного числа осуществляется с помощью метода Хартли, но я не могу...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
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
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru