mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
1 line
8.3 KiB
C
1 line
8.3 KiB
C
/* -*-c,save-*- */
|
||
|
||
/*
|
||
|
||
* rstory.c - random story generator
|
||
|
||
* Robert Heller. Created: Sun Feb 23, 1986 15:50:57.96
|
||
|
||
* Last Mod:
|
||
|
||
*
|
||
|
||
* (c) Copyright 1986 by Robert Heller
|
||
|
||
* All Rights Reserved
|
||
|
||
*
|
||
|
||
*
|
||
|
||
*/
|
||
|
||
|
||
|
||
#include <stdio.h>
|
||
|
||
|
||
|
||
#include "patdef.h"
|
||
|
||
|
||
|
||
#define LOCAL static
|
||
|
||
|
||
|
||
/* #define DEBUG /* debugging hacks */
|
||
|
||
|
||
|
||
/* #define ROFF4_STRIDE /* for roff4 hacks (output reformatting) */
|
||
|
||
|
||
|
||
#ifdef DEBUG
|
||
|
||
#define LOCAL /* static */
|
||
|
||
#endif
|
||
|
||
|
||
|
||
#define CHAR_RV 0
|
||
|
||
#define PET_RV 1
|
||
|
||
#define BAR_RV 2
|
||
|
||
#define LAST_RV 3
|
||
|
||
#define SUBJ_RV 4
|
||
|
||
#define VERB_RV 5
|
||
|
||
#define LIST_RV 6
|
||
|
||
|
||
|
||
LOCAL PATTERN_NODE *BB,*SB,*ph1,*ph2,*ph3,*ph4,*pat1,*pat2,*pat3,*wont,*comma;
|
||
|
||
|
||
|
||
typedef struct {
|
||
|
||
char *synname;
|
||
|
||
char *synval;
|
||
|
||
} SYNVAR;
|
||
|
||
|
||
|
||
SYNVAR *rsen_lkp();
|
||
|
||
|
||
|
||
LOCAL STRING_DESCR SUBJ_VB,OBJS,VAR,OBJ,SUBJ,VERB;
|
||
|
||
LOCAL char objs[4096],var[256];
|
||
|
||
LOCAL char temp[4096],obj[256];
|
||
|
||
|
||
|
||
ARG_DESCR *acons();
|
||
|
||
char *malloc(),*calloc(),*index(),*fgets(),*g_rsentv();
|
||
|
||
FILE *fopen();
|
||
|
||
SYNVAR *rsen_lkp();
|
||
|
||
|
||
|
||
#define MAXACT 256
|
||
|
||
|
||
|
||
LOCAL SYNVAR actions[MAXACT];
|
||
|
||
LOCAL int act_cnt = 0;
|
||
|
||
|
||
|
||
LOCAL char rstory[30000];
|
||
|
||
|
||
|
||
main()
|
||
|
||
{
|
||
|
||
register FILE *actfile;
|
||
|
||
char actline[256];
|
||
|
||
STRING_DESCR matched;
|
||
|
||
register SYNVAR *rentry;
|
||
|
||
register char *sv,*o,*last,*subj,*verb,*list;
|
||
|
||
register int len,try;
|
||
|
||
SYNVAR *act_lkp();
|
||
|
||
|
||
|
||
srand(gettime());
|
||
|
||
rsent_init("RSTORY.SYN");
|
||
|
||
BB = breakk_c(" \t");
|
||
|
||
SB = span_c(" \t");
|
||
|
||
pat1 = cassign(BB,acons(STRING,&SUBJ));
|
||
|
||
pat1 = concat(pat1,SB);
|
||
|
||
pat1 = concat(pat1,cassign(REM,acons(STRING,&VERB)));
|
||
|
||
pat2 = concat(c_lit_string(" "),
|
||
|
||
concat(lit_string(&SUBJ),c_lit_string(" ")));
|
||
|
||
pat3 = concat(c_lit_string(" "),
|
||
|
||
concat(lit_string(&VERB),c_lit_string(" ")));
|
||
|
||
wont = c_lit_string("won't");
|
||
|
||
comma = c_lit_string(",");
|
||
|
||
ph1 = concat(BB,SB);
|
||
|
||
ph1 = concat(ph1,BB);
|
||
|
||
ph1 = cassign(ph1,acons(STRING,&SUBJ_VB));
|
||
|
||
ph1 = concat(ph1,SB);
|
||
|
||
ph1 = concat(ph1,cassign(REM,acons(STRING,&OBJS)));
|
||
|
||
ph2 = cassign(breakk_c(">"),acons(STRING,&VAR));
|
||
|
||
ph2 = concat(ph2,c_lit_string(">"));
|
||
|
||
ph2 = concat(c_lit_string("<"),ph2);
|
||
|
||
ph2 = concat(pos(0),ph2);
|
||
|
||
ph3 = concat(pos(0),c_lit_string("|"));
|
||
|
||
ph4 = concat(cassign(breakk_c("|"),acons(STRING,&OBJ)),c_lit_string("|"));
|
||
|
||
|
||
|
||
actfile = fopen("RSTORY.ACT","r");
|
||
|
||
if (actfile == NULL) {
|
||
|
||
perror("rstory (fopen(actions))");
|
||
|
||
abort(0);
|
||
|
||
}
|
||
|
||
for (;;) {
|
||
|
||
if (fgets(actline,256,actfile) == NULL) break;
|
||
|
||
trim(actline);
|
||
|
||
#ifdef DEBUG
|
||
|
||
printf("***actline = %s\n",actline);
|
||
|
||
#endif
|
||
|
||
if (strcmp(actline,"END") == 0) break;
|
||
|
||
pmatch(actline,ph1,&matched);
|
||
|
||
strncpy(objs,OBJS.base+OBJS.offset,OBJS.length);
|
||
|
||
objs[OBJS.length] = '|';
|
||
|
||
objs[OBJS.length+1] = '\0';
|
||
|
||
for (;;) {
|
||
|
||
#ifdef DEBUG
|
||
|
||
printf("***objs = %s\n",objs);
|
||
|
||
#endif
|
||
|
||
if (pmatch(objs,ph2,&matched) == MATCH_SUCCESS) {
|
||
|
||
strncpy(var,VAR.base+VAR.offset,VAR.length);
|
||
|
||
var[VAR.length] = '\0';
|
||
|
||
rentry = rsen_lkp(var);
|
||
|
||
if (rentry == NULL) strcpy(objs,objs+matched.length);
|
||
|
||
else {
|
||
|
||
strcpy(temp,rentry->synval);
|
||
|
||
strcat(temp,objs+matched.length);
|
||
|
||
strcpy(objs,temp);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if (pmatch(objs,ph3,&matched) == MATCH_SUCCESS) {
|
||
|
||
strcpy(objs,objs+1);
|
||
|
||
continue;
|
||
|
||
}
|
||
|
||
if (pmatch(objs,ph4,&matched) != MATCH_SUCCESS) break;
|
||
|
||
strncpy(obj,OBJ.base+OBJ.offset,OBJ.length);
|
||
|
||
obj[OBJ.length] = '\0';
|
||
|
||
strcpy(objs,objs+matched.length);
|
||
|
||
rentry = act_lkp(obj);
|
||
|
||
if (rentry == NULL) {
|
||
|
||
sv = malloc(SUBJ_VB.length+2);
|
||
|
||
strncpy(sv+1,SUBJ_VB.base+SUBJ_VB.offset,SUBJ_VB.length);
|
||
|
||
*sv = '|';
|
||
|
||
sv[SUBJ_VB.length+1] = '\0';
|
||
|
||
o = malloc(OBJ.length+1);
|
||
|
||
strcpy(o,obj);
|
||
|
||
act_ins(o,sv);
|
||
|
||
}
|
||
|
||
else {
|
||
|
||
sv = malloc(strlen(rentry->synval)+SUBJ_VB.length+2);
|
||
|
||
strcpy(sv,rentry->synval);
|
||
|
||
strcat(sv,"|");
|
||
|
||
strncat(sv,SUBJ_VB.base+SUBJ_VB.offset,SUBJ_VB.length);
|
||
|
||
sv[SUBJ_VB.length+strlen(rentry->synval)+1] = '\0';
|
||
|
||
free(rentry->synval);
|
||
|
||
rentry->synval = sv;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
rsentence("<OPENING>",rstory);
|
||
|
||
o = g_rsentv(PET_RV);
|
||
|
||
sv = g_rsentv(BAR_RV);
|
||
|
||
len = strlen(o) + 2 + strlen(" won't jump over the ") + strlen(sv) + 1;
|
||
|
||
list = malloc(len);
|
||
|
||
strcpy(list," ");
|
||
|
||
strcat(list,o);
|
||
|
||
strcat(list," won't jump over the ");
|
||
|
||
strcat(list,sv);
|
||
|
||
s_rsentv(LIST_RV,list);
|
||
|
||
last = malloc(strlen(o)+1);
|
||
|
||
strcpy(last,o);
|
||
|
||
s_rsentv(LAST_RV,last);
|
||
|
||
while (strlen(list) < 175) {
|
||
|
||
#ifdef DEBUG
|
||
|
||
printf("***list = %s\n***rstory = %s\n",list,rstory);
|
||
|
||
#endif
|
||
|
||
rentry = act_lkp(last);
|
||
|
||
#ifdef DEBUG
|
||
|
||
printf("***rentry->synval = %s\n",rentry->synval);
|
||
|
||
#endif
|
||
|
||
for (try=0;try<10;try++) {
|
||
|
||
rselect(rentry->synval,objs);
|
||
|
||
#ifdef DEBUG
|
||
|
||
printf("***try = %d; objs = %s\n",try,objs);
|
||
|
||
#endif
|
||
|
||
rsentence(objs,temp);
|
||
|
||
#ifdef DEBUG
|
||
|
||
printf("***temp = %s\n",temp);
|
||
|
||
len =
|
||
|
||
#endif
|
||
|
||
pmatch(temp,pat1,&matched);
|
||
|
||
#ifdef DEBUG
|
||
|
||
printf("***pat1 match status %d\n",len);
|
||
|
||
#endif
|
||
|
||
if (pmatch(rstory,pat2,&matched) == MATCH_SUCCESS) continue;
|
||
|
||
else if (pmatch(rstory,pat3,&matched) == MATCH_SUCCESS) continue;
|
||
|
||
else break;
|
||
|
||
}
|
||
|
||
subj = g_rsentv(SUBJ_RV);
|
||
|
||
verb = g_rsentv(VERB_RV);
|
||
|
||
if (subj == NULL) {
|
||
|
||
subj = malloc(SUBJ.length+1);
|
||
|
||
strncpy(subj,SUBJ.base+SUBJ.offset,SUBJ.length);
|
||
|
||
subj[SUBJ.length] = '\0';
|
||
|
||
s_rsentv(SUBJ_RV,subj);
|
||
|
||
}
|
||
|
||
else if (strlen(subj) > SUBJ.length) {
|
||
|
||
strncpy(subj,SUBJ.base+SUBJ.offset,SUBJ.length);
|
||
|
||
subj[SUBJ.length] = '\0';
|
||
|
||
}
|
||
|
||
else {
|
||
|
||
free(subj);
|
||
|
||
subj = malloc(SUBJ.length+1);
|
||
|
||
strncpy(subj,SUBJ.base+SUBJ.offset,SUBJ.length);
|
||
|
||
subj[SUBJ.length] = '\0';
|
||
|
||
s_rsentv(SUBJ_RV,subj);
|
||
|
||
}
|
||
|
||
if (verb == NULL) {
|
||
|
||
verb = malloc(VERB.length+1);
|
||
|
||
strncpy(verb,VERB.base+VERB.offset,VERB.length);
|
||
|
||
verb[VERB.length] = '\0';
|
||
|
||
s_rsentv(VERB_RV,verb);
|
||
|
||
}
|
||
|
||
else if (strlen(verb) > VERB.length) {
|
||
|
||
strncpy(verb,VERB.base+VERB.offset,VERB.length);
|
||
|
||
verb[VERB.length] = '\0';
|
||
|
||
}
|
||
|
||
else {
|
||
|
||
free(verb);
|
||
|
||
verb = malloc(VERB.length+1);
|
||
|
||
strncpy(verb,VERB.base+VERB.offset,VERB.length);
|
||
|
||
verb[VERB.length] = '\0';
|
||
|
||
s_rsentv(VERB_RV,verb);
|
||
|
||
}
|
||
|
||
rsentence("<REFUSAL>",temp);
|
||
|
||
strcat(rstory,temp);
|
||
|
||
len = strlen(list) + 1 + SUBJ.length + 7 + VERB.length + 5 +
|
||
|
||
strlen(last) + 2 + 1;
|
||
|
||
o = malloc(len);
|
||
|
||
strcpy(o," ");
|
||
|
||
strcat(o,subj);
|
||
|
||
strcat(o," won't ");
|
||
|
||
strcat(o,verb);
|
||
|
||
strcat(o," the ");
|
||
|
||
strcat(o,last);
|
||
|
||
strcat(o,", ");
|
||
|
||
strcat(o,list);
|
||
|
||
free(list);
|
||
|
||
list = o;
|
||
|
||
s_rsentv(LIST_RV,list);
|
||
|
||
free(last);
|
||
|
||
last = malloc(strlen(subj)+1);
|
||
|
||
strcpy(last,subj);
|
||
|
||
s_rsentv(LAST_RV,last);
|
||
|
||
}
|
||
|
||
strcpy(temp,list);
|
||
|
||
free(list);
|
||
|
||
while (pmatch(temp,wont,&matched) == MATCH_SUCCESS) {
|
||
|
||
strncpy(objs,temp,matched.offset);
|
||
|
||
strcpy(objs+matched.offset,"began to");
|
||
|
||
strcat(objs,temp+matched.offset+matched.length);
|
||
|
||
strcpy(temp,objs);
|
||
|
||
}
|
||
|
||
while (pmatch(temp,comma,&matched) == MATCH_SUCCESS) {
|
||
|
||
strncpy(objs,temp,matched.offset);
|
||
|
||
strcpy(objs+matched.offset,"; the");
|
||
|
||
strcat(objs,temp+matched.offset+matched.length);
|
||
|
||
strcpy(temp,objs);
|
||
|
||
}
|
||
|
||
s_rsentv(LIST_RV,temp);
|
||
|
||
rsentence("<PERSUADED>",objs);
|
||
|
||
strcat(rstory,objs);
|
||
|
||
#ifdef ROFF4_STRIDE
|
||
|
||
printf(".ow 80\n");
|
||
|
||
printf(".rm 70\n");
|
||
|
||
printf(".in 10\n");
|
||
|
||
printf(".sa Type in your name\n");
|
||
|
||
printf("..\\name\\\n");
|
||
|
||
printf(".ce 2\n");
|
||
|
||
printf("^BA Story for \\name\\\n");
|
||
|
||
printf("Generated on \\date\\ by a Stride 440^b\n");
|
||
|
||
printf(".sp 4\n");
|
||
|
||
printf(".ti +5\n");
|
||
|
||
#endif
|
||
|
||
len = 0;
|
||
|
||
o = rstory;
|
||
|
||
while (*o != '\0') {
|
||
|
||
if (*o == ' ' && len > 50) {
|
||
|
||
putchar('\n');
|
||
|
||
while (*o == ' ') o++;
|
||
|
||
len = 0;
|
||
|
||
}
|
||
|
||
putchar(*o);
|
||
|
||
len++; o++;
|
||
|
||
}
|
||
|
||
printf("\n\n");
|
||
|
||
}
|
||
|
||
SYNVAR *act_lkp(synn)
|
||
|
||
register char *synn;
|
||
|
||
{
|
||
|
||
register first,last,indx,cmp;
|
||
|
||
|
||
|
||
first = 0; last = act_cnt;
|
||
|
||
while (first < last) {
|
||
|
||
indx = ((last - first) >> 1) + first;
|
||
|
||
cmp = strcmp(synn,actions[indx].synname);
|
||
|
||
if (cmp == 0) return(&actions[indx]);
|
||
|
||
else if (cmp < 0) last = indx;
|
||
|
||
else first = indx+1;
|
||
|
||
}
|
||
|
||
return(NULL);
|
||
|
||
}
|
||
|
||
act_ins(name,val)
|
||
|
||
register char *name,*val;
|
||
|
||
{
|
||
|
||
int syncmp();
|
||
|
||
|
||
|
||
actions[act_cnt].synname = name;
|
||
|
||
actions[act_cnt].synval = val;
|
||
|
||
act_cnt++;
|
||
|
||
qsort(actions,act_cnt,sizeof(SYNVAR),syncmp);
|
||
|
||
}
|
||
|
||
|