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