Консультация № 172284
17.09.2009, 21:33
0.00 руб.
0 2 2
Уважаемые Эксперты помогите написать игру(ну просто очень надо:)), смысл которой состоит в следующем. на игровом поле имеется 16 кнопок, список счетчик и индикатор. При запуске игры (кнопка "новая игра") на кнопки помещаються 16 случайных чисел из диапазона от 0 до 100. Задача состоит в том чтобы за указаное время успеть (пока не заполниться весь индикатор) щелкнуть повсем кнопкам в порядке возростания чисел. При нажатии на кнопку числодолжно добавляться в список только в том случае, если это число являеться следующим по возростанию. Время продолжения игры(в секундах) устанавливаетьяся с помощью счетчика. Заранее Спасибо!!!

Обсуждение

давно
Посетитель
7438
7205
21.09.2009, 01:04
общий
это ответ
Здравствуйте, Каминский Руслан Анатольевич.
Держите программу, раз уж очень надо...
Прикрепленный файл - проект под MSC++ 6.0 (включая файл ресурса, пиктограммку)
Думаю, разберетесь...
Удачи!

Приложение:
#include <windows.h>
#include <Commctrl.h>
#include <time.h>
#include <stdlib.h>
#include "resource.h"

#pragma comment (lib, "Comctl32.lib")

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; //прототипы использованных функций
HWND Do_ProgressBar(HWND, WORD, WORD);
void SetStart(HWND);
int compare(const void *, const void *);

#define DEFAULT_TIME 60 //время по-умолчанию

HINSTANCE hInst;
HWND hStatus, hProgress;
unsigned int iErrors, iTime, iCurrent, iData[16], iDataCurrent;
char *pMessInit = "'Новая игра' - начало игры";
char *pMessContinue = "Ошибок %d. %s";
char *pMessBreak = "Игра прервана. %s";
char *pMessTimeOut = "Вы не успели. %s";
char sText[80];

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd ; //дескриптор (handle) окна
MSG msg ; //структура для анализа сооьщений
WNDCLASSEX wndclass ; //структура для регистрации нашего класса

hInst = hInstance;
wndclass.cbSize = sizeof (wndclass) ; //размер структуры
wndclass.style = CS_HREDRAW | CS_VREDRAW; //стили окна
wndclass.lpfnWndProc = WndProc ; //функция окна
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = DLGWINDOWEXTRA ; //необходимо задать,чтобы задать класс окна диалога в ресурсах
wndclass.hInstance = hInstance ; //handle приложения
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_GAME)) ; //32-битная иконка из ресурсов
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;//стандартный курсор
wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ; //стандартный фон окна (обычно белый)
wndclass.lpszMenuName = NULL ; //меню у нас нет
wndclass.lpszClassName = "GameClass" ; //имя класса
wndclass.hIconSm = wndclass.hIcon; //16-битная иконка (мы задали ту же самую)

RegisterClassEx (&wndclass) ; //регистрируем класс

InitCommonControls() ; //для статуса и прогресса
hwnd = CreateDialog (hInstance, MAKEINTRESOURCE(IDD_GAME), 0, NULL) ; //создаем окно из диалога из ресурсов

SendDlgItemMessage(hwnd, IDC_TIME, EM_SETLIMITTEXT, 4, 0) ; //зададим ограничение на длину числа секунд
SetDlgItemInt(hwnd, IDC_TIME, DEFAULT_TIME, TRUE); //зададим значение времени

ShowWindow (hwnd, iCmdShow) ; //показываем

while (GetMessage (&msg, NULL, 0, 0)) //цикл обработки сообщений
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;//выход
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
RECT rcStatus, rc;
int i;
BOOL fOk;
char sNum[4];

