home *** CD-ROM | disk | FTP | other *** search
- /* QST.C Copyright (C) 1994 Fergus Patrick Duniho */
-
- #define MAXLINE 256
- #define NO_PREFERENCE 16
- #define UNKNOWN 16
- #define UNANSWERED 17
- #define INCOMPLETE 17
-
- typedef struct qnode {
- int p[2]; /* Preference Array Numbers */
- int num, ans, strength;
- char *Qtext, *Atext[2];
- struct qnode *pv, *nx;
- } qst;
-
- char *Version;
-
- qst *RND_QList (qst *Q, int size);
- void Get_QList (char *fname, qst *Q, int size);
- void AskQuestions (qst *Q, int col);
- int AskQ (qst *Q, int col);
- qst *new_qnode (int num);
- qst *nth_qnode (qst *Q, unsigned int n);
- qst *qnode_n (qst *Q, unsigned int n);
- void save_scores (qst *Q, int type, int col);
- void read_scores (char *fname, qst *S);
-
- qst *new_qnode (int num) {
- qst *node;
-
- if ((node = (qst *)malloc(sizeof(qst))) == NULL) {
- perror ("Malloc can't allocate enough memory for a new qnode.\n");
- exit (2);
- }
- node->ans = UNANSWERED;
- node->num = num;
- node->strength = 0;
- return node;
- }
-
- /* Get_QList: Reads questions from a file into a linked list.
- Returns the version # string from the beginning of the
- questions file. */
-
- void Get_QList (char *fname, qst *Q, int size) {
- FILE *fptr;
- int i, j, k;
- qst *S;
-
- S = Q;
- RdOpen (fptr, fname);
- Version = clone_line(fptr, MAXLINE);
- for (i = 1; i <= size; i++) {
- k = fgetp(fptr);
- Q->nx = new_qnode(k);
- Q->nx->pv = Q;
- Q = Q->nx;
- Q->Qtext = clone_line(fptr, MAXLINE);
- for (j = 0; j < 2; j++) {
- Q->p[j] = fgetp(fptr);
- Q->Atext[j] = clone_line(fptr, MAXLINE);
- }
- }
- fclose (fptr);
- Q->nx = S;
- }
-
- /* nth_qnode: Returns the nth member of a linked list of qst nodes. */
-
- qst *nth_qnode (qst *Q, unsigned int n) {
- while (n--)
- Q = Q->nx;
- return Q;
- }
-
- /* qnode_n: Returns the qnode for question #n. */
-
- qst *qnode_n (qst *Q, unsigned int n) {
- while (Q->num != n)
- Q = Q->nx;
- return Q;
- }
-
- /* RND_QList: Randomizes a linked list of questions. */
-
- qst *RND_QList (qst *Q, int size) {
- qst *S, *L, *N, *SN;
- unsigned int i, j;
- char *temp;
-
- SN = N = new_qnode(0);
- S = Q;
-
- /* Randomizes Answer Order */
- for (i = 0; i < size; i++)
- if (rand() % 2) {
- L = nth_qnode(S, i);
- j = L->p[1]; L->p[1] = L->p[0]; L->p[0] = j;
- temp = L->Atext[1];
- L->Atext[1] = L->Atext[0];
- L->Atext[0] = temp;
- }
-
- /* Randomizes Question Order */
- for (; size; size--) {
- i = (rand() % size) + 1;
- L = nth_qnode(S, i);
- L->nx->pv = L->pv;
- L->pv->nx = L->nx;
- N->nx = L;
- L->pv = N;
- N = L;
- }
- free (S);
- N->nx = SN;
- SN->pv = N;
- return SN;
- }
-
- void AskQuestions (qst *Q, int col) {
- int more = 1, num, i, A;
- qst *S;
-
- S = Q;
- while (more) {
- for (Q = Q->nx, num = 1; Q->num > 0; Q = Q->nx, num++) {
- if (Q->ans != UNANSWERED)
- continue;
- printf ("\nQuestion #%d\n", num);
- for (;;) {
- A = AskQ(Q, col);
- if (A == 4) { /* Goto Question #N */
- wrapwrite (stdout, 0, 0, col,
- "Please enter a question number.\n", 0);
- i = getp(1, num);
- Q = nth_qnode(S, num = i);
- printf ("\nQuestion #%d\n", num);
- }
- else if (A == 5) /* Save Scores */
- save_scores (S, INCOMPLETE, col);
- else if (A == 6) { /* Quit */
- wrapwrite (stdout, 0, 0, col, "Do you want to save",
- "your scores before you quit?", 0);
- if (yes())
- save_scores (S, INCOMPLETE, col);
- exit (2);
- }
- else /* Skipped or Answered */
- break;
- }
- }
- more = 0;
- for (Q = Q->nx; Q->num > 0; Q = Q->nx) {
- if (Q->ans == UNANSWERED) more = 1;
- break;
- }
- }
- }
-
- /* AskQ: Asks a single question. */
-
- int AskQ (qst *Q, int col) {
- int A;
-
- wrapwrite (stdout, 0, 0, col, Q->Qtext, 0);
- wrapwrite (stdout, 0, 4, col, "(0)", Q->Atext[0], 0);
- puts (" ... Or");
- wrapwrite (stdout, 0, 4, col, "(1)", Q->Atext[1], 0);
- wrapwrite (stdout, 0, 0, col, "\n(2) No Preference\n",
- "(3) Skip Until Later\n(4) Goto Question #N\n",
- "(5) Save Scores\n(6) Quit\n", 0);
-
- if ((A = getp(0, 6)) <= 1) {
- Q->ans = Q->p[A];
- wrapwrite (stdout, 0, 0, col, "Please rate the strength of this",
- "preference on a scale of 1 to 7.\n1 = Faint\n2 = Weak\n",
- "3 = Modest\n4 = Moderate\n5 = Strong\n6 = Extreme\n",
- "7 = Excessive\n", 0);
- Q->strength = getp(1, 7);
- }
- else if (A == 2)
- Q->ans = NO_PREFERENCE;
- return A;
- }
-
- void save_scores (qst *Q, int type, int col) {
- static char *fname = 0;
- int i;
- FILE *fptr;
- char *types[] = {"INFP", "INFJ", "INTP", "INTJ", "ISFP", "ISFJ", "ISTP",
- "ISTJ", "ENFP", "ENFJ", "ENTP", "ENTJ", "ESFP", "ESFJ",
- "ESTP", "ESTJ", "????", "****"};
-
- if (fname == 0) {
- wrapwrite (stderr, 4, 0, col, "The DDLI will now save your scores",
- "in a file. What will you call this file?", 0);
- fname = clone_line(stdin, FILE_NAME_MAX);
- }
- printf ("\nSending raw scores to \"%s\".\n", fname);
- WrOpen (fptr, fname);
- if (type == INCOMPLETE) {
- wrapwrite (fptr, 0, 0, 75, "This is an unfinished scores file",
- "for the DDLI.\n\nTo reaccess this file type:\n\n",
- "ddli", fname, "\n\n", 0);
- }
- else {
- if (type == UNKNOWN) {
- wrapwrite (fptr, 0, 0, 75, "This is a completed scores file for",
- "the DDLI. If you determine what your type is INDEPENDENTLY",
- "from your results on the DDLI, please replace the \"????\"",
- "with your type and email this file to me.\n\n", 0);
- }
- else {
- wrapwrite (fptr, 0, 0, 75, "This is a completed scores file for",
- "the DDLI. Please email this file to me.\n\n", 0);
- }
- wrapwrite (fptr, 0, 0, 75, "You can reach me via the internet at:\n\n",
- EMAIL, "\n\nOr you can reach me via the Fidonet at:\n\n",
- NETMAIL, "\n\nPlease send this file to me as is. Do not",
- "uuencode, MIME-encode, or otherwise encode this file.\n\n", 0);
- }
- fprintf (fptr, "%s\n%s\n", Version, types[type]);
- i = 0;
- for (Q = Q->nx; Q->num > 0; Q = Q->nx) {
- fprintf (fptr, "#%d-%d-%d", Q->num, Q->ans, Q->strength);
- i++;
- if (i == 8) {
- fputc ('\n', fptr);
- i = 0;
- }
- }
- fclose (fptr);
- }
-
- void read_scores (char *fname, qst *S) {
- FILE *fptr;
- int num;
- qst *Q;
-
- RdOpen (fptr, fname);
- if (find (fptr, Version)) {
- nextline (fptr);
- while ((num = fgetp(fptr)) != EOF) {
- Q = qnode_n(S, num);
- Q->ans = fgetp(fptr);
- Q->strength = fgetp(fptr);
- }
- }
- else {
- fprintf (stderr, "\"%s\" is not a scores file for %s.\n", fname, Version);
- exit (1);
- }
- fclose (fptr);
- }
-