home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / cpm68k / snobol4.lbr / RSTORY.CQ / RSTORY.C
Text File  |  1986-05-22  |  8KB  |  318 lines

  1. /* -*-c,save-*- */
  2. /*
  3.  * rstory.c - random story generator
  4.  * Robert Heller. Created: Sun Feb 23, 1986 15:50:57.96
  5.  * Last Mod: 
  6.  * 
  7.  * (c) Copyright 1986 by Robert Heller
  8.  *     All Rights Reserved
  9.  * 
  10.  * 
  11.  */
  12.  
  13. #include <stdio.h>
  14.  
  15. #include "patdef.h"
  16.  
  17. #define LOCAL static
  18.  
  19. /* #define DEBUG /* debugging hacks */
  20.  
  21. /* #define ROFF4_STRIDE /* for roff4 hacks (output reformatting) */
  22.  
  23. #ifdef DEBUG
  24. #define LOCAL /* static */
  25. #endif
  26.  
  27. #define CHAR_RV 0
  28. #define PET_RV 1
  29. #define BAR_RV 2
  30. #define LAST_RV 3
  31. #define SUBJ_RV 4
  32. #define VERB_RV 5
  33. #define LIST_RV 6
  34.  
  35. LOCAL PATTERN_NODE *BB,*SB,*ph1,*ph2,*ph3,*ph4,*pat1,*pat2,*pat3,*wont,*comma;
  36.  
  37. typedef struct {
  38.     char *synname;
  39.     char *synval;
  40.     } SYNVAR;
  41.  
  42. SYNVAR *rsen_lkp();
  43.  
  44. LOCAL STRING_DESCR SUBJ_VB,OBJS,VAR,OBJ,SUBJ,VERB;
  45. LOCAL char objs[4096],var[256];
  46. LOCAL char temp[4096],obj[256];
  47.  
  48. ARG_DESCR *acons();
  49. char *malloc(),*calloc(),*index(),*fgets(),*g_rsentv();
  50. FILE *fopen();
  51. SYNVAR *rsen_lkp();
  52.  
  53. #define MAXACT 256
  54.  
  55. LOCAL SYNVAR actions[MAXACT];
  56. LOCAL int act_cnt = 0;
  57.  
  58. LOCAL char rstory[30000];
  59.  
  60. main()
  61. {
  62.     register FILE *actfile;
  63.     char actline[256];
  64.     STRING_DESCR matched;
  65.     register SYNVAR *rentry;
  66.     register char *sv,*o,*last,*subj,*verb,*list;
  67.     register int len,try;
  68.     SYNVAR *act_lkp();
  69.  
  70.     srand(gettime());
  71.     rsent_init("RSTORY.SYN");
  72.     BB = breakk_c(" \t");
  73.     SB = span_c(" \t");
  74.     pat1 = cassign(BB,acons(STRING,&SUBJ));
  75.     pat1 = concat(pat1,SB);
  76.     pat1 = concat(pat1,cassign(REM,acons(STRING,&VERB)));
  77.     pat2 = concat(c_lit_string(" "),
  78.               concat(lit_string(&SUBJ),c_lit_string(" ")));
  79.     pat3 = concat(c_lit_string(" "),
  80.               concat(lit_string(&VERB),c_lit_string(" ")));
  81.     wont = c_lit_string("won't");
  82.     comma = c_lit_string(",");
  83.     ph1 = concat(BB,SB);
  84.     ph1 = concat(ph1,BB);
  85.     ph1 = cassign(ph1,acons(STRING,&SUBJ_VB));
  86.     ph1 = concat(ph1,SB);
  87.     ph1 = concat(ph1,cassign(REM,acons(STRING,&OBJS)));
  88.     ph2 = cassign(breakk_c(">"),acons(STRING,&VAR));
  89.     ph2 = concat(ph2,c_lit_string(">"));
  90.     ph2 = concat(c_lit_string("<"),ph2);
  91.     ph2 = concat(pos(0),ph2);
  92.     ph3 = concat(pos(0),c_lit_string("|"));
  93.     ph4 = concat(cassign(breakk_c("|"),acons(STRING,&OBJ)),c_lit_string("|"));
  94.  
  95.     actfile = fopen("RSTORY.ACT","r");
  96.     if (actfile == NULL) {
  97.     perror("rstory (fopen(actions))");
  98.     abort(0);
  99.     }
  100.     for (;;) {
  101.     if (fgets(actline,256,actfile) == NULL) break;
  102.     trim(actline);
  103. #ifdef DEBUG
  104.     printf("***actline = %s\n",actline);
  105. #endif
  106.     if (strcmp(actline,"END") == 0) break;
  107.     pmatch(actline,ph1,&matched);
  108.     strncpy(objs,OBJS.base+OBJS.offset,OBJS.length);
  109.     objs[OBJS.length] = '|';
  110.     objs[OBJS.length+1] = '\0';
  111.     for (;;) {
  112. #ifdef DEBUG
  113.         printf("***objs = %s\n",objs);
  114. #endif
  115.         if (pmatch(objs,ph2,&matched) == MATCH_SUCCESS) {
  116.         strncpy(var,VAR.base+VAR.offset,VAR.length);
  117.         var[VAR.length] = '\0';
  118.         rentry = rsen_lkp(var);
  119.         if (rentry == NULL) strcpy(objs,objs+matched.length);
  120.         else {
  121.             strcpy(temp,rentry->synval);
  122.             strcat(temp,objs+matched.length);
  123.             strcpy(objs,temp);
  124.             }
  125.         }
  126.         if (pmatch(objs,ph3,&matched) == MATCH_SUCCESS) {
  127.         strcpy(objs,objs+1);
  128.         continue;
  129.         }
  130.         if (pmatch(objs,ph4,&matched) != MATCH_SUCCESS) break;
  131.         strncpy(obj,OBJ.base+OBJ.offset,OBJ.length);
  132.         obj[OBJ.length] = '\0';
  133.         strcpy(objs,objs+matched.length);
  134.         rentry = act_lkp(obj);
  135.         if (rentry == NULL) {
  136.         sv = malloc(SUBJ_VB.length+2);
  137.         strncpy(sv+1,SUBJ_VB.base+SUBJ_VB.offset,SUBJ_VB.length);
  138.         *sv = '|';
  139.         sv[SUBJ_VB.length+1] = '\0';
  140.         o = malloc(OBJ.length+1);
  141.         strcpy(o,obj);
  142.         act_ins(o,sv);
  143.         }
  144.         else {
  145.         sv = malloc(strlen(rentry->synval)+SUBJ_VB.length+2);
  146.         strcpy(sv,rentry->synval);
  147.         strcat(sv,"|");
  148.         strncat(sv,SUBJ_VB.base+SUBJ_VB.offset,SUBJ_VB.length);
  149.         sv[SUBJ_VB.length+strlen(rentry->synval)+1] = '\0';
  150.         free(rentry->synval);
  151.         rentry->synval = sv;
  152.         }
  153.         }
  154.     }
  155.     rsentence("<OPENING>",rstory);
  156.     o = g_rsentv(PET_RV);
  157.     sv = g_rsentv(BAR_RV);
  158.     len = strlen(o) + 2 + strlen(" won't jump over the ") + strlen(sv) + 1;
  159.     list = malloc(len);
  160.     strcpy(list,"  ");
  161.     strcat(list,o);
  162.     strcat(list," won't jump over the ");
  163.     strcat(list,sv);
  164.     s_rsentv(LIST_RV,list);
  165.     last = malloc(strlen(o)+1);
  166.     strcpy(last,o);
  167.     s_rsentv(LAST_RV,last);
  168.     while (strlen(list) < 175) {
  169. #ifdef DEBUG
  170.     printf("***list = %s\n***rstory = %s\n",list,rstory);
  171. #endif
  172.     rentry = act_lkp(last);
  173. #ifdef DEBUG
  174.     printf("***rentry->synval = %s\n",rentry->synval);
  175. #endif
  176.     for (try=0;try<10;try++) {
  177.         rselect(rentry->synval,objs);
  178. #ifdef DEBUG
  179.         printf("***try = %d; objs = %s\n",try,objs);
  180. #endif
  181.         rsentence(objs,temp);
  182. #ifdef DEBUG
  183.         printf("***temp = %s\n",temp);
  184.         len = 
  185. #endif
  186.         pmatch(temp,pat1,&matched);
  187. #ifdef DEBUG
  188.         printf("***pat1 match status %d\n",len);
  189. #endif
  190.         if (pmatch(rstory,pat2,&matched) == MATCH_SUCCESS) continue;
  191.         else if (pmatch(rstory,pat3,&matched) == MATCH_SUCCESS) continue;
  192.         else break;
  193.         }
  194.     subj = g_rsentv(SUBJ_RV);
  195.     verb = g_rsentv(VERB_RV);
  196.     if (subj == NULL) {
  197.         subj = malloc(SUBJ.length+1);
  198.         strncpy(subj,SUBJ.base+SUBJ.offset,SUBJ.length);
  199.         subj[SUBJ.length] = '\0';
  200.         s_rsentv(SUBJ_RV,subj);
  201.         }
  202.     else if (strlen(subj) > SUBJ.length) {
  203.         strncpy(subj,SUBJ.base+SUBJ.offset,SUBJ.length);
  204.         subj[SUBJ.length] = '\0';
  205.         }
  206.     else {
  207.         free(subj);
  208.         subj = malloc(SUBJ.length+1);
  209.         strncpy(subj,SUBJ.base+SUBJ.offset,SUBJ.length);
  210.         subj[SUBJ.length] = '\0';
  211.         s_rsentv(SUBJ_RV,subj);
  212.         }
  213.     if (verb == NULL) {
  214.         verb = malloc(VERB.length+1);
  215.         strncpy(verb,VERB.base+VERB.offset,VERB.length);
  216.         verb[VERB.length] = '\0';
  217.         s_rsentv(VERB_RV,verb);
  218.         }
  219.     else if (strlen(verb) > VERB.length) {
  220.         strncpy(verb,VERB.base+VERB.offset,VERB.length);
  221.         verb[VERB.length] = '\0';
  222.         }
  223.     else {
  224.         free(verb);
  225.         verb = malloc(VERB.length+1);
  226.         strncpy(verb,VERB.base+VERB.offset,VERB.length);
  227.         verb[VERB.length] = '\0';
  228.         s_rsentv(VERB_RV,verb);
  229.         }
  230.     rsentence("<REFUSAL>",temp);
  231.     strcat(rstory,temp);
  232.     len = strlen(list) + 1 + SUBJ.length + 7 + VERB.length + 5 +
  233.           strlen(last) + 2 + 1;
  234.     o = malloc(len);
  235.     strcpy(o," ");
  236.     strcat(o,subj);
  237.     strcat(o," won't ");
  238.     strcat(o,verb);
  239.     strcat(o," the ");
  240.     strcat(o,last);
  241.     strcat(o,", ");
  242.     strcat(o,list);
  243.     free(list);
  244.     list = o;
  245.     s_rsentv(LIST_RV,list);
  246.     free(last);
  247.     last = malloc(strlen(subj)+1);
  248.     strcpy(last,subj);
  249.     s_rsentv(LAST_RV,last);
  250.     }
  251.     strcpy(temp,list);
  252.     free(list);
  253.     while (pmatch(temp,wont,&matched) == MATCH_SUCCESS) {
  254.     strncpy(objs,temp,matched.offset);
  255.     strcpy(objs+matched.offset,"began to");
  256.     strcat(objs,temp+matched.offset+matched.length);
  257.     strcpy(temp,objs);
  258.     }
  259.     while (pmatch(temp,comma,&matched) == MATCH_SUCCESS) {
  260.     strncpy(objs,temp,matched.offset);
  261.     strcpy(objs+matched.offset,"; the");
  262.     strcat(objs,temp+matched.offset+matched.length);
  263.     strcpy(temp,objs);
  264.     }
  265.     s_rsentv(LIST_RV,temp);
  266.     rsentence("<PERSUADED>",objs);
  267.     strcat(rstory,objs);
  268. #ifdef ROFF4_STRIDE
  269.     printf(".ow 80\n");
  270.     printf(".rm 70\n");
  271.     printf(".in 10\n");
  272.     printf(".sa Type in your name\n");
  273.     printf("..\\name\\\n");
  274.     printf(".ce 2\n");
  275.     printf("^BA Story for \\name\\\n");
  276.     printf("Generated on \\date\\ by a Stride 440^b\n");
  277.     printf(".sp 4\n");
  278.     printf(".ti +5\n");
  279. #endif
  280.     len = 0;
  281.     o = rstory;
  282.     while (*o != '\0') {
  283.     if (*o == ' ' && len > 50) {
  284.         putchar('\n');
  285.         while (*o == ' ') o++;
  286.         len = 0;
  287.         }
  288.     putchar(*o);
  289.     len++; o++;
  290.     }
  291.     printf("\n\n");
  292.     }
  293. SYNVAR *act_lkp(synn)
  294. register char *synn;
  295. {
  296.     register first,last,indx,cmp;
  297.     
  298.     first = 0; last = act_cnt;
  299.     while (first < last) {
  300.     indx = ((last - first) >> 1) + first;
  301.     cmp = strcmp(synn,actions[indx].synname);
  302.     if (cmp == 0) return(&actions[indx]);
  303.     else if (cmp < 0) last = indx;
  304.     else first = indx+1;
  305.     }
  306.     return(NULL);
  307.     }
  308. act_ins(name,val)
  309. register char *name,*val;
  310. {
  311.     int syncmp();
  312.  
  313.     actions[act_cnt].synname = name;
  314.     actions[act_cnt].synval = val;
  315.     act_cnt++;
  316.     qsort(actions,act_cnt,sizeof(SYNVAR),syncmp);
  317.     }
  318.