switch (iMsg)
{
case WM_CREATE:
//создадим статус
hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP,
NULL, hWnd, IDC_STATUS) ;
//увеличим окно на величину статуса
//узнаем размер окна
GetWindowRect(hWnd, &rc);
//размер окна статуса
GetClientRect(hStatus, &rcStatus);
//увеличим окно на величину статуса
SetWindowPos(hWnd, 0, 0, 0, rc.right-rc.left, rc.bottom-rc.top+rcStatus.bottom,
SWP_NOMOVE | SWP_NOZORDER);
//переместим статус вниз экрана
MoveWindow( hStatus,0,0,0,0,TRUE );
//зададим строку приглашения
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)pMessInit);
//проинициализируем генератор псевдослучайных величин
srand((unsigned)time(NULL));
break ;
case WM_COMMAND :
switch(LOWORD(wParam))
{// нажатие на 16 кнопок
case IDC_KEY_0:
case IDC_KEY_1:
case IDC_KEY_2:
case IDC_KEY_3:
case IDC_KEY_4:
case IDC_KEY_5:
case IDC_KEY_6:
case IDC_KEY_7:
case IDC_KEY_8:
case IDC_KEY_9:
case IDC_KEY_10:
case IDC_KEY_11:
case IDC_KEY_12:
case IDC_KEY_13:
case IDC_KEY_14:
case IDC_KEY_15:
if (hProgress) //работают только в начавшейся игре
{
//проверим на совпадение кода с кнопки с ожидаемым числом
if (iData[iDataCurrent] == GetDlgItemInt(hWnd, LOWORD(wParam), &fOk, FALSE))
{ //равно! добавим к строке, выводимой в список
itoa(iData[iDataCurrent++], sNum, 10);
if (sText[0])
lstrcat(sText,"\r\n");
lstrcat(sText,sNum);
SetDlgItemText(hWnd, IDC_LIST, sText);
//прокрутим, чтобы введенная строка была видна в конце списка
SendDlgItemMessage(hWnd, IDC_LIST, EM_SCROLL, SB_PAGEDOWN, 0);
if (iDataCurrent == 16) //прошли все?
{ //да!
SetStart(hWnd); //сброс режима
//вывод сообщения с числом ошибок попадания
wsprintf(sText, pMessContinue, iErrors, pMessInit);
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)sText);
}
}
else
{ //увы, промазали...
iErrors++; //считаем ошибки
//штраф - уменьшим на 1 секунду оставшееся время!!!
SendMessage(hWnd, WM_TIMER , 1, 0);
}
}
break;
case IDC_START:
//кнопка начала (прерывания) игры
if (hProgress) //если идет игра
{
SetStart(hWnd); //сброс режимов
//вывод сообщения
wsprintf(sText, pMessBreak, pMessInit);
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)sText);
}
else //стартуем
{
//генерируем псевдослучайные числа (могут быть одинаковые)
for (i=0; i<16; i++)
{
//запоминаем в массиве iData для удобства сравнения н совпадение
itoa(iData[i]=rand() % 101, sNum, 10);
//выведем на кнопки
SetDlgItemText(hWnd, IDC_KEY_0+i, sNum);
}
//отсортируем массив iData по возрастанию!!!
// iData сейчас определяет ожидаемую последовательность нажатий
qsort(iData, 16, sizeof(int), compare);
sText[0] = 0; //сбросим строку вывода в редактор

//получим время
iTime = GetDlgItemInt(hWnd, IDC_TIME, &fOk, FALSE);
if (0==iTime) //если пусто или 0, то ставим по-умолчанию
SetDlgItemInt(hWnd, IDC_TIME, iTime=DEFAULT_TIME, TRUE);
iErrors = iDataCurrent = iCurrent = 0; //сбрасываем все счетчики
EnableWindow(GetDlgItem(hWnd, IDC_TIME), FALSE); //запретим изменение времени
SetDlgItemText(hWnd, IDC_START, "Стоп"); //поменяем надпись на кнопке "Начало игры"
SetDlgItemText(hWnd, IDC_LIST, sText); //сбросим список
//создадим прогресс-бар в статусе
hProgress = Do_ProgressBar(hStatus, (WORD)IDC_PROGRESS, (WORD)(iTime-1));
//запускаем таймер на 1 сек
SetTimer(hWnd, 1, 1000, NULL);
}
break;
}
break;
case WM_TIMER: //каждую секунду
if (iCurrent == iTime) //досчитали до конца выделенного времени - Тайм-аут!
{
SetStart(hWnd); //сбрасываем режимы
//выводим сообщение
wsprintf(sText, pMessTimeOut, pMessInit);
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)sText);
}
else //меняем позицию прогресс-бара
SendMessage(hProgress, PBM_SETPOS , ++iCurrent, 0);
break;
case WM_DESTROY : //сюда попадем по нажатию "крестика"
if (hProgress)
DestroyWindow(hProgress); //если вдруг выходим в процессе игры
PostQuitMessage (0) ; //посылка сообщения, по которому произойдет выход из
break ; // цикла обработки сообщений и выход из программы
default:
return DefWindowProc (hWnd, iMsg, wParam, lParam) ; //все остальные сообщения обрабатываются стандартным образом
}
return 0 ;
}

