BSD 2 development
[unix-history] / src / chessclock.c
CommitLineData
783c5c09
BJ
1/* Copyright (c) 1979 Regents of the University of California */
2#include <retrofit.h>
3#include <stdio.h>
4#include <ctype.h>
5#include <sgtty.h>
6#include <signal.h>
7
8#define CTRL(x) ('x' & 037)
9#define DELETE 0177
10
11int btime, wtime;
12int state;
13int paused;
14int move;
15int movebrk;
16int cmoves;
17int ctime;
18
19#define WHITE 0
20#define BLACK 1
21
22struct sgttyb norm;
23struct sgttyb raw;
24
25char *pt();
26
27main(argc, argv)
28 int argc;
29 char *argv[];
30{
31
32 argc--, argv++;
33 gtty(1, &norm);
34 gtty(1, &raw); /* No structure assignment */
35 btime = wtime = 300;
36 movebrk = 80, ctime = 0, cmoves = 0;
37 while (argc > 0) {
38 if (argv[0][0] != '-') {
39usage:
40 fprintf(stderr, "Usage: chessclock [ -m moves ] [ -t tlim ] [ -M xmoves ] [ -T xtime ]\n");
41 exit (1);
42 }
43 if (argc < 2)
44 goto usage;
45 switch (argv[0][1]) {
46
47 case 'm':
48 if (!number(argv[1]))
49 goto usage;
50 movebrk = 2 * getn(argv[1]) + 1;
51 break;
52
53 case 't':
54 if (!istime(argv[1]))
55 goto usage;
56 btime = wtime = gettime(argv[1]);
57 break;
58
59 case 'M':
60 if (!number(argv[1]))
61 goto usage;
62 cmoves = 2 * getn(argv[1]);
63 break;
64
65 case 'T':
66 if (!istime(argv[1]))
67 goto usage;
68 ctime = gettime(argv[1]);
69 break;
70
71 default:
72 goto usage;
73 }
74 argv += 2, argc -= 2;
75 }
76 if (movebrk) {
77 if (cmoves == 0)
78 cmoves = movebrk - 1;
79 if (ctime == 0)
80 ctime = btime;
81 }
82 raw.sg_flags |= RAW;
83 raw.sg_flags &= ~ECHO;
84 stty(1, &raw);
85 printf("Hit space to begin, ? for information\r\n");
86 state = BLACK;
87 paused = 1;
88 doit();
89}
90
91onalrm()
92{
93 char tbuf[10];
94
95 signal(SIGALRM, onalrm);
96 if (paused)
97 return;
98 charge(1);
99 printf("\b\b\b\b%s\b", pt(tbuf, state == BLACK ? btime : wtime));
100 alarm(1);
101}
102
103doit()
104{
105 int t, c;
106
107 move = 0;
108 signal(SIGALRM, onalrm);
109 for (;;) {
110 alarm(1);
111 c = readone();
112 t = 1 - alarm(0);
113 switch (c) {
114
115 default:
116 printf("\r\n\r\nSpace move\r\n");
117 printf("p pause\r\n");
118 printf("c continue\r\n");
119 printf("q quit\r\n");
120 printf("! shell escape\r\n");
121 printf("\r\n");
122 fixit();
123 continue;
124
125 case ' ':
126 if (!paused) {
127 charge(t);
128 if (state == BLACK)
129 printf("\r\n");
130 }
131 paused = 0;
132 move++;
133 if (move == movebrk && cmoves != 0) {
134 movebrk += cmoves;
135 btime = wtime = ctime;
136 }
137 state = state == WHITE ? BLACK : WHITE;
138 fixit();
139 continue;
140
141 case 'c':
142 if (!paused)
143 charge(t);
144 paused = 0;
145 continue;
146
147 case '!':
148 if (!paused)
149 charge(t);
150 stty(1, &norm);
151 printf("\r\n!");
152 system("sh -t");
153 printf("!\r\n");
154 printf("Hit c to continue\r\n");
155 stty(1, &raw);
156 t = 0;
157 fixit();
158 paused = 1;
159 continue;
160
161 case 'p':
162 if (!paused)
163 charge(t);
164 paused = 1;
165 continue;
166
167 case 'q':
168 case CTRL(\\\\):
169 case DELETE:
170 printf("\r\n");
171 exit(1);
172 }
173 }
174}
175
176fixit()
177{
178 register int i;
179 char wbuf[10], bbuf[10];
180
181 printf("\r%3d %s %s", (move + 1) / 2,
182 pt(wbuf, wtime), pt(bbuf, btime));
183 if (state == WHITE)
184 for (i = 0; i < 8; i++)
185 printf("\b");
186 printf("\b");
187}
188
189charge(c)
190 int c;
191{
192
193 if (state == WHITE) {
194 wtime -= c;
195 if (wtime <= 0) {
196 printf("\r\n\07\07\07\07\07White loses on time\r\n");
197 exit(0);
198 }
199 } else {
200 btime -= c;
201 if (btime <= 0) {
202 printf("\r\n\07\07\07\07\07Black loses on time\r\n");
203 exit(0);
204 }
205 }
206}
207
208readone()
209{
210 char c;
211
212 while (read(0, &c, 1) != 1)
213 if (!isatty(0))
214 exit(1);
215 return (c);
216}
217
218exit(c)
219 int c;
220{
221
222 stty(1, &norm);
223 _exit(c);
224}
225
226char *
227pt(buf, tim)
228 char *buf;
229 int tim;
230{
231
232 sprintf(buf, "%2d:%1d%1d", tim / 60, (tim % 60) / 10, tim % 10);
233 return (buf);
234}
235
236number(cp)
237 char *cp;
238{
239
240 if (!isdigit(*cp))
241 return (0);
242 while (isdigit(*cp))
243 cp++;
244 return (*cp == 0);
245}
246
247istime(cp)
248 char *cp;
249{
250
251 if (*cp != ':' && !isdigit(*cp))
252 return (0);
253 while (isdigit(*cp))
254 cp++;
255 if (*cp == ':')
256 cp++;
257 while (isdigit(*cp))
258 cp++;
259 return (*cp == 0);
260}
261
262gettime(cp)
263 char *cp;
264{
265 int t = 0, s = 0;
266
267 while (isdigit(*cp))
268 t = t * 10 + *cp++ - '0';
269 if (*cp != ':')
270 return (t * 60);
271 cp++;
272 s = 0;
273 while (isdigit(*cp))
274 s = s * 10 + *cp++ - '0';
275 return (t * 60 + s);
276}
277
278getn(cp)
279 char *cp;
280{
281
282 int i = 0;
283
284 while (*cp)
285 i = i * 10 + *cp++ - '0';
286 return (i);
287}