Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

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 = {" &#9472;&#9552;"};
const char *LineV = {" &#9474;&#9553;"};
const char *LeftUp = {" &#9484;&#9556;"};
const char *RightUp = {" &#9488;&#9559;"};
const char *LeftDown = {" &#9492;&#9562;"};
const char *RightDown = {" &#9496;&#9565;"};
 
// Пункты меню
// Главное меню
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 ("&#9618;"); // Заполняем экран этим символом
        }
    _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
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru