BSD 4_3 release
[unix-history] / usr / src / games / arithmetic.c
CommitLineData
f9dc10a0
C
1
2static char sccsid[] = " arithmetic.c 4.1 82/10/24 ";
3
4#include <stdio.h>
5#include <signal.h>
6#define MAX 100
7
8char types[10];
9int right[MAX];
10int left[MAX];
11int rights;
12int wrongs;
13long stvec;
14long etvec;
15long dtvec;
16
17main(argc,argv)
18char *argv[];
19{
20 int range, k, dif, l;
21 char line[100];
22 int ans,pans,i,j,t;
23 char dir,sense;
24 extern delete();
25
26 signal(SIGINT, delete);
27
28 range = 11;
29 dif = 0;
30 while(argc > 1) {
31 switch(*argv[1]) {
32 case '+':
33 case '-':
34 case 'x':
35 case '/':
36 while(types[dif] = argv[1][dif])
37 dif++;
38 break;
39
40 default:
41 range = getnum(argv[1]) + 1;
42 }
43 argv++;
44 argc--;
45 }
46 if(range > MAX) {
47 printf("Range is too large.\n");
48 exit();
49 }
50
51 if(dif == 0) {
52 types[0] = '+';
53 types[1] = '-';
54 dif = 2;
55 }
56
57 for(i = 0; i < range; i++) {
58 left[i] = right[i] = i;
59 }
60 time(&stvec);
61 k = stvec;
62 srand(k);
63 k = 0;
64 l = 0;
65 goto start;
66
67loop:
68 if(++k%20 == 0)
69 score();
70
71start:
72 i = skrand(range);
73 j = skrand(range);
74 if(dif > 1)
75 l = random(dif);
76
77 switch(types[l]) {
78 case '+':
79 default:
80 ans = left[i] + right[j];
81 printf("%d + %d = ", left[i], right[j]);
82 break;
83
84 case '-':
85 t = left[i] + right[j];
86 ans = left[i];
87 printf("%d - %d = ", t, right[j]);
88 break;
89
90 case 'x':
91 ans = left[i] * right[j];
92 printf("%d x %d = ", left[i], right[j]);
93 break;
94
95 case '/':
96 while(right[j] == 0)
97 j = random(range);
98 t = left[i] * right[j] + random(right[j]);
99 ans = left[i];
100 printf("%d / %d = ", t, right[j]);
101 break;
102 }
103
104
105loop1:
106 getline(line);
107 dtvec += etvec - stvec;
108 if(line[0]=='\n') goto loop1;
109 pans = getnum(line);
110 if(pans == ans) {
111 printf("Right!\n");
112 rights++;
113 goto loop;
114 }
115 else {
116 printf("What?\n");
117 wrongs++;
118 if(range >= MAX) goto loop1;
119 left[range] = left[i];
120 right[range++] = right[j];
121 goto loop1;
122 }
123}
124
125getline(s)
126char *s;
127{
128 register char *rs;
129
130 rs = s;
131
132 while((*rs = getchar()) == ' ');
133 while(*rs != '\n')
134 if(*rs == 0)
135 exit();
136 else if(rs >= &s[99]) {
137 while((*rs = getchar()) != '\n')
138 if(*rs == '\0') exit();
139 }
140 else
141 *++rs = getchar();
142 while(*--rs == ' ')
143 *rs = '\n';
144}
145
146getnum(s)
147char *s;
148{
149 int a;
150 char c;
151
152 a = 0;
153 while((c = *s++) >= '0' && c <= '9') {
154 a = a*10 + c - '0';
155 }
156 return(a);
157}
158
159int arand;
160
161srand(n)
162{
163 arand = n&077774 | 01;
164}
165
166rand() /*uniform on 0 to 2**13-1*/
167{
168
169 arand *= 3125;
170 arand &= 077777;
171 return(arand/4);
172}
173
174random(range)
175{
176 return(hmul(rand(), 8*range));
177}
178
179skrand(range){
180int temp;
181 temp = rand() + rand();
182 if(temp >017777) temp = 040000 - temp;
183 return(hmul(temp,8*range));
184 }
185
186/* 'hmul' returns the upper 16 bits of the product, where the operands
187 are assumed to be 16-bit integers. It replaces an old PDP-11
188 assembler language subroutine. -- dks.
189*/
190hmul(a,b) { return(a*b >> 16); }
191score()
192{
193 time(&etvec);
194
195 printf("\n\nRights %d; Wrongs %d; Score %d%%\n", rights, wrongs,
196 (rights * 100)/(rights + wrongs));
197
198 if(rights == 0) return;
199 printf("Total time %ld seconds; %.1f seconds per problem\n\n\n",
200 etvec - stvec,
201 (etvec - stvec) / (rights + 0.));
202
203 sleep(3);
204 time(&dtvec);
205 stvec += dtvec - etvec;
206 return(0);
207}
208
209delete()
210{
211 if(rights + wrongs == 0.) {
212 printf("\n");
213 exit();
214 }
215 score();
216 exit();
217}
218