home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / tinygo1.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  13.5 KB  |  528 lines

  1. #! /bin/sh
  2. # This is a shell archive.  Remove anything before this line, then unpack
  3. # it by saving it into a file and typing "sh file".  To overwrite existing
  4. # files, type "sh file -c".  You can also feed this as standard input via
  5. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  6. # will see the following message at the end:
  7. #        "End of archive 1 (of 1)."
  8. # Contents:  README Makefile debug.c disp.c go.c go.h
  9. # Wrapped by jdr@hebe.weh.andrew.cmu.edu on Wed Dec 12 14:49:51 1990
  10. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  11. if test -f README -a "${1}" != "-c" ; then 
  12.   echo shar: Will not over-write existing file \"README\"
  13. else
  14. echo shar: Extracting \"README\" \(846 characters\)
  15. sed "s/^X//" >README <<'END_OF_README'
  16. X
  17. XThe four files included with the current README comprise the go skeleton
  18. Xprogram written by Jeff Rosenfeld at Carnegie Mellon University in
  19. XSeptember of 1988. It is hereby placed in the public domain.
  20. X
  21. XThe code includes some termcap/curses dependencies that would be trivial
  22. Xto remove were anyone so inclined. It should build and run easily on any
  23. Xsystem that supports curses.
  24. X
  25. XThe commands are single-characters, as follows:
  26. X
  27. X    h,j,k,l: move the cursor left, down, up, or right, respectively.
  28. X    y,u,b,n: move the cursor NW, NE, SW, SE, respectively.
  29. X    s: set SKIP mode.
  30. X    p: pass your turn and turn off SKIP mode.
  31. X    .: enter your move at the current cursor location.
  32. X    ^L: redraw the board.
  33. X    (space): continues after a debug message.
  34. X
  35. XSKIP mode allows you to set multiple stones down in the current color.
  36. X
  37. XEnjoy,
  38. X        - Jeff,
  39. X          (jdr@andrew.cmu.edu).
  40. END_OF_README
  41. if test 846 -ne `wc -c <README`; then
  42.     echo shar: \"README\" unpacked with wrong size!
  43. fi
  44. # end of overwriting check
  45. fi
  46. if test -f Makefile -a "${1}" != "-c" ; then 
  47.   echo shar: Will not over-write existing file \"Makefile\"
  48. else
  49. echo shar: Extracting \"Makefile\" \(93 characters\)
  50. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  51. XCFLAGS = -g -O
  52. X
  53. XOBJS = go.o disp.o debug.o
  54. X
  55. Xgo: $(OBJS)
  56. X    cc -o go $(OBJS) -lcurses -ltermcap
  57. END_OF_Makefile
  58. if test 93 -ne `wc -c <Makefile`; then
  59.     echo shar: \"Makefile\" unpacked with wrong size!
  60. fi
  61. # end of overwriting check
  62. fi
  63. if test -f debug.c -a "${1}" != "-c" ; then 
  64.   echo shar: Will not over-write existing file \"debug.c\"
  65. else
  66. echo shar: Extracting \"debug.c\" \(753 characters\)
  67. sed "s/^X//" >debug.c <<'END_OF_debug.c'
  68. X#include <curses.h>
  69. X#include "go.h"
  70. X
  71. X/* highlight a group on the board and display a message
  72. X   concerning that group until the space bar is pressed */
  73. Xshow(pgrp,str)
  74. X struct group *pgrp;
  75. X char *str;
  76. X{
  77. X    register struct elem *spot;
  78. X    int x,y;
  79. X    getyx(stdscr,y,x);
  80. X    standout();
  81. X    mvaddstr(1,15,str);
  82. X    standend();
  83. X    for (spot=pgrp->head; spot; spot=spot->next) spot->color |= 0x80;
  84. X    draw();
  85. X    while (getch() != ' ') beep();
  86. X    for (spot=pgrp->head; spot; spot=spot->next) spot->color &= 0x7F;
  87. X    move(1,15);
  88. X    clrtoeol();
  89. X    move(y,x);
  90. X    draw();
  91. X}
  92. X
  93. X/* display a message near the bottom of the screen */
  94. Xcomment(fmt,a,b,c,d,e,f)
  95. X char *fmt;
  96. X int a,b,c,d,e,f;
  97. X{
  98. X    int x,y;
  99. X    getyx(stdscr,y,x);
  100. X    move(23,15);
  101. X    printw(fmt,a,b,c,d,e,f);
  102. X    clrtoeol();
  103. X    move(y,x);
  104. X    refresh();
  105. X}
  106. END_OF_debug.c
  107. if test 753 -ne `wc -c <debug.c`; then
  108.     echo shar: \"debug.c\" unpacked with wrong size!
  109. fi
  110. # end of overwriting check
  111. fi
  112. if test -f disp.c -a "${1}" != "-c" ; then 
  113.   echo shar: Will not over-write existing file \"disp.c\"
  114. else
  115. echo shar: Extracting \"disp.c\" \(2159 characters\)
  116. sed "s/^X//" >disp.c <<'END_OF_disp.c'
  117. X#include <curses.h>
  118. X#include "go.h"
  119. X
  120. X/* initialize the curses package and display mode */
  121. Xsetup()
  122. X{
  123. X    initscr();
  124. X    crmode();
  125. X    noecho();
  126. X    move(3,7);
  127. X}
  128. X
  129. X/* draws the current game board
  130. X   the debug package might set the high bit on some stones to indicate
  131. X   that those spots should be highlighted */
  132. Xdraw()
  133. X{
  134. X    register int i,j;
  135. X    int x,y;
  136. X    getyx(stdscr,y,x);
  137. X    mvaddstr(2,5,"|---------------------------------------|");
  138. X    for (i=0; i<19; ++i) {
  139. X    mvaddch(3+i,5,'|');
  140. X    for (j=0; j<19; ++j) {
  141. X        addch(' ');
  142. X        if (Board[j][i].color & 0x80) standout();
  143. X        switch(Board[j][i].color & 0x7F) {
  144. X          case NONE: addch('+'); break;
  145. X          case BLACK: addch('@'); break;
  146. X          case WHITE: addch('O'); break;
  147. X          default: addch('!'); break; /* ERROR! */
  148. X        }
  149. X        if ((Board[j][i].color & 0x80) &&
  150. X        j+1<19 && !(Board[j+1][i].color & 0x80)) standend();
  151. X    }
  152. X    addch(' '); addch('|');
  153. X    }
  154. X    mvaddstr(3+i,5,"|---------------------------------------|");
  155. X    move(y,x);
  156. X    refresh();
  157. X}
  158. X
  159. X/* relative cursor motion on a flat board with bounds-checking */
  160. Xrup(dy,dx)
  161. X int dy,dx;
  162. X{
  163. X    int x,y;
  164. X    getyx(stdscr,y,x);
  165. X    x += dx; y += dy;
  166. X    if (x < 7 || x >= 45) x -= dx;
  167. X    if (y < 3 || y >= 22) y -= dy;
  168. X    move(y,x);
  169. X    refresh();
  170. X}
  171. X
  172. Xfetchmove(ploc)
  173. X struct location *ploc;
  174. X{
  175. X    static int setmode = 0;
  176. X    int done = 0;
  177. X    while (!done) switch (getch()) {
  178. X      case 'j': rup(1,0); break;
  179. X      case 'k': rup(-1,0); break;
  180. X      case 'h': rup(0,-2); break;
  181. X      case 'l': rup(0,2); break;
  182. X      case 'y': rup(-1,-2); break;
  183. X      case 'u': rup(-1,2); break;
  184. X      case 'b': rup(1,-2); break;
  185. X      case 'n': rup(1,2); break;
  186. X      case 's': setmode=1; break;
  187. X      case 'p': setmode=0; return PASS;
  188. X      case 'L'&0x1F: draw(); break;
  189. X      case '.': done=1; break;
  190. X      default: beep(); break;
  191. X    }
  192. X    getyx(stdscr,ploc->y,ploc->x);
  193. X    ploc->x -= 7; ploc->y -= 3;
  194. X    ploc->x /= 2;
  195. X    return setmode?SKIP:MOVE;
  196. X}
  197. X
  198. Xbeep()
  199. X{
  200. X    static int inited = 0;
  201. X    static char *str = NULL;
  202. X    if (!inited) {
  203. X        str = getcap("bl");
  204. X        if (str == NULL) str = getcap("vb");
  205. X        if (str == NULL) str = "";
  206. X        inited = 1;
  207. X    }
  208. X    write(2,str,strlen(str));
  209. X}
  210. X
  211. X/* the opposite of setup() */
  212. Xcleanup()
  213. X{
  214. X    move(23,0);
  215. X    refresh();
  216. X    endwin();
  217. X}
  218. END_OF_disp.c
  219. if test 2159 -ne `wc -c <disp.c`; then
  220.     echo shar: \"disp.c\" unpacked with wrong size!
  221. fi
  222. # end of overwriting check
  223. fi
  224. if test -f go.c -a "${1}" != "-c" ; then 
  225.   echo shar: Will not over-write existing file \"go.c\"
  226. else
  227. echo shar: Extracting \"go.c\" \(5069 characters\)
  228. sed "s/^X//" >go.c <<'END_OF_go.c'
  229. X#include <sys/signal.h>
  230. X#include "go.h"
  231. X
  232. X/* offsets for pointer arithmetic in a 19x19 2-space;
  233. X   the first four correspond to N,S,W,E, next are the diagonals, and last is
  234. X   the no-movement offset - this facilitates restricting motion to the
  235. X   taxicab directions without using two arrays */
  236. Xint Dir[9] = { -19,19,-1,1, -20,-18,18,20, 0 };
  237. X
  238. Xstruct elem Board[19][19];
  239. Xstruct group Groups[50];    /* static limit of 50 groups - ick! */
  240. X
  241. X/* there is only ever one spot on the board that cannot be played despite
  242. X   that it will have liberties after the play - this marks that spot */
  243. Xstruct elem *KoSpot;
  244. X
  245. X/* number of consecutive passes */
  246. Xint Pass;
  247. X
  248. X/* bounds-checking */
  249. X#define onboard(a) ((a) >= &Board[0][0] && (a) <= &Board[19][19])
  250. X
  251. X/* runs code for each taxicab direction about the center */
  252. X#define LOOPAROUND(center,ptr,code) \
  253. X    { register int _i; \
  254. X      for (ptr=(center)+Dir[_i=0]; _i<4; ptr=(center)+Dir[++_i]) \
  255. X          if (onboard(ptr) && adjacent(ptr,(center))) \
  256. X              { code } }
  257. X
  258. Xsigexit()
  259. X{
  260. X    cleanup();
  261. X    exit(1);
  262. X}
  263. X
  264. Xmain()
  265. X{
  266. X    register int i,j;
  267. X    for (j=0; j<19; ++j) for (i=0; i<19; ++i) {
  268. X    Board[i][j].loc.x = i;
  269. X    Board[i][j].loc.y = j;
  270. X    }
  271. X    setup();
  272. X    signal(SIGINT,sigexit);
  273. X    draw();
  274. X    Pass = 0;
  275. X    do {
  276. X        doturn(BLACK);
  277. X        doturn(WHITE);
  278. X    } while(Pass != 2);
  279. X    cleanup();
  280. X}
  281. X
  282. Xdoturn(whose)
  283. Xcolor_t whose;
  284. X{
  285. X    struct location loc;
  286. X    while (1) {
  287. X    comment("%s's turn.",whose==BLACK?"BLACK":"WHITE");
  288. X    switch (fetchmove(&loc)) {
  289. X      case PASS:
  290. X        ++Pass;
  291. X        return;
  292. X      case MOVE:
  293. X        if (checkmove(whose,&loc)) { beep(); continue; }
  294. X        domove(whose,&loc);
  295. X        break;
  296. X      case SKIP:
  297. X        domove(whose,&loc);
  298. X        continue;
  299. X    }
  300. X    break;
  301. X    }
  302. X    Pass = 0;            /* if move was not PASS, reset Pass */
  303. X    draw();
  304. X}
  305. X
  306. X/* check the validity of a move - 0 indicates validity, 1 does not.
  307. X   the kospot may be occupied only when a snapback occurs - this is
  308. X   when one of the opponent's groups touching the kospot has only
  309. X   one liberty and more than one element */
  310. Xcheckmove(turn,loc)
  311. Xcolor_t turn;
  312. Xregister struct location *loc;
  313. X{
  314. X    register int i;
  315. X    struct elem *targ;
  316. X    struct elem *spot = &Board[loc->x][loc->y];
  317. X    if (spot->color != EMPTY) return 1;
  318. X    if (spot == KoSpot) {
  319. X    LOOPAROUND(spot,targ,    /* check for snapback */
  320. X           if (targ->color != turn &&
  321. X               targ->group->liberties == 1 &
  322. X               targ->group->head->next != NULL)
  323. X             return 0;    /* snapback! */
  324. X           );
  325. X    return 1;        /* catch `ko's */
  326. X    }
  327. X    return 0;
  328. X}
  329. X
  330. X/* perform a valid move.
  331. X   this includes updating the group list, possibly joining two or more
  332. X   groups together or creating a new group. we also update liberty counts,
  333. X   killing groups with zero liberties. */
  334. Xdomove(turn,loc)
  335. X color_t turn;
  336. X register struct location *loc;
  337. X{
  338. X    register int i;
  339. X    int tmp;
  340. X    struct elem *targ;
  341. X    struct elem *spot = &Board[loc->x][loc->y];
  342. X    KoSpot = NULL;
  343. X    mkgroup(spot);
  344. X    spot->group->owner = spot->color = turn;
  345. X    LOOPAROUND(spot,targ,
  346. X           if (targ->color == turn) {
  347. X           if (spot->group != targ->group)
  348. X               nattach(targ->group,spot->group);
  349. X           }
  350. X           else if (targ->color != EMPTY) {
  351. X           tmp = countlibs(targ->group);
  352. X           if (tmp == 0) kill(targ->group);
  353. X           else targ->group->liberties = tmp;
  354. X           }
  355. X           );
  356. X    if ((spot->group->liberties = countlibs(spot->group)) == 0) {
  357. X    kill(spot->group);
  358. X    KoSpot = NULL;
  359. X    }
  360. X    return 0;
  361. X}
  362. X
  363. Xmkgroup(spot)
  364. Xstruct elem *spot;
  365. X{
  366. X    register struct group *pgrp;
  367. X    for (pgrp = &Groups[0]; pgrp < &Groups[50]; ++pgrp)
  368. X        if (pgrp->head == NULL) {
  369. X            pgrp->head = spot;
  370. X            pgrp->owner = spot->color;
  371. X        pgrp->flags = 0;
  372. X        spot->group = pgrp;
  373. X        spot->next = NULL;
  374. X            return 0;
  375. X        }
  376. X    return 1;
  377. X}
  378. X
  379. Xkill(grp)
  380. Xstruct group *grp;
  381. X{
  382. X    register struct elem *spot;
  383. X    show(grp,"killing");
  384. X    if (grp->head->next == NULL) KoSpot = grp->head;
  385. X    for (spot=grp->head; spot; spot=spot->next)
  386. X        spot->color = EMPTY;
  387. X    grp->head = NULL;
  388. X}
  389. X
  390. X/* attach two groups together without counting liberties */
  391. Xnattach(dst,grp)
  392. Xstruct group *dst, *grp;
  393. X{
  394. X    register struct elem *spot, *tmp;
  395. X    show(grp,"attaching this...");
  396. X    show(dst,"...to this.");
  397. X    for (spot=grp->head; spot; tmp=spot,spot=spot->next)
  398. X        spot->group = dst;
  399. X    tmp->next = dst->head;
  400. X    dst->head = grp->head;
  401. X    grp->head = NULL;
  402. X    return 0;
  403. X}
  404. X
  405. X/* attach two groups, returning the number of liberties in the
  406. X   resulting group */
  407. Xattach(dst,grp)
  408. Xstruct group *dst, *grp;
  409. X{
  410. X    nattach(dst,grp);
  411. X    return (dst->liberties = countlibs(dst));
  412. X}
  413. X
  414. Xcountlibs(grp)
  415. Xstruct group *grp;
  416. X{
  417. X    register struct elem *elem, *spot;
  418. X    int count = 0;
  419. X    show(grp,"counting liberties");
  420. X    for (elem=grp->head; elem; elem=elem->next)
  421. X    LOOPAROUND(elem,spot,
  422. X           if (!spot->mark) {
  423. X               spot->mark = 1;
  424. X               if (spot->color == EMPTY)
  425. X               ++count;
  426. X           }
  427. X           );
  428. X    for (elem=grp->head; elem; elem=elem->next)
  429. X    LOOPAROUND(elem,spot,
  430. X           spot->mark = 0;
  431. X           );
  432. X    comment("counted %d liberties",count);
  433. X    return count;
  434. X}
  435. END_OF_go.c
  436. if test 5069 -ne `wc -c <go.c`; then
  437.     echo shar: \"go.c\" unpacked with wrong size!
  438. fi
  439. # end of overwriting check
  440. fi
  441. if test -f go.h -a "${1}" != "-c" ; then 
  442.   echo shar: Will not over-write existing file \"go.h\"
  443. else
  444. echo shar: Extracting \"go.h\" \(1523 characters\)
  445. sed "s/^X//" >go.h <<'END_OF_go.h'
  446. Xtypedef unsigned short color_t;
  447. Xtypedef unsigned long bits_t;
  448. X
  449. Xstruct location {
  450. X    char x,y;            /* assumes chars are SIGNED */
  451. X};
  452. X
  453. X#define EMPTY 0
  454. X#define NONE EMPTY
  455. X#define BLACK 1
  456. X#define WHITE 2
  457. X
  458. Xstruct elem {
  459. X    struct elem *next;        /* ptr to next stone in group */
  460. X    struct group *group;    /* ptr to group descriptor */
  461. X    int mark;            /* temp. marker - must always be reset to 0 */
  462. X    struct location loc;    /* coordinates of this stone */
  463. X    color_t color;        /* color of this stone */
  464. X};
  465. X
  466. Xstruct group {
  467. X    struct elem *head;        /* some stone in the group */
  468. X    color_t owner;        /* head->color */
  469. X    short liberties;        /* how many liberties this group has */
  470. X    bits_t flags;        /* group-specific flags */
  471. X};
  472. X
  473. X#define GR_EYE        0x01    /* group has at least one eye */
  474. X#define GR_LIVE        0x02    /* group is alive */
  475. X
  476. X#define setf(bit,place) (place |= (bit))
  477. X#define clrf(bit,place) (place &= ~(bit))
  478. X#define getf(bit,place) ((place) & (bit))
  479. X
  480. X#define abs(a) ((a)>0 ? (a) : -(a))
  481. X#define adjacent(a,b) ((abs((a)->loc.x - (b)->loc.x) +    \
  482. X                        abs((a)->loc.y - (b)->loc.y)) == 1)
  483. X
  484. X#define PASS 0            /* player passes */
  485. X#define MOVE 1            /* player attempts to make a move */
  486. X#define SKIP 2            /* player enters setup mode */
  487. X
  488. X#define UP    0
  489. X#define DOWN    1
  490. X#define LEFT    2
  491. X#define RIGHT    3
  492. X#define UPLEFT    4
  493. X#define UPRIGHT    5
  494. X#define DNLEFT    6
  495. X#define DNRIGHT    7
  496. X
  497. X#ifndef NULL
  498. X#define NULL 0
  499. X#endif
  500. X
  501. Xextern struct elem Board[19][19]; /* the game board */
  502. Xextern int Dir[];        /* offsets for relative motion on the board */
  503. END_OF_go.h
  504. if test 1523 -ne `wc -c <go.h`; then
  505.     echo shar: \"go.h\" unpacked with wrong size!
  506. fi
  507. # end of overwriting check
  508. fi
  509. echo shar: End of archive 1 \(of 1\).
  510. cp /dev/null ark1isdone
  511. MISSING=""
  512. for I in 1 ; do
  513.     if test ! -f ark${I}isdone ; then
  514.     MISSING="${MISSING} ${I}"
  515.     fi
  516. done
  517. if test "${MISSING}" = "" ; then
  518.     echo You have unpacked all 1 archives.
  519.     rm -f ark[1-9]isdone
  520. else
  521.     echo You still need to unpack the following archives:
  522.     echo "        " ${MISSING}
  523. fi
  524. ##  End of shell archive.
  525. exit 0
  526.  
  527.  
  528.