1 #ifndef lint 2 static char sccsid[] = "@(#)selunit.c 4.4 (Berkeley) 09/11/87"; 3 #endif not lint 4 5 #include "stdio.h" 6 #include "lrnref.h" 7 8 int nsave = 0; 9 int review = 0; 10 11 selunit() 12 { 13 static char dobuff[50]; 14 static char saved[20]; 15 char fnam[80], s[80], zb[200]; 16 char posslev[20][20]; 17 int diff[20], i, k, m, n, best, alts; 18 char *getlesson(); 19 FILE *f; 20 21 if (again) { 22 again = 0; 23 if (todo=getlesson()) { 24 if (!review) 25 unsetdid(todo); 26 return; 27 } 28 wrapup(1); 29 } 30 while (ask) { 31 printf("What lesson? "); 32 fflush(stdout); 33 if (gets(dobuff) == NULL) 34 wrapup(1); 35 if (strcmp(dobuff, "bye") == 0) 36 wrapup(1); 37 level = dobuff; 38 if (todo=getlesson()) 39 return; 40 } 41 alts = 0; 42 retry: 43 f = scrin; /* use old lesson to find next */ 44 if (f==NULL) { 45 sprintf(fnam, "%s/%s/L%s", direct, sname, level); 46 f = fopen(fnam, "r"); 47 if (f==NULL) { 48 perror(fnam); 49 fprintf(stderr, "Selunit: no script for lesson %s.\n", level); 50 wrapup(1); 51 } 52 while (fgets(zb, 200, f)) { 53 trim(zb); 54 if (strcmp(zb, "#next")==0) 55 break; 56 } 57 } 58 if (feof(f)) { 59 printf("Congratulations; you have finished this sequence.\n"); 60 fflush(stdout); 61 todo = 0; 62 wrapup(-1); 63 } 64 for(i=0; fgets(s, 80, f); i++) { 65 sscanf(s, "%s %d", posslev[i], &diff[i]); 66 } 67 best = -1; 68 /* cycle through lessons from random start */ 69 /* first try the current place, failing that back up to 70 last place there are untried alternatives (but only one backup) */ 71 n = grand()%i; 72 for(k=0; k<i; k++) { 73 m = (n+k)%i; 74 if (already(posslev[m])) 75 continue; 76 if (best<0) 77 best = m; 78 alts++; /* real alternatives */ 79 if (abs(diff[m]-speed) < abs(diff[best]-speed)) 80 best = m; 81 } 82 if (best < 0 && nsave) { 83 nsave--; 84 strcpy(level, saved); 85 goto retry; 86 } 87 if (best < 0) { 88 /* lessons exhausted or missing */ 89 printf("Sorry, there are no alternative lessons at this stage.\n"); 90 printf("See someone for help.\n"); 91 fflush(stdout); 92 todo = 0; 93 return; 94 } 95 strcpy (dobuff, posslev[best]); 96 if (alts>1) { 97 nsave = 1; 98 strcpy(saved, level); 99 } 100 todo = dobuff; 101 fclose(f); 102 } 103 104 abs(x) 105 { 106 return(x>=0 ? x : -x); 107 } 108 109 grand() 110 { 111 static int garbage; 112 int a[2], b; 113 114 time(a); 115 b = a[1]+10*garbage++; 116 return(b&077777); 117 } 118