home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / BBSCHAT.ZIP / CHAT.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1987-04-12  |  11.7 KB  |  454 lines

  1. program eliza;
  2.  
  3. const
  4.   bbs_chat_file = 'bbschat.net';    {script file name}
  5.  
  6. type
  7.   string_12 = string[12];           { global types }
  8.   string_25 = string[25];
  9.   string_80 = string[80];
  10.   string_255 = string[255];
  11.   bull_line_ptr = ^string_80;
  12.   charset = set of char;
  13.  
  14. const
  15.   alphabet : charset = ['A'..'Z'];      {global variables used in the bbs}
  16.   locase : array['A'..'Z'] of char =
  17.     ('a','b','c','d','e','f','g','h','i','j','k',
  18.      'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
  19.  
  20. var
  21.   case_switch : boolean;       {tells the input routine on the bbs to}
  22.                                {convert lower case to upper.  serves}
  23.                                {no purpose here, though}
  24.   text_file : text[4096];
  25.  
  26. procedure check_time_limit;
  27.  
  28. begin
  29. end;
  30.  
  31. procedure clear_buffer;
  32.  
  33. begin
  34. end;
  35.  
  36.   procedure chat_with_eliza;
  37.  
  38.   const
  39.     max_trans = 24;   {number of words to transpose}
  40.     max_reply = 20;   {the maximum number of replies for each set of responses}
  41.     max_key = 100;    {maximum number of key words}
  42.  
  43.   type
  44.     keyrec = record
  45.                word : string_25;
  46.                resp_set : integer;
  47.              end;
  48.  
  49.     reprec = record
  50.                tot_resp : integer;
  51.                last_resp : integer;
  52.                reply : array[0..max_reply] of bull_line_ptr;
  53.              end;
  54.  
  55.     key_word_array = array[1..max_key] of keyrec;
  56.  
  57.     resp_set_array = array[1..max_key] of reprec;
  58.  
  59.     transpose_array = array[1..max_trans] of string_12;
  60.  
  61.    var
  62.     tmp_str               : string_255;
  63.     end_of_chat           : boolean;
  64.     this_keyword          : string_255;
  65.     user_input            : string_255;
  66.     current_response      : integer;
  67.     i                     : integer;
  68.     key_no                : integer;
  69.     key                   : key_word_array;
  70.     key_found             : boolean;
  71.     keywords              : integer;
  72.     l                     : integer;
  73.     my_resp               : reprec;
  74.     my_str                : string_255;
  75.     no_key                : reprec;
  76.     null_input            : boolean;
  77.     null_resp             : reprec;
  78.     prog_output           : string_255;
  79.     puncs                 : set of char;
  80.     resp_no               : integer;
  81.     response              : string_255;
  82.     responses             : integer;
  83.     response_set          : resp_set_array;
  84.     save_key_no           : integer;
  85.     signon                : reprec;
  86.     transpose             : integer;
  87.     wordin                : transpose_array;
  88.     wordout               : transpose_array;
  89.     x                     : byte;
  90.  
  91.   function right(rstr : string_255; len : integer) : string_255;
  92.  
  93.   begin
  94.     right := copy(rstr,(length(rstr) - len + 1),len);
  95.   end;
  96.  
  97.   procedure write_line(tstr : string_255);
  98.  
  99.   var
  100.     i : integer;
  101.  
  102.     procedure write_char(char1 : char);
  103.  
  104.     begin
  105.       delay(60 + random(75));
  106.       if char1 in alphabet then
  107.         char1 := locase[char1];
  108.       write(char1);
  109.     end;
  110.  
  111.   begin
  112.     for i := 1 to length(tstr) do
  113.       begin
  114.         if random(50) = 0 then
  115.           begin
  116.             write_char(chr(random(26)+65));
  117.             delay(100 + random(100));
  118.             write_char(#8);
  119.           end;
  120.         write_char(tstr[i]);
  121.       end;
  122.     writeln;
  123.   end;
  124.  
  125.   procedure read_script;
  126.  
  127.   var
  128.     line_buffered : boolean;
  129.     line_no : integer;
  130.     rec_type : char;
  131.  
  132.     procedure read_script_line;
  133.  
  134.     begin
  135.       repeat
  136.         if not eof(text_file) then
  137.           begin
  138.             line_no := line_no + 1;
  139.             readln(text_file,tmp_str);
  140.             if tmp_str = '' then
  141.               tmp_str := ';';
  142.           end
  143.         else
  144.           tmp_str := #0;
  145.       until tmp_str[1] <> ';';
  146.     end;
  147.  
  148.     procedure add_transpose;
  149.  
  150.     begin
  151.       if transpose <> max_trans then
  152.         begin
  153.           transpose := transpose + 1;
  154.           tmp_str[0] := pred(tmp_str[0]);
  155.           wordin[transpose] := tmp_str;
  156.           read_script_line;
  157.           if tmp_str[1] = 'T' then
  158.             begin
  159.               delete(tmp_str,1,1);
  160.               tmp_str[0] := pred(tmp_str[0]);
  161.               wordout[transpose] := tmp_str;
  162.             end
  163.           else
  164.             end_of_chat := true;
  165.         end;
  166.     end;
  167.  
  168.     procedure add_keyword;
  169.  
  170.     begin
  171.       if keywords <> max_key then
  172.         begin
  173.           keywords := keywords + 1;
  174.           tmp_str[0] := pred(tmp_str[0]);
  175.           key[keywords].word := tmp_str;
  176.           key[keywords].resp_set := current_response;
  177.         end
  178.       else
  179.         end_of_chat := true;
  180.     end;
  181.  
  182.     procedure add_response(var tmp_resp : reprec);
  183.  
  184.     begin
  185.       with tmp_resp do
  186.         if tot_resp <= max_reply then
  187.           begin
  188.             new(reply[tot_resp]);
  189.             reply[tot_resp]^ := tmp_str;
  190.             tot_resp := tot_resp + 1;
  191.           end
  192.         else
  193.           end_of_chat := true;
  194.     end;
  195.  
  196.     procedure add_response_set;
  197.  
  198.     begin
  199.       with response_set[current_response] do
  200.         begin
  201.           responses := responses + 1;
  202.           tot_resp := 0;
  203.           while rec_type = 'R' do
  204.             begin
  205.               add_response(response_set[current_response]);
  206.               read_script_line;
  207.               rec_type := tmp_str[1];
  208.               delete(tmp_str,1,1);
  209.             end;
  210.         end;
  211.       current_response := current_response + 1;
  212.       line_buffered := (rec_type <> #0);
  213.     end;
  214.  
  215.   begin
  216.     assign(text_file, bbs_chat_file);
  217.     {$i-}
  218.     reset(text_file);
  219.     {$i+}
  220.     line_no := 0;
  221.     if ioresult <> 0 then
  222.       end_of_chat := true
  223.     else
  224.       begin
  225.         keywords := 0;
  226.         transpose := 0;
  227.         current_response := 1;
  228.         my_resp.tot_resp := 0;
  229.         null_resp.tot_resp := 0;
  230.         no_key.tot_resp := 0;
  231.         signon.tot_resp := 0;
  232.         responses := 0;
  233.         line_buffered := false;
  234.         while not (eof(text_file) or end_of_chat) do
  235.           begin
  236.             if not line_buffered then
  237.               begin
  238.                 read_script_line;
  239.                 rec_type := tmp_str[1];
  240.                 delete(tmp_str,1,1);
  241.               end;
  242.             line_buffered := false;
  243.             case rec_type of
  244.               'S' : add_response(signon);
  245.               'T' : add_transpose;
  246.               'N' : add_response(null_resp);
  247.               'M' : add_response(my_resp);
  248.               'X' : add_response(no_key);
  249.               'K' : add_keyword;
  250.               'R' : add_response_set;
  251.             else
  252.               end_of_chat := true;
  253.             end;
  254.           end;
  255.         close(text_file);
  256.       end;
  257.     if end_of_chat then
  258.       begin
  259.         writeln('Script file error.  Line ',line_no);
  260.         writeln;
  261.       end;
  262.   end;
  263.  
  264.   procedure get_response;
  265.  
  266.   begin
  267.     check_time_limit;
  268.     clear_buffer;
  269.     readln(user_input);
  270.     tmp_str := '';
  271.     i := 0;
  272.     for l := 1 to length(user_input) do
  273.       begin
  274.         if not (user_input[l] in puncs) then
  275.           begin
  276.             i := i + 1;
  277.             tmp_str[i] := upcase(user_input[l]);
  278.           end;
  279.       end;
  280.     tmp_str[0] := char(i);
  281.     while tmp_str[length(tmp_str)] = ' ' do
  282.       tmp_str[0] := pred(tmp_str[0]);
  283.     while tmp_str[1] = ' ' do
  284.       begin
  285.         tmp_str[1] := #0;
  286.         delete(tmp_str,1,1);
  287.       end;
  288.     null_input := (tmp_str = '');
  289.     user_input := '  ' + tmp_str + '  ';
  290.     if copy(user_input,3,4) = 'QUIT' then
  291.       begin
  292.         writeln;
  293.         write_line('NICE TALKING TO YOU...');
  294.         end_of_chat := true;
  295.       end;
  296.   end;
  297.  
  298.   procedure find_keyword;
  299.  
  300.   begin
  301.     key_found := false;
  302.     this_keyword := '';
  303.     prog_output := '';
  304.     key_no := 0;
  305.     while (not key_found) and (key_no <> keywords) do
  306.       begin
  307.         key_no := key_no + 1;
  308.         for i := 1 to (length(user_input)-length(key[key_no].word)+1) do
  309.           if copy(user_input,i,length(key[key_no].word)) =
  310.              key[key_no].word then
  311.             begin
  312.               this_keyword := key[key_no].word;
  313.               l := i;
  314.               key_found := true;
  315.             end;
  316.       end;
  317.     if key_found then
  318.       prog_output := ' ' +
  319.         right(user_input,(length(user_input)-length(this_keyword)-l+1)) +
  320.         ' ';
  321.   end;
  322.  
  323.   procedure conjugate_and_transpose;
  324.  
  325.   begin
  326.     l := 1;
  327.     while l <= length(prog_output) do
  328.       begin
  329.         for i := 1 to transpose do
  330.           if (copy(prog_output,l,length(wordin[i])) = wordin[i]) then
  331.             begin
  332.               prog_output := copy(prog_output,1,l-1) + wordout[i] +
  333.                 right(prog_output,(length(prog_output) - l - length(wordin[i]) + 1));
  334.               l := l + length(wordout[i]) - 2;
  335.             end;
  336.         l := l + 1;
  337.       end;
  338.     while prog_output[1] = ' ' do
  339.       begin
  340.         prog_output[1] := #0;
  341.         delete(prog_output,1,1);
  342.       end;
  343.     x := length(prog_output);
  344.     while prog_output[x] = ' ' do
  345.       x := x-1;
  346.     prog_output[0] := chr(x);
  347.     if this_keyword = 'MY ' then
  348.       my_str := prog_output;
  349.   end;
  350.  
  351.   procedure show_response(var rset : reprec; var prog_out : string_255);
  352.  
  353.   begin
  354.     with rset do
  355.       begin
  356.         resp_no := random(tot_resp);
  357.         if tot_resp > 1 then
  358.           while resp_no = last_resp do
  359.             resp_no := random(tot_resp);
  360.         response := reply[resp_no]^;
  361.         last_resp := resp_no;
  362.         i := pos('*',response);
  363.         if i = 0 then
  364.           write_line(response)
  365.         else
  366.           begin
  367.             if i <> length(response)-1 then
  368.               tmp_str := copy(response,1,(i-1)) +
  369.                           ' ' + prog_out + ' ' +
  370.                           copy(response,(i+1),length(response)-i)
  371.             else
  372.               tmp_str := copy(response,1,(i-1)) +
  373.                           ' ' + prog_out + response[i+1];
  374.             write_line(tmp_str);
  375.           end;
  376.       end;
  377.     writeln;
  378.   end;
  379.  
  380.   procedure show_reply;
  381.  
  382.   begin
  383.     writeln;
  384.     if (not key_found) then
  385.       begin
  386.         if (my_str <> '') and (random(5) = 0) then
  387.           show_response(my_resp,my_str)
  388.         else
  389.           begin
  390.             tmp_str := '';
  391.             if null_input then
  392.               show_response(null_resp,tmp_str)
  393.             else
  394.               show_response(no_key,tmp_str);
  395.           end;
  396.       end
  397.     else
  398.       begin
  399.         current_response := key[key_no].resp_set;
  400.         show_response(response_set[current_response],prog_output);
  401.       end;
  402.   end;
  403.  
  404.   begin
  405.     my_resp.last_resp := -1;
  406.     null_resp.last_resp := -1;
  407.     no_key.last_resp := -1;
  408.     for i := 1 to max_key do
  409.       response_set[i].last_resp := -1;
  410.     puncs := ['.', ',', ';', '!', '?'];
  411.     my_str := '';
  412.     end_of_chat := false;
  413.     case_switch := false;
  414.     writeln('Enter QUIT to quit chatting');
  415.     writeln;
  416.     read_script;
  417.     if not end_of_chat then
  418.       begin
  419.         i := random(signon.tot_resp);
  420.         write_line(signon.reply[i]^);
  421.         writeln;
  422.         get_response;
  423.         while not end_of_chat do
  424.           begin
  425.             find_keyword;
  426.             if key_found then
  427.               conjugate_and_transpose;
  428.             show_reply;
  429.             get_response;
  430.           end;
  431.       end;
  432.     case_switch := true;
  433.     with signon do
  434.       for i := 1 to tot_resp do
  435.         dispose(reply[i-1]);
  436.     with null_resp do
  437.       for i := 1 to tot_resp do
  438.         dispose(reply[i-1]);
  439.     with no_key do
  440.       for i := 1 to tot_resp do
  441.         dispose(reply[i-1]);
  442.     with my_resp do
  443.       for i := 1 to tot_resp do
  444.         dispose(reply[i-1]);
  445.     for l := 1 to responses do
  446.       with response_set[l] do
  447.         for i := 1 to tot_resp do
  448.           dispose(reply[i-1]);
  449.   end;
  450.  
  451. begin
  452.   randomize;
  453.   chat_with_eliza;
  454. end.