LuckyELF
Newbie | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <graphics.h> #include <string.h> #include <bios.h> // Макроопределения кодов клавиш #define ESC 283 #define F1 15104 #define ENTER 7181 #define UP 18432 #define DOWN 20480 #define LEFT 19200 #define RIGHT 19712 // Макрос вычисления адреса элемента в массиве #define ITEM(Y,X,SIZE_X) (Y*SIZE_X + X) // Размерность матрицы 7х8 #define ARRAY_SIZE_X 8 #define ARRAY_SIZE_Y 7 // Кол-во буферов (частей) заставки #define IMG_BUF_COUNT 12 // --------------------------------------------------------------------------- // Псевдографика для обрамления окошек const char *LineG = {" ─═"}; const char *LineV = {" │║"}; const char *LeftUp = {" ┌╔"}; const char *RightUp = {" ┐╗"}; const char *LeftDown = {" └╚"}; const char *RightDown = {" ┘╝"}; // Пункты меню // Главное меню const char *MainMenuItems[] = {" Файл ", " Обработка ", " Справка "}; // Меню файл const char *FileMenuItems[] = {" Загрузить данные ", " Сохранить данные ", " Ввод исходных данных ", " Редактирование данных ", " Заполнить случайными ", " Вывод результатов ", " Выход из программы "}; // Меню помощь const char *HelpMenuItems[] = {" Руководство пользователя ", " Об авторах ... "}; const UserGuideCount = 6; // Кол-во страниц в руководстве пользоваетеля // Текст руководства пользователя const char *UserGuideText[] = { " Данные программный продукт предназначен для\r\n" "обработки матриц.\r\n" " Программа способна выполнять следующие функции:\r\n" " 1. Формировать массив из модулей произведений " "отрицательных элементов каждой строки; если таких" "элементов в строке нет, результат будет = 0.\r\n" " 2. Определять сумму произведений сформированного" "массива и общее количество отрицательных\r\n" "элементов строк.", " 3. Определять минимальное и максимальное\r\n" "значения произведений и менять местами строки\r\n" "исходной матрицы, в которых они найдены.\r\n" " Исходные данные могут быть введены как\r\n" "с клавиатуры так и из файла, результат\r\n" "также может быть сохранен в файл.\r\n" " Меню файл - данное меню предоставляет\r\n" "набор операций по вводу исходных данных.\r\n", " Загрузить данные - данная опция\r\n" "позволяет загрузить данные из файла,\r\n" "при ее выборе программа просит ввести\r\n" "имя загружаемого файла.\r\n" " Сохранить данные - данная опция меню\r\n" "позволяет сохранить исходный набор\r\n" "данных в файле, для их последующего\r\n" "использования. Для сохранения необходимо\r\n" "ввести имя файла.\r\n", " Ввод исходных данных - данный пункт меню\r\n" "позволяет ввести данные с клавиатуры в режиме\r\n" "диалога с пользователем.\r\n" " Редактирование данных - данная опрция меню\r\n" "позволяет отредактировать ранее введенные или\r\n" "загруженные данные.\r\n" " Заполнить случайными - программа производит\r\n" "автозаполнение матрицы случайными числами.\r\n", " Вывод результатов - данный пункт меню\r\n" "позволяет пользователю просмотреть результаты\r\n" "работы программы.\r\n" "\r\n" " Выход из программы - данные пункт меню\r\n" "завершает работу программы и возвращает\r\n" "управление ОС.\r\n", " Меню обработка. Данное меню позволяет\r\n" "выполнять функции над матрицей. Краткое\r\n" "описание всех функций дано выше.\r\n" " Меню справка позволяет получить\r\n" "справочную информацию о программе и\r\n" "ее авторах.\r\n"}; // --------------------------------------------------------------------------- // Определения новых типов typedef unsigned char byte; // байт typedef unsigned int word; // слово // --------------------------------------------------------------------------- // Глобальные переменные // Разрешение экрана в графическом режиме int MaxX, MaxY; // Для хранения Суммы, Мин, Мах, и кол-во отрицательных элементов long gSum, gMin, gMax, gMinus; // Номера строк с Мах и Мин элементами int MinLine, MaxLine; // Матрицы int Matrix1 [ARRAY_SIZE_Y][ARRAY_SIZE_X]; // Исходная int Matrix2 [ARRAY_SIZE_Y][ARRAY_SIZE_X]; // Результирующая long VectorAbs [ARRAY_SIZE_Y]; // Результирующий массив произведений // --------------------------------------------------------------------------- // Описание прототипов функций // Выбирает Мах из двух целых int max(int value1, int value2); // Выбирает Мин из двух целых int min(int value1, int value2); // Рисует окошко в графическом режиме void ShowWindow (int x1, int y1, int x2, int y2, int color); // Рисует кнопку в графическом режиме void ShowKey (int x, int y, int paper, int color, char *text); // Выводит заставку в графическом режиме int SplashScreen (void); // Инициализирует графику void InitGraph (void); // Запролняет экран белыми квадратиками (в точечку) в текстовом режиме void DeskTop (void); // Рисует окошко в текстовом режиме void ShowWin (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder, byte Shadow, byte Color, byte Paper, const char *Title); // Показывает на экране один элемент меню в заданной позиции и заданным цветом void ShowMenuItem (byte xPos, byte yPos, byte Paper, byte Color, const char *Item); // Оконное меню int Menu (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder, byte Shadow, byte Color, byte Paper, byte CursPaper, byte CursColor, const char *Title, int item, const char *Items[], word defaultItem); // Рисует строку внизу экрана и выводит на ней заданный текст // текст заключенный в ~ТЕКСТ~ выводится красным цветом void TaskBar (const char *Text); // Выводит окошко диалога, и считывает с клавиатуры строку с именем файла // считанную строку и возвращает char *GetFileName (byte xPos, byte yPos, byte xSize); // Сохраняет указанную матрицу // *Vector - указатель на матрицу // size_y,size_x размерность матрицы (7,8) void SaveData (int *vector, word size_y, word size_x); // Загружает данные из файла void LoadData (int *vector, word size_y, word size_x); // Рисует один элемент массива в заданных координатах с // указанным цветом и фоном void ShowVectItem (int item, word xPos, word yPos, byte Color, byte Paper); // Для именения элемента int ChangeItem (word x, word y); // Рисует матрицу с возможностью редактирования void ShowMatrix (int *vector, word size_y, word size_x); // Выполняет ввод матрицы void InputMatrix (int *vector, int size_y, int size_x); // Заполняет матрицу случайными числами из диапозона [-50;50] void RandMatrix (int *vector, int size_y, int size_x); // Показывает резутаты работы void ViewResult (int *m_vector, int size_y, int size_x, long *abs_vect, long pMin, long pMax, long pSum, long pMinus, int *m_vect, int nMin, int nMax); // Выполняе решение void CreateAbsVector (int *vector, int size_y, int size_x, long *resVector, long *pMin, long *pMax, long *pSum, long *pMinus, int *r_vect, int *n_Min, int *n_Max); // Главная функция - управляет работой всей программы void AppRun (void); // Выводин информацию о разработчиках void About (void); // Выводит одну страницу руководства пользователя void ShowUserGuide (const char *Text); // Выполняет работу диалога руководство пользователя void UserGuide (void); // Востанавливает часть экрана void RestoreScreen (byte xPos, byte yPos, byte xSize, byte ySize, byte *buf); // Сохраняет часть экрана byte *SaveScreen (byte xPos, byte yPos, byte xSize, byte ySize); // --------------------------------------------------------------------------- // Определения тел функций // Выбирает Мах из двух целых int max(int value1, int value2) { return ( (value1 > value2) ? value1 : value2); } // Выбирает Мин из двух целых int min(int value1, int value2) { return ( (value1 < value2) ? value1 : value2); } // Рисует окошко в графическом режиме void ShowWindow (int x1, int y1, int x2, int y2, int color) { setcolor (DARKGRAY); rectangle (x1,y1,x2,y2); rectangle (x1+3,y1+3,x2-3,y2-3); line (x2,y1,x2-3,y1+3); line (x1,y2,x1+3,y2-3); setfillstyle (1,LIGHTGRAY); floodfill (x1+2,y1+2,DARKGRAY); setfillstyle (1,DARKGRAY); floodfill (x2-2,y2-2,DARKGRAY); setfillstyle (1,color); floodfill (x1+6,y1+6,DARKGRAY); } // Рисует кнопку в графическом режиме void ShowKey (int x, int y, int paper, int color, char *text) { int t = strlen (text); setcolor (DARKGRAY); rectangle (x, y, x + t * 8 + 10, y + 20); rectangle (x + 3, y + 3, x + t * 8 + 7, y + 17); line (x + t * 8 + 10, y, x + t * 8 + 7, y + 13); line (x, y + 20, x + 3, y + 17); setfillstyle (1, LIGHTGRAY); floodfill (x + 2, y + 2, DARKGRAY); setfillstyle (1, DARKGRAY); floodfill (x + t * 8 + 8, y + 18, DARKGRAY); setfillstyle (1, paper); floodfill (x + 6, y + 6, DARKGRAY); settextstyle (0,0,1); setcolor (color); settextjustify(LEFT_TEXT, TOP_TEXT); outtextxy (x + 5, y + 7, text); } // Выводит заставку в графическом режиме int SplashScreen (void) { InitGraph (); randomize (); setactivepage (1); int midx = MaxX / 2; setbkcolor (CYAN); ShowWindow (141, 101, 499, 249, BLUE); ShowKey (160,217,CYAN,BLUE,"F1 - About"); ShowKey (270,217,CYAN,BLUE,"Enter - Run"); ShowKey (390,217,CYAN,BLUE,"ESC - Exit"); setcolor (WHITE); settextstyle (0, HORIZ_DIR, 1); settextjustify(CENTER_TEXT, CENTER_TEXT); setcolor (YELLOW); // Вставить нужный текст outtextxy (midx, 115, "The Matrix v.099"); // Название проги outtextxy (midx, 125, "(C) April 2004"); // Типа Дата создания setcolor (WHITE); outtextxy (midx, 145, "Created by"); // Разработано setcolor (LIGHTCYAN); outtextxy (midx, 165, "Berov Andrey"); // ФИО // outtextxy (midx, 180, "4-4b ISE"); // Курс, группа и т.д. outtextxy (midx, 195, "Kamensk YRGTU 2004"); // Универ и т.д. int step = (500 - 140) / IMG_BUF_COUNT; int img_size = imagesize (140, 100, 140 + step, 250); void *img_buf[IMG_BUF_COUNT]; for (int i = 0; i < IMG_BUF_COUNT; i++) { img_buf[i] = new char [img_size]; if (!img_buf[i]) { printf("Нет свободной памяти! buffer %d, size %d, all size = %d\n", i, img_size, img_size * IMG_BUF_COUNT); bioskey (0); exit (1); } getimage (140+step*i, 100, (140+step)+step*i, 250, img_buf[i]); } setactivepage (0); setbkcolor (CYAN); cleardevice (); for (int y = 100; y >= 0; y--) { for (int i = 0; i < IMG_BUF_COUNT; i++) { if ( i % 2 ) putimage (140+step*i, 100+y, img_buf[i], COPY_PUT); else putimage (140+step*i, 100-y, img_buf[i], COPY_PUT); } } for (int x = 0; x < IMG_BUF_COUNT; x++) delete [] img_buf[x]; setactivepage (1); setbkcolor (CYAN); cleardevice (); ShowWindow (141, 101, 499, 249, MAGENTA); ShowKey (390,217,BLUE,YELLOW,"ESC - Exit"); settextstyle (0, HORIZ_DIR, 1); settextjustify(CENTER_TEXT, CENTER_TEXT); setcolor (YELLOW); // Вставить нужный текст outtextxy (midx, 115, "The Matrix v.099"); // Название проги outtextxy (midx, 125, "(C) April 2004"); // Типа Дата создания setcolor (WHITE); outtextxy (midx, 145, "Демонстрационная программа"); outtextxy (midx, 165, "выполняет работу с массивами данных"); outtextxy (midx, 195, "Kamensk YRGTU 2004"); // Универ и т.д. setactivepage (0); int key; for (;;) { key = bioskey (0); switch (key) { case ESC: restorecrtmode (); return 0; case F1: // Показываеть хелп, он на второй страницы setvisualpage (1); // Переключим на вторую страницу bioskey (0); // Подождем нажатия на кнопку setvisualpage (0); // Вернем первую страницы break; case ENTER: restorecrtmode (); return 1; } } } // Инициализирует графику void InitGraph (void) { // Выбран VGA дривер с 2-мя страницами видео памяти int gdriver = VGA, gmode = VGAMED, errorcode; // При необходимости изменить путь к драйверу (VGAEGA.BGI) initgraph(&gdriver, &gmode, ""); errorcode = graphresult(); if (errorcode != grOk) { printf("Ошибка при работе с графикой: %s\n", grapherrormsg(errorcode)); printf("Нажмите любую клавишу для прекращения работы:"); bioskey (0); exit(1); /* return with error code */ } // Проинициализируем макимальным разрешением экрана MaxX = getmaxx (); MaxY = getmaxy (); } // Запролняет экран белыми квадратиками (в точечку) в текстовом режиме void DeskTop (void) { textcolor (WHITE); // Цвет текста на экране textbackground (BLUE); // Цвет фона экрана _wscroll = 0; for (int y = 1; y <= 25; y++) for (int x = 1; x <= 80; x++) { gotoxy (x,y); cprintf ("▒"); // Заполняем экран этим символом } _wscroll = 1; } // Рисует окошко в текстовом режиме void ShowWin (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder, byte Shadow, byte Color, byte Paper, const char *Title) { // Расчет недостоющих координат int y, x, yEnd = yPos + ySize, xEnd = xPos + xSize; // Установка цвета символов и фона textcolor (Color); textbackground (Paper); // Рисуем квадратик for (y = yPos; y <= yEnd; y++) for (x = xPos; x <= xEnd; x++) { gotoxy (x, y); cprintf (" "); } // Проводим вертикальные линии for (y = yPos; y <= yEnd; y++) { gotoxy (xPos, y); cprintf ("%c", LineV [Bolder]); gotoxy (xEnd, y); cprintf ("%c", LineV [Bolder]); } // Проводим горизонтальные линии for (x = xPos; x <= xEnd; x++) { gotoxy (x, yPos); cprintf ("%c", LineG [Bolder]); gotoxy (x, yEnd); cprintf ("%c", LineG [Bolder]); } // Рисуем уголки окошка gotoxy (xPos, yPos); cprintf ("%c", LeftUp [Bolder]); gotoxy (xPos, yEnd); cprintf ("%c", LeftDown [Bolder]); gotoxy (xEnd, yPos); cprintf ("%c", RightUp [Bolder]); gotoxy (xEnd, yEnd); cprintf ("%c", RightDown [Bolder]); // Если есть надпись, то выведем ее в верху окошка if (Title) { // Расчитаем середину окна int midx = xPos + (xSize / 2) - (strlen (Title) / 2) + xSize % 2; gotoxy (midx, yPos); cprintf ("%s", Title); } // Если окошко должно быть с тень, то нарисуем ее if (Shadow) { int i; word buf_size = xSize * 2 + 1; byte *pbuf; byte *buf = new byte [buf_size]; gettext (xPos + 2, yEnd + 1, xEnd + 2, yEnd + 1, buf); for (pbuf=&buf[1], i=0; i<buf_size; *pbuf=1+2+4, i+=2, pbuf+=2); puttext (xPos + 2, yEnd + 1, xEnd + 2, yEnd + 1, buf); delete [] buf; buf_size = ySize * 2 * 2 + 1; buf = new byte [buf_size]; gettext (xEnd + 1, yPos + 1, xEnd + 2, yEnd, buf); for (pbuf=&buf[1], i=0; i<buf_size; *pbuf=1+2+4, i+=2, pbuf+=2); puttext (xEnd + 1, yPos + 1, xEnd + 2, yEnd, buf); delete [] buf; } } // Показывает на экране один элемент меню в заданной позиции и заданным цветом void ShowMenuItem (byte xPos, byte yPos, byte Paper, byte Color, const char *Item) { textcolor (Color); textbackground (Paper); gotoxy (xPos, yPos); cprintf ("%s", Item); } // Оконное меню int Menu (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder, byte Shadow, byte Color, byte Paper, byte CursPaper, byte CursColor, const char *Title, int item, const char *Items[], word defaultItem) { _setcursortype (_NOCURSOR); // вырубим мигающий курсор // Нарисуем окошко ShowWin (xPos, yPos, xSize, ySize, Bolder, Shadow, Color, Paper, Title); int CurrItem = defaultItem; byte bExit = 1; int key; // Нарисуем все элементы for (int i=0; i < item; i++) ShowMenuItem (xPos+2, yPos+1+i, Paper, Color, Items[i]); // Цикл работы меню while (bExit) { // Рисуем курсор ShowMenuItem (xPos+2, yPos+1+CurrItem, CursPaper, CursColor, Items[CurrItem]); key = bioskey (0); // Опрос клавиатуры // Скрываем выделенный пункт ShowMenuItem (xPos+2, yPos+1+CurrItem, Paper, Color, Items[CurrItem]); // Обрабатываем нажатие клавиш switch (key) { case DOWN: CurrItem++; // нажали вниз if (CurrItem >= item) CurrItem = 0; break; case UP: CurrItem--; // нажали вверх if (CurrItem < 0) CurrItem = item - 1; break; case ESC: CurrItem = -1; // ESCAPE case ENTER: bExit = 0; break; // ENTER } } _setcursortype (_NORMALCURSOR); // Включим курсор return CurrItem; // Вернем номер выбранного пункта (начинается с 0) } // Рисует строку внизу экрана и выводит на ней заданный текст // текст заключенный в ~ТЕКСТ~ выводится красным цветом void TaskBar (const char *Text) { word i = 80; byte color = 0; _wscroll = 0; // Чтобы экран не "убегал" вверх // установим начальную позицию и цвета gotoxy (1,25); textcolor (BLACK); textbackground (WHITE); // Рисуем линию из начальной позиции while (i--) cprintf (" "); // Вывод текста i = 0; gotoxy (1,25); while (Text[i]) { // Если встретили в тексте ~, то переключим цвет if (Text[i] == '~') color = !color; else // Иначе просто выведем очедной символ cprintf ("%c", Text[i]); // Установим цвет в соответсвии с выбранным if (color) textcolor (RED); // Красный else textcolor (BLACK); // Черный i++; // Чтоб перейте к следующему символу в строку } _wscroll = 1; // Включим скролирование экрана } // Выводит окошко диалога, и считывает с клавиатуры строку с именем файла // считанную строку и возвращает char *GetFileName (byte xPos, byte yPos, byte xSize) { // Запомним кусочек экрана под окошком byte *buf = SaveScreen (xPos, yPos, xSize + 2, 2 + 1); char str[255], param[25], sparam[50] = {"%"}; ShowWin (xPos, yPos, xSize, 2, 1, 1, LIGHTCYAN, BLUE, " Укажите имя файла "); gotoxy (xPos+1, yPos+1); itoa(xSize, param, 10); strcat (sparam, param); strcat (sparam, "s"); scanf (sparam, str); // Востановим испорченный кусочек экрана RestoreScreen (xPos, yPos, xSize + 2, 2 + 1, buf); return str; } // Сохраняет указанную матрицу // *Vector - указатель на матрицу // size_y,size_x размерность матрицы (7,8) void SaveData (int *vector, word size_y, word size_x) { // Выведем диалог, чтобы нам написали имя файла char *str = GetFileName (25, 5, 50); // Откроем указанный файл FILE *out = fopen (str, "wb"); // Если не получилось открыть файл, то ничего делать не будем if (!out) { printf ("Ошибка! Не могу открыть файл данных.\n"); return; } // цикл записи данных в файл for (int y = 0, *ptr = vector; y < size_y; y++) { for (int x = 0; x < size_x; x++, ptr++) fprintf (out, "%d ", *ptr); fprintf (out, "\n"); } fclose (out); // Закроем файл } // Загружает данные из файла void LoadData (int *vector, word size_y, word size_x) { // Выведем диалог, чтобы взять у пользователя имя файла char *str = GetFileName (25, 5, 50); FILE *in = fopen (str, "rb"); // Откроем файл // Если не получилось, то ничего делать не будем if (!in) { printf ("Ошибка! Не могу открыть файл данных.\n"); return; } // Цикл чтения данных из файла for (int y = 0, *ptr = vector, data; y < size_y; y++) for (int x = 0; x < size_x; x++, ptr++) { fscanf (in, "%d", &data); *ptr = data; } fclose (in); // Закроем файл } // Рисует один элемент массива в заданных координатах с // указанным цветом и фоном void ShowVectItem (int item, word xPos, word yPos, byte Color, byte Paper) { textcolor (Color); textbackground (Paper); gotoxy (xPos, yPos); cprintf ("%-3d", item); } // Для именения элемента int ChangeItem (word x, word y) { // Запомним чать экрана byte *buf = SaveScreen (x + 1, y + 1, 10 + 2, 2 + 1); // выведем окошко ShowWin (x + 1, y + 1, 10, 2, 1, 1, WHITE, RED, ""); int newitem; gotoxy (x + 2, y + 2); scanf ("%3d", &newitem); // Прочитаем новое значение с клавиатуры // Востановим испорченный экран RestoreScreen (x + 1, y + 1, 10 + 2, 2 + 1, buf); return newitem; } // Рисует матрицу с возможностью редактирования void ShowMatrix (int *vector, word size_y, word size_x) { _setcursortype (_NOCURSOR); word xPos=1, yPos=1, xSize = min (80, size_x * 4), ySize = min (24, size_y + 1); int *ptr = vector, data; byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1); byte bExit = 1; // Окошко для вывода ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Матрица "); // Цикл вывода данных на экран for (int y = 0; y < size_y; y++) { for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4) { gotoxy (pos, y + yPos + 1); printf ("%-3d", *ptr); } } // Меню для редактирования int x, key; x = y = 0; while (bExit) { ptr = vector + ITEM (y, x, size_x); // Вычислим Адрес текущего элемента // Покажем его на экране другим цветом ShowVectItem (*ptr, x*4 + xPos + 1, y + yPos + 1, BLUE, LIGHTCYAN); key = bioskey (0); // Прочитам клавиатуру // Потушим выделенный элемент ShowVectItem (*ptr, x*4 + xPos + 1, y + yPos + 1, LIGHTCYAN, BLUE); // Обработаем нажатую клавишу switch (key) { case LEFT: x--; if (x<0) x = size_x-1; break; // нажали влево case RIGHT: x++; if (x>=size_x) x = 0; break; // нажали вправо case UP: y--; if (y<0) y = size_y - 1; break; // вниз case DOWN: y++; if (y>=size_y) y = 0; break; // вверх case ESC: bExit = 0; break; // отмена // изменить текущий элемент case ENTER: *ptr = ChangeItem (x*4+xPos+1, y+yPos+1); break; } } // Востановим ипорченную часть экрана RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf); _setcursortype (_NORMALCURSOR); // включим курсор } // Выполняет ввод матрицы void InputMatrix (int *vector, int size_y, int size_x) { word xPos=1, yPos=1, xSize = min (80, size_x * 4), ySize = min (24, size_y + 1); int *ptr = vector, data; byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1); // Рисуем окошко ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Матрица "); // Цикл ввода for (int y = 0; y < size_y; y++) { for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4) { gotoxy (pos, y + yPos + 1); scanf ("%3d", &data); *ptr = data; } } bioskey (0); // Подождем нажатия на любую клавищу RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf); } // Заполняет матрицу случайными числами из диапозона [-50;50] void RandMatrix (int *vector, int size_y, int size_x) { for (int y = 0, *ptr = vector; y < size_y; y++) { for (int x = 0; x < size_x; x++, ptr++) *ptr = (random (99) - 50); } } // Показывает резутаты работы void ViewResult (int *m_vector, int size_y, int size_x, long *abs_vect, long pMin, long pMax, long pSum, long pMinus, int *m_vect, int nMin, int nMax) { _setcursortype (_NOCURSOR); // Выключаем курсор // Расчитываем параметры окошек word xPos=1, yPos=1, xSize = min (50, size_x * 4), ySize = min (12, size_y + 1); word xPos1=60, yPos1=1, xSize1 = 18, ySize1 = 7; word xPos2=xPos + xSize + 2 + 2, yPos2=1, xSize2 = 10, ySize2 = ySize; word xPos3=1, yPos3=ySize + 1 + 2, xSize3 = xSize, ySize3 = ySize; // Настраиваем указатели на данные int *ptr = m_vector, data, *ptr1 = m_vect; // Запомним кусочки экрана куда будут выводится окошки byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1); byte *buf1 = SaveScreen (xPos1, yPos1, xSize1 + 2, ySize1 + 1); byte *buf2 = SaveScreen (xPos2, yPos2, xSize2 + 2, ySize2 + 1); byte *buf3 = SaveScreen (xPos3, yPos3, xSize3 + 2, ySize3 + 1); // Нарисуем окошки ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Исх. матрица "); ShowWin (xPos1, yPos1, xSize1, ySize1, 2, 1, WHITE, MAGENTA, " Статистика "); ShowWin (xPos2, yPos2, xSize2, ySize2, 2, 1, WHITE, GREEN, ""); ShowWin (xPos3, yPos3, xSize3, ySize3, 2, 1, WHITE, BLUE, " Рез. матрица "); // Вывод инфы на экран gotoxy (xPos1 + 2, yPos1 + 2); printf (" Min = %ld", pMin); gotoxy (xPos1 + 2, yPos1 + 3); printf (" Max = %ld", pMax); gotoxy (xPos1 + 2, yPos1 + 4); printf (" \"-\" = %ld", pMinus); gotoxy (xPos1 + 2, yPos1 + 5); printf ("Сумма = %ld", pSum); // Цикл вывода данных из матрицы на экран for (int y = 0; y < size_y; y++) { // Подсветка строки с минимальным и максимальным произведением if (y == nMin || y == nMax) { textbackground (CYAN); for (int a = 0; a < size_x * 4 - 1; a++) { gotoxy (xPos+1+a, y + yPos + 1); cprintf (" "); gotoxy (xPos+1+a, y + yPos3 + 1); cprintf (" "); } } // Вывод данных из матрицы на экран for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4, ptr1++) { gotoxy (pos, y + yPos + 1); // Первая матрица printf ("%-3d", *ptr); gotoxy (pos, y + yPos3 + 1); // вторая матрица printf ("%-3d", *ptr1); } gotoxy (xPos2 + 1, y + yPos2 + 1); // массив произведений printf ("%ld", abs_vect[y]); } bioskey (0); // ждем нажатия на любую клавишу // востанавливаем испорченные кусочки экрана RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf); RestoreScreen (xPos1, yPos1, xSize1 + 2, ySize1 + 1, buf1); RestoreScreen (xPos2, yPos2, xSize2 + 2, ySize2 + 1, buf2); RestoreScreen (xPos3, yPos3, xSize3 + 2, ySize3 + 1, buf3); _setcursortype (_NORMALCURSOR); // включаем курсор } // Выполняе решение void CreateAbsVector (int *vector, int size_y, int size_x, long *resVector, long *pMin, long *pMax, long *pSum, long *pMinus, int *r_vect, int *n_Min, int *n_Max) { long summ = 0; // Сумма произведений, пока 0 // Цикл стоит массив из модулей произведений отрицательных // элементов каждой строки, если таких элементов в строке нет, // то результат = 0 // а также считает кол-во отрицательных элементов // и определяет сумму произведений сформированного массива for (int y = 0, i = 0, *ptr = vector, abs_count = 0; y < size_y; y++, i++) { resVector[i] = 0; // снача = 0 for (int x = 0; x < size_x; x++, ptr++) { if (*ptr < 0) // элемент отрицательный { if (resVector[i] == 0) // пока 0 resVector[i] = abs (*ptr); // тогда пишем первое число else // уже не 0 resVector[i] *= abs (*ptr); // тогда умножим на элемент abs_count++; // счетчик отрицательных, увеличим } } summ += resVector[i]; // не забудем прибавить к общей сумме } // уже вычисленные значения вернем через указатель *pSum = summ; *pMinus = abs_count; // Найдем мин и мах элементы и поменяем строки местами long Min, Max; int nMin, nMax; // номера строк с мин и мах элементами // цикл для нахождения for (i = 0; i < size_y; i++) { if (!i) // если это первый элемент { // то положим его равным мин и мах и запомним номер строки Max = Min = resVector [i]; nMin = nMax = i; } else // элеменет не первый { // тогда ищем if (Max < resVector [i]) // выбор мах из очередной пары { Max = resVector [i]; nMax = i; } if (Min > resVector [i]) // выбор мин из очередной пары { Min = resVector [i]; nMin = i; } } } // вернем результаты *pMin = Min; *pMax = Max; *n_Min = nMin; *n_Max = nMax; // поменяем строки с мин и мах местами int *ptr_cpy = r_vect; ptr = vector; // скопируем первую матрицу во вторую memcpy (ptr_cpy, ptr, sizeof (int) * size_y * size_x); // Если надо менять строки в исходной матрице, то // закоментировать следующие 2 строки и "в исходной" // разкоментировать 2 строки "в результирующей" // указатели на строки с мин и мах элементами, вычислим адресе int *ptr_min = r_vect + ITEM (nMin, 0, size_x); // в исходной int *ptr_max = r_vect + ITEM (nMax, 0, size_x); // в исходной // это было чтобы менять в исходной матрицы строки // int *ptr_min = vector + ITEM (nMin, 0, size_x); // в результирующей // int *ptr_max = vector + ITEM (nMax, 0, size_x); // в результирующей int *tmp = new int [size_x]; // временный массив для хранения строки // поменяем местами строки, через временный массив memcpy (tmp, ptr_min, sizeof (int) * size_x); memcpy (ptr_min, ptr_max, sizeof (int) * size_x); memcpy (ptr_max, tmp, sizeof (int) * size_x); // освободим временный массив delete [] tmp; } // Главная функция - управляет работой всей программы void AppRun (void) { DeskTop (); // нарисуем экран TaskBar (" ~ESC~ Выход"); // строку статуса byte bExit = 1; byte buf_size; byte *buf; // переменные для записи результатов работы меню word MainMenuResult = 0, FileMenuResult, HelpMenuResult; // основной цикл работы while (bExit) { // вызов главного меню MainMenuResult = Menu (5,3,18,4,2,1,YELLOW,BLUE,CYAN,BLUE, " Главное меню ", 3, MainMenuItems, MainMenuResult); // Обработка результатов работы главного меню switch (MainMenuResult) { case -1: bExit = 0; break; // выход из программы case 0: // запуск меню "Файл" buf = SaveScreen (20, 4, 28 + 2, 8 + 1); FileMenuResult = Menu (20, 4, 28, 8, 2, 1, YELLOW,MAGENTA, CYAN,BLUE, " Меню файл ", 7, FileMenuItems,0); // обработка результатов работы меню файл switch (FileMenuResult) { case -1: break; case 0: LoadData (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // load data case 1: SaveData (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // save data case 2: InputMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // input data case 3: ShowMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // edit data case 4: RandMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // random data case 5: ViewResult (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X, VectorAbs, gMin, gMax, gSum, gMinus, &Matrix2[0][0], MinLine, MaxLine); break; // show result case 6: bExit = 0; break; // exit } RestoreScreen (20, 4, 28 + 2, 8 + 1, buf); break; case 1: // выполнение вычислейний CreateAbsVector (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X, &VectorAbs[0], &gMin, &gMax, &gSum, &gMinus, &Matrix2[0][0], &MinLine, &MaxLine); _setcursortype (_NOCURSOR); buf = SaveScreen (20, 5, 44 + 2, 6 + 1); ShowWin (20, 5, 44, 6, 2, 1, WHITE, MAGENTA, " Результат "); gotoxy (32,7); printf ("Вычисления выполнены."); gotoxy (24,9); printf ("Нажмите любую клавишу для продолжение"); bioskey (0); RestoreScreen (20, 5, 44 + 2, 6 + 1, buf); _setcursortype (_NORMALCURSOR); break; case 2: // вызов меню "Справка" buf = SaveScreen (20, 6, 31 + 2, 3 + 1); HelpMenuResult = Menu (20, 6, 31, 3, 2, 1, YELLOW,MAGENTA, CYAN,BLUE, " Меню справка ", 2, HelpMenuItems,0); // обработка результатов меню справка switch (HelpMenuResult) { case 0: UserGuide (); break; // User guide case 1: About (); break; // About ... } RestoreScreen (20, 6, 31 + 2, 3 + 1, buf); break; } } } // Выводин информацию о разработчиках void About (void) { _setcursortype (_NOCURSOR); byte *buf = SaveScreen (18, 7, 44 + 2, 11 + 1); ShowWin (18, 7, 44, 11, 2, 1, BLUE, CYAN, " Об авторах ... "); gotoxy (20, 9); printf ("Програмный продукт: ********************"); gotoxy (20,11); printf (" Разработчик: ********************"); gotoxy (20,13); printf (" Дата выпуска: ********************"); gotoxy (20,17); printf (" Нажмите любую клавишу для выхода "); bioskey (0); RestoreScreen (18, 7, 44 + 2, 11 + 1, buf); _setcursortype (_NORMALCURSOR); } // Выводит одну страницу руководства пользователя void ShowUserGuide (const char *Text) { ShowWin (15, 7, 50, 11, 2, 1, WHITE, GREEN, " Руководство пользователя "); window (16,8,64,17); cprintf ("%s", Text); textcolor (BLUE); gotoxy (9,10); cprintf ("ESC - Выход. Up, Down - Листать."); window (1,1,80,25); } // Выполняет работу диалога руководство пользователя void UserGuide (void) { _setcursortype (_NOCURSOR); int key; byte bExit = 1; byte *buf = SaveScreen (15, 7, 50 + 2, 11 + 1); int GuideCount = 0; while (bExit) { ShowUserGuide (UserGuideText [GuideCount]); key = bioskey (0); switch (key) { case ESC: bExit = 0; break; case UP: GuideCount--; if (GuideCount < 0) GuideCount = 0; break; case DOWN: GuideCount++; if (GuideCount >= UserGuideCount - 1) GuideCount = UserGuideCount - 1; break; } } RestoreScreen (15, 7, 50 + 2, 11 + 1, buf); _setcursortype (_NORMALCURSOR); } // Востанавливает часть экрана void RestoreScreen (byte xPos, byte yPos, byte xSize, byte ySize, byte *buf) { puttext (xPos, yPos, xPos + xSize, yPos + ySize, buf); delete [] buf; } // Сохраняет часть экрана byte *SaveScreen (byte xPos, byte yPos, byte xSize, byte ySize) { word buf_size = (xSize + 1) * (ySize + 1) * 2; byte *buf = new byte [buf_size]; if (!buf) { printf ("Нет свободной памяти для выполнения операции!\n"); return NULL; } gettext (xPos, yPos, xPos + xSize, yPos + ySize, buf); return buf; } // Главная функциия - отсюда происходит старт программы void main (void) { if (SplashScreen ()) // вывод заставки, если пользователь не нажал выход AppRun (); // то запускаем работу программы } | Всего записей: 29 | Зарегистр. 06-03-2005 | Отправлено: 22:20 19-05-2008 | Исправлено: LuckyELF, 22:29 19-05-2008 |
|