games-request@tekred.TEK.COM (03/10/88)
Submitted by: John Gilmore <hoptoad.UUCP!gnu@cgl.ucsf.edu> Comp.sources.games: Volume 3, Issue 94 Archive-name: backgammon/Part01 [This is the backgammon game distributed with Berkeley 4.3BSD Unix. The game source has been "declassified", which means you no longer need a Unix source license to legally have a copy of this. See the copyright notice at the begining of each file for details. Thanks to Kirk McKusick and John Gilmore for making this available. -br] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 3)." # Contents: README MANIFEST data.c fancy.c main.c move.c save.c # Wrapped by billr@saab on Wed Mar 9 09:37:12 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README\" else echo shar: Extracting \"README\" \(261 characters\) sed "s/^X//" >README <<'END_OF_README' XThis is the backgammon game distributed with Berkeley 4.3BSD Unix. XThe game source has been "declassified", which means you no longer Xneed a Unix source license to legally have a copy of this. See the Xcopyright notice at the begining of each file for details. END_OF_README if test 261 -ne `wc -c <README`; then echo shar: \"README\" unpacked with wrong size! fi # end of overwriting check fi if test -f MANIFEST -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MANIFEST\" else echo shar: Extracting \"MANIFEST\" \(894 characters\) sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 2 X README 1 X allow.c 3 X back.h 2 X backgammon.1 2 X board.c 3 X check.c 3 X data.c 1 X extra.c 2 X fancy.c 1 X init.c 3 X main.c 1 X move.c 1 X odds.c 3 X one.c 3 X save.c 1 X subs.c 2 X table.c 2 X teach.c 3 X text.c 2 X ttext1.c 2 X ttext2.c 2 X tutor.c 3 X tutor.h 3 X version.c 2 END_OF_MANIFEST if test 894 -ne `wc -c <MANIFEST`; then echo shar: \"MANIFEST\" unpacked with wrong size! fi # end of overwriting check fi if test -f data.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"data.c\" else echo shar: Extracting \"data.c\" \(8647 characters\) sed "s/^X//" >data.c <<'END_OF_data.c' X/* X * Copyright (c) 1980 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#ifndef lint Xstatic char sccsid[] = "@(#)data.c 5.2 (Berkeley) 2/16/88"; X#endif /* not lint */ X X#include "tutor.h" X Xint maxmoves = 23; X Xchar *text0[] = { X "To start the game, I roll a 3, and you roll a 1. This means", X "that I get to start first. I move 8-5,6-5 since this makes a", X "new point and helps to trap your back men on 1. You should be", X "able to do a similar move with your roll.", X 0 X}; X Xchar *text1[] = { X "Now you shall see a move using doubles. I just rolled double", X "5's. I will move two men from position 13 to position 3. The", X "notation for this is 13-8,13-8,8-3,8-3. You will also roll dou-", X "bles, but you will be able to make a much stronger move.", X 0 X}; X Xchar *text2[] = { X "Excellent! As you can see, you are beginning to develop a wall", X "which is trapping my men on position 24. Also, moving your back", X "men forward not only improves your board position safely, but it", X "thwarts my effort to make a wall.", X "", X "My roll now is 5 6. Normally, I would use that roll to move from", X "position 24 to position 13 (24-18-13), but your new point prevents", X "that. Instead, I am forced to move from 13 to 2, where my man is", X "open but cannot be hit.", X 0 X}; X Xchar *text3[] = { X "As you can see, although you left a man open, it is a rela-", X "tively safe move to an advantageous position, which might help", X "you make a point later. Only two rolls (4 5 or 5 4) will allow", X "me to hit you. With an unprecedented amount of luck, I happen", X "to roll a 4 5 and hit you as just mentioned.", X 0 X}; X Xchar *text4[] = { X "You're pretty lucky yourself, you know. I follow by rolling 2 3", X "and moving 25-22,24-22, forming a new point.", X 0 X}; X Xchar *text5[] = { X "Not a spectacular move, but a safe one. I follow by rolling 6 1.", X "I decide to use this roll to move 22-16,16-17. It leaves me with", X "one man still open, but the blot is farther back on the board, and", X "would suffer less of a loss by being hit.", X 0 X}; X Xchar *text6[] = { X "By moving your two men from 17 to 20, you lessen my chance of", X "getting my man off the board. In fact, the odds are 5 to 4", X "against me getting off. I roll with the odds and helplessly", X "receive a 3 5.", X 0 X}; X Xchar *text7[] = { X "Note that the blot on 7 cannot be hit unless I get off the bar", X "and have a 1 or a 6 left over, and doing so will leave two of", X "my men open. Also, the blot on 16 cannot be hit at all! With", X "a sigh of frustration, I roll double 6's and remain immobile.", X 0 X}; X Xchar *text8[] = { X "See, you did not get hit and, you got to 'cover up' your open men.", X "Quite an accomplishment. Finally, I get off the bar by rolling", X "6 2 and moving 25-23,23-17.", X 0 X}; X Xchar *text9[] = { X "My venture off the bar did not last long. However, I got lucky", X "and rolled double 1's, allowing me to move 0-1,1-2,15-14,15-14.", X 0 X}; X Xchar *text10[] = { X "You are improving your position greatly and safely, and are well", X "on the way to winning the game. I roll a 6 2 and squeak past", X "your back man. Now the game becomes a race to the finish.", X 0 X}; X Xchar *text11[] = { X "Now that it is merely a race, you are trying to get as many men", X "as possible into the inner table, so you can start removing them.", X "I roll a 3 4 and move my two men farthest back to position 11", X "(15-11,14-11).", X 0 X}; X Xchar *text12[] = { X "The race is still on, and you have seem to be doing all right.", X "I roll 6 1 and move 14-8,13-12.", X 0 X}; X Xchar *text13[] = { X "Notice that you get to remove men the instant you have all of", X "them at your inner table, even if it is the middle of a turn.", X "I roll 1 2 and move 13-11,12-11.", X 0 X}; X Xchar *text14[] = { X "Although you could have removed a man, this move illustrates two", X "points: 1) You never have to remove men, and 2) You should try", X "to spread out your men on your inner table. Since you have one", X "man on each position, you should be able to remove at least two", X "men next turn. I roll 2 5 and move 8-6,11-6.", X 0 X}; X Xchar *text15[] = { X "This time you were able to remove men. I roll 3 4 and move", X "11-7,11-8. The race continues.", X 0 X}; X Xchar *text16[] = { X "More holes are opening up in your inner table, but you are", X "still very much ahead. If we were doubling, you would have", X "doubled long ago. I roll 2 6 and move 8-6,11-5.", X 0 X}; X Xchar *text17[] = { X "It pays to spread out your men. I roll 3 5 and move 7-4,8-3.", X 0 X}; X Xchar *text18[] = { X "You can only remove some men, but you spread out more and", X "more, in order to be able to remove men more efficiently.", X "I roll double 3's, which help, but not that much. I move", X "8-5,3-0,3-0,3-0.", X 0 X}; X Xchar *text19[] = { X "I roll 1 4 and move 5-4,4-0.", X 0 X}; X Xchar *text20[] = { X "You are now nicely spread out to win a game. I roll 5 6 and", X "move 5-0,6-0.", X 0 X}; X Xchar *text21[] = { X "Any minute now. Just a few short steps from victory. I roll", X "2 4 and move 6-4,4-0.", X 0 X}; X Xchar *text22[] = { X "It looks pretty hopeless for me, but I play on, rolling 1 3 and", X "moving 4-3,3-0.", X 0 X}; X Xchar *text23[] = { X "Congratulations! You just won a game of backgammon against the", X "computer! You will now be able to play a game, but remember,", X "when you start playing, that doubling will be enabled, which", X "will add another factor to the game... Good luck!!", X "", X 0 X}; X Xstruct situatn test[] = { X { X {0,2,0,0,0,0,-5,0,-3,0,0,0,5,-5,0,0,0,3,0,5,0,0,0,0,-2,0}, X 3, 1, {8,6,0,0}, {5,5,0,0}, 4, 2, text0 X }, X { X {0,2,0,0,0,-2,-4,0,-2,0,0,0,5,-5,0,0,0,2,0,4,0,2,0,0,-2,0}, X 5, 5, {13,13,8,8}, {8,8,3,3}, 6, 6, text1 X }, X { X {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-3,0,0,0,2,2,4,0,2,0,0,-2,0}, X 6, 5, {13,8,0,0}, {8,2,0,0}, 1, 2, text2 X }, X { X {0,0,-1,-2,0,-2,-4,2,-2,0,0,0,2,-2,0,1,0,2,2,4,0,2,0,0,-2,0}, X 4, 5, {24,20,0,0}, {20,15,0,0}, 2, 5, text3 X }, X { X {0,0,0,-2,0,-2,-4,3,-2,0,0,0,2,-2,0,-1,0,2,2,4,0,2,0,0,-1,-1}, X 2, 3, {25,24,0,0}, {22,22,0,0}, 4, 1, text4 X }, X { X {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-2,0,-1,0,2,2,4,0,2,-2,0,0,0}, X 6, 1, {22,16,0,0}, {16,15,0,0}, 3, 3, text5 X }, X { X {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-2,0,-2,0,0,2,2,2,2,2,0,0,-1}, X 3, 5, {0,0,0,0}, {0,0,0,0}, 5, 4, text6 X }, X { X {0,0,0,-2,0,-2,-4,1,-2,0,0,0,3,-2,0,-2,1,0,2,2,2,2,2,0,0,-1}, X 6, 6, {0,0,0,0}, {0,0,0,0}, 3, 6, text7 X }, X { X {0,0,0,-2,0,-2,-4,0,-2,0,0,0,3,-2,0,-2,2,0,2,2,2,2,2,0,0,-1}, X 2, 6, {25,23,0,0}, {23,17,0,0}, 5, 1, text8 X }, X { X {0,0,0,-2,0,-2,-4,0,-2,0,0,0,2,-2,0,-2,2,0,3,2,2,2,2,0,0,-1}, X 1, 1, {25,24,15,15}, {24,23,14,14}, 4, 6, text9 X }, X { X {0,0,0,-2,0,-2,-4,0,-2,0,0,0,0,-2,-2,0,3,0,4,2,2,2,2,-1,0,0}, X 6, 2, {23,17,0,0}, {17,15,0,0}, 1, 3, text10 X }, X { X {0,0,0,-2,0,-2,-4,0,-2,0,0,0,0,-2,-2,-1,2,0,3,4,2,2,2,0,0,0}, X 4, 3, {15,14,0,0}, {11,11,0,0}, 5, 3, text11 X }, X { X {0,0,0,-2,0,-2,-4,0,-2,0,0,-2,0,-2,-1,0,0,0,3,5,2,3,2,0,0,0}, X 6, 1, {14,13,0,0}, {8,12,0,0}, 4, 4, text12 X }, X { X {0,0,0,-2,0,-2,-4,0,-3,0,0,-2,-1,-1,0,0,0,0,0,5,2,2,5,0,0,0}, X 2, 1, {13,12,0,0}, {11,11,0,0}, 2, 1, text13 X }, X { X {0,0,0,-2,0,-2,-4,0,-3,0,0,-4,0,0,0,0,0,0,0,5,2,2,3,1,1,0}, X 2, 5, {8,11,0,0}, {6,6,0,0}, 6, 3, text14 X }, X { X {0,0,0,-2,0,-2,-6,0,-2,0,0,-3,0,0,0,0,0,0,0,4,2,2,2,1,1,0}, X 4, 3, {11,11,0,0}, {7,8,0,0}, 2, 5, text15 X }, X { X {0,0,0,-2,0,-2,-6,-1,-3,0,0,-1,0,0,0,0,0,0,0,4,1,2,2,0,1,0}, X 2, 6, {8,11,0,0}, {6,5,0,0}, 6, 1, text16 X }, X { X {0,0,0,-2,0,-3,-7,-1,-2,0,0,0,0,0,0,0,0,0,0,3,1,2,2,0,0,0}, X 5, 3, {8,7,0,0}, {3,4,0,0}, 5, 2, text17 X }, X { X {0,0,0,-3,-1,-3,-7,0,-1,0,0,0,0,0,0,0,0,0,0,3,0,1,2,1,0,0}, X 3, 3, {8,3,3,3}, {5,0,0,0}, 1, 6, text18 X }, X { X {0,0,0,0,-1,-4,-7,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,1,0,0}, X 1, 4, {4,5,0,0}, {0,4,0,0}, 2, 3, text19 X }, X { X {0,0,0,0,-1,-3,-7,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0}, X 5, 6, {6,5,0,0}, {0,0,0,0}, 1, 4, text20 X }, X { X {0,0,0,0,-1,-2,-6,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0}, X 2, 4, {4,6,0,0}, {0,4,0,0}, 6, 2, text21 X }, X { X {0,0,0,0,-1,-2,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, X 3, 1, {4,3,0,0}, {3,0,0,0}, 4, 3, text22 X }, X { X {0,0,0,0,0,-2,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, X 0, 0, {0,0,0,0}, {0,0,0,0}, 0, 0, text23 X } X}; END_OF_data.c if test 8647 -ne `wc -c <data.c`; then echo shar: \"data.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f fancy.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"fancy.c\" else echo shar: Extracting \"fancy.c\" \(15617 characters\) sed "s/^X//" >fancy.c <<'END_OF_fancy.c' X/* X * Copyright (c) 1980 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#ifndef lint Xstatic char sccsid[] = "@(#)fancy.c 5.3 (Berkeley) 2/16/88"; X#endif /* not lint */ X X#include "back.h" X Xchar PC; /* padding character */ Xchar *BC; /* backspace sequence */ Xchar *CD; /* clear to end of screen sequence */ Xchar *CE; /* clear to end of line sequence */ Xchar *CL; /* clear screen sequence */ Xchar *CM; /* cursor movement instructions */ Xchar *HO; /* home cursor sequence */ Xchar *MC; /* column cursor movement map */ Xchar *ML; /* row cursor movement map */ Xchar *ND; /* forward cursor sequence */ Xchar *UP; /* up cursor sequence */ X Xint lHO; /* length of HO */ Xint lBC; /* length of BC */ Xint lND; /* length of ND */ Xint lUP; /* length of UP */ Xint CO; /* number of columns */ Xint LI; /* number of lines */ Xint *linect; /* array of lengths of lines on screen X (the actual screen is not stored) */ X X /* two letter codes */ Xchar tcap[] = "bccdceclcmhomcmlndup"; X /* corresponding strings */ Xchar **tstr[] = { &BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP }; X Xint buffnum; /* pointer to output buffer */ X Xchar tbuf[1024]; /* buffer for decoded termcap entries */ X Xint oldb[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X Xint oldr; Xint oldw; X /* "real" cursor positions, so X * it knows when to reposition. X * These are -1 if curr and curc X * are accurate */ Xint realr; Xint realc; X Xvoid addbuf(); X Xfboard () { X register int i, j, l; X X curmove (0,0); /* do top line */ X for (i = 0; i < 53; i++) X fancyc ('_'); X X curmove (15,0); /* do botttom line */ X for (i = 0; i < 53; i++) X fancyc ('_'); X X l = 1; /* do vertical lines */ X for (i = 52; i > -1; i -= 28) { X curmove ( (l == 1? 1: 15) ,i); X fancyc ('|'); X for (j = 0; j < 14; j++) { X curmove (curr+l,curc-1); X fancyc ('|'); X } X if (i == 24) X i += 32; X l = -l; /* alternate directions */ X } X X curmove (2,1); /* label positions 13-18 */ X for (i = 13; i < 18; i++) { X fancyc ('1'); X fancyc ((i % 10)+'0'); X curmove (curr,curc+2); X } X fancyc ('1'); X fancyc ('8'); X X curmove (2,29); /* label positions 19-24 */ X fancyc ('1'); X fancyc ('9'); X for (i = 20; i < 25; i++) { X curmove (curr,curc+2); X fancyc ('2'); X fancyc ((i % 10)+'0'); X } X X curmove (14,1); /* label positions 12-7 */ X fancyc ('1'); X fancyc ('2'); X for (i = 11; i > 6; i--) { X curmove (curr,curc+2); X fancyc (i > 9? '1': ' '); X fancyc ((i % 10)+'0'); X } X X curmove (14,30); /* label positions 6-1 */ X fancyc ('6'); X for (i = 5; i > 0; i--) { X curmove (curr,curc+3); X fancyc (i+'0'); X } X X for (i = 12; i > 6; i--) /* print positions 12-7 */ X if (board[i]) X bsect (board[i],13,1+4*(12-i),-1); X X if (board[0]) /* print red men on bar */ X bsect (board[0],13,25,-1); X X for (i = 6; i > 0; i--) /* print positions 6-1 */ X if (board[i]) X bsect (board[i],13,29+4*(6-i),-1); X X l = (off[1] < 0? off[1]+15: off[1]); /* print white's home */ X bsect (l,3,54,1); X X curmove (8,25); /* print the word BAR */ X fancyc ('B'); X fancyc ('A'); X fancyc ('R'); X X for (i = 13; i < 19; i++) /* print positions 13-18 */ X if (board[i]) X bsect (board[i],3,1+4*(i-13),1); X X if (board[25]) /* print white's men on bar */ X bsect (board[25],3,25,1); X X for (i = 19; i < 25; i++) /* print positions 19-24 */ X if (board[i]) X bsect (board[i],3,29+4*(i-19),1); X X l = (off[0] < 0? off[0]+15: off[0]); /* print red's home */ X bsect (-l,13,54,-1); X X for (i = 0; i < 26; i++) /* save board position X * for refresh later */ X oldb[i] = board[i]; X oldr = (off[1] < 0? off[1]+15: off[1]); X oldw = -(off[0] < 0? off[0]+15: off[0]); X} X X/* X * bsect (b,rpos,cpos,cnext) X * Print the contents of a board position. "b" has the value of the X * position, "rpos" is the row to start printing, "cpos" is the column to X * start printing, and "cnext" is positive if the position starts at the top X * and negative if it starts at the bottom. The value of "cpos" is checked X * to see if the position is a player's home, since those are printed X * differently. X */ X Xbsect (b,rpos,cpos,cnext) Xint b; /* contents of position */ Xint rpos; /* row of position */ Xint cpos; /* column of position */ Xint cnext; /* direction of position */ X X{ X register int j; /* index */ X register int n; /* number of men on position */ X register int bct; /* counter */ X int k; /* index */ X char pc; /* color of men on position */ X X n = abs(b); /* initialize n and pc */ X pc = (b > 0? 'r': 'w'); X X if (n < 6 && cpos < 54) /* position cursor at start */ X curmove (rpos,cpos+1); X else X curmove (rpos,cpos); X X for (j = 0; j < 5; j++) { /* print position row by row */ X X for (k = 0; k < 15; k += 5) /* print men */ X if (n > j+k) X fancyc (pc); X X if (j < 4) { /* figure how far to X * back up for next X * row */ X if (n < 6) { /* stop if none left */ X if (j+1 == n) X break; X bct = 1; /* single column */ X } else { X if (n < 11) { /* two columns */ X if (cpos == 54) { /* home pos */ X if (j+5 >= n) X bct = 1; X else X bct = 2; X } X if (cpos < 54) { /* not home */ X if (j+6 >= n) X bct = 1; X else X bct = 2; X } X } else { /* three columns */ X if (j+10 >= n) X bct = 2; X else X bct = 3; X } X } X curmove (curr+cnext,curc-bct); /* reposition cursor */ X } X } X} X Xrefresh() { X register int i, r, c; X X r = curr; /* save current position */ X c = curc; X X for (i = 12; i > 6; i--) /* fix positions 12-7 */ X if (board[i] != oldb[i]) { X fixpos (oldb[i],board[i],13,1+(12-i)*4,-1); X oldb[i] = board[i]; X } X X if (board[0] != oldb[0]) { /* fix red men on bar */ X fixpos (oldb[0],board[0],13,25,-1); X oldb[0] = board[0]; X } X X for (i = 6; i > 0; i--) /* fix positions 6-1 */ X if (board[i] != oldb[i]) { X fixpos (oldb[i],board[i],13,29+(6-i)*4,-1); X oldb[i] = board[i]; X } X X i = -(off[0] < 0? off[0]+15: off[0]); /* fix white's home */ X if (oldw != i) { X fixpos (oldw,i,13,54,-1); X oldw = i; X } X X for (i = 13; i < 19; i++) /* fix positions 13-18 */ X if (board[i] != oldb[i]) { X fixpos (oldb[i],board[i],3,1+(i-13)*4,1); X oldb[i] = board[i]; X } X X if (board[25] != oldb[25]) { /* fix white men on bar */ X fixpos (oldb[25],board[25],3,25,1); X oldb[25] = board[25]; X } X X for (i = 19; i < 25; i++) /* fix positions 19-24 */ X if (board[i] != oldb[i]) { X fixpos (oldb[i],board[i],3,29+(i-19)*4,1); X oldb[i] = board[i]; X } X X i = (off[1] < 0? off[1]+15: off[1]); /* fix red's home */ X if (oldr != i) { X fixpos (oldr,i,3,54,1); X oldr = i; X } X X curmove (r,c); /* return to saved position */ X newpos(); X buflush(); X} X Xfixpos (old,new,r,c,inc) Xint old, new, r, c, inc; X X{ X register int o, n, nv; X int ov, nc; X char col; X X if (old*new >= 0) { X ov = abs(old); X nv = abs(new); X col = (old+new > 0? 'r': 'w'); X o = (ov-1)/5; X n = (nv-1)/5; X if (o == n) { X if (o == 2) X nc = c+2; X if (o == 1) X nc = c < 54? c: c+1; X if (o == 0) X nc = c < 54? c+1: c; X if (ov > nv) X fixcol (r+inc*(nv-n*5),nc,abs(ov-nv),' ',inc); X else X fixcol (r+inc*(ov-o*5),nc,abs(ov-nv),col,inc); X return; X } else { X if (c < 54) { X if (o+n == 1) { X if (n) { X fixcol (r,c,abs(nv-5),col,inc); X if (ov != 5) X fixcol (r+inc*ov,c+1,abs(ov-5),col,inc); X } else { X fixcol (r,c,abs(ov-5),' ',inc); X if (nv != 5) X fixcol (r+inc*nv,c+1,abs(nv-5),' ',inc); X } X return; X } X if (n == 2) { X if (ov != 10) X fixcol (r+inc*(ov-5),c,abs(ov-10),col,inc); X fixcol (r,c+2,abs(nv-10),col,inc); X } else { X if (nv != 10) X fixcol (r+inc*(nv-5),c,abs(nv-10),' ',inc); X fixcol (r,c+2,abs(ov-10),' ',inc); X } X return; X } X if (n > o) { X fixcol (r+inc*(ov%5),c+o,abs(5*n-ov),col,inc); X if (nv != 5*n) X fixcol (r,c+n,abs(5*n-nv),col,inc); X } else { X fixcol (r+inc*(nv%5),c+n,abs(5*n-nv),' ',inc); X if (ov != 5*o) X fixcol (r,c+o,abs(5*o-ov),' ',inc); X } X return; X } X } X nv = abs(new); X fixcol (r,c+1,nv,new > 0? 'r': 'w',inc); X if (abs(old) <= abs(new)) X return; X fixcol (r+inc*new,c+1,abs(old+new),' ',inc); X} X Xfixcol (r,c,l,ch,inc) Xregister int l, ch; Xint r, c, inc; X X{ X register int i; X X curmove (r,c); X fancyc (ch); X for (i = 1; i < l; i++) { X curmove (curr+inc,curc-1); X fancyc (ch); X } X} X Xcurmove (r,c) Xregister int r, c; X X{ X if (curr == r && curc == c) X return; X if (realr == -1) { X realr = curr; X realc = curc; X } X curr = r; X curc = c; X} X Xnewpos () { X register int r; /* destination row */ X register int c; /* destination column */ X register int mode = -1; /* mode of movement */ X X int count = 1000; /* character count */ X int i; /* index */ X int j; /* index */ X int n; /* temporary variable */ X char *m; /* string containing CM movement */ X X X if (realr == -1) /* see if already there */ X return; X X r = curr; /* set current and dest. positions */ X c = curc; X curr = realr; X curc = realc; X X /* double check position */ X if (curr == r && curc == c) { X realr = realc = -1; X return; X } X X if (CM) { /* try CM to get there */ X mode = 0; X m = (char *)tgoto (CM,c,r); X count = strlen (m); X } X X /* try HO and local movement */ X if (HO && (n = r+c*lND+lHO) < count) { X mode = 1; X count = n; X } X X /* try various LF combinations */ X if (r >= curr) { X /* CR, LF, and ND */ X if ((n = (r-curr)+c*lND+1) < count) { X mode = 2; X count = n; X } X /* LF, ND */ X if (c >= curc && (n = (r-curr)+(c-curc)*lND) < count) { X mode = 3; X count = n; X } X /* LF, BS */ X if (c < curc && (n = (r-curr)+(curc-c)*lBC) < count) { X mode = 4; X count = n; X } X } X X /* try corresponding UP combinations */ X if (r < curr) { X /* CR, UP, and ND */ X if ((n = (curr-r)*lUP+c*lND+1) < count) { X mode = 5; X count = n; X } X /* UP and ND */ X if (c >= curc && (n = (curr-r)*lUP+(c-curc)*lND) < count) { X mode = 6; X count = n; X } X /* UP and BS */ X if (c < curc && (n = (curr-r)*lUP+(curc-c)*lBC) < count) { X mode = 7; X count = n; X } X } X X /* space over */ X if (curr == r && c > curc && linect[r] < curc && c-curc < count) X mode = 8; X X switch (mode) { X X case -1: /* error! */ X write (2,"\r\nInternal cursor error.\r\n",26); X getout(); X X /* direct cursor motion */ X case 0: X tputs (m,abs(curr-r),addbuf); X break; X X /* relative to "home" */ X case 1: X tputs (HO,r,addbuf); X for (i = 0; i < r; i++) X addbuf ('\012'); X for (i = 0; i < c; i++) X tputs (ND,1,addbuf); X break; X X /* CR and down and over */ X case 2: X addbuf ('\015'); X for (i = 0; i < r-curr; i++) X addbuf ('\012'); X for (i = 0; i < c; i++) X tputs (ND,1,addbuf); X break; X X /* down and over */ X case 3: X for (i = 0; i < r-curr; i++) X addbuf ('\012'); X for (i = 0; i < c-curc; i++) X tputs (ND,1,addbuf); X break; X X /* down and back */ X case 4: X for (i = 0; i < r-curr; i++) X addbuf ('\012'); X for (i = 0; i < curc-c; i++) X addbuf ('\010'); X break; X X /* CR and up and over */ X case 5: X addbuf ('\015'); X for (i = 0; i < curr-r; i++) X tputs (UP,1,addbuf); X for (i = 0; i < c; i++) X tputs (ND,1,addbuf); X break; X X /* up and over */ X case 6: X for (i = 0; i < curr-r; i++) X tputs (UP,1,addbuf); X for (i = 0; i < c-curc; i++) X tputs (ND,1,addbuf); X break; X X /* up and back */ X case 7: X for (i = 0; i < curr-r; i++) X tputs (UP,1,addbuf); X for (i = 0; i < curc-c; i++) { X if (BC) X tputs (BC,1,addbuf); X else X addbuf ('\010'); X } X break; X X /* safe space */ X case 8: X for (i = 0; i < c-curc; i++) X addbuf (' '); X } X X /* fix positions */ X curr = r; X curc = c; X realr = -1; X realc = -1; X} X Xclear () { X register int i; X X /* double space if can't clear */ X if (CL == 0) { X writel ("\n\n"); X return; X } X X curr = curc = 0; /* fix position markers */ X realr = realc = -1; X for (i = 0; i < 24; i++) /* clear line counts */ X linect[i] = -1; X buffnum = -1; /* ignore leftover buffer contents */ X tputs (CL,CO,addbuf); /* put CL in buffer */ X} X Xtos () { /* home cursor */ X curmove (0,0); X} X Xfancyc (c) Xregister char c; /* character to output */ X{ X register int sp; /* counts spaces in a tab */ X X if (c == '\007') { /* bells go in blindly */ X addbuf (c); X return; X } X X /* process tabs, use spaces if the X * the tab should be erasing things, X * otherwise use cursor movement X * routines. Note this does not use X * hardware tabs at all. */ X if (c == '\t') { X sp = (curc+8) & (~ 7); /* compute spaces */ X /* check line length */ X if (linect[curr] >= curc || sp < 4) { X for (; sp > curc; sp--) X addbuf (' '); X curc = sp; /* fix curc */ X } else X curmove (curr,sp); X return; X } X X /* do newline be calling newline */ X if (c == '\n') { X newline(); X return; X } X X /* ignore any other control chars */ X if (c < ' ') X return; X X /* if an erasing space or non-space, X * just add it to buffer. Otherwise X * use cursor movement routine, so that X * multiple spaces will be grouped X * together */ X if (c > ' ' || linect[curr] >= curc) { X newpos (); /* make sure position correct */ X addbuf (c); /* add character to buffer */ X /* fix line length */ X if (c == ' ' && linect[curr] == curc) X linect[curr]--; X else if (linect[curr] < curc) X linect[curr] = curc; X curc++; /* fix curc */ X } else X /* use cursor movement routine */ X curmove (curr,curc+1); X} X Xclend() { X register int i; X register char *s; X X X if (CD) { X tputs (CD,CO-curr,addbuf); X for (i = curr; i < LI; i++) X linect[i] = -1; X return; X } X X curmove (i = curr,0); X cline(); X while (curr < LI-1) { X curmove (curr+1,0); X if (linect[curr] > -1) X cline (); X } X curmove (i,0); X} X Xcline () { X register int i; X register int c; X register char *s; X X if (curc > linect[curr]) X return; X newpos (); X if (CE) { X tputs (CE,1,addbuf); X linect[curr] = curc-1; X } else { X c = curc-1; X while (linect[curr] > c) { X addbuf (' '); X curc++; X linect[curr]--; X } X curmove (curr,c+1); X } X} X Xnewline () { X cline(); X if (curr == LI-1) X curmove (begscr,0); X else X curmove (curr+1,0); X} X Xgetcaps (s) Xregister char *s; X X{ X register char *code; /* two letter code */ X register char ***cap; /* pointer to cap string */ X char *bufp; /* pointer to cap buffer */ X char tentry[1024]; /* temporary uncoded caps buffer */ X X tgetent (tentry,s); /* get uncoded termcap entry */ X X LI = tgetnum ("li"); /* get number of lines */ X if (LI == -1) X LI = 12; X CO = tgetnum ("co"); /* get number of columns */ X if (CO == -1) X CO = 65; X X bufp = tbuf; /* get padding character */ X tgetstr ("pc",&bufp); X if (bufp != tbuf) X PC = *tbuf; X else X PC = 0; X X bufp = tbuf; /* get string entries */ X cap = tstr; X for (code = tcap; *code; code += 2) X **cap++ = (char *)tgetstr (code,&bufp); X X /* get pertinent lengths */ X if (HO) X lHO = strlen (HO); X if (BC) X lBC = strlen (BC); X else X lBC = 1; X if (UP) X lUP = strlen (UP); X if (ND) X lND = strlen (ND); X if (LI < 24 || CO < 72 || !(CL && UP && ND)) X return (0); X linect = (int *)calloc (LI+1,sizeof(int)); X return (1); X} END_OF_fancy.c if test 15617 -ne `wc -c <fancy.c`; then echo shar: \"fancy.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f main.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"main.c\" else echo shar: Extracting \"main.c\" \(11532 characters\) sed "s/^X//" >main.c <<'END_OF_main.c' X/* X * Copyright (c) 1980 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#ifndef lint Xchar copyright[] = X"@(#) Copyright (c) 1980 Regents of the University of California.\n\ X All rights reserved.\n"; X#endif /* not lint */ X X#ifndef lint Xstatic char sccsid[] = "@(#)main.c 5.4 (Berkeley) 2/16/88"; X#endif /* not lint */ X X#include <stdio.h> X#include "back.h" X X#define MVPAUSE 5 /* time to sleep when stuck */ X#define MAXUSERS 35 /* maximum number of users */ X Xchar *instr[]; /* text of instructions */ Xchar *message[]; /* update message */ Xchar ospeed; /* tty output speed */ X Xchar *helpm[] = { /* help message */ X "Enter a space or newline to roll, or", X " R to reprint the board\tD to double", X " S to save the game\tQ to quit", X 0 X}; X Xchar *contin[] = { /* pause message */ X "(Type a newline to continue.)", X "", X 0 X}; X Xstatic char user1a[] = X "Sorry, you cannot play backgammon when there are more than "; Xstatic char user1b[] = X " users\non the system."; Xstatic char user2a[] = X "\nThere are now more than "; Xstatic char user2b[] = X " users on the system, so you cannot play\nanother game. "; Xstatic char rules[] = "\nDo you want the rules of the game?"; Xstatic char noteach[] = "Teachgammon not available!\n\007"; Xstatic char need[] = "Do you need instructions for this program?"; Xstatic char askcol[] = X "Enter 'r' to play red, 'w' to play white, 'b' to play both:"; Xstatic char rollr[] = "Red rolls a "; Xstatic char rollw[] = ". White rolls a "; Xstatic char rstart[] = ". Red starts.\n"; Xstatic char wstart[] = ". White starts.\n"; Xstatic char toobad1[] = "Too bad, "; Xstatic char unable[] = " is unable to use that roll.\n"; Xstatic char toobad2[] = ". Too bad, "; Xstatic char cantmv[] = " can't move.\n"; Xstatic char bgammon[] = "Backgammon! "; Xstatic char gammon[] = "Gammon! "; Xstatic char again[] = ".\nWould you like to play again?"; Xstatic char svpromt[] = "Would you like to save this game?"; X Xstatic char password[] = "losfurng"; Xstatic char pbuf[10]; X Xmain (argc,argv) Xint argc; Xchar **argv; X X{ X register int i; /* non-descript index */ X register int l; /* non-descript index */ X register char c; /* non-descript character storage */ X long t; /* time for random num generator */ X X /* initialization */ X bflag = 2; /* default no board */ X signal (2,getout); /* trap interrupts */ X if (gtty (0,&tty) == -1) /* get old tty mode */ X errexit ("backgammon(gtty)"); X old = tty.sg_flags; X#ifdef V7 X raw = ((noech = old & ~ECHO) | CBREAK); /* set up modes */ X#else X raw = ((noech = old & ~ECHO) | RAW); /* set up modes */ X#endif X ospeed = tty.sg_ospeed; /* for termlib */ X X /* check user count */ X# ifdef CORY X if (ucount() > MAXUSERS) { X writel (user1a); X wrint (MAXUSERS); X writel (user1b); X getout(); X } X# endif X X /* get terminal X * capabilities, and X * decide if it can X * cursor address */ X tflag = getcaps (getenv ("TERM")); X /* use whole screen X * for text */ X if (tflag) X begscr = 0; X t = time(0); X srandom(t); /* 'random' seed */ X X#ifdef V7 X while (*++argv != 0) /* process arguments */ X#else X while (*++argv != -1) /* process arguments */ X#endif X getarg (&argv); X args[acnt] = '\0'; X if (tflag) { /* clear screen */ X noech &= ~(CRMOD|XTABS); X raw &= ~(CRMOD|XTABS); X clear(); X } X fixtty (raw); /* go into raw mode */ X X /* check if restored X * game and save flag X * for later */ X if (rfl = rflag) { X text (message); /* print message */ X text (contin); X wrboard(); /* print board */ X /* if new game, pretend X * to be a non-restored X * game */ X if (cturn == 0) X rflag = 0; X } else { X rscore = wscore = 0; /* zero score */ X text (message); /* update message X * without pausing */ X X if (aflag) { /* print rules */ X writel (rules); X if (yorn(0)) { X X fixtty (old); /* restore tty */ X execl (TEACH,"teachgammon",args,0); X X tflag = 0; /* error! */ X writel (noteach); X exit(); X } else { /* if not rules, then X * instructions */ X writel (need); X if (yorn(0)) { /* print instructions */ X clear(); X text (instr); X } X } X } X X init(); /* initialize board */ X X if (pnum == 2) { /* ask for color(s) */ X writec ('\n'); X writel (askcol); X while (pnum == 2) { X c = readc(); X switch (c) { X X case 'R': /* red */ X pnum = -1; X break; X X case 'W': /* white */ X pnum = 1; X break; X X case 'B': /* both */ X pnum = 0; X break; X X case 'P': X if (iroll) X break; X if (tflag) X curmove (curr,0); X else X writec ('\n'); X writel ("Password:"); X signal (14,getout); X cflag = 1; X alarm (10); X for (i = 0; i < 10; i++) { X pbuf[i] = readc(); X if (pbuf[i] == '\n') X break; X } X if (i == 10) X while (readc() != '\n'); X alarm (0); X cflag = 0; X if (i < 10) X pbuf[i] = '\0'; X for (i = 0; i < 9; i++) X if (pbuf[i] != password[i]) X getout(); X iroll = 1; X if (tflag) X curmove (curr,0); X else X writec ('\n'); X writel (askcol); X break; X X default: /* error */ X writec ('\007'); X } X } X } else if (!aflag) X /* pause to read X * message */ X text (contin); X X wrboard(); /* print board */ X X if (tflag) X curmove (18,0); X else X writec ('\n'); X } X /* limit text to bottom X * of screen */ X if (tflag) X begscr = 17; X X for (;;) { /* begin game! */ X /* initial roll if X * needed */ X if ((! rflag) || raflag) X roll(); X X /* perform ritual of X * first roll */ X if (! rflag) { X if (tflag) X curmove (17,0); X while (D0 == D1) /* no doubles */ X roll(); X X /* print rolls */ X writel (rollr); X writec (D0+'0'); X writel (rollw); X writec (D1+'0'); X X /* winner goes first */ X if (D0 > D1) { X writel (rstart); X cturn = 1; X } else { X writel (wstart); X cturn = -1; X } X } X X /* initalize variables X * according to whose X * turn it is */ X X if (cturn == 1) { /* red */ X home = 25; X bar = 0; X inptr = &in[1]; X inopp = &in[0]; X offptr = &off[1]; X offopp = &off[0]; X Colorptr = &color[1]; X colorptr = &color[3]; X colen = 3; X } else { /* white */ X home = 0; X bar = 25; X inptr = &in[0]; X inopp = &in[1]; X offptr = &off[0]; X offopp = &off[1]; X Colorptr = &color[0]; X colorptr = &color[2]; X colen = 5; X } X X /* do first move X * (special case) */ X if (! (rflag && raflag)) { X if (cturn == pnum) /* computer's move */ X move (0); X else { /* player's move */ X mvlim = movallow(); X /* reprint roll */ X if (tflag) X curmove (cturn == -1? 18: 19,0); X proll(); X getmove(); /* get player's move */ X } X } X if (tflag) { X curmove (17,0); X cline(); X begscr = 18; X } X X /* no longer any diff- X * erence between normal X * game and recovered X * game. */ X rflag = 0; X X /* move as long as it's X * someone's turn */ X while (cturn == 1 || cturn == -1) { X X /* board maintainence */ X if (tflag) X refresh(); /* fix board */ X else X /* redo board if -p */ X if (cturn == bflag || bflag == 0) X wrboard(); X X /* do computer's move */ X if (cturn == pnum) { X move (1); X X /* see if double X * refused */ X if (cturn == -2 || cturn == 2) X break; X X /* check for winning X * move */ X if (*offopp == 15) { X cturn *= -2; X break; X } X continue; X X } X X /* (player's move) */ X X /* clean screen if X * safe */ X if (tflag && hflag) { X curmove (20,0); X clend (); X hflag = 1; X } X X /* if allowed, give him X * a chance to double */ X if (dlast != cturn && gvalue < 64) { X if (tflag) X curmove (cturn == -1? 18: 19,0); X writel (*Colorptr); X c = readc(); X X /* character cases */ X switch (c) { X X /* reprint board */ X case 'R': X wrboard(); X break; X X /* save game */ X case 'S': X raflag = 1; X save (1); X break; X X /* quit */ X case 'Q': X quit(); X break; X X /* double */ X case 'D': X dble(); X break; X X /* roll */ X case ' ': X case '\n': X roll(); X writel (" rolls "); X writec (D0+'0'); X writec (' '); X writec (D1+'0'); X writel (". "); X X /* see if he can move */ X if ( (mvlim = movallow()) == 0) { X X /* can't move */ X writel (toobad1); X writel (*colorptr); X writel (unable); X if (tflag) { X if (pnum) { X buflush(); X sleep (MVPAUSE); X } X } X nexturn(); X break; X } X X /* get move */ X getmove(); X X /* okay to clean X * screen */ X hflag = 1; X break; X X /* invalid character */ X default: X X /* print help message */ X if (tflag) X curmove (20,0); X else X writec ('\n'); X text (helpm); X if (tflag) X curmove (cturn == -1? 18: 19,0); X else X writec ('\n'); X X /* don't erase */ X hflag = 0; X } X } else { /* couldn't double */ X X /* print roll */ X roll(); X if (tflag) X curmove (cturn == -1? 18: 19,0); X proll (); X X /* can he move? */ X if ((mvlim = movallow()) == 0) { X X /* he can't */ X writel (toobad2); X writel (*colorptr); X writel (cantmv); X buflush(); X sleep (MVPAUSE); X nexturn(); X continue; X } X X /* get move */ X getmove(); X } X } X X /* don't worry about who X * won if quit */ X if (cturn == 0) X break; X X /* fix cturn = winner */ X cturn /= -2; X X /* final board pos. */ X if (tflag) X refresh(); X X /* backgammon? */ X mflag = 0; X l = bar+7*cturn; X for (i = bar; i != l; i += cturn) X if (board[i]*cturn) mflag++; X X /* compute game value */ X if (tflag) X curmove (20,0); X if (*offopp == 15) { X if (mflag) { X writel (bgammon); X gvalue *= 3; X } X else if (*offptr <= 0) { X writel (gammon); X gvalue *= 2; X } X } X X /* report situation */ X if (cturn == -1) { X writel ("Red wins "); X rscore += gvalue; X } else { X writel ("White wins "); X wscore += gvalue; X } X wrint (gvalue); X writel (" point"); X if (gvalue > 1) X writec ('s'); X writel (".\n"); X X /* write score */ X wrscore(); X X /* check user count */ X# ifdef CORY X if (ucount() > MAXUSERS) { X writel (user2a); X wrint (MAXUSERS); X writel (user2b); X rfl = 1; X break; X } X# endif X X /* see if he wants X * another game */ X writel (again); X if ((i = yorn ('S')) == 0) X break; X X init(); X if (i == 2) { X writel (" Save.\n"); X cturn = 0; X save (0); X } X X /* yes, reset game */ X wrboard(); X } X X /* give him a chance to save if game was recovered */ X if (rfl && cturn) { X writel (svpromt); X if (yorn (0)) { X /* re-initialize for X * recovery */ X init(); X cturn = 0; X save(0); X } X } X X /* leave peacefully */ X getout (); X} END_OF_main.c if test 11532 -ne `wc -c <main.c`; then echo shar: \"main.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f move.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"move.c\" else echo shar: Extracting \"move.c\" \(11131 characters\) sed "s/^X//" >move.c <<'END_OF_move.c' X/* X * Copyright (c) 1980 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#ifndef lint Xstatic char sccsid[] = "@(#)move.c 5.3 (Berkeley) 2/16/88"; X#endif /* not lint */ X X#include "back.h" X X#ifdef DEBUG X#include <stdio.h> XFILE *trace; Xstatic char tests[20]; X#endif X Xstruct BOARD { /* structure of game position */ X int b_board[26]; /* board position */ X int b_in[2]; /* men in */ X int b_off[2]; /* men off */ X int b_st[4], b_fn[4]; /* moves */ X X struct BOARD *b_next; /* forward queue pointer */ X}; X Xstruct BOARD *freeq = 0; Xstruct BOARD *checkq = 0; Xstruct BOARD *bsave(); Xstruct BOARD *nextfree(); X X /* these variables are values for the X * candidate move */ Xstatic int ch; /* chance of being hit */ Xstatic int op; /* computer's open men */ Xstatic int pt; /* comp's protected points */ Xstatic int em; /* farthest man back */ Xstatic int frc; /* chance to free comp's men */ Xstatic int frp; /* chance to free pl's men */ X X /* these values are the values for the X * move chosen (so far) */ Xstatic int chance; /* chance of being hit */ Xstatic int openmen; /* computer's open men */ Xstatic int points; /* comp's protected points */ Xstatic int endman; /* farthest man back */ Xstatic int barmen; /* men on bar */ Xstatic int menin; /* men in inner table */ Xstatic int menoff; /* men off board */ Xstatic int oldfrc; /* chance to free comp's men */ Xstatic int oldfrp; /* chance to free pl's men */ X Xstatic int cp[5]; /* candidate start position */ Xstatic int cg[5]; /* candidate finish position */ X Xstatic int race; /* game reduced to a race */ X Xmove (okay) Xint okay; /* zero if first move */ X{ X register int i; /* index */ X register int l; /* last man */ X X if (okay) { X /* see if comp should double */ X if (gvalue < 64 && dlast != cturn && dblgood()) { X writel (*Colorptr); X dble(); /* double */ X /* return if declined */ X if (cturn != 1 && cturn != -1) X return; X } X roll(); X } X X race = 0; X for (i = 0; i < 26; i++) { X if (board[i] < 0) X l = i; X } X for (i = 0; i < l; i++) { X if (board[i] > 0) X break; X } X if (i == l) X race = 1; X X /* print roll */ X if (tflag) X curmove (cturn == -1? 18: 19,0); X writel (*Colorptr); X writel (" rolls "); X writec (D0+'0'); X writec (' '); X writec (D1+'0'); X /* make tty interruptable X * while thinking */ X if (tflag) X cline(); X fixtty (noech); X X /* find out how many moves */ X mvlim = movallow(); X if (mvlim == 0) { X writel (" but cannot use it.\n"); X nexturn(); X fixtty (raw); X return; X } X X /* initialize */ X for (i = 0; i < 4; i++) X cp[i] = cg[i] = 0; X X /* strategize */ X trymove (0,0); X pickmove(); X X /* print move */ X writel (" and moves "); X for (i = 0; i < mvlim; i++) { X if (i > 0) X writec (','); X wrint (p[i] = cp[i]); X writec ('-'); X wrint (g[i] = cg[i]); X makmove (i); X } X writec ('.'); X X /* print blots hit */ X if (tflag) X curmove (20,0); X else X writec ('\n'); X for (i = 0; i < mvlim; i++) X if (h[i]) X wrhit(g[i]); X /* get ready for next move */ X nexturn(); X if (!okay) { X buflush(); X sleep (3); X } X fixtty (raw); /* no more tty interrupt */ X} X Xtrymove (mvnum,swapped) Xregister int mvnum; /* number of move (rel zero) */ Xint swapped; /* see if swapped also tested */ X X{ X register int pos; /* position on board */ X register int rval; /* value of roll */ X X /* if recursed through all dice X * values, compare move */ X if (mvnum == mvlim) { X binsert (bsave()); X return; X } X X /* make sure dice in always X * same order */ X if (d0 == swapped) X swap; X /* choose value for this move */ X rval = dice[mvnum != 0]; X X /* find all legitimate moves */ X for (pos = bar; pos != home; pos += cturn) { X /* fix order of dice */ X if (d0 == swapped) X swap; X /* break if stuck on bar */ X if (board[bar] != 0 && pos != bar) X break; X /* on to next if not occupied */ X if (board[pos]*cturn <= 0) X continue; X /* set up arrays for move */ X p[mvnum] = pos; X g[mvnum] = pos+rval*cturn; X if (g[mvnum]*cturn >= home) { X if (*offptr < 0) X break; X g[mvnum] = home; X } X /* try to move */ X if (makmove (mvnum)) X continue; X else X trymove (mvnum+1,2); X /* undo move to try another */ X backone (mvnum); X } X X /* swap dice and try again */ X if ((!swapped) && D0 != D1) X trymove (0,1); X} X Xstruct BOARD * Xbsave () { X register int i; /* index */ X struct BOARD *now; /* current position */ X X now = nextfree (); /* get free BOARD */ X X /* store position */ X for (i = 0; i < 26; i++) X now->b_board[i] = board[i]; X now->b_in[0] = in[0]; X now->b_in[1] = in[1]; X now->b_off[0] = off[0]; X now->b_off[1] = off[1]; X for (i = 0; i < mvlim; i++) { X now->b_st[i] = p[i]; X now->b_fn[i] = g[i]; X } X return (now); X} X Xbinsert (new) Xstruct BOARD *new; /* item to insert */ X{ X register struct BOARD *p = checkq; /* queue pointer */ X register int result; /* comparison result */ X X if (p == 0) { /* check if queue empty */ X checkq = p = new; X p->b_next = 0; X return; X } X X result = bcomp (new,p); /* compare to first element */ X if (result < 0) { /* insert in front */ X new->b_next = p; X checkq = new; X return; X } X if (result == 0) { /* duplicate entry */ X mvcheck (p,new); X makefree (new); X return; X } X X while (p->b_next != 0) { /* traverse queue */ X result = bcomp (new,p->b_next); X if (result < 0) { /* found place */ X new->b_next = p->b_next; X p->b_next = new; X return; X } X if (result == 0) { /* duplicate entry */ X mvcheck (p->b_next,new); X makefree (new); X return; X } X p = p->b_next; X } X /* place at end of queue */ X p->b_next = new; X new->b_next = 0; X} X Xbcomp (a,b) Xstruct BOARD *a; Xstruct BOARD *b; X{ X register int *aloc = a->b_board; /* pointer to board a */ X register int *bloc = b->b_board; /* pointer to board b */ X register int i; /* index */ X int result; /* comparison result */ X X for (i = 0; i < 26; i++) { /* compare boards */ X result = cturn*(aloc[i]-bloc[i]); X if (result) X return (result); /* found inequality */ X } X return (0); /* same position */ X} X Xmvcheck (incumbent,candidate) Xregister struct BOARD *incumbent; Xregister struct BOARD *candidate; X{ X register int i; X register int result; X X for (i = 0; i < mvlim; i++) { X result = cturn*(candidate->b_st[i]-incumbent->b_st[i]); X if (result > 0) X return; X if (result < 0) X break; X } X if (i == mvlim) X return; X for (i = 0; i < mvlim; i++) { X incumbent->b_st[i] = candidate->b_st[i]; X incumbent->b_fn[i] = candidate->b_fn[i]; X } X} X Xmakefree (dead) Xstruct BOARD *dead; /* dead position */ X{ X dead->b_next = freeq; /* add to freeq */ X freeq = dead; X} X Xstruct BOARD * Xnextfree () { X struct BOARD *new; X X if (freeq == 0) { X new = (struct BOARD *)calloc (1,sizeof (struct BOARD)); X if (new == 0) { X writel ("\nOut of memory\n"); X getout(); X } X new->b_next = 0; X return (new); X } X X new = freeq; X freeq = freeq->b_next; X return new; X} X Xpickmove () { X /* current game position */ X register struct BOARD *now = bsave(); X register struct BOARD *next; /* next move */ X X#ifdef DEBUG X if (trace == NULL) X trace = fopen ("bgtrace","w"); X fprintf (trace,"\nRoll: %d %d%s\n",D0,D1,race? " (race)": ""); X fflush (trace); X#endif X do { /* compare moves */ X bcopy (checkq); X next = checkq->b_next; X makefree (checkq); X checkq = next; X movcmp(); X } while (checkq != 0); X X bcopy (now); X} X Xbcopy (s) Xregister struct BOARD *s; /* game situation */ X{ X register int i; /* index */ X X for (i = 0; i < 26; i++) X board[i] = s->b_board[i]; X for (i = 0; i < 2; i++) { X in[i] = s->b_in[i]; X off[i] = s->b_off[i]; X } X for (i = 0; i < mvlim; i++) { X p[i] = s->b_st[i]; X g[i] = s->b_fn[i]; X } X} X Xmovcmp () { X register int i; X register int c; X X#ifdef DEBUG X if (trace == NULL) X trace = fopen ("bgtrace","w"); X#endif X X odds (0,0,0); X if (!race) { X ch = op = pt = 0; X for (i = 1; i < 25; i++) { X if (board[i] == cturn) X ch = canhit (i,1); X op += abs (bar-i); X } X for (i = bar+cturn; i != home; i += cturn) X if (board[i]*cturn > 1) X pt += abs(bar-i); X frc = freemen (bar)+trapped (bar,cturn); X frp = freemen (home)+trapped (home,-cturn); X } X for (em = bar; em != home; em += cturn) X if (board[em]*cturn > 0) X break; X em = abs(home-em); X#ifdef DEBUG X fputs ("Board: ",trace); X for (i = 0; i < 26; i++) X fprintf (trace, " %d",board[i]); X if (race) X fprintf (trace,"\n\tem = %d\n",em); X else X fprintf (trace, X "\n\tch = %d, pt = %d, em = %d, frc = %d, frp = %d\n", X ch,pt,em,frc,frp); X fputs ("\tMove: ",trace); X for (i = 0; i < mvlim; i++) X fprintf (trace," %d-%d",p[i],g[i]); X fputs ("\n",trace); X fflush (trace); X strcpy (tests,""); X#endif X if ((cp[0] == 0 && cg[0] == 0) || movegood()) { X#ifdef DEBUG X fprintf (trace,"\t[%s] ... wins.\n",tests); X fflush (trace); X#endif X for (i = 0; i < mvlim; i++) { X cp[i] = p[i]; X cg[i] = g[i]; X } X if (!race) { X chance = ch; X openmen = op; X points = pt; X endman = em; X barmen = abs(board[home]); X oldfrc = frc; X oldfrp = frp; X } X menin = *inptr; X menoff = *offptr; X } X#ifdef DEBUG X else { X fprintf (trace,"\t[%s] ... loses.\n",tests); X fflush (trace); X } X#endif X} X Xmovegood () { X register int n; X X if (*offptr == 15) X return (1); X if (menoff == 15) X return (0); X if (race) { X#ifdef DEBUG X strcat (tests,"o"); X#endif X if (*offptr-menoff) X return (*offptr > menoff); X#ifdef DEBUG X strcat (tests,"e"); X#endif X if (endman-em) X return (endman > em); X#ifdef DEBUG X strcat (tests,"i"); X#endif X if (menin == 15) X return (0); X if (*inptr == 15) X return (1); X#ifdef DEBUG X strcat (tests,"i"); X#endif X if (*inptr-menin) X return (*inptr > menin); X return (rnum(2)); X } else { X n = barmen-abs(board[home]); X#ifdef DEBUG X strcat (tests,"c"); X#endif X if (abs(chance-ch)+25*n > rnum(150)) X return (n? (n < 0): (ch < chance)); X#ifdef DEBUG X strcat (tests,"o"); X#endif X if (*offptr-menoff) X return (*offptr > menoff); X#ifdef DEBUG X strcat (tests,"o"); X#endif X if (abs(openmen-op) > 7+rnum(12)) X return (openmen > op); X#ifdef DEBUG X strcat (tests,"b"); X#endif X if (n) X return (n < 0); X#ifdef DEBUG X strcat (tests,"e"); X#endif X if (abs(endman-em) > rnum(2)) X return (endman > em); X#ifdef DEBUG X strcat (tests,"f"); X#endif X if (abs(frc-oldfrc) > rnum(2)) X return (frc < oldfrc); X#ifdef DEBUG X strcat (tests,"p"); X#endif X if (abs(n = pt-points) > rnum(4)) X return (n > 0); X#ifdef DEBUG X strcat (tests,"i"); X#endif X if (*inptr-menin) X return (*inptr > menin); X#ifdef DEBUG X strcat (tests,"f"); X#endif X if (abs(frp-oldfrp) > rnum(2)) X return (frp > oldfrp); X return (rnum(2)); X } X} END_OF_move.c if test 11131 -ne `wc -c <move.c`; then echo shar: \"move.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f save.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"save.c\" else echo shar: Extracting \"save.c\" \(3405 characters\) sed "s/^X//" >save.c <<'END_OF_save.c' X/* X * Copyright (c) 1980 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#ifndef lint Xstatic char sccsid[] = "@(#)save.c 5.2 (Berkeley) 2/16/88"; X#endif /* not lint */ X X#include "back.h" X Xextern int errno; X Xstatic char confirm[] = "Are you sure you want to leave now?"; Xstatic char prompt[] = "Enter a file name: "; Xstatic char exist1[] = "The file '"; Xstatic char exist2[] = X "' already exists.\nAre you sure you want to use this file?"; Xstatic char cantuse[] = "\nCan't use "; Xstatic char saved[] = "This game has been saved on the file '"; Xstatic char type[] = "'.\nType \"backgammon "; Xstatic char rec[] = "\" to recover your game.\n\n"; Xstatic char cantrec[] = "Can't recover file: "; X Xsave (n) Xregister int n; X X{ X register int fdesc; X register char *fs; X char fname[50]; X X if (n) { X if (tflag) { X curmove (20,0); X clend(); X } else X writec ('\n'); X writel (confirm); X if (! yorn(0)) X return; X } X cflag = 1; X for (;;) { X writel (prompt); X fs = fname; X while ((*fs = readc()) != '\n') { X if (*fs == tty.sg_erase) { X if (fs > fname) { X fs--; X if (tflag) X curmove (curr,curc-1); X else X writec (*fs); X } else X writec ('\007'); X continue; X } X writec (*fs++); X } X *fs = '\0'; X if ((fdesc = open(fname,2)) == -1 && errno == 2) { X if ((fdesc = creat (fname,0700)) != -1) X break; X } X if (fdesc != -1) { X if (tflag) { X curmove (18,0); X clend(); X } else X writec ('\n'); X writel (exist1); X writel (fname); X writel (exist2); X cflag = 0; X close (fdesc); X if (yorn (0)) { X unlink (fname); X fdesc = creat (fname,0700); X break; X } else { X cflag = 1; X continue; X } X } X writel (cantuse); X writel (fname); X writel (".\n"); X close (fdesc); X cflag = 1; X } X write (fdesc,board,sizeof board); X write (fdesc,off,sizeof off); X write (fdesc,in,sizeof in); X write (fdesc,dice,sizeof dice); X write (fdesc,&cturn,sizeof cturn); X write (fdesc,&dlast,sizeof dlast); X write (fdesc,&pnum,sizeof pnum); X write (fdesc,&rscore,sizeof rscore); X write (fdesc,&wscore,sizeof wscore); X write (fdesc,&gvalue,sizeof gvalue); X write (fdesc,&raflag,sizeof raflag); X close (fdesc); X if (tflag) X curmove (18,0); X writel (saved); X writel (fname); X writel (type); X writel (fname); X writel (rec); X if (tflag) X clend(); X getout (); X} X Xrecover (s) Xchar *s; X X{ X register int i; X int fdesc; X X if ((fdesc = open (s,0)) == -1) X norec (s); X read (fdesc,board,sizeof board); X read (fdesc,off,sizeof off); X read (fdesc,in,sizeof in); X read (fdesc,dice,sizeof dice); X read (fdesc,&cturn,sizeof cturn); X read (fdesc,&dlast,sizeof dlast); X read (fdesc,&pnum,sizeof pnum); X read (fdesc,&rscore,sizeof rscore); X read (fdesc,&wscore,sizeof wscore); X read (fdesc,&gvalue,sizeof gvalue); X read (fdesc,&raflag,sizeof raflag); X close (fdesc); X rflag = 1; X} X Xnorec (s) Xregister char *s; X X{ X register char *c; X X tflag = 0; X writel (cantrec); X c = s; X while (*c != '\0') X writec (*c++); X getout (); X} END_OF_save.c if test 3405 -ne `wc -c <save.c`; then echo shar: \"save.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 3\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0