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