⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 megahal.c

📁 megahal is the conversation simulators conversing with a user in natural language. The program will
💻 C
📖 第 1 页 / 共 5 页
字号:
	exithal();	break;    case SAVE:	save_model("megahal.brn", model);	break;    case DELAY:	typing_delay=!typing_delay;	printf("MegaHAL typing is now %s.\n", typing_delay?"on":"off");	return 1;    case SPEECH:	speech=!speech;	printf("MegaHAL speech is now %s.\n", speech?"on":"off");	return 1;    case HELP:	help();	return 1;    case VOICELIST:	listvoices();	return 1;    case VOICE:	changevoice(words, position);	return 1;    case BRAIN:	change_personality(words, position, &model);	make_greeting(greets);	output=generate_reply(model, greets);	write_output(output);	return 1;    case QUIET:	quiet=!quiet;	return 1;    default:	return 0;    }    return 0;}/*   megahal_cleanup --   Clean up everything. Prepare for exit.  */void megahal_cleanup(void){    save_model("megahal.brn", model);#ifdef AMIGA    CloseLocale(_AmigaLocale);#endif}/*---------------------------------------------------------------------------*//* *		Function:	Execute_Command * *		Purpose:		Detect whether the user has typed a command, and *						execute the corresponding function. */COMMAND_WORDS execute_command(DICTIONARY *words, int *position){    register unsigned int i;    register unsigned int j;    /*     *		If there is only one word, then it can't be a command.     */    *position=words->size+1;    if(words->size<=1) return(UNKNOWN);    /*     *		Search through the word array.  If a command prefix is found,     *		then try to match the following word with a command word.  If     *		a match is found, then return a command identifier.  If the     *		Following word is a number, then change the judge.  Otherwise,     *		continue the search.     */    for(i=0; i<words->size-1; ++i)	/*	 *		The command prefix was found.	 */	if(words->entry[i].word[words->entry[i].length - 1] == '#') {	    /*	     *		Look for a command word.	     */	    for(j = 0; j < COMMAND_SIZE; ++j)		if(wordcmp(command[j].word, words->entry[i + 1]) == 0) {		    *position = i + 1;		    return(command[j].command);		}	}    return(UNKNOWN);}/*---------------------------------------------------------------------------*//* *		Function:	ExitHAL * *		Purpose:		Terminate the program. */void exithal(void){#ifdef __mac_os    /*     *		Must be called because it does use some system memory     */    if (gSpeechChannel) {	StopSpeech(gSpeechChannel);	DisposeSpeechChannel(gSpeechChannel);	gSpeechChannel = nil;    }#endif    exit(0);}/*---------------------------------------------------------------------------*//* *		Function:	Read_Input * *		Purpose:		Read an input string from the user. */char *read_input(char *prompt){    static char *input=NULL;    bool finish;    int length;    int c;    /*     *		Perform some initializations.  The finish boolean variable is used     *		to detect a double line-feed, while length contains the number of     *		characters in the input string.     */    finish=FALSE;    length=0;    if(input==NULL) {	input=(char *)malloc(sizeof(char));	if(input==NULL) {	    error("read_input", "Unable to allocate the input string");	    return(input);	}    }    /*     *		Display the prompt to the user.     */    fprintf(stdout, prompt);    fflush(stdout);    /*     *		Loop forever, reading characters and putting them into the input     *		string.     */    while(TRUE) {	/*	 *		Read a single character from stdin.	 */	c=getc(stdin);	/*	 *		If the character is a line-feed, then set the finish variable	 *		to TRUE.  If it already is TRUE, then this is a double line-feed,	 *		in which case we should exit.  After a line-feed, display the	 *		prompt again, and set the character to the space character, as	 *		we don't permit linefeeds to appear in the input.	 */	if((char)(c)=='\n') {	    if(finish==TRUE) break;	    fprintf(stdout, prompt);	    fflush(stdout);	    finish=TRUE;	    c=32;	} else {	    finish=FALSE;	}	/*	 *		Re-allocate the input string so that it can hold one more	 *		character.	 */	++length;	input=(char *)realloc((char *)input,sizeof(char)*(length+1));	if(input==NULL) {	    error("read_input", "Unable to re-allocate the input string");	    return(NULL);	}	/*	 *		Add the character just read to the input string.	 */	input[length-1]=(char)c;	input[length]='\0';    }    while(isspace(input[length-1])) --length;    input[length]='\0';    /*     *		We have finished, so return the input string.     */    return(input);}/*---------------------------------------------------------------------------*//* *		Function:	Initialize_Error * *		Purpose:		Close the current error file pointer, and open a new one. */bool initialize_error(char *filename){    if(errorfp!=stderr) fclose(errorfp);    if(filename==NULL) return(TRUE);    errorfp = fopen(filename, "a");    if(errorfp==NULL) {	errorfp=stderr;	return(FALSE);    }    return(print_header(errorfp));}/*---------------------------------------------------------------------------*//* *		Function:	Error * *		Purpose:		Print the specified message to the error file. */void error(char *title, char *fmt, ...){    va_list argp;    fprintf(errorfp, "%s: ", title);    va_start(argp, fmt);    vfprintf(errorfp, fmt, argp);    va_end(argp);    fprintf(errorfp, ".\n");    fflush(errorfp);    fprintf(stderr, "MegaHAL died for some reason; check the error log.\n");    exit(1);}/*---------------------------------------------------------------------------*/bool warn(char *title, char *fmt, ...){    va_list argp;    fprintf(errorfp, "%s: ", title);    va_start(argp, fmt);    vfprintf(errorfp, fmt, argp);    va_end(argp);    fprintf(errorfp, ".\n");    fflush(errorfp);    fprintf(stderr, "MegaHAL emitted a warning; check the error log.\n");    return(TRUE);}/*---------------------------------------------------------------------------*//* *		Function:	Initialize_Status * *		Purpose:		Close the current status file pointer, and open a new one. */bool initialize_status(char *filename){    if(statusfp!=stdout) fclose(statusfp);    if(filename==NULL) return(FALSE);    statusfp=fopen(filename, "a");    if(statusfp==NULL) {	statusfp=stdout;	return(FALSE);    }    return(print_header(statusfp));}/*---------------------------------------------------------------------------*//* *		Function:	Status * *		Purpose:		Print the specified message to the status file. */bool status(char *fmt, ...){    va_list argp;    va_start(argp, fmt);    vfprintf(statusfp, fmt, argp);    va_end(argp);    fflush(statusfp);    return(TRUE);}/*---------------------------------------------------------------------------*//* *		Function:	Print_Header * *		Purpose:		Display a copyright message and timestamp. */bool print_header(FILE *file){    time_t clock;    char timestamp[1024];    struct tm *local;    clock=time(NULL);    local=localtime(&clock);    strftime(timestamp, 1024, "Start at: [%Y/%m/%d %H:%M:%S]\n", local);    fprintf(file, "MegaHALv8\n");    fprintf(file, "Copyright (C) 1998 Jason Hutchens\n");    fprintf(file, timestamp);    fflush(file);    return(TRUE);}/*---------------------------------------------------------------------------*//* *    Function:   Write_Output * *    Purpose:    Display the output string. */void write_output(char *output){    char *formatted;    char *bit;    capitalize(output);    speak(output);    width=75;    formatted=format_output(output);    delay(formatted);    width=64;    formatted=format_output(output);    bit=strtok(formatted, "\n");    if(bit==NULL) (void)status("MegaHAL: %s\n", formatted);    while(bit!=NULL) {	(void)status("MegaHAL: %s\n", bit);	bit=strtok(NULL, "\n");    }}/*---------------------------------------------------------------------------*//* *		Function:	Capitalize * *		Purpose:		Convert a string to look nice. */void capitalize(char *string){    register unsigned int i;    bool start=TRUE;    for(i=0; i<strlen(string); ++i) {	if(isalpha(string[i])) {	    if(start==TRUE) string[i]=(char)toupper((int)string[i]);	    else string[i]=(char)tolower((int)string[i]);	    start=FALSE;	}	if((i>2)&&(strchr("!.?", string[i-1])!=NULL)&&(isspace(string[i])))	    start=TRUE;    }}/*---------------------------------------------------------------------------*//* *		Function:	Upper * *		Purpose:		Convert a string to its uppercase representation. */void upper(char *string){    register unsigned int i;    for(i=0; i<strlen(string); ++i) string[i]=(char)toupper((int)string[i]);}/*---------------------------------------------------------------------------*//* *    Function:   Write_Input * *    Purpose:    Log the user's input */void write_input(char *input){    char *formatted;    char *bit;    width=64;    formatted=format_output(input);    bit=strtok(formatted, "\n");    if(bit==NULL) (void)status("User:    %s\n", formatted);    while(bit!=NULL) {	(void)status("User:    %s\n", bit);	bit=strtok(NULL, "\n");    }}/*---------------------------------------------------------------------------*//* *    Function:   Format_Output * *    Purpose:    Format a string to display nicely on a terminal of a given *                width. */static char *format_output(char *output){    static char *formatted=NULL;    register unsigned int i,j,c;    int l;    if(formatted==NULL) {	formatted=(char *)malloc(sizeof(char));	if(formatted==NULL) {	    error("format_output", "Unable to allocate formatted");	    return("ERROR");	}    }    formatted=(char *)realloc((char *)formatted, sizeof(char)*(strlen(output)+2));    if(formatted==NULL) {	error("format_output", "Unable to re-allocate formatted");	return("ERROR");    }    l=0;    j=0;    for(i=0; i<strlen(output); ++i) {	if((l==0)&&(isspace(output[i]))) continue;	formatted[j]=output[i];	++j;	++l;	if(!nowrap)	    if(l>=width)		for(c=j-1; c>0; --c)		    if(formatted[c]==' ') {			formatted[c]='\n';			l=j-c-1;			break;		    }    }    if((j>0)&&(formatted[j-1]!='\n')) {	formatted[j]='\n';	++j;    }    formatted[j]='\0';    return(formatted);}/*---------------------------------------------------------------------------*//* *		Function:	Add_Word * *		Purpose:		Add a word to a dictionary, and return the identifier *						assigned to the word.  If the word already exists in *						the dictionary, then return its current identifier *						without adding it again. */BYTE2 add_word(DICTIONARY *dictionary, STRING word){    register int i;    int position;    bool found;    /*     *		If the word's already in the dictionary, there is no need to add it     */    position=search_dictionary(dictionary, word, &found);    if(found==TRUE) goto succeed;    /*     *		Increase the number of words in the dictionary     */    dictionary->size+=1;    /*     *		Allocate one more entry for the word index     */    if(dictionary->index==NULL) {	dictionary->index=(BYTE2 *)malloc(sizeof(BYTE2)*					  (dictionary->size));    } else {	dictionary->index=(BYTE2 *)realloc((BYTE2 *)					   (dictionary->index),sizeof(BYTE2)*(dictionary->size));    }    if(dictionary->index==NULL) {	error("add_word", "Unable to reallocate the index.");	goto fail;    }    /*     *		Allocate one more entry for the word array     */    if(dictionary->entry==NULL) {	dictionary->entry=(STRING *)malloc(sizeof(STRING)*(dictionary->size));    } else {	dictionary->entry=(STRING *)realloc((STRING *)(dictionary->entry),					    sizeof(STRING)*(dictionary->size));    }    if(dictionary->entry==NULL) {	error("add_word", "Unable to reallocate the dictionary to %d elements.", dictionary->size);	goto fail;    }    /*     *		Copy the new word into the word array     */    dictionary->entry[dictionary->size-1].length=word.length;    dictionary->entry[dictionary->size-1].word=(char *)malloc(sizeof(char)*							      (word.length));    if(dictionary->entry[dictionary->size-1].word==NULL) {	error("add_word", "Unable to allocate the word.");	goto fail;    }    for(i=0; i<word.length; ++i)	dictionary->entry[dictionary->size-1].word[i]=word.word[i];    /*     *		Shuffle the word index to keep it sorted alphabetically     */    for(i=(dictionary->size-1); i>position; --i)	dictionary->index[i]=dictionary->index[i-1];    /*     *		Copy the new symbol identifier into the word index

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -