Ку: Сионизм
Jan. 8th, 2003 01:26 amА всей проги-то было — всего ничего
/*
BioRhythm
рассчёт биоритмов человека
каждый из ритмов представляется синусоидой
цикл каждой задан константой.
Внешние данные - дата рождения, ФИО, интересующий период
дата рождения и месяц прогноза проверяются на правильность
и при необходимости корректируются
*/
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include <dos.h>
#include <graphics.h>
#define VERSION "0.4.20030108"
/* Продолжительность циклов */
#define CICLE_PHYS 23 /* физический */
#define CICLE_EMOT 28 /* эмоциональный */
#define CICLE_INTL 33 /* интеллектуальный */
/* Цвета */
#define COLOR_BG BLACK /* фон */
#define COLOR_AXIS LIGHTGRAY /* ось */
#define COLOR_PHYS YELLOW /* циклы */
#define COLOR_EMOT LIGHTGREEN
#define COLOR_INTL LIGHTBLUE
#define COLOR_WHO WHITE /* для кого */
#define COLOR_ALARM LIGHTRED /* критические дни */
/* Шрифт */
#define FONT DEFAULT_FONT
#define AXIS_RMARGIN 10 /* Правое поле - чтоб число 30 влезло */
#define LEGEND 100 /* Верхнее */
/* Глобальные переменные */
int month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
maxx, maxy; /* Вспомогательные переменные */
/* Прототипы функций */
int isleap(int);
int dayinyear(int, int, int);
void date_input(struct date*);
long daysbetween(int, int, int, int, int, int);
int isOK(char*);
int ny(float);
char* getst(int);
/*********************************/
void main()
{
char *name; /* Персональные данные */
struct date date_birth;
int res_year, res_month, /* Интересующая дата */
mdays, /* количество дней в месяце */
critical[33], /* критические дни */
period[3] = {CICLE_PHYS, CICLE_EMOT, CICLE_INTL},
color[3] = {COLOR_PHYS, COLOR_EMOT, COLOR_INTL};
char* cyname[3] = {"физический", "эмоциональный", "интеллектуальный"};
/* Зачем? А чтоб
1) все константы висели в начале программы и ясно назывались
2) можно было использовать циклы */
long age; /* Возраст на начало периода */
char ch, *st, stb[255]; /* Вспомогательные переменные */
int i, j, day, gd = DETECT, gm, stry;
float cycle[3][33]; /* Массив значений графиков */
/* Крутимся в цикле, пока пользователю не надоест */
do
{
/* Ввод данных */
textattr(0x1F); clrscr();
cprintf("\n\n\r Рассчёт биоритмов\n\r Введи необходимые данные\n\n\r");
textattr(0x1B); cprintf(" Фамилия, имя, отчество ");
textattr(0x4E); cprintf(" ");
gotoxy(30, wherey() );
strcpy(name, getst(30)); /* без strcpy строка name портится сразу же */
textattr(0x1B); cprintf("\n\r Дата рождения ");
textattr(0x1B); gotoxy(50, wherey());
cprintf("Введи день (1..31)");
gotoxy(29, wherey() );
textattr(0x4E); cprintf(" ");
gotoxy(30, wherey() );
st = getst(2);
date_birth.da_day = atoi(st);
textattr(0x1B); gotoxy(50, wherey());
cprintf("Введи месяц (1..12)");
gotoxy(32, wherey());
textattr(0x4E); cprintf(". ");
gotoxy(33, wherey() );
st = getst(2);
date_birth.da_mon = atoi(st);
textattr(0x1B); gotoxy(50, wherey());
cprintf("Введи год (4 цифры)");
gotoxy(35, wherey());
textattr(0x4E); cprintf(". ");
gotoxy(36, wherey() );
st = getst(4);
date_birth.da_year = atoi(st);
/* Проверка правильности даты и коррекция в случае необходимости */
date_birth.da_mon = (date_birth.da_mon < 1) ? 1 : (date_birth.da_mon > 12) ? 12 : date_birth.da_mon;
date_birth.da_day = (date_birth.da_day < 1) ? 1 : (date_birth.da_day > month[date_birth.da_mon-1]+isleap(date_birth.da_year)) ? month[date_birth.da_mon-1]+isleap(date_birth.da_year) : date_birth.da_day;
textattr(0x1B); gotoxy(50, wherey());
cprintf(" \r\n");
textattr(0x1B); cprintf(" Год прогноза ");
textattr(0x4E); cprintf(" ");
gotoxy(30, wherey() );
st = getst(4);
res_year = atoi(st);
textattr(0x1B); cprintf("\r\n Месяц (1..12) ");
textattr(0x4E); cprintf(" ");
gotoxy(30, wherey() );
st = getst(2);
res_month = atoi(st);
/* Проверка и коррекция */
res_month = (res_month < 1) ? 1 : (res_month > 12) ? 12 : res_month;
textattr(0x1B);
age = daysbetween(date_birth.da_year, date_birth.da_mon, date_birth.da_day, res_year, res_month, 1);
if ((age < -30) || (date_birth.da_year > res_year))
{
textattr(0x9E);
cprintf("\r\n\n Ошибка!");
textattr(0x1C);
cprintf("\r\n Прогнозируемый период находится до даты рождения\r\n\n");
textattr(0x1B);
}
else
{
cprintf("\r\n\n %s (род. %d.%02d.%04d)", name, date_birth.da_day, date_birth.da_mon, date_birth.da_year);
cprintf("\r\n Возраст на 1.%02d.%04d - %ld дней", res_month, res_year, age);
mdays = month[res_month-1];
for (j=0; j<=mdays; j++) /* i - цикл, j - день */
{
critical[j] = 0; /* Считаем критические дни */
for (i=0; i<3; i++)
{
day = (age+j) % period[i]; /* Дней от начала периода */
if ((day == 0) ||
(day == floor((float) period[i]/2)) ||
(day == ceil((float) period[i]/2)))
/* Проверяем оба перехода через 0 */
critical[j]++;
cycle[i][j] = sin((float) day / period[i]*2*M_PI);
}
}
textcolor(0x1F);
cprintf("\r\n Критические дни: ");
for (j=1; j<=mdays; j++)
if (critical[j] > 1)
cprintf("%d, ", j);
/* Графика */
textcolor(0x1B);
cprintf("\r\n Нарисовать график? (Y/n) ");
st = getst(1);
if (isOK(st))
{
initgraph(&gd, &gm, ""); /* Инициализируем графику*/
setbkcolor(COLOR_BG);
cleardevice();
maxx = getmaxx(); /* и определяем размер экрана */
maxy = getmaxy();
setcolor(COLOR_AXIS); /* рисуем оси */
line(0, LEGEND, 0, maxy);
line(0, (maxy+LEGEND)/2, maxx, (maxy+LEGEND)/2);
settextstyle(FONT, HORIZ_DIR, 1);
for (i=1; i <= mdays; i++)
{
for (j=0; j < 3; j++)
{
setcolor(color[j]); /* рисуем синусы */
line((i-1)*(maxx-AXIS_RMARGIN)/mdays, ny(cycle[j][i-1]),
i*(maxx-AXIS_RMARGIN)/mdays, ny(cycle[j][i]));
}
setcolor(COLOR_AXIS);
if (critical[i] > 1)
setcolor(COLOR_ALARM);
line(i*(maxx-AXIS_RMARGIN)/mdays, maxy/2+40, i*(maxx-AXIS_RMARGIN)/mdays, maxy/2+60);
if ((i%5 == 0) || (critical[i] > 1))
{
itoa(i, st, 10);
outtextxy(i*(maxx-AXIS_RMARGIN)/mdays-textwidth(st)/2, maxy/2+65, st);
}
} /* for */
/* Текст */
settextstyle(FONT, HORIZ_DIR, 2);
stry = textheight("Hj")+1;
outtextxy(0, 0, "Биоритмы");
strcpy(stb, "Нажми [ENTER]");
outtextxy(maxx - textwidth(stb), maxy-stry, stb);
for (j=0; j < 3; j++)
{
setcolor(color[j]); /* рисуем легенду */
outtextxy(0, stry*(j+1)+10, cyname[j]);
}
settextstyle(FONT, HORIZ_DIR, 1);
setcolor(COLOR_WHO);
sprintf(stb, "%s (род. %d.%02d.%04d). Прогноз на %02d.%04d", name, date_birth.da_day, date_birth.da_mon, date_birth.da_year, res_month, res_year);
outtextxy(0, stry, stb);
getst(1);
closegraph();
textattr(0x1B); clrscr();
} /* Графика */
} /* if age */
cprintf("\r\n\n Повторить рассчёт с другими данными? (Y/n) ");
st = getst(1);
} while (isOK(st));
textattr(0x07);
clrscr();
printf("BioRhythm %s\n", VERSION);
} /* main */
/********* функции ********/
/* Год високосный? */
int isleap(int num)
{
return !(num % 4 || (!(num % 100) && (num % 400)));
}
/* Номер дня в году */
int dayinyear(int y, int m, int d)
{
int ret = 0, /* Возвращаемое значение */
i;
for(i=1; i<m; i++) /* Считаем дни */
ret += month[i-1]; /* Массив месяцев начинается с 0 */
ret += d; /* Получили номер дня без поправки на високосность */
if (isleap(y) && (m > 2)) /* Если год високосный и месяц - март и т.д. */
ret++;
return ret;
}
/* Вычисляет разницу между датами в днях */
long daysbetween(int y1, int m1, int d1, int y2, int m2, int d2)
{
long ret = 0; /* Возвращаемое значение */
int i;
for(i=y1; i<y2; i++) /* Считаем годы */
ret += 365+isleap(i); /* в цикле прибавляем дни */
ret += dayinyear(y2, m2, d2) - dayinyear(y1, m1, d1);
return ret;
}
/* Возвращает флаг положительного ответа юзера */
int isOK(char *st)
{
return !(strcmp(st, "") && /* По умолчанию - ENTER = Да */
strcmp(st, "Y") && strcmp(st, "y") &&
strcmp(st, "Д") && strcmp(st, "д"));
}
/* Преобразует координаты [-1..1] в экранные [LEGEND..maxy]*/
int ny(float f)
{
return LEGEND+(maxy-LEGEND)*(1-f)/2;
}
/* Читает строку длиной не более len символов */
char* getst(int len)
{
char buf[256];
buf[0] = len+1;
return cgets(buf);
}
/*************** The END **************/