Pers.narod.ru. Алгоритмы. Простейший "гипертекст" на C++ |
Совсем простой учебный пример "собственного гипертекста", почти такого же, как в этой старой программе, только без полноценного меню, поддержки мыши и т.п.
Основная идея - весь текст истории, пункты которой могут быть перекрестно связаны между собой, хранится в одном массиве строк, одна строка - один пункт истории.
При этом символ "$" в тексте статей имеет особое значение - показывает, что после него следует номер пункта, к которому можно перейти. Так как в C++ элементы массивов нумеруются с нуля, то и статьи в массиве game считаются так же.
Нетрудно сделать "более полноценные" ссылки, выделяя цветом слово-якорь ссылки, которое мы тогда будем помечать долларами с 2 сторон:
$2 слово$
и удалять из выводимой на экран строки номер статьи после доллара и сами знаки доллара... это лишь немного усложнит разбор. Вот полный текст программы-примера:
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
void main () {
const int n=5; //общее число статей
const int lmax=3; //макс.число ссылок из статьи
char *game[n] = { //дерево игры в примере сознательно неверно!
"В лесу родилась елочка, что она делала дальше? Если думаете, \n\
что росла, вам к статье $1, иначе к статье $3",
"Если елочка все еще не выросла, давайте вернемся к началу, \n\
статье $0, а иначе нам дальше, к пункту $2",
"Пришел мужчиок, срубил елочку, тут и сказке конец",
"Выберите, что делала елочка: росла - $0, уже выросла - $1, \n\
нет никакой елочки - $2, недостижимая ссылка - $4",
"Эту строку никто не увидит в тексте, к ней нет \n\
правильного перехода"
};
int links[lmax],i=0;
clrscr();
do {
char *p=game[i];
for (int j=0; j<3; j++) links[j]=-1; //помечаем ссылки как пустые
j=0;
for (int l=0; l<strlen(p); l++) { //cобираем номера статей, на которые ссылаемся
if (p[l]=='$') links[j++]=atoi(&p[l+1]);
if (j==lmax) {
printf ("В статье номер %d есть лишние ссылки, пропущено\n",i);
break;
}
}
puts (p);
puts ("\nВведите номер статьи для перехода или -1 для выхода");
int k;
for (k=0; k<j; k++) if (links[k]>-1) printf ("%d ",links[k]);
puts ("\n");
fflush (stdin);
int i2=0;
scanf ("%d",&i2);
if (i2<0) break;
else if (i2>n-1) {
printf ("Введен недопустимый номер статьи %d, возвращаемся к началу\n",i2);
i=0;
}
else {
int found=0;
for (k=0; k<j; k++) if (links[k]==i2) {
found=1; i=i2; break;
}
if (!found) printf ("Из статьи номер %d нет ссылки на %d, пропущено\n",i,i2);
else {
i=i2;
clrscr();
}
}
} while (1);
}
Новая статья, если всё правильно, выводится с пустого экрана консоли, пользователь вводит номер нужной статьи, который присутствует в её тексте, или отрицательное число для выхода. Допустимость ссылок контролируется, их максимальное число из одной статьи программно ограничено (см. листинг).
Наверное, правильнее было сделать структуру ддя узла текста, а текст хранить как массив этих структур.
|
|