// Функция создания прогресс-бара
// Параметры:
// HWND hWndParent - окно родителя
// WORD wID - идентификатор окна
// WORD wRange - верхняя граница прогресс-бара

HWND Do_ProgressBar(HWND hWndParent, WORD wID, WORD wRange )
{
int iBorders[3] ;
HWND hWndProgress ;
RECT Rct ;

//определим размеры окна родителя
GetWindowRect( hWndParent, &Rct ) ;

//определим размеры границ родителя
SendMessage(hWndParent, SB_GETBORDERS, 0, (LPARAM)&iBorders);

//создаем прогресс-бар
hWndProgress = CreateWindowEx ( 0L,
PROGRESS_CLASS,
"",
WS_CHILD | WS_VISIBLE,
iBorders[0], //начало x - ширина бордера
iBorders[1], //начало y - высота бордера
Rct.right - Rct.left - 2*iBorders[0], //длина
Rct.bottom - Rct.top - 2*iBorders[1], //высота
hWndParent, //родитель
(HMENU)wID, //ID прогресса
hInst, //handle приложения
NULL ) ;

//зададим цвет ползунка прогресса
SendMessage(hWndProgress, PBM_SETBARCOLOR, 0, (LPARAM)RGB(0x80,0xc0,0x80));
//зададим верхнюю границу прогресса
SendMessage(hWndProgress, PBM_SETRANGE, 0, MAKELPARAM(0, wRange));
return (hWndProgress);
} // end of Do_ProgressBar()

//сброс режимов
void SetStart(HWND hWnd)
{
//восстанавливаем надпись на кнопке
SetDlgItemText(hWnd, IDC_START, "Новая игра");
//разрешаем редактирование времени
EnableWindow(GetDlgItem(hWnd, IDC_TIME), TRUE);
//уничтожаем прогресс
DestroyWindow(hProgress);
hProgress = NULL;
//останавливаем таймер
KillTimer(hWnd, 1);
}

//функция сравнения для сортировки
int compare(const void * elem1, const void * elem2)
{
if (*((int*)elem1) < *((int*)elem2))
return -1;
else if (*((int*)elem1) > *((int*)elem2))
return 1;
else
return 0;
}
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
21.09.2009, 01:04
общий
это ответ
Здравствуйте, Каминский Руслан Анатольевич.
Держите программу, раз уж очень надо...
Прикрепленный файл - проект под MSC++ 6.0 (включая файл ресурса, пиктограммку)
Думаю, разберетесь...
Удачи!

Приложение:
#include <windows.h>
#include <Commctrl.h>
#include <time.h>
#include <stdlib.h>
#include "resource.h"

#pragma comment (lib, "Comctl32.lib")

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; //прототипы использованных функций
HWND Do_ProgressBar(HWND, WORD, WORD);
void SetStart(HWND);
int compare(const void *, const void *);

#define DEFAULT_TIME 60 //время по-умолчанию

HINSTANCE hInst;
HWND hStatus, hProgress;
unsigned int iErrors, iTime, iCurrent, iData[16], iDataCurrent;
char *pMessInit = "'Новая игра' - начало игры";
char *pMessContinue = "Ошибок %d. %s";
char *pMessBreak = "Игра прервана. %s";
char *pMessTimeOut = "Вы не успели. %s";
char sText[80];

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd ; //дескриптор (handle) окна
MSG msg ; //структура для анализа сооьщений
WNDCLASSEX wndclass ; //структура для регистрации нашего класса

hInst = hInstance;
wndclass.cbSize = sizeof (wndclass) ; //размер структуры
wndclass.style = CS_HREDRAW | CS_VREDRAW; //стили окна
wndclass.lpfnWndProc = WndProc ; //функция окна
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = DLGWINDOWEXTRA ; //необходимо задать,чтобы задать класс окна диалога в ресурсах
wndclass.hInstance = hInstance ; //handle приложения
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_GAME)) ; //32-битная иконка из ресурсов
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;//стандартный курсор
wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ; //стандартный фон окна (обычно белый)
wndclass.lpszMenuName = NULL ; //меню у нас нет
wndclass.lpszClassName = "GameClass" ; //имя класса
wndclass.hIconSm = wndclass.hIcon; //16-битная иконка (мы задали ту же самую)

