Pers.narod.ru. Алгоритмы. Простейший граф на C++ в графическом режиме консоли |
Если предельно упростить определение, то граф - это набор узлов (вершин), связанных между собой линиями (рёбрами, дугами), по которым можно переходить от узла к узлу.
Это учебное упражнение демонстрирует работу с графом как массивом структур на C++.
Одна структура описывает один кружок на экране таким образом:
const int maxlinks=2;
typedef struct krug {
int cx,cy; //координаты центра
int r; //радиус
int links[maxlinks]; //номера связанных кружков, не более maxlinks
};
Вся совокупность кружков графа описана как массив структур:
const int n=4; //количество кружков
krug k[n]={ //описали n кружков
{100,100,40,{-1,1}}, //-1 - отсутствие связи
{350,200,50,{1,2}},
{100,400,45,{-1,-1}},
{450,430,35,{1,2}}
};
В демке отрисовывается несложный граф из этих кружков и выполняется навигация по нему.
Так как программа использует графический режим, запускать её следует через эмулятор,
при этом в папке приложения (по умолчанию c:\BorlandC\Program) должен находиться файл графического драйвера
egavga.bgi (скопировать из папки c:\BorlandC\BGI).
Стрелки влево/вправо проходят по кружкам последовательно, стрелки вверх/вниз - через один, если это возможно (в нашем случае связаны кружки 2 и 4). Клавиша Esc - выход из программы. Все связи предполагаются двустронними и достаточно одной записи о связи в массиве k. В этом плане программу несложно изменить.
Не забывайте, что нумерация элементов массивов в С++ производится с нуля.
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
void init () {
int gdriver = VGA, gmode = VGAHI, errorcode;
initgraph(&gdriver, &gmode, "");
errorcode = graphresult();
if (errorcode != grOk) {
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1);
}
}
const int maxlinks=2;
typedef struct krug {
int cx,cy; //координаты центра
int r; //радиус
int links[maxlinks]; //номера связанных кружков, не более maxlinks
};
void draw (krug *k, int color) { //рисует фишку заданным цветом
setfillstyle (SOLID_FILL,color);
fillellipse (k->cx,k->cy,k->r/4,k->r/4);
}
int find (krug *k1, int n1, krug *k2, int n2) { //да, если кружки связаны
for (int i=0; i<maxlinks; i++)
if (k1->links[i] == n2 || k2->links[i] == n1) return 1;
return 0;
}
void main () {
init();
const int n=4; //количество кружков
krug k[n]={ //описали n кружков
{100,100,40,{-1,1}}, //-1 - отсутствие связи
{350,200,50,{1,2}},
{100,400,45,{-1,-1}},
{450,430,35,{1,2}}
};
bar (0,0,639,479);
setcolor (RED);
for (int i=0; i<n; i++) { //отрисовали контуры кружков и связи
circle (k[i].cx,k[i].cy,k[i].r);
for (int j=0; j<2; j++) {
int l=k[i].links[j];
if (l!=-1) line (k[i].cx,k[i].cy,k[l].cx,k[l].cy);
}
}
setfillstyle (SOLID_FILL,GREEN);
char s[10];
for (i=0; i<n; i++) { //залили кружки цветом и вывели номера
fillellipse (k[i].cx,k[i].cy,k[i].r,k[i].r);
itoa (i+1,s,10);
outtextxy (k[i].cx+k[i].r/3,k[i].cy+k[i].r/3,s);
}
i=0;
int ch;
do {
draw (&k[i],RED);
ch=getch();
draw (&k[i],GREEN);
if (!ch) {
ch=getch();
switch (ch) {
case 75: if (i) i--; break;
case 77: if (i<n-1) i++; break;
case 72: if (i>1 && find(&k[i],i,&k[i-2],i-2)) i-=2; break;
case 80: if (i<n-2 && find(&k[i],i,&k[i+2],i+2)) i+=2; break;
}
}
} while (ch!=27); //до нажатия Esc
closegraph();
}
|
|