add directory study
This commit is contained in:
305
study/linux-travel/MINIX-1.5/1.5/Source/commands/animals.c
Normal file
305
study/linux-travel/MINIX-1.5/1.5/Source/commands/animals.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/* animals - guessing game Authors: Terrence W. Holm & Edwin L. Froese */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sgtty.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ANIMALS "/usr/lib/animals"
|
||||
#define DEFAULT_ANIMAL "beaver"
|
||||
#define MAX_NODES 999 /* Enough for 500 animals */
|
||||
#define MAX_LINE 90
|
||||
|
||||
void Abort();
|
||||
char *Get_Animal();
|
||||
char *Get_Question();
|
||||
char *A_or_An();
|
||||
char *Alloc();
|
||||
|
||||
struct node {
|
||||
int question;
|
||||
char *text;
|
||||
int yes;
|
||||
int no;
|
||||
} animals[MAX_NODES];
|
||||
|
||||
int count = 0;
|
||||
struct sgttyb old_tty_mode;
|
||||
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
|
||||
{
|
||||
char *animal_file = ANIMALS;
|
||||
|
||||
if (argc > 2) {
|
||||
fprintf(stderr, "Usage: %s [ data_base ]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc == 2) animal_file = argv[1];
|
||||
|
||||
ioctl(0, TIOCGETP, &old_tty_mode);
|
||||
|
||||
signal(SIGINT, Abort);
|
||||
signal(SIGQUIT, Abort);
|
||||
|
||||
if (access(animal_file, R_OK) == 0)
|
||||
Read_Animals(animal_file);
|
||||
else {
|
||||
animals[0].question = 0;
|
||||
animals[0].text = DEFAULT_ANIMAL;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
while (Ask("\nAre you thinking of an animal?")) {
|
||||
int i = 0;
|
||||
|
||||
while (1) {
|
||||
if (animals[i].question) {
|
||||
if (Ask(animals[i].text))
|
||||
i = animals[i].yes;
|
||||
else
|
||||
i = animals[i].no;
|
||||
} else {
|
||||
printf("Were you thinking of %s %s",
|
||||
A_or_An(animals[i].text), animals[i].text);
|
||||
|
||||
if (Ask("?")) printf("I knew it!\n");
|
||||
|
||||
else {
|
||||
/* Insert a new question and animal name */
|
||||
|
||||
if (count + 2 > MAX_NODES)
|
||||
Error("Too many animal names");
|
||||
|
||||
animals[count].question = 0;
|
||||
animals[count].text = animals[i].text;
|
||||
++count;
|
||||
|
||||
animals[count].question = 0;
|
||||
printf("What animal were you thinking of? ");
|
||||
animals[count].text = Get_Animal();
|
||||
++count;
|
||||
|
||||
animals[i].question = 1;
|
||||
printf("What question would distinguish %s %s from\n%s %s? ",
|
||||
A_or_An(animals[count - 2].text), animals[count - 2].text,
|
||||
A_or_An(animals[count - 1].text), animals[count - 1].text);
|
||||
|
||||
animals[i].text = Get_Question();
|
||||
|
||||
printf("For %s %s, the answer would be",
|
||||
A_or_An(animals[count - 1].text), animals[count - 1].text);
|
||||
|
||||
if (Ask("?")) {
|
||||
animals[i].yes = count - 1;
|
||||
animals[i].no = count - 2;
|
||||
} else {
|
||||
animals[i].yes = count - 2;
|
||||
animals[i].no = count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} /* End while ( 1 ) */
|
||||
|
||||
}
|
||||
|
||||
|
||||
ioctl(0, TIOCSETP, &old_tty_mode);
|
||||
|
||||
printf("\nThank you for playing \"animals\".\n");
|
||||
printf("The animal data base is now being updated.\n");
|
||||
|
||||
Write_Animals(animal_file);
|
||||
|
||||
sleep(1);
|
||||
printf("\nBye.\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/* Reading and writing the animal data base */
|
||||
|
||||
|
||||
Read_Animals(animal_file)
|
||||
char *animal_file;
|
||||
|
||||
{
|
||||
FILE *f;
|
||||
char buffer[MAX_LINE];
|
||||
|
||||
if ((f = fopen(animal_file, "r")) == NULL)
|
||||
Error("Can not open animal data base");
|
||||
|
||||
while (fgets(buffer, MAX_LINE, f) != NULL) {
|
||||
int string_length;
|
||||
char *string;
|
||||
|
||||
buffer[strlen(buffer) - 1] = '\0';
|
||||
|
||||
swab(buffer, buffer, strlen(buffer));
|
||||
|
||||
if (buffer[0] == 'q') {
|
||||
char *end = strchr(buffer, '?');
|
||||
string_length = end - buffer;
|
||||
animals[count].question = 1;
|
||||
sscanf(end+1, "%d:%d",&animals[count].yes,&animals[count].no);
|
||||
} else {
|
||||
animals[count].question = 0;
|
||||
string_length = strlen(buffer) - 1;
|
||||
}
|
||||
|
||||
string = Alloc(string_length + 1);
|
||||
|
||||
string[0] = '\0';
|
||||
strncat(string, buffer + 1, string_length);
|
||||
|
||||
animals[count].text = string;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
Write_Animals(animal_file)
|
||||
char *animal_file;
|
||||
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
char buffer[MAX_LINE];
|
||||
|
||||
if ((f = fopen(animal_file, "w")) == NULL)
|
||||
Error("Can not write animal data base");
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (animals[i].question) sprintf(buffer, "q%s%d:%d", animals[i].text,
|
||||
animals[i].yes, animals[i].no);
|
||||
else
|
||||
sprintf(buffer, "a%s", animals[i].text);
|
||||
|
||||
/* Make the data base a bit difficult to read */
|
||||
swab(buffer, buffer, strlen(buffer));
|
||||
fprintf(f, "%s\n", buffer);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
chmod(animal_file, 0666);
|
||||
}
|
||||
|
||||
|
||||
/* Reading data from the user */
|
||||
int Ask(question)
|
||||
char *question;
|
||||
{
|
||||
struct sgttyb new_tty_mode;
|
||||
int response;
|
||||
|
||||
new_tty_mode = old_tty_mode;
|
||||
new_tty_mode.sg_flags |= CBREAK;
|
||||
ioctl(0, TIOCSETP, &new_tty_mode);
|
||||
|
||||
printf("%s ", question);
|
||||
|
||||
while ((response = getchar()) != 'y' && response != 'n')
|
||||
printf("\n%s [yn]?", question);
|
||||
putchar('\n');
|
||||
ioctl(0, TIOCSETP, &old_tty_mode);
|
||||
if (response == 'y')
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
char *Get_Animal()
|
||||
{
|
||||
char s[MAX_LINE];
|
||||
char *text;
|
||||
int text_length;
|
||||
|
||||
fgets(s, MAX_LINE, stdin);
|
||||
text_length = strlen(s);
|
||||
text = Alloc(text_length);
|
||||
text[0] = '\0';
|
||||
strncat(text, s, text_length - 1);
|
||||
return(text);
|
||||
}
|
||||
|
||||
|
||||
char *Get_Question()
|
||||
{
|
||||
char s[MAX_LINE];
|
||||
char *end;
|
||||
char *text;
|
||||
|
||||
fgets(s, MAX_LINE, stdin);
|
||||
|
||||
/* Capitalize the first letter */
|
||||
if (islower(s[0])) s[0] = toupper(s[0]);
|
||||
|
||||
/* Make sure the question ends with a '?' */
|
||||
if ((end = strchr(s, '?')) == NULL)
|
||||
s[strlen(s) - 1] = '?';
|
||||
else
|
||||
end[1] = '\0';
|
||||
|
||||
text = Alloc(strlen(s) + 1);
|
||||
strcpy(text, s);
|
||||
return(text);
|
||||
}
|
||||
|
||||
|
||||
/* Utility routines */
|
||||
char *A_or_An(word)
|
||||
char *word;
|
||||
{
|
||||
if (strchr("aeiouAEIOU", word[0]) == NULL)
|
||||
return("a");
|
||||
else
|
||||
return("an");
|
||||
}
|
||||
|
||||
|
||||
char *Alloc(size)
|
||||
int size;
|
||||
{
|
||||
char *malloc();
|
||||
char *memory;
|
||||
|
||||
if ((memory = malloc(size)) == NULL)
|
||||
Error("No room in memory for all the animals");
|
||||
|
||||
return(memory);
|
||||
}
|
||||
|
||||
|
||||
void Abort()
|
||||
{
|
||||
ioctl(0, TIOCSETP, &old_tty_mode);
|
||||
|
||||
printf("\nThank you for playing \"animals\".\n");
|
||||
printf("Since you aborted, the animal data base will not be updated.\n");
|
||||
sleep(1);
|
||||
printf("\nBye.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
Error(message)
|
||||
char *message;
|
||||
{
|
||||
ioctl(0, TIOCSETP, &old_tty_mode);
|
||||
fprintf(stderr, "Error: %s\n", message);
|
||||
exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user