home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / misc / ddli-3.41.lha / DDLI / qst.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-25  |  7.2 KB  |  255 lines

  1. /* QST.C  Copyright (C) 1994 Fergus Patrick Duniho */
  2.  
  3. #define MAXLINE 256
  4. #define NO_PREFERENCE 16
  5. #define UNKNOWN 16
  6. #define UNANSWERED 17
  7. #define INCOMPLETE 17
  8.  
  9. typedef struct qnode {
  10.     int p[2]; /* Preference Array Numbers */
  11.     int num, ans, strength;
  12.     char *Qtext, *Atext[2];
  13.     struct qnode *pv, *nx;
  14. } qst;
  15.  
  16. char *Version;
  17.  
  18. qst *RND_QList (qst *Q, int size);
  19. void Get_QList (char *fname, qst *Q, int size);
  20. void AskQuestions (qst *Q, int col);
  21. int AskQ (qst *Q, int col);
  22. qst *new_qnode (int num);
  23. qst *nth_qnode (qst *Q, unsigned int n);
  24. qst *qnode_n (qst *Q, unsigned int n);
  25. void save_scores (qst *Q, int type, int col);
  26. void read_scores (char *fname, qst *S);
  27.  
  28. qst *new_qnode (int num) {
  29.     qst *node;
  30.  
  31.     if ((node = (qst *)malloc(sizeof(qst))) == NULL) {
  32.       perror ("Malloc can't allocate enough memory for a new qnode.\n");
  33.       exit (2);
  34.    }
  35.    node->ans = UNANSWERED;
  36.    node->num = num;
  37.    node->strength = 0;
  38.    return node;
  39. }
  40.  
  41. /* Get_QList: Reads questions from a file into a linked list.
  42.    Returns the version # string from the beginning of the
  43.    questions file. */
  44.  
  45. void Get_QList (char *fname, qst *Q, int size) {
  46.     FILE *fptr;
  47.     int i, j, k;
  48.     qst *S;
  49.  
  50.     S = Q;
  51.     RdOpen (fptr, fname);
  52.     Version = clone_line(fptr, MAXLINE);
  53.     for (i = 1; i <= size; i++) {
  54.         k = fgetp(fptr);
  55.         Q->nx = new_qnode(k);
  56.         Q->nx->pv = Q;
  57.         Q = Q->nx;
  58.         Q->Qtext = clone_line(fptr, MAXLINE);
  59.         for (j = 0; j < 2; j++) {
  60.             Q->p[j] = fgetp(fptr);
  61.             Q->Atext[j] = clone_line(fptr, MAXLINE);
  62.         }
  63.     }
  64.     fclose (fptr);
  65.     Q->nx = S;
  66. }
  67.  
  68. /* nth_qnode: Returns the nth member of a linked list of qst nodes. */
  69.  
  70. qst *nth_qnode (qst *Q, unsigned int n) {
  71.     while (n--)
  72.         Q = Q->nx;
  73.     return Q;
  74. }
  75.  
  76. /* qnode_n: Returns the qnode for question #n. */
  77.  
  78. qst *qnode_n (qst *Q, unsigned int n) {
  79.     while (Q->num != n)
  80.         Q = Q->nx;
  81.     return Q;
  82. }
  83.  
  84. /* RND_QList: Randomizes a linked list of questions. */
  85.  
  86. qst *RND_QList (qst *Q, int size) {
  87.     qst *S, *L, *N, *SN;
  88.     unsigned int i, j;
  89.     char *temp;
  90.  
  91.     SN = N = new_qnode(0);
  92.     S = Q;
  93.  
  94.     /* Randomizes Answer Order */
  95.     for (i = 0; i < size; i++)
  96.         if (rand() % 2) {
  97.             L = nth_qnode(S, i);
  98.             j = L->p[1]; L->p[1] = L->p[0]; L->p[0] = j;
  99.             temp = L->Atext[1];
  100.             L->Atext[1] = L->Atext[0];
  101.             L->Atext[0] = temp;
  102.         }
  103.  
  104.     /* Randomizes Question Order */
  105.     for (; size; size--) {
  106.         i = (rand() % size) + 1;
  107.         L = nth_qnode(S, i);
  108.         L->nx->pv = L->pv;
  109.         L->pv->nx = L->nx;
  110.         N->nx = L;
  111.         L->pv = N;
  112.         N = L;
  113.     }
  114.     free (S);
  115.     N->nx = SN;
  116.     SN->pv = N;
  117.     return SN;
  118. }
  119.  
  120. void AskQuestions (qst *Q, int col) {
  121.     int more = 1, num, i, A;
  122.     qst *S;
  123.  
  124.     S = Q;
  125.     while (more) {
  126.         for (Q = Q->nx, num = 1; Q->num > 0; Q = Q->nx, num++) {
  127.             if (Q->ans != UNANSWERED)
  128.                 continue;
  129.             printf ("\nQuestion #%d\n", num);
  130.             for (;;) {
  131.                 A = AskQ(Q, col);
  132.                 if (A == 4) { /* Goto Question #N */
  133.                     wrapwrite (stdout, 0, 0, col,
  134.                         "Please enter a question number.\n", 0);
  135.                     i = getp(1, num);
  136.                     Q = nth_qnode(S, num = i);
  137.                     printf ("\nQuestion #%d\n", num);
  138.                 }
  139.                 else if (A == 5) /* Save Scores */
  140.                     save_scores (S, INCOMPLETE, col);
  141.                 else if (A == 6) { /* Quit */
  142.                     wrapwrite (stdout, 0, 0, col, "Do you want to save",
  143.                         "your scores before you quit?", 0);
  144.                     if (yes())
  145.                         save_scores (S, INCOMPLETE, col);
  146.                     exit (2);
  147.                 }
  148.                 else /* Skipped or Answered */
  149.                     break;
  150.             }
  151.         }
  152.         more = 0;
  153.         for (Q = Q->nx; Q->num > 0; Q = Q->nx) {
  154.             if (Q->ans == UNANSWERED) more = 1;
  155.             break;
  156.         }
  157.     }
  158. }
  159.  
  160. /* AskQ: Asks a single question. */
  161.  
  162. int AskQ (qst *Q, int col) {
  163.     int A;
  164.  
  165.     wrapwrite (stdout, 0, 0, col, Q->Qtext, 0);
  166.     wrapwrite (stdout, 0, 4, col, "(0)", Q->Atext[0], 0);
  167.     puts (" ... Or");
  168.     wrapwrite (stdout, 0, 4, col, "(1)", Q->Atext[1], 0);
  169.     wrapwrite (stdout, 0, 0, col, "\n(2) No Preference\n",
  170.         "(3) Skip Until Later\n(4) Goto Question #N\n",
  171.         "(5) Save Scores\n(6) Quit\n", 0);
  172.  
  173.     if ((A = getp(0, 6)) <= 1) {
  174.         Q->ans = Q->p[A];
  175.         wrapwrite (stdout, 0, 0, col, "Please rate the strength of this",
  176.             "preference on a scale of 1 to 7.\n1 = Faint\n2 = Weak\n",
  177.             "3 = Modest\n4 = Moderate\n5 = Strong\n6 = Extreme\n",
  178.             "7 = Excessive\n", 0);
  179.         Q->strength = getp(1, 7);
  180.     }
  181.     else if (A == 2)
  182.         Q->ans = NO_PREFERENCE;
  183.     return A;
  184. }
  185.  
  186. void save_scores (qst *Q, int type, int col) {
  187.     static char *fname = 0;
  188.     int i;
  189.     FILE *fptr;
  190.     char *types[] = {"INFP", "INFJ", "INTP", "INTJ", "ISFP", "ISFJ", "ISTP",
  191.             "ISTJ", "ENFP", "ENFJ", "ENTP", "ENTJ", "ESFP", "ESFJ",
  192.             "ESTP", "ESTJ", "????", "****"};
  193.  
  194.     if (fname == 0) {
  195.         wrapwrite (stderr, 4, 0, col, "The DDLI will now save your scores",
  196.             "in a file.  What will you call this file?", 0);
  197.         fname = clone_line(stdin, FILE_NAME_MAX);
  198.     }
  199.     printf ("\nSending raw scores to \"%s\".\n", fname);
  200.     WrOpen (fptr, fname);
  201.     if (type == INCOMPLETE) {
  202.         wrapwrite (fptr, 0, 0, 75, "This is an unfinished scores file",
  203.             "for the DDLI.\n\nTo reaccess this file type:\n\n",
  204.             "ddli", fname, "\n\n", 0);
  205.     }
  206.     else {
  207.         if (type == UNKNOWN) {
  208.             wrapwrite (fptr, 0, 0, 75, "This is a completed scores file for",
  209.                 "the DDLI.  If you determine what your type is INDEPENDENTLY",
  210.                 "from your results on the DDLI, please replace the \"????\"",
  211.                 "with your type and email this file to me.\n\n", 0);
  212.         }
  213.         else {
  214.             wrapwrite (fptr, 0, 0, 75, "This is a completed scores file for",
  215.                 "the DDLI.  Please email this file to me.\n\n", 0);
  216.         }
  217.         wrapwrite (fptr, 0, 0, 75, "You can reach me via the internet at:\n\n",
  218.             EMAIL, "\n\nOr you can reach me via the Fidonet at:\n\n",
  219.             NETMAIL, "\n\nPlease send this file to me as is.  Do not",
  220.             "uuencode, MIME-encode, or otherwise encode this file.\n\n", 0);
  221.     }
  222.     fprintf (fptr, "%s\n%s\n", Version, types[type]);
  223.     i = 0;
  224.     for (Q = Q->nx; Q->num > 0; Q = Q->nx) {
  225.         fprintf (fptr, "#%d-%d-%d", Q->num, Q->ans, Q->strength);
  226.         i++;
  227.         if (i == 8) {
  228.             fputc ('\n', fptr);
  229.             i = 0;
  230.         }
  231.     }
  232.     fclose (fptr);
  233. }
  234.  
  235. void read_scores (char *fname, qst *S) {
  236.     FILE *fptr;
  237.     int num;
  238.     qst *Q;
  239.  
  240.     RdOpen (fptr, fname);
  241.     if (find (fptr, Version)) {
  242.         nextline (fptr);
  243.         while ((num = fgetp(fptr)) != EOF) {
  244.             Q = qnode_n(S, num);
  245.             Q->ans = fgetp(fptr);
  246.             Q->strength = fgetp(fptr);
  247.         }
  248.     }
  249.     else {
  250.         fprintf (stderr, "\"%s\" is not a scores file for %s.\n", fname, Version);
  251.         exit (1);
  252.     }
  253.     fclose (fptr);
  254. }
  255.