RegisterClassEx (&wndclass) ; //регистрируем класс

InitCommonControls() ; //для статуса и прогресса
hwnd = CreateDialog (hInstance, MAKEINTRESOURCE(IDD_GAME), 0, NULL) ; //создаем окно из диалога из ресурсов

SendDlgItemMessage(hwnd, IDC_TIME, EM_SETLIMITTEXT, 4, 0) ; //зададим ограничение на длину числа секунд
SetDlgItemInt(hwnd, IDC_TIME, DEFAULT_TIME, TRUE); //зададим значение времени

ShowWindow (hwnd, iCmdShow) ; //показываем

while (GetMessage (&msg, NULL, 0, 0)) //цикл обработки сообщений
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;//выход
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
RECT rcStatus, rc;
int i;
BOOL fOk;
char sNum[4];

switch (iMsg)
{
case WM_CREATE:
//создадим статус
hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP,
NULL, hWnd, IDC_STATUS) ;
//увеличим окно на величину статуса
//узнаем размер окна
GetWindowRect(hWnd, &rc);
//размер окна статуса
GetClientRect(hStatus, &rcStatus);
//увеличим окно на величину статуса
SetWindowPos(hWnd, 0, 0, 0, rc.right-rc.left, rc.bottom-rc.top+rcStatus.bottom,
SWP_NOMOVE | SWP_NOZORDER);
//переместим статус вниз экрана
MoveWindow( hStatus,0,0,0,0,TRUE );
//зададим строку приглашения
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)pMessInit);
//проинициализируем генератор псевдослучайных величин
srand((unsigned)time(NULL));
break ;
case WM_COMMAND :
switch(LOWORD(wParam))
{// нажатие на 16 кнопок
case IDC_KEY_0:
case IDC_KEY_1:
case IDC_KEY_2:
case IDC_KEY_3:
case IDC_KEY_4:
case IDC_KEY_5:
case IDC_KEY_6:
case IDC_KEY_7:
case IDC_KEY_8:
case IDC_KEY_9:
case IDC_KEY_10:
case IDC_KEY_11:
case IDC_KEY_12:
case IDC_KEY_13:
case IDC_KEY_14:
case IDC_KEY_15:
if (hProgress) //работают только в начавшейся игре
{
//проверим на совпадение кода с кнопки с ожидаемым числом
if (iData[iDataCurrent] == GetDlgItemInt(hWnd, LOWORD(wParam), &fOk, FALSE))
{ //равно! добавим к строке, выводимой в список
itoa(iData[iDataCurrent++], sNum, 10);
if (sText[0])
lstrcat(sText,"\r\n");
lstrcat(sText,sNum);
SetDlgItemText(hWnd, IDC_LIST, sText);
//прокрутим, чтобы введенная строка была видна в конце списка
SendDlgItemMessage(hWnd, IDC_LIST, EM_SCROLL, SB_PAGEDOWN, 0);
if (iDataCurrent == 16) //прошли все?
{ //да!
SetStart(hWnd); //сброс режима
//вывод сообщения с числом ошибок попадания
wsprintf(sText, pMessContinue, iErrors, pMessInit);
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)sText);
}
}
else
{ //увы, промазали...
iErrors++; //считаем ошибки
//штраф - уменьшим на 1 секунду оставшееся время!!!
SendMessage(hWnd, WM_TIMER , 1, 0);
}
}
break;
case IDC_START:
//кнопка начала (прерывания) игры
if (hProgress) //если идет игра
{
SetStart(hWnd); //сброс режимов
//вывод сообщения
wsprintf(sText, pMessBreak, pMessInit);
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)sText);
}
else //стартуем
{
//генерируем псевдослучайные числа (могут быть одинаковые)
for (i=0; i<16; i++)
{
//запоминаем в массиве iData для удобства сравнения н совпадение
itoa(iData[i]=rand() % 101, sNum, 10);
//выведем на кнопки
SetDlgItemText(hWnd, IDC_KEY_0+i, sNum);
}
//отсортируем массив iData по возрастанию!!!
// iData сейчас определяет ожидаемую последовательность нажатий
qsort(iData, 16, sizeof(int), compare);
sText[0] = 0; //сбросим строку вывода в редактор

//получим время
iTime = GetDlgItemInt(hWnd, IDC_TIME, &fOk, FALSE);
if (0==iTime) //если пусто или 0, то ставим по-умолчанию
SetDlgItemInt(hWnd, IDC_TIME, iTime=DEFAULT_TIME, TRUE);
iErrors = iDataCurrent = iCurrent = 0; //сбрасываем все счетчики
EnableWindow(GetDlgItem(hWnd, IDC_TIME), FALSE); //запретим изменение времени
SetDlgItemText(hWnd, IDC_START, "Стоп"); //поменяем надпись на кнопке "Начало игры"
SetDlgItemText(hWnd, IDC_LIST, sText); //сбросим список
//создадим прогресс-бар в статусе
hProgress = Do_ProgressBar(hStatus, (WORD)IDC_PROGRESS, (WORD)(iTime-1));
//запускаем таймер на 1 сек
SetTimer(hWnd, 1, 1000, NULL);
}
break;
}
break;
case WM_TIMER: //каждую секунду
if (iCurrent == iTime) //досчитали до конца выделенного времени - Тайм-аут!
{
SetStart(hWnd); //сбрасываем режимы
//выводим сообщение
wsprintf(sText, pMessTimeOut, pMessInit);
SendMessage(hStatus, SB_SETTEXT, (WPARAM) 0, (LPARAM)sText);
}
else //меняем позицию прогресс-бара
SendMessage(hProgress, PBM_SETPOS , ++iCurrent, 0);
break;
case WM_DESTROY : //сюда попадем по нажатию "крестика"
if (hProgress)
DestroyWindow(hProgress); //если вдруг выходим в процессе игры
PostQuitMessage (0) ; //посылка сообщения, по которому произойдет выход из
break ; // цикла обработки сообщений и выход из программы
default:
return DefWindowProc (hWnd, iMsg, wParam, lParam) ; //все остальные сообщения обрабатываются стандартным образом
}
return 0 ;
}

