home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
cpm68k
/
snobol4.lbr
/
RSTORY.CQ
/
RSTORY.C
Wrap
Text File
|
1986-05-22
|
8KB
|
318 lines
/* -*-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);
}