home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / eliza / chat.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1994-04-21  |  11.8 KB  |  456 lines

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