// Функция создания прогресс-бара
// Параметры:
// HWND hWndParent - окно родителя
// WORD wID - идентификатор окна
// WORD wRange - верхняя граница прогресс-бара

HWND Do_ProgressBar(HWND hWndParent, WORD wID, WORD wRange )
{
int iBorders[3] ;
HWND hWndProgress ;
RECT Rct ;

//определим размеры окна родителя
GetWindowRect( hWndParent, &Rct ) ;

//определим размеры границ родителя
SendMessage(hWndParent, SB_GETBORDERS, 0, (LPARAM)&iBorders);

//создаем прогресс-бар
hWndProgress = CreateWindowEx ( 0L,
PROGRESS_CLASS,
"",
WS_CHILD | WS_VISIBLE,
iBorders[0], //начало x - ширина бордера
iBorders[1], //начало y - высота бордера
Rct.right - Rct.left - 2*iBorders[0], //длина
Rct.bottom - Rct.top - 2*iBorders[1], //высота
hWndParent, //родитель
(HMENU)wID, //ID прогресса
hInst, //handle приложения
NULL ) ;

//зададим цвет ползунка прогресса
SendMessage(hWndProgress, PBM_SETBARCOLOR, 0, (LPARAM)RGB(0x80,0xc0,0x80));
//зададим верхнюю границу прогресса
SendMessage(hWndProgress, PBM_SETRANGE, 0, MAKELPARAM(0, wRange));
return (hWndProgress);
} // end of Do_ProgressBar()

//сброс режимов
void SetStart(HWND hWnd)
{
//восстанавливаем надпись на кнопке
SetDlgItemText(hWnd, IDC_START, "Новая игра");
//разрешаем редактирование времени
EnableWindow(GetDlgItem(hWnd, IDC_TIME), TRUE);
//уничтожаем прогресс
DestroyWindow(hProgress);
hProgress = NULL;
//останавливаем таймер
KillTimer(hWnd, 1);
}

//функция сравнения для сортировки
int compare(const void * elem1, const void * elem2)
{
if (*((int*)elem1) < *((int*)elem2))
return -1;
else if (*((int*)elem1) > *((int*)elem2))
return 1;
else
return 0;
}
Прикрепленные файлы:
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа