Commit | Line | Data |
---|---|---|
07d1919e | 1 | /*- |
e0719df9 KB |
2 | * Copyright (c) 1991, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
07d1919e | 4 | * |
ad787160 C |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. All advertising materials mentioning features or use of this software | |
14 | * must display the following acknowledgement: | |
15 | * This product includes software developed by the University of | |
16 | * California, Berkeley and its contributors. | |
17 | * 4. Neither the name of the University nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
07d1919e | 32 | */ |
c4c2d2dc | 33 | |
07d1919e | 34 | #ifndef lint |
ad787160 | 35 | static char sccsid[] = "@(#)backgammon.c 8.1 (Berkeley) 5/31/93"; |
07d1919e | 36 | #endif /* not lint */ |
c4c2d2dc KM |
37 | |
38 | /* | |
39 | ** The game of Backgammon | |
40 | */ | |
41 | ||
42 | #include <stdio.h> | |
43 | ||
44 | #define WHITE 0 | |
45 | #define BROWN 1 | |
46 | #define NIL (-1) | |
47 | #define MAXGMOV 10 | |
48 | #define MAXIMOVES 1000 | |
49 | #define RULES "/usr/games/lib/backrules" | |
50 | ||
51 | char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/ | |
52 | ||
53 | int die1; | |
54 | int die2; | |
55 | int i; | |
56 | int j; | |
57 | int l; | |
58 | int m; | |
59 | int pflg = 1; | |
60 | int nobroll = 0; | |
61 | int count; | |
62 | int imoves; | |
63 | int goodmoves[MAXGMOV]; | |
64 | int probmoves[MAXGMOV]; | |
65 | ||
66 | int brown[] = { /* brown position table */ | |
67 | 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, | |
68 | 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, | |
69 | 0, 0, 0, 0, 0, 0 | |
70 | }; | |
71 | ||
72 | int white[] = { /* white position table */ | |
73 | 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, | |
74 | 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, | |
75 | 0, 0, 0, 0, 0, 0 | |
76 | }; | |
77 | ||
78 | int probability[] = { | |
79 | 0, 11, 12, 13, 14, 15, 16, | |
80 | 06, 05, 04, 03, 02, 01 | |
81 | }; | |
82 | ||
83 | struct { | |
84 | int pos[4]; | |
85 | int mov[4]; | |
86 | } moves[MAXIMOVES]; | |
87 | ||
88 | main() | |
89 | { | |
90 | int go[5], tvec[2]; | |
91 | int k, n, pid, ret, rpid, t; | |
92 | char s[100]; | |
93 | ||
94 | srand(time(0)); | |
95 | go[5] = NIL; | |
96 | fprintf(stdout, "Instructions? "); | |
97 | gets(s); | |
98 | if(*s == 'y') | |
99 | instructions(); | |
100 | putchar('\n'); | |
101 | fprintf(stdout, "Opponent's level: b - beginner,\n"); | |
102 | fprintf(stdout, "i - intermediate, e - expert? "); | |
103 | level='e'; | |
104 | gets(s); | |
105 | if(*s == 'b') | |
106 | level = 'b'; | |
107 | else if(*s == 'i') | |
108 | level = 'i'; | |
109 | putchar('\n'); | |
110 | fprintf(stdout, "You will play brown.\n\n"); | |
111 | fprintf(stdout, "Would you like to roll your own dice? "); | |
112 | gets(s); | |
113 | putchar('\n'); | |
114 | if(*s == 'y') | |
115 | nobroll = 1; | |
116 | fprintf(stdout, "Would you like to go first? "); | |
117 | gets(s); | |
118 | putchar('\n'); | |
119 | if(*s == 'y') | |
120 | goto nowhmove; | |
121 | whitesmv: | |
122 | roll(WHITE); | |
123 | fprintf(stdout, "white rolls %d, %d\n", die1, die2); | |
124 | fprintf(stdout, "white's move is:"); | |
125 | if(nextmove(white, brown) == NIL) | |
126 | goto nowhmove; | |
127 | if(piececount(white, 0, 24) == 0){ | |
128 | fprintf(stdout, "White wins"); | |
129 | if(piececount(brown, 0, 6) != 0) | |
130 | fprintf(stdout, " with a Backgammon!\n"); | |
131 | else if (piececount(brown, 0, 24) == 24) | |
132 | fprintf(stdout, " with a Gammon.\n"); | |
133 | else | |
134 | fprintf(stdout, ".\n"); | |
135 | exit(0); | |
136 | } | |
137 | nowhmove: | |
138 | if(pflg) | |
139 | prtbrd(); | |
140 | roll(BROWN); | |
141 | retry: | |
142 | fprintf(stdout, "\nYour roll is %d %d\n", die1, die2); | |
143 | fprintf(stdout, "Move? "); | |
144 | gets(s); | |
145 | switch(*s) { | |
146 | case '\0': /* empty line */ | |
147 | fprintf(stdout, "Brown's move skipped.\n"); | |
148 | goto whitesmv; | |
149 | ||
150 | case 'b': /* how many beared off? */ | |
151 | fprintf(stdout, "Brown: %d\n", piececount(brown, 0, 24) - 15); | |
152 | fprintf(stdout, "White: %d\n", piececount(white, 0, 24) - 15); | |
153 | goto retry; | |
154 | ||
155 | case 'p': /* print board */ | |
156 | prtbrd(); | |
157 | goto retry; | |
158 | ||
159 | case 's': /* stop auto printing of board */ | |
160 | pflg = 0; | |
161 | goto retry; | |
162 | ||
163 | case 'r': /* resume auto printing */ | |
164 | pflg = 1; | |
165 | goto retry; | |
166 | ||
167 | case 'm': /* print possible moves */ | |
168 | pmoves(); | |
169 | goto retry; | |
170 | ||
171 | case 'q': /* i give up */ | |
172 | exit(0); | |
173 | ||
174 | case '!': /* escape to Shell */ | |
175 | if(s[1] != '\0') | |
176 | system(s+1); | |
177 | else if((pid = fork()) == 0) { | |
178 | execl("/bin/sh", "sh", "-", 0); | |
179 | fprintf(stderr, "back: cannot exec /bin/sh!\n"); | |
180 | exit(2); | |
181 | } | |
182 | while((rpid = wait(&ret)) != pid && rpid != -1) | |
183 | ; | |
184 | goto retry; | |
185 | ||
186 | case '?': /* well, what can i do? */ | |
187 | fprintf(stdout, "<newline> skip this move\n"); | |
188 | fprintf(stdout, "b number beared off\n"); | |
189 | fprintf(stdout, "p print board\n"); | |
190 | fprintf(stdout, "q quit\n"); | |
191 | fprintf(stdout, "r resume auto print of board\n"); | |
192 | fprintf(stdout, "s stop auto print of board\n"); | |
193 | fprintf(stdout, "! escape to Shell\n"); | |
194 | goto retry; | |
195 | } | |
196 | n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]); | |
197 | if((die1 != die2 && n > 2) || n > 4){ | |
198 | fprintf(stdout, "Too many moves.\n"); | |
199 | goto retry; | |
200 | } | |
201 | go[n] = NIL; | |
202 | if(*s=='-'){ | |
203 | go[0]= -go[0]; | |
204 | t=die1; | |
205 | die1=die2; | |
206 | die2=t; | |
207 | } | |
208 | for(k = 0; k < n; k++){ | |
209 | if(0 <= go[k] && go[k] <= 24) | |
210 | continue; | |
211 | else{ | |
212 | fprintf(stdout, "Move %d illegal.\n", go[k]); | |
213 | goto retry; | |
214 | } | |
215 | } | |
216 | if(play(brown, white, go)) | |
217 | goto retry; | |
218 | if(piececount(brown, 0, 24) == 0){ | |
219 | fprintf(stdout, "Brown wins"); | |
220 | if(piececount(white, 0, 6) != 0) | |
221 | fprintf(stdout, " with a Backgammon.\n"); | |
222 | else if(piececount(white, 0, 24) == 24) | |
223 | fprintf(stdout, " with a gammon.\n"); | |
224 | else | |
225 | fprintf(stdout, ".\n"); | |
226 | exit(0); | |
227 | } | |
228 | goto whitesmv; | |
229 | } | |
230 | ||
231 | play(player,playee,pos) | |
232 | int *player,*playee,pos[]; | |
233 | { | |
234 | int k, n, die, ipos; | |
235 | ||
236 | for(k=0; k < player[0]; k++){ /*blots on player[0] must be moved first*/ | |
237 | if(pos[k] == NIL) | |
238 | break; | |
239 | if(pos[k] != 0){ | |
240 | fprintf(stdout, "Stone on bar must be moved first.\n"); | |
241 | return(NIL); | |
242 | } | |
243 | } | |
244 | for(k = 0; (ipos=pos[k]) != NIL; k++){ | |
245 | die = k?die2:die1; | |
246 | n = 25-ipos-die; | |
247 | if(player[ipos] == 0) | |
248 | goto badmove; | |
249 | if(n > 0 && playee[n] >= 2) | |
250 | goto badmove; | |
251 | if(n <= 0){ | |
252 | if(piececount(player,0,18) != 0) | |
253 | goto badmove; | |
254 | if((ipos+die) != 25 && piececount(player,19,24-die)!=0) | |
255 | goto badmove; | |
256 | } | |
257 | player[ipos]--; | |
258 | player[ipos+die]++; | |
259 | } | |
260 | for(k = 0; pos[k] != NIL; k++){ | |
261 | die = k?die2:die1; | |
262 | n = 25-pos[k]-die; | |
263 | if(n>0 && playee[n]==1){ | |
264 | playee[n]=0; | |
265 | playee[0]++; | |
266 | } | |
267 | } | |
268 | return(0); | |
269 | ||
270 | badmove: | |
271 | fprintf(stdout, "Move %d illegal.\n", ipos); | |
272 | while(k--){ | |
273 | die=k?die2:die1; | |
274 | player[pos[k]]++; | |
275 | player[pos[k]+die]--; | |
276 | } | |
277 | return(NIL); | |
278 | } | |
279 | nextmove(player,playee) | |
280 | int *player,*playee; | |
281 | { | |
282 | int k; | |
283 | ||
284 | imoves=0; | |
285 | movegen(player,playee); | |
286 | if(die1!=die2){ | |
287 | k=die1; | |
288 | die1=die2; | |
289 | die2=k; | |
290 | movegen(player,playee); | |
291 | } | |
292 | if(imoves==0){ | |
293 | fprintf(stdout, "no move possible.\n"); | |
294 | return(NIL); | |
295 | } | |
296 | k=strategy(player,playee); /*select kth possible move*/ | |
297 | prtmov(k); | |
298 | update(player,playee,k); | |
299 | return(0); | |
300 | } | |
301 | prtmov(k) | |
302 | int k; | |
303 | { | |
304 | int n; | |
305 | ||
306 | if(k == NIL) | |
307 | fprintf(stdout, "No move possible\n"); | |
308 | else for(n = 0; n < 4; n++){ | |
309 | if(moves[k].pos[n] == NIL) | |
310 | break; | |
311 | fprintf(stdout, " %d, %d",25-moves[k].pos[n],moves[k].mov[n]); | |
312 | } | |
313 | fprintf(stdout, "\n"); | |
314 | } | |
315 | update(player,playee,k) | |
316 | int *player,*playee,k; | |
317 | { | |
318 | int n,t; | |
319 | ||
320 | for(n = 0; n < 4; n++){ | |
321 | if(moves[k].pos[n] == NIL) | |
322 | break; | |
323 | player[moves[k].pos[n]]--; | |
324 | player[moves[k].pos[n]+moves[k].mov[n]]++; | |
325 | t=25-moves[k].pos[n]-moves[k].mov[n]; | |
326 | if(t>0 && playee[t]==1){ | |
327 | playee[0]++; | |
328 | playee[t]--; | |
329 | } | |
330 | } | |
331 | } | |
332 | piececount(player,startrow,endrow) | |
333 | int *player,startrow,endrow; | |
334 | { | |
335 | int sum; | |
336 | ||
337 | sum=0; | |
338 | while(startrow <= endrow) | |
339 | sum += player[startrow++]; | |
340 | return(sum); | |
341 | } | |
342 | pmoves() | |
343 | { | |
344 | int i1, i2; | |
345 | ||
346 | fprintf(stdout, "Possible moves are:\n"); | |
347 | for(i1 = 0; i1 < imoves; i1++){ | |
348 | fprintf(stdout, "\n%d",i1); | |
349 | for (i2 = 0; i2<4; i2++){ | |
350 | if(moves[i1].pos[i2] == NIL) | |
351 | break; | |
352 | fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]); | |
353 | } | |
354 | } | |
355 | fprintf(stdout, "\n"); | |
356 | } | |
357 | ||
358 | roll(who) | |
359 | { | |
360 | register n; | |
361 | char s[10]; | |
362 | ||
363 | if(who == BROWN && nobroll) { | |
364 | fprintf(stdout, "Roll? "); | |
365 | gets(s); | |
366 | n = sscanf(s, "%d%d", &die1, &die2); | |
367 | if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6) | |
368 | fprintf(stdout, "Illegal - I'll do it!\n"); | |
369 | else | |
370 | return; | |
371 | } | |
372 | die1 = ((rand()>>8) % 6) + 1; | |
373 | die2 = ((rand()>>8) % 6) + 1; | |
374 | } | |
375 | ||
376 | movegen(mover,movee) | |
377 | int *mover,*movee; | |
378 | { | |
379 | int k; | |
380 | ||
381 | for(i = 0; i <= 24; i++){ | |
382 | count = 0; | |
383 | if(mover[i] == 0) | |
384 | continue; | |
385 | if((k=25-i-die1) > 0 && movee[k] >= 2) | |
386 | if(mover[0] > 0) | |
387 | break; | |
388 | else | |
389 | continue; | |
390 | if(k <= 0){ | |
391 | if(piececount(mover, 0, 18) != 0) | |
392 | break; | |
393 | if((i+die1) != 25 && piececount(mover,19,i-1) != 0) | |
394 | break; | |
395 | } | |
396 | mover[i]--; | |
397 | mover[i+die1]++; | |
398 | count = 1; | |
399 | for(j = 0; j <= 24; j++){ | |
400 | if(mover[j]==0) | |
401 | continue; | |
402 | if((k=25-j-die2) > 0 && movee[k] >= 2) | |
403 | if(mover[0] > 0) | |
404 | break; | |
405 | else | |
406 | continue; | |
407 | if(k <= 0){ | |
408 | if(piececount(mover,0,18) != 0) | |
409 | break; | |
410 | if((j+die2) != 25 && piececount(mover,19,j-1) != 0) | |
411 | break; | |
412 | } | |
413 | mover[j]--; | |
414 | mover[j+die2]++; | |
415 | count = 2; | |
416 | if(die1 != die2){ | |
417 | moverecord(mover); | |
418 | if(mover[0] > 0) | |
419 | break; | |
420 | else | |
421 | continue; | |
422 | } | |
423 | for(l = 0; l <= 24; l++){ | |
424 | if(mover[l] == 0) | |
425 | continue; | |
426 | if((k=25-l-die1) > 0 && movee[k] >= 2) | |
427 | if(mover[0] > 0) | |
428 | break; | |
429 | else | |
430 | continue; | |
431 | if(k <= 0){ | |
432 | if(piececount(mover, 0, 18) != 0) | |
433 | break; | |
434 | if((l+die2) != 25 && piececount(mover,19,l-1) != 0) | |
435 | break; | |
436 | } | |
437 | mover[l]--; | |
438 | mover[l+die1]++; | |
439 | count=3; | |
440 | for(m=0;m<=24;m++){ | |
441 | if(mover[m]==0) | |
442 | continue; | |
443 | if((k=25-m-die1) >= 0 && movee[k] >= 2) | |
444 | if(mover[0] > 0) | |
445 | break; | |
446 | else | |
447 | continue; | |
448 | if(k <= 0){ | |
449 | if(piececount(mover,0,18) != 0) | |
450 | break; | |
451 | if((m+die2) != 25 && piececount(mover,19,m-1) != 0) | |
452 | break; | |
453 | } | |
454 | count=4; | |
455 | moverecord(mover); | |
456 | if(mover[0] > 0) | |
457 | break; | |
458 | } | |
459 | if(count == 3) | |
460 | moverecord(mover); | |
461 | else{ | |
462 | mover[l]++; | |
463 | mover[l+die1]--; | |
464 | } | |
465 | if(mover[0] > 0) | |
466 | break; | |
467 | } | |
468 | if(count == 2) | |
469 | moverecord(mover); | |
470 | else{ | |
471 | mover[j]++; | |
472 | mover[j+die1]--; | |
473 | } | |
474 | if(mover[0] > 0) | |
475 | break; | |
476 | } | |
477 | if(count == 1) | |
478 | moverecord(mover); | |
479 | else{ | |
480 | mover[i]++; | |
481 | mover[i+die1]--; | |
482 | } | |
483 | if(mover[0] > 0) | |
484 | break; | |
485 | } | |
486 | } | |
487 | moverecord(mover) | |
488 | int *mover; | |
489 | { | |
490 | int t; | |
491 | ||
492 | if(imoves < MAXIMOVES) { | |
493 | for(t = 0; t <= 3; t++) | |
494 | moves[imoves].pos[t] = NIL; | |
495 | switch(count) { | |
496 | case 4: | |
497 | moves[imoves].pos[3]=m; | |
498 | moves[imoves].mov[3]=die1; | |
499 | ||
500 | case 3: | |
501 | moves[imoves].pos[2]=l; | |
502 | moves[imoves].mov[2]=die1; | |
503 | ||
504 | case 2: | |
505 | moves[imoves].pos[1]=j; | |
506 | moves[imoves].mov[1]=die2; | |
507 | ||
508 | case 1: | |
509 | moves[imoves].pos[0]=i; | |
510 | moves[imoves].mov[0]=die1; | |
511 | imoves++; | |
512 | } | |
513 | } | |
514 | switch(count) { | |
515 | case 4: | |
516 | break; | |
517 | ||
518 | case 3: | |
519 | mover[l]++; | |
520 | mover[l+die1]--; | |
521 | break; | |
522 | ||
523 | case 2: | |
524 | mover[j]++; | |
525 | mover[j+die2]--; | |
526 | break; | |
527 | ||
528 | case 1: | |
529 | mover[i]++; | |
530 | mover[i+die1]--; | |
531 | } | |
532 | } | |
533 | ||
534 | strategy(player,playee) | |
535 | int *player,*playee; | |
536 | { | |
537 | int k, n, nn, bestval, moveval, prob; | |
538 | ||
539 | n = 0; | |
540 | if(imoves == 0) | |
541 | return(NIL); | |
542 | goodmoves[0] = NIL; | |
543 | bestval = -32000; | |
544 | for(k = 0; k < imoves; k++){ | |
545 | if((moveval=eval(player,playee,k,&prob)) < bestval) | |
546 | continue; | |
547 | if(moveval > bestval){ | |
548 | bestval = moveval; | |
549 | n = 0; | |
550 | } | |
551 | if(n<MAXGMOV){ | |
552 | goodmoves[n]=k; | |
553 | probmoves[n++]=prob; | |
554 | } | |
555 | } | |
556 | if(level=='e' && n>1){ | |
557 | nn=n; | |
558 | n=0; | |
559 | prob=32000; | |
560 | for(k = 0; k < nn; k++){ | |
561 | if((moveval=probmoves[k]) > prob) | |
562 | continue; | |
563 | if(moveval<prob){ | |
564 | prob=moveval; | |
565 | n=0; | |
566 | } | |
567 | goodmoves[n]=goodmoves[k]; | |
568 | probmoves[n++]=probmoves[k]; | |
569 | } | |
570 | } | |
571 | return(goodmoves[(rand()>>4)%n]); | |
572 | } | |
573 | ||
574 | eval(player,playee,k,prob) | |
575 | int *player,*playee,k,*prob; | |
576 | { | |
577 | int newtry[31], newother[31], *r, *q, *p, n, sum, first; | |
578 | int ii, lastwhite, lastbrown; | |
579 | ||
580 | *prob = sum = 0; | |
581 | r = player+25; | |
582 | p = newtry; | |
583 | q = newother; | |
584 | while(player<r){ | |
585 | *p++= *player++; | |
586 | *q++= *playee++; | |
587 | } | |
588 | q=newtry+31; | |
589 | for(p = newtry+25; p < q; p++) /* zero out spaces for hit pieces */ | |
590 | *p = 0; | |
591 | for(n = 0; n < 4; n++){ | |
592 | if(moves[k].pos[n] == NIL) | |
593 | break; | |
594 | newtry[moves[k].pos[n]]--; | |
595 | newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++; | |
596 | if(ii<25 && newother[25-ii]==1){ | |
597 | newother[25-ii]=0; | |
598 | newother[0]++; | |
599 | if(ii<=15 && level=='e') /* hit if near other's home */ | |
600 | sum++; | |
601 | } | |
602 | } | |
603 | for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++); | |
604 | ; | |
605 | for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++) | |
606 | ; | |
607 | lastwhite = 25-lastwhite; | |
608 | if(lastwhite<=6 && lastwhite<lastbrown) | |
609 | sum=1000; | |
610 | /* experts running game. */ | |
611 | /* first priority is to */ | |
612 | /* get all pieces into */ | |
613 | /* white's home */ | |
614 | if(lastwhite<lastbrown && level=='e' && lastwhite>6) { | |
615 | for(sum = 1000; lastwhite > 6; lastwhite--) | |
616 | sum = sum-lastwhite*newtry[25-lastwhite]; | |
617 | } | |
618 | for(first = 0; first < 25; first++) | |
619 | if(newother[first] != 0) /*find other's first piece*/ | |
620 | break; | |
621 | q = newtry+25; | |
622 | for(p = newtry+1; p < q;) /* blocked points are good */ | |
623 | if(*p++ > 1) | |
624 | sum++; | |
625 | if(first > 5) { /* only stress removing pieces if */ | |
626 | /* homeboard cannot be hit */ | |
627 | q = newtry+31; | |
628 | p=newtry+25; | |
629 | for(n = 6; p < q; n--) | |
630 | sum += *p++ * n; /*remove pieces, but just barely*/ | |
631 | } | |
632 | if(level != 'b'){ | |
633 | r = newtry+25-first; /*singles past this point can't be hit*/ | |
634 | for(p = newtry+7; p < r; ) | |
635 | if(*p++ == 1) /*singles are bad after 1st 6 points if they can be hit*/ | |
636 | sum--; | |
637 | q = newtry+3; | |
638 | for(p = newtry; p < q; ) /*bad to be on 1st three points*/ | |
639 | sum -= *p++; | |
640 | } | |
641 | ||
642 | for(n = 1; n <= 4; n++) | |
643 | *prob += n*getprob(newtry,newother,6*n-5,6*n); | |
644 | return(sum); | |
645 | } | |
646 | instructions() | |
647 | { | |
648 | register fd, r; | |
649 | char buf[BUFSIZ]; | |
650 | ||
651 | if((fd = open(RULES, 0)) < 0) { | |
652 | fprintf(stderr, "back: cannot open %s\n", RULES); | |
653 | return; | |
654 | } | |
655 | while(r = read(fd, buf, BUFSIZ)) | |
656 | write(1, buf, r); | |
657 | } | |
658 | ||
659 | getprob(player,playee,start,finish) | |
660 | int *player,*playee,start,finish; | |
661 | { /*returns the probability (times 102) that any | |
662 | pieces belonging to 'player' and lying between | |
663 | his points 'start' and 'finish' will be hit | |
664 | by a piece belonging to playee | |
665 | */ | |
666 | int k, n, sum; | |
667 | ||
668 | sum = 0; | |
669 | for(; start <= finish; start++){ | |
670 | if(player[start] == 1){ | |
671 | for(k = 1; k <= 12; k++){ | |
672 | if((n=25-start-k) < 0) | |
673 | break; | |
674 | if(playee[n] != 0) | |
675 | sum += probability[k]; | |
676 | } | |
677 | } | |
678 | } | |
679 | return(sum); | |
680 | } | |
681 | prtbrd() | |
682 | { | |
683 | int k; | |
684 | static char undersc[]="______________________________________________________"; | |
685 | ||
686 | fprintf(stdout, "White's Home\n%s\r",undersc); | |
687 | for(k = 1; k <= 6; k++) | |
688 | fprintf(stdout, "%4d",k); | |
689 | fprintf(stdout, " "); | |
690 | for(k = 7; k <= 12; k++) | |
691 | fprintf(stdout, "%4d",k); | |
692 | putchar('\n'); | |
693 | numline(brown, white, 1, 6); | |
694 | fprintf(stdout, " "); | |
695 | numline(brown, white, 7, 12); | |
696 | putchar('\n'); | |
697 | colorline(brown, 'B', white, 'W', 1, 6); | |
698 | fprintf(stdout, " "); | |
699 | colorline(brown, 'B', white, 'W', 7, 12); | |
700 | putchar('\n'); | |
701 | if(white[0] != 0) | |
702 | fprintf(stdout, "%28dW\n",white[0]); | |
703 | else | |
704 | putchar('\n'); | |
705 | if(brown[0] != 0) | |
706 | fprintf(stdout, "%28dB\n", brown[0]); | |
707 | else | |
708 | putchar('\n'); | |
709 | colorline(white, 'W', brown, 'B', 1, 6); | |
710 | fprintf(stdout, " "); | |
711 | colorline(white, 'W', brown, 'B', 7, 12); | |
712 | fprintf(stdout, "\n%s\r",undersc); | |
713 | numline(white, brown, 1, 6); | |
714 | fprintf(stdout, " "); | |
715 | numline(white, brown, 7, 12); | |
716 | putchar('\n'); | |
717 | for(k = 24; k >= 19; k--) | |
718 | fprintf(stdout, "%4d",k); | |
719 | fprintf(stdout, " "); | |
720 | for(k = 18; k >= 13; k--) | |
721 | fprintf(stdout, "%4d",k); | |
722 | fprintf(stdout, "\nBrown's Home\n\n\n\n\n"); | |
723 | } | |
724 | numline(upcol,downcol,start,fin) | |
725 | int *upcol,*downcol,start,fin; | |
726 | { | |
727 | int k, n; | |
728 | ||
729 | for(k = start; k <= fin; k++){ | |
730 | if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0) | |
731 | fprintf(stdout, "%4d", n); | |
732 | else | |
733 | fprintf(stdout, " "); | |
734 | } | |
735 | } | |
736 | colorline(upcol,c1,downcol,c2,start,fin) | |
737 | int *upcol,*downcol,start,fin; | |
738 | char c1,c2; | |
739 | { | |
740 | int k; | |
741 | char c; | |
742 | ||
743 | for(k = start; k <= fin; k++){ | |
744 | c = ' '; | |
745 | if(upcol[k] != 0) | |
746 | c = c1; | |
747 | if(downcol[25-k] != 0) | |
748 | c = c2; | |
749 | fprintf(stdout, " %c",c); | |
750 | } | |
751 | } |