billr@saab.CNA.TEK.COM (Bill Randle) (09/15/89)
Submitted-by: Stacey Campbell <staceyc@uunet.uu.net> Posting-number: Volume 8, Issue 24 Archive-name: cutup/Part01 [Since I'm not running System V, I can't test this first. -br] [[This is the game of cutup, a similar game was around the amusement arcades in the mid-70s. Two players control a character that moves around the screen, the game stops when either of the characters runs into something. This version allows for two human players, or two computer players or one computer player with one human player. This version of cutup was developed under XENIX 2.3 on a 386 box. It uses named pipes and curses. As such it will compile and run on almost any System 5 implementation. Stacey Campbell @ SCO - uunet!sco!staceyc]] #! /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 1)." # Contents: README Makefile comp.c consts.h cut.c fifo.c funcs.h # initend.c macros.h move.c scr.c types.h usleep.c # Wrapped by billr@saab on Thu Sep 14 12:21:59 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1953 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XREADME for cutup release 1.0 X---------------------------- X XDescription X----------- X XThis is the game of cutup, a similar game was around the Xamusement arcades in the mid-70s. Two players control a Xcharacter that moves around the screen, the game stops when Xeither of the characters runs into something. A match is Xwon when a player achieves three wins, or since simultaneous Xcrashes are possible, a player has at least three wins and Xwins one more game than the opponent. X XThis version allows for two human players, or two computer Xplayers or one computer player with one human player. The Xappropriate flags are; X X -b two computer players, a match X -d two computer players continuous X -c a human player against a computer player X XNo flags specified means two human players. X XAn extra flag, -s, should be used if the computer heuristic Xis hammering the CPU too hard, though this will make the Xheuristic even less intelligent. X XPorting Notes X------------- X XThis version of cutup was developed under XENIX 2.3 on a 386 box. XIt uses named pipes and curses. As such it will compile and run Xon almost any System 5 implementation. X XEdit the Makefile to ensure it is doing what you want/need. X XYou will have to edit usleep.c to make sure that MillisecondSleep() Xis implemented in a sensible way. X XSystem 5.[12] and System 5.3.[01] people may have to be creative here. XSystem 5.3.2 (or later) supports nap(), this should be used. XBasically, if you don't have nap() then try napms() (should be in Xcurses library), if that doesn't work then try poll(). If poll() Xisn't around then have a look at SIGALRM, signal(), fork() and Xkill(). If that screws up then have a look in usleep.c at the Xlast implementation of MillisecondSleep(), if that makes you Xsick to the stomache then you are probably out of luck. X XImplemented by: X X Stacey Campbell @ SCO X uucp: uunet!sco!staceyc X XDisclaimer: X X ...the usual stuff, i.e. if it trashes your system then X tough luck. END_OF_FILE if test 1953 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(558 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Makefile for cutup X X# CFLAGS= -O # non-XENIX systems can do this XCFLAGS= -O -DM_TERMINFO X X# LIBS= -lcurses -lx # non-XENIX systems should do this XLIBS= -ltinfo -lx X XOBJS= cut.o scr.o fifo.o move.o initend.o comp.o usleep.o XSRC= cut.c scr.c fifo.c move.c initend.c comp.c usleep.c XINCLUDES= consts.h funcs.h macros.h types.h XEXE= cutup XLDFLAGS= -O X X$(EXE): $(OBJS) X $(CC) $(LDFLAGS) $(OBJS) -o $(EXE) $(LIBS) X Xlint: X lint $(CFLAGS) $(SRC) > lint.out X Xclean: X rm -f $(OBJS) $(EXE) lint.out X Xshar: X xshar README Makefile $(SRC) $(INCLUDES) > $(EXE).shar END_OF_FILE if test 558 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'comp.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'comp.c'\" else echo shar: Extracting \"'comp.c'\" \(6555 characters\) sed "s/^X//" >'comp.c' <<'END_OF_FILE' X#include <curses.h> X#include "consts.h" X#include "types.h" X#include "macros.h" X#include "funcs.h" X Xextern int StopIO; Xextern delta_t Delta[S_DELTA_MAX]; Xextern int SlowCPU; X Xstatic int Direct[S_DIR_MAX][C_MAX]; Xstatic int Order[LR_MAX][C_MAX]; Xstatic int Opposite[S_DIR_MAX]; Xstatic int RndMoveProb; X Xint CollisionImminent(); Xint CutupImminent(); Xint MakeRndMove(); Xint MakeMoveTo(); Xint DomainSize(); Xvoid AvoidCutup(); Xint CalcDomains(); Xvoid GenRndCoord(); X Xvoid ComputeMove(board, us, them) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; Xcoords_t *them; X X { X int dom_right, dom_left; X int flag; X X SETUP_THEM(board, them); X if (CollisionImminent(board, us)) X { X ++RndMoveProb; X dom_right = DomainSize(board, us, C_RIGHT); X dom_left = DomainSize(board, us, C_LEFT); X flag = 0; X if (dom_right > dom_left) X flag = MakeMoveTo(board, us, C_RIGHT); X if (! flag) X { X if (! MakeMoveTo(board, us, C_LEFT)) X MAINTAIN_COURSE(us); X } X } X else X if (CutupImminent(board, us)) X AvoidCutup(board, us); X else X if (MakeRndMove()) X GenRndCoord(board, us); X else X MAINTAIN_COURSE(us); X REMOVE_THEM(board, them); X } X Xstatic void AvoidCutup(board, us) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; X X { X int left_dom, right_dom, forward_dom; X int flag = 0; X coords_t attempt; X int board_spot; X X if (SlowCPU) X { X GenRndCoord(board, us); X return; X } X X attempt.dir = Direct[us->dir][C_FORWARD]; X attempt.y = us->y + Delta[attempt.dir].dy; X attempt.x = us->x + Delta[attempt.dir].dx; X board_spot = board[attempt.y][attempt.x]; X board[attempt.y][attempt.x] = S_ONE; X left_dom = CalcDomains(board, us, C_LEFT); X right_dom = CalcDomains(board, us, C_RIGHT); X board[attempt.y][attempt.x] = board_spot; X forward_dom = CalcDomains(board, us, C_FORWARD) + 2; X X if (forward_dom >= left_dom && forward_dom >= right_dom) X flag = MakeMoveTo(board, us, C_FORWARD); X else X if (right_dom > left_dom) X flag = MakeMoveTo(board, us, C_RIGHT); X else X flag = MakeMoveTo(board, us, C_LEFT); X if (! flag) X MAINTAIN_COURSE(us); X } X Xstatic int CalcDomains(board, us, rel) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; Xint rel; X X { X coords_t us_test; X int domain_total = 0; X int dom_left, dom_right; X X us_test.dir = Direct[us->dir][rel]; X us_test.y = us->y + Delta[us_test.dir].dy; X us_test.x = us->x + Delta[us_test.dir].dx; X if (rel == C_FORWARD) X us_test.dir = Opposite[us_test.dir]; X if (board[us_test.y][us_test.x] == S_FREE) X { X board[us_test.y][us_test.x] |= S_ONE; X dom_left = DomainSize(board, &us_test, C_LEFT); X dom_right = DomainSize(board, &us_test, C_RIGHT); X domain_total = dom_left > dom_right ? dom_left : dom_right; X board[us_test.y][us_test.x] = S_FREE; X } X X return domain_total; X } X Xstatic void GenRndCoord(board, us) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; X X { X int dir, start_dir, flag; X int y, x; X X dir = lrand48() % 4; X start_dir = dir; X do { X y = us->y + Delta[dir].dy; X x = us->x + Delta[dir].dx; X flag = board[y][x] == S_FREE; X if (! flag) X dir = (dir + 1) % 4; X } while (! flag && dir != start_dir); X if (flag) X { X us->y = y; X us->x = x; X us->dir = dir; X } X else X { X us->y += Delta[us->dir].dy; X us->x += Delta[us->dir].dx; X } X } X Xvoid CompGameInit() X X { X RndMoveProb = lrand48() % 10 + 3; X } X Xvoid CompInit() X X { X Direct[S_NORTH][C_REVERSE] = S_SOUTH; X Direct[S_NORTH][C_FORWARD] = S_NORTH; X Direct[S_NORTH][C_LEFT] = S_WEST; X Direct[S_NORTH][C_RIGHT] = S_EAST; X Direct[S_SOUTH][C_REVERSE] = S_NORTH; X Direct[S_SOUTH][C_FORWARD] = S_SOUTH; X Direct[S_SOUTH][C_LEFT] = S_EAST; X Direct[S_SOUTH][C_RIGHT] = S_WEST; X Direct[S_EAST][C_REVERSE] = S_WEST; X Direct[S_EAST][C_FORWARD] = S_EAST; X Direct[S_EAST][C_LEFT] = S_NORTH; X Direct[S_EAST][C_RIGHT] = S_SOUTH; X Direct[S_WEST][C_REVERSE] = S_EAST; X Direct[S_WEST][C_FORWARD] = S_WEST; X Direct[S_WEST][C_LEFT] = S_SOUTH; X Direct[S_WEST][C_RIGHT] = S_NORTH; X Order[C_RIGHT][0] = C_RIGHT; X Order[C_RIGHT][1] = C_FORWARD; X Order[C_RIGHT][2] = C_LEFT; X Order[C_RIGHT][3] = C_REVERSE; X Order[C_LEFT][0] = C_LEFT; X Order[C_LEFT][1] = C_FORWARD; X Order[C_LEFT][2] = C_RIGHT; X Order[C_LEFT][3] = C_REVERSE; X Opposite[S_NORTH] = S_SOUTH; X Opposite[S_SOUTH] = S_NORTH; X Opposite[S_EAST] = S_WEST; X Opposite[S_WEST] = S_EAST; X } X Xstatic int CollisionImminent(board, us) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; X X { X int y, x; X X y = us->y + Delta[us->dir].dy; X x = us->x + Delta[us->dir].dx; X X return board[y][x] != S_FREE; X } X Xstatic int MakeRndMove() X X { X return ! (lrand48() % RndMoveProb); X } X Xstatic int CutupImminent(board, us) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; X X { X int y, x; X int dir; X int board_spot; X int back_spot; X int board_right, board_left; X X y = us->y + Delta[us->dir].dy; X x = us->x + Delta[us->dir].dx; X dir = Direct[us->dir][C_RIGHT]; X board_spot = board[y + Delta[dir].dy][x + Delta[dir].dx]; X back_spot = board[us->y + Delta[dir].dy][us->x + Delta[dir].dx]; X board_right = board_spot != S_FREE && !(board_spot & S_BORDER) && X back_spot == S_FREE; X if (! board_right) X { X dir = Direct[us->dir][C_LEFT]; X board_spot = board[y + Delta[dir].dy][x + Delta[dir].dx]; X back_spot = board[us->y + Delta[dir].dy][us->x + Delta[dir].dx]; X board_left = board_spot != S_FREE && !(board_spot & S_BORDER) && X back_spot == S_FREE; X } X X return board_left || board_right; X } X Xstatic int MakeMoveTo(board, us, rel) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; Xint rel; X X { X coords_t attempt; X int illegal; X X attempt.dir = Direct[us->dir][rel]; X attempt.y = us->y + Delta[attempt.dir].dy; X attempt.x = us->x + Delta[attempt.dir].dx; X illegal = board[attempt.y][attempt.x] != S_FREE; X if (! illegal) X *us = attempt; X X return ! illegal; X } X Xstatic int DomainSize(board, us, rel) X Xint board[Y_MAX][X_MAX]; Xcoords_t *us; Xint rel; X X { X int dir; X int y, x; X int count; X X count = 0; X dir = us->dir; X y = us->y; X x = us->x; X do { X ++count; X dir = FindBestDir(board, y, x, dir, rel, &count); X y += Delta[dir].dy; X x += Delta[dir].dx; X } while (count < COUNT_LIMIT && ! (y == us->y && x == us->x)); X X return count; X } X Xstatic int FindBestDir(board, y, x, dir, rel, count_p) X Xint board[Y_MAX][X_MAX]; Xint y; Xint x; Xint dir; Xint rel; Xint *count_p; X X { X int i = 0; X int y_new, x_new; X int new_order; X X new_order = Order[rel][i]; X y_new = y + Delta[Direct[dir][new_order]].dy; X x_new = x + Delta[Direct[dir][new_order]].dx; X while (BAD_COORDS(y_new, x_new) || board[y_new][x_new] == S_FREE) X { X ++i; X new_order = Order[rel][i]; X y_new = y + Delta[Direct[dir][new_order]].dy; X x_new = x + Delta[Direct[dir][new_order]].dx; X } X *count_p += i; X X return Direct[dir][new_order]; X } END_OF_FILE if test 6555 -ne `wc -c <'comp.c'`; then echo shar: \"'comp.c'\" unpacked with wrong size! fi # end of 'comp.c' fi if test -f 'consts.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'consts.h'\" else echo shar: Extracting \"'consts.h'\" \(1036 characters\) sed "s/^X//" >'consts.h' <<'END_OF_FILE' X#define ASCII_BS 8 X#define ASCII_DEL 127 X X#ifndef LFNMAX X#define NAME_MAX 7 X#else X#define NAME_MAX ((LFNMAX) / 2) X#endif X X#ifndef LPNMAX X#define FN_MAX 256 X#else X#define FN_MAX LPNMAX X#endif X X#define Y_MAX 21 X#define X_MAX 78 X X#define S_FREE 0x000 X#define S_ONE 0x001 X#define S_OTHER 0x002 X#define S_BOTH 0x003 X#define S_BORDER 0x004 X#define S_CRASH 0x080 X#define S_TEMP 0x100 X X#define S_NO_COLLISION 0x0000 X#define S_WE_COLLIDE 0x0001 X#define S_THEY_COLLIDE 0x0002 X X#define S_NORTH 0 X#define S_SOUTH 1 X#define S_EAST 2 X#define S_WEST 3 X#define S_SAME 4 X#define S_BOGUS 5 X#define S_DELTA_MAX (S_BOGUS + 1) X#define S_DIR_MAX (S_WEST + 1) X X#define S_LEFT_CH 'h' X#define S_RIGHT_CH 'l' X#define S_UP_CH 'k' X#define S_DOWN_CH 'j' X X#define S_US_CHAR '@' X#define S_THEM_CHAR '#' X#define S_BANG_CHAR '*' X X#define SCORE_MAX 3 X X#define C_RIGHT 0 X#define C_LEFT 1 X#define C_FORWARD 2 X#define C_REVERSE 3 X X#define C_MAX (C_REVERSE + 1) X#define LR_MAX (C_LEFT + 1) X X#define COUNT_LIMIT 200 END_OF_FILE if test 1036 -ne `wc -c <'consts.h'`; then echo shar: \"'consts.h'\" unpacked with wrong size! fi # end of 'consts.h' fi if test -f 'cut.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cut.c'\" else echo shar: Extracting \"'cut.c'\" \(6723 characters\) sed "s/^X//" >'cut.c' <<'END_OF_FILE' X#include <errno.h> X#include <curses.h> X#include "consts.h" X#include "types.h" X#include "macros.h" X#include "funcs.h" X X#define ARG_STRING "bcsd" X Xvoid GetNames(); Xvoid ErrorExit(); Xvoid EndGame(); Xvoid ProcessArgs(); Xvoid SwapNames(); XWINDOW *InitBoard(); Xvoid DecisionScreen(); X Xint ComputerOpponent; Xint IComputer; Xint StopIO; Xint ChildPid; Xint SlowCPU; Xint DisplayPlay; X Xstatic int OurScore; Xstatic int TheirScore; X Xint main(argc, argv) X Xint argc; Xchar *argv; X X { X WINDOW *play_w, *board_w; X char you[NAME_MAX + 1], hom[NAME_MAX + 1]; X int p_write, p_read; X int status; X int collision; X int board[Y_MAX][X_MAX]; X coords_t us, them; X coords_t c1, c2; X int game_count = 0; X X SeedRnd(); X DeltaInits(); X play_w = InitScreen(); X ProcessArgs(play_w, argc, argv); X Welcome(play_w); X GetNames(play_w, you, hom); X if (ComputerOpponent) X if (! (ChildPid = status = fork())) X { X SwapNames(you, hom); X IComputer = 1; X StopIO = 1; X BlockSignals(); X (void)nice(5); X sleep(2); X SeedRnd(); X } X else X if (status == -1) X ErrorExit(play_w, errno); X if (status = GetFIFOName(play_w, &p_write, &p_read, you, hom, &c1, &c2)) X ErrorExit(play_w, status); X if (IComputer) X CompInit(); X do { X ++game_count; X GetReady(play_w, p_read, p_write, game_count, hom); X board_w = InitBoard(play_w, board, &us, &them, &c1, &c2); X CompGameInit(); X DrawPositions(board_w, board, &us, &them); X do { X collision = GetMoves(board_w, board, p_read, p_write, X &us, &them); X DrawPositions(board_w, board, &us, &them); X } while (! collision); X DecisionScreen(play_w, board_w, collision, you, hom); X } while (((OurScore < SCORE_MAX && TheirScore < SCORE_MAX) X || OurScore == TheirScore) || DisplayPlay); X EndGame(play_w, you, hom); X if (! StopIO) X EndScreen(); X return 0; X } X Xstatic void GetNames(old_w, you, hom) X XWINDOW *old_w; Xchar *you; Xchar *hom; X X { X WINDOW *namesW; X int you_len, hom_len; X char test1[FN_MAX]; X char test2[FN_MAX]; X static char opponent[] = "Opponent's name: "; X static char you_str[] = " Your name: "; X X namesW = CreateWindow(old_w, 4, sizeof opponent + NAME_MAX + 2, 1, 1); X mvwaddstr(namesW, 1, 1, you_str); X mvwaddstr(namesW, 2, 1, opponent); X wmove(namesW, 1, sizeof you_str); X you_len = GetString(namesW, you, NAME_MAX); X wmove(namesW, 2, sizeof opponent); X hom_len = GetString(namesW, hom, NAME_MAX); X if (you_len == 0 || hom_len == 0) X { X DISPLAY_ERROR(namesW, "Null name given - try again."); X GetNames(old_w, you, hom); X } X else X { X sprintf(test1, "%s%s", you, hom); X sprintf(test2, "%s%s", hom, you); X if (SAME(test1, test2)) X { X DISPLAY_ERROR(namesW, X "Concatenated names are bad - try again."); X GetNames(old_w, you, hom); X } X } X RemoveWindow(old_w, namesW); X } X Xstatic void ErrorExit(old_w, status) X XWINDOW *old_w; Xint status; X X { X extern char *sys_errlist[]; X extern int sys_nerr; X X EndFIFO(); X if (! StopIO) X EndScreen(); X if (status > sys_nerr) X fprintf(stderr, "Unknown error number: %d\n", status); X else X fprintf(stderr, "error no: %d - %s\n", status, X sys_errlist[status]); X exit(1); X } X Xstatic void EndGame(old_w, you, hom) X XWINDOW *old_w; Xchar *you; Xchar *hom; X X { X WINDOW *final_w; X static char hdr[] = "Cutup - Final Score"; X char mesg[256]; X int max_len, len; X X if (! StopIO) X { X sprintf(mesg, "%s: %d - %s: %d ", you, OurScore, hom, X TheirScore); X len = strlen(mesg); X max_len = len < sizeof hdr ? sizeof hdr : len; X max_len += 3; X final_w = CreateWindow(old_w, 5, max_len, 9, SM_CENTRE(max_len, X COLS)); X wstandout(final_w); X mvwaddstr(final_w, 1, SM_CENTRE(sizeof hdr, max_len), hdr); X wstandend(final_w); X mvwaddstr(final_w, 3, SM_CENTRE(len, max_len), mesg); X wrefresh(final_w); X } X EndFIFO(); X } X Xstatic void ProcessArgs(old_w, argc, argv) X XWINDOW *old_w; Xint argc; Xchar **argv; X X { X int found; X char mess[23]; X extern int opterr; X extern char *optarg; X X opterr = 1; X while ((found = getopt(argc, argv, ARG_STRING)) != EOF) X switch (found) X { X case 'b' : X IComputer = 1; X ComputerOpponent = 1; X break; X case 'c' : X ComputerOpponent = 1; X IComputer = 0; X break; X case 's' : X SlowCPU = 1; X break; X case 'd' : X DisplayPlay = 1; X IComputer = 1; X ComputerOpponent = 1; X break; X default : X sprintf(mess, "Ignoring argument: %c", found); X DISPLAY_ERROR(old_w, mess); X break; X } X } X Xstatic void SwapNames(you, hom) X Xchar *you; Xchar *hom; X X { X char temp[NAME_MAX + 1]; X X strcpy(temp, you); X strcpy(you, hom); X strcpy(hom, temp); X } X Xstatic WINDOW *InitBoard(play_w, board, us, them, c1, c2) X XWINDOW *play_w; Xint board[Y_MAX][X_MAX]; Xcoords_t *us; Xcoords_t *them; Xcoords_t *c1; Xcoords_t *c2; X X { X WINDOW *board_w; X int i, j; X X *us = *c1; X *them = *c2; X for (i = 1; i < Y_MAX - 1; ++i) X for (j = 1; j < X_MAX - 1; ++j) X board[i][j] = S_FREE; X for (i = 0; i < Y_MAX; ++i) X { X board[i][0] = S_BORDER; X board[i][X_MAX - 1] = S_BORDER; X } X for (j = 0; j < X_MAX; ++j) X { X board[0][j] = S_BORDER; X board[Y_MAX - 1][j] = S_BORDER; X } X board[us->y][us->x] = S_ONE; X board[them->y][them->x] = S_OTHER; X if (! StopIO) X { X board_w = CreateWindow(play_w, Y_MAX, X_MAX, 1, 1); X mvwaddch(board_w, us->y, us->x, S_US_CHAR); X mvwaddch(board_w, them->y, them->x, S_THEM_CHAR); X nodelay(board_w, TRUE); X wrefresh(board_w); X } X return board_w; X } X Xstatic void DecisionScreen(old_w, board_w, col_mask, you, hom) X XWINDOW *old_w; XWINDOW *board_w; Xint col_mask; Xchar *you; Xchar *hom; X X { X WINDOW *decisW; X int they_collide, we_collide; X char decis[256]; X char score[256]; X int len; X int decis_len; X int score_len; X static char mesg[] = "** Collision **"; X static char clr_mesg[] = " "; X X if (StopIO) X return; X nodelay(board_w, FALSE); X crmode(); X flushinp(); X mvwaddstr(old_w, 22, CENTRE(mesg), mesg); X wrefresh(old_w); X sleep(2); X flushinp(); X mvwaddstr(old_w, 22, CENTRE(mesg), clr_mesg); X wrefresh(old_w); X if (we_collide = col_mask & S_WE_COLLIDE) X ++TheirScore; X if (they_collide = col_mask & S_THEY_COLLIDE) X ++OurScore; X if (we_collide && they_collide) X sprintf(decis, "%s and %s crashed simultaneously", you, hom); X else X if (we_collide) X sprintf(decis, "%s crashed, %s lives", you, hom); X else X sprintf(decis, "%s crashed, %s lives!", hom, you); X sprintf(score, "%s: %d %s: %d", you, OurScore, hom, TheirScore); X decis_len = strlen(decis); X score_len = strlen(score); X len = decis_len > score_len ? decis_len : score_len; X decisW = CreateWindow(board_w, 4, len + 3, 7, SM_CENTRE(len, COLS)); X mvwaddstr(decisW, 2, SM_CENTRE(score_len, len), score); X mvwaddstr(decisW, 1, SM_CENTRE(decis_len, len), decis); X wrefresh(decisW); X sleep(3); X RemoveWindow(board_w, decisW); X RemoveWindow(old_w, board_w); X flushinp(); X } END_OF_FILE if test 6723 -ne `wc -c <'cut.c'`; then echo shar: \"'cut.c'\" unpacked with wrong size! fi # end of 'cut.c' fi if test -f 'fifo.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fifo.c'\" else echo shar: Extracting \"'fifo.c'\" \(2183 characters\) sed "s/^X//" >'fifo.c' <<'END_OF_FILE' X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/fcntl.h> X#include <errno.h> X#include <curses.h> X#include "consts.h" X#include "types.h" X#include "funcs.h" X#include "macros.h" X X#define FIFO_MODE (S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO) X Xextern int StopIO; X Xstatic char Fifo1[FN_MAX]; Xstatic char Fifo2[FN_MAX]; X Xint PipeOpen(); X Xint GetFIFOName(old_w, pipe_w, pipe_r, you, hom, us, them) X XWINDOW *old_w; Xint *pipe_w; Xint *pipe_r; Xchar *you; Xchar *hom; Xcoords_t *us; Xcoords_t *them; X X { X int err, cmask; X WINDOW *fifo_w; X char mesg[256]; X int len; X X cmask = umask(0); X if (! StopIO) X { X sprintf(mesg, "waiting for %s...", hom); X len = strlen(mesg) + 3; X fifo_w = CreateWindow(old_w, 3, len, 1, 1); X mvwaddstr(fifo_w, 1, 1, mesg); X wrefresh(fifo_w); X } X sprintf(Fifo1, "/tmp/%s%s", you, hom); X sprintf(Fifo2, "/tmp/%s%s", hom, you); X if (mknod(Fifo1, FIFO_MODE, 0)) X if (mknod(Fifo2, FIFO_MODE, 0)) X { X if (err = PipeOpen(fifo_w, Fifo1, Fifo2, pipe_r, pipe_w, X O_RDONLY, O_WRONLY, us, them)) X return err; X } X else X { X if (err = PipeOpen(fifo_w, Fifo2, Fifo1, pipe_r, pipe_w, X O_RDONLY, O_WRONLY, them, us)) X return err; X } X else X if (mknod(Fifo2, FIFO_MODE, 0)) X { X if (err = PipeOpen(fifo_w, Fifo1, Fifo2, pipe_w, pipe_r, X O_WRONLY, O_RDONLY, us, them)) X return err; X } X else X { X if (err = PipeOpen(fifo_w, Fifo2, Fifo1, pipe_w, pipe_r, X O_WRONLY, O_RDONLY, them, us)) X return err; X } X (void)umask(cmask); X if (! StopIO) X RemoveWindow(old_w, fifo_w); X return 0; X } X Xstatic int PipeOpen(old_w, fifo1, fifo2, pipe1, pipe2, mode1, mode2, c1, c2) X XWINDOW *old_w; Xchar *fifo1; Xchar *fifo2; Xint *pipe1; Xint *pipe2; Xint mode1; Xint mode2; Xcoords_t *c1; Xcoords_t *c2; X X { X int status; X X c2->y = 10; X c2->x = 20; X c2->dir = S_WEST; X c1->y = 10; X c1->x = 57; X c1->dir = S_EAST; X if ((*pipe1 = open(fifo1, mode1)) == -1) X { X status = errno; X DISPLAY_ERROR(old_w, "Open failure 1."); X return status; X } X if ((*pipe2 = open(fifo2, mode2)) == -1) X { X status = errno; X DISPLAY_ERROR(old_w, "Open failure 2."); X return status; X } X return 0; X } X Xvoid EndFIFO() X X { X (void)unlink(Fifo1); X (void)unlink(Fifo2); X } END_OF_FILE if test 2183 -ne `wc -c <'fifo.c'`; then echo shar: \"'fifo.c'\" unpacked with wrong size! fi # end of 'fifo.c' fi if test -f 'funcs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'funcs.h'\" else echo shar: Extracting \"'funcs.h'\" \(379 characters\) sed "s/^X//" >'funcs.h' <<'END_OF_FILE' XWINDOW *InitScreen(); XWINDOW *CreateWindow(); Xint GetString(); Xvoid EndScreen(); Xvoid RemoveWindow(); Xint GetFIFOName(); Xvoid EndFIFO(); Xint GetMoves(); Xvoid DrawPositions(); Xvoid DeltaInits(); Xvoid Welcome(); Xlong lrand48(); Xvoid srand48(); Xvoid SeedRnd(); Xvoid BlockSignals(); Xvoid ComputeMove(); Xvoid CompInit(); Xvoid CompGameInit(); Xvoid MillisecondSleep(); Xvoid GetReady(); END_OF_FILE if test 379 -ne `wc -c <'funcs.h'`; then echo shar: \"'funcs.h'\" unpacked with wrong size! fi # end of 'funcs.h' fi if test -f 'initend.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'initend.c'\" else echo shar: Extracting \"'initend.c'\" \(1973 characters\) sed "s/^X//" >'initend.c' <<'END_OF_FILE' X#include <curses.h> X#include "consts.h" X#include "types.h" X#include "funcs.h" X#include "macros.h" X Xextern int IComputer; Xextern int StopIO; X Xvoid Welcome(wel_w) X XWINDOW *wel_w; X X { X static char header[] = "C U T U P"; X X wstandout(wel_w); X mvwaddstr(wel_w, 3, CENTRE(header), header); X wstandend(wel_w); X wmove(wel_w, 5, 5); X wprintw(wel_w, "Control the %c character...", S_US_CHAR); X wmove(wel_w, 7, 5); X wprintw(wel_w, "Avoid other %c and %c characters...", S_US_CHAR, X S_THEM_CHAR); X mvwaddstr(wel_w, 9, 5, "Avoid hitting the border..."); X mvwaddstr(wel_w, 11, 5, "First to crash is the loser..."); X wrefresh(wel_w); X wstandout(wel_w); X if (! IComputer) X { X mvwaddstr(wel_w, 14, 30, "Controls"); X wstandend(wel_w); X wmove(wel_w, 16, 5); X wprintw(wel_w, "Left: '%c' Right: '%c'", S_LEFT_CH, X S_RIGHT_CH); X wmove(wel_w, 18, 5); X wprintw(wel_w, "Up: '%c' Down: '%c'", S_UP_CH, S_DOWN_CH); X mvwaddstr(wel_w, 20, 25, "--press space to start--"); X wrefresh(wel_w); X while (wgetch(wel_w) != ' '); X } X else X sleep(2); X werase(wel_w); X box(wel_w, 0, 0); X wrefresh(wel_w); X } X Xvoid SeedRnd() X X { X extern long time(); X X srand48(time((long *) 0)); X } X Xvoid GetReady(win, p_read, p_write, game_count, hom) X XWINDOW *win; Xint p_read; Xint p_write; Xchar *hom; X X { X WINDOW *ready_w; X char mesg[256]; X char waiting[256]; X char ack; X int len, wait_len; X X if (! IComputer) X { X sprintf(mesg, "Game: %d - press space to begin...", game_count); X sprintf(waiting, "waiting for %s...", hom); X len = strlen(mesg) + 3; X wait_len = strlen(waiting) + 3; X if (wait_len > len) X len = wait_len; X ready_w = CreateWindow(win, 3, len, 10, (COLS - len) / 2); X mvwaddstr(ready_w, 1, 1, mesg); X wrefresh(ready_w); X while (wgetch(ready_w) != ' '); X werase(ready_w); X box(ready_w, 0, 0); X mvwaddstr(ready_w, 1, 1, waiting); X wrefresh(ready_w); X } X write(p_write, &ack, sizeof ack); X read(p_read, &ack, sizeof ack); X if (! IComputer) X RemoveWindow(win, ready_w); X } END_OF_FILE if test 1973 -ne `wc -c <'initend.c'`; then echo shar: \"'initend.c'\" unpacked with wrong size! fi # end of 'initend.c' fi if test -f 'macros.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'macros.h'\" else echo shar: Extracting \"'macros.h'\" \(1404 characters\) sed "s/^X//" >'macros.h' <<'END_OF_FILE' X#define B_INC(e) (sizeof(e) + 2) X#define CENTRE(e) ((COLS - B_INC(e)) / 2) X#define SM_CENTRE(width, len) (((len) - (width)) / 2 + 1) X#define SAME(a, b) (strcmp((a), (b)) == 0) X#define DISPLAY_ERROR(back_win, e) \ X { \ X WINDOW *err_win; \ X extern int StopIO; \ X { \ X err_win = CreateWindow(back_win, 3, B_INC(e), 10, CENTRE(e)); \ X mvwaddstr(err_win, 1, 1, e); \ X wrefresh(err_win); \ X sleep(3); \ X RemoveWindow(back_win, err_win); \ X } \ X } X#define BANG_PRINT(w, c, b, v) (b[c->y][c->x] & S_CRASH ? \ X mvwaddch(w, c->y, c->x, S_BANG_CHAR) : \ X mvwaddch(w, c->y, c->x, v)) X X#define BAD_COORDS(y, x) (y < 0 || y >= Y_MAX || x < 0 || x >= X_MAX) X X#define SETUP_THEM(board, t) \ X { \ X board[t->y + Delta[S_NORTH].dy][t->x + Delta[S_NORTH].dx] |= S_TEMP; \ X board[t->y + Delta[S_SOUTH].dy][t->x + Delta[S_SOUTH].dx] |= S_TEMP; \ X board[t->y + Delta[S_EAST].dy][t->x + Delta[S_EAST].dx] |= S_TEMP; \ X board[t->y + Delta[S_WEST].dy][t->x + Delta[S_WEST].dx] |= S_TEMP; \ X } X X#define REMOVE_THEM(board, t) \ X { \ X board[t->y + Delta[S_NORTH].dy][t->x + Delta[S_NORTH].dx] &= ~S_TEMP; \ X board[t->y + Delta[S_SOUTH].dy][t->x + Delta[S_SOUTH].dx] &= ~S_TEMP; \ X board[t->y + Delta[S_EAST].dy][t->x + Delta[S_EAST].dx] &= ~S_TEMP; \ X board[t->y + Delta[S_WEST].dy][t->x + Delta[S_WEST].dx] &= ~S_TEMP; \ X } X X#define MAINTAIN_COURSE(us) \ X { \ X us->y += Delta[us->dir].dy; \ X us->x += Delta[us->dir].dx; \ X } END_OF_FILE if test 1404 -ne `wc -c <'macros.h'`; then echo shar: \"'macros.h'\" unpacked with wrong size! fi # end of 'macros.h' fi if test -f 'move.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'move.c'\" else echo shar: Extracting \"'move.c'\" \(2101 characters\) sed "s/^X//" >'move.c' <<'END_OF_FILE' X#include <curses.h> X#include "consts.h" X#include "types.h" X#include "macros.h" X#include "funcs.h" X Xextern int IComputer; Xextern int ComputerOpponent; Xextern int StopIO; X Xvoid HumanMove(); X Xint DeltaI[128]; Xdelta_t Delta[S_DELTA_MAX]; X Xint GetMoves(board_w, board, pipe_r, pipe_w, us, them) X XWINDOW *board_w; Xint board[Y_MAX][X_MAX]; Xint pipe_r; Xint pipe_w; Xcoords_t *us; Xcoords_t *them; X X { X int status = S_NO_COLLISION; X X if (IComputer) X ComputeMove(board, us, them); X else X HumanMove(board_w, us); X X write(pipe_w, (char *)us, sizeof *us); X read(pipe_r, (char *)them, sizeof *them); X X if (board[us->y][us->x] != S_FREE) X { X board[us->y][us->x] |= S_CRASH; X status |= S_WE_COLLIDE; X } X board[us->y][us->x] |= S_ONE; X if (board[them->y][them->x] != S_FREE) X { X board[them->y][them->x] |= S_CRASH; X status |= S_THEY_COLLIDE; X } X board[them->y][them->x] |= S_OTHER; X X return status; X } X Xvoid DeltaInits() X X { X int i; X X for (i = 1; i < 128; ++i) X DeltaI[i] = S_BOGUS; X X DeltaI[S_RIGHT_CH] = S_EAST; X DeltaI[S_LEFT_CH] = S_WEST; X DeltaI[S_UP_CH] = S_NORTH; X DeltaI[S_DOWN_CH] = S_SOUTH; X DeltaI[0] = S_SAME; X X Delta[S_NORTH].dy = -1; X Delta[S_NORTH].dx = 0; X Delta[S_SOUTH].dy = 1; X Delta[S_SOUTH].dx = 0; X Delta[S_EAST].dy = 0; X Delta[S_EAST].dx = 1; X Delta[S_WEST].dy = 0; X Delta[S_WEST].dx = -1; X } X Xstatic void HumanMove(board_w, us) X XWINDOW *board_w; Xcoords_t *us; X X { X int ch; X int tmp_dir; X X wrefresh(board_w); X ch = wgetch(board_w); X if (ch != ERR) X tmp_dir = DeltaI[ch]; X else X tmp_dir = S_SAME; X switch (tmp_dir) X { X case S_BOGUS : X tmp_dir = us->dir; X flash(); X break; X case S_SAME : X tmp_dir = us->dir; X break; X default : X X us->dir = tmp_dir; X break; X } X us->y += Delta[tmp_dir].dy; X us->x += Delta[tmp_dir].dx; X } X Xvoid DrawPositions(board_w, board, us, them) X XWINDOW *board_w; Xint board[Y_MAX][X_MAX]; Xcoords_t *us; Xcoords_t *them; X X { X if (! StopIO) X { X BANG_PRINT(board_w, us, board, S_US_CHAR); X BANG_PRINT(board_w, them, board, S_THEM_CHAR); X wmove(board_w, us->y, us->x); X wrefresh(board_w); X } X if (! IComputer) X MillisecondSleep(140); X } END_OF_FILE if test 2101 -ne `wc -c <'move.c'`; then echo shar: \"'move.c'\" unpacked with wrong size! fi # end of 'move.c' fi if test -f 'scr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'scr.c'\" else echo shar: Extracting \"'scr.c'\" \(2383 characters\) sed "s/^X//" >'scr.c' <<'END_OF_FILE' X#include <signal.h> X#include <fcntl.h> X#include <ctype.h> X#include <curses.h> X#include "consts.h" X#include "types.h" X#include "funcs.h" X#include "macros.h" X Xextern int StopIO; Xextern int ChildPid; X Xvoid KillChild(); Xvoid FixNodelay(); Xvoid zap(); Xvoid dumpcore(); X Xstatic int SavedFcntl; X XWINDOW *CreateWindow(old_win, lines, cols, y, x) X XWINDOW *old_win; Xint lines, cols; Xint y, x; X X { X WINDOW *front_win; X X front_win = newwin(lines, cols, y, x); X touchwin(front_win); X box(front_win, 0, 0); X old_win = old_win; X X return front_win; X } X Xvoid RemoveWindow(old_win, new_win) X XWINDOW *old_win; XWINDOW *new_win; X X { X werase(new_win); X wrefresh(new_win); X delwin(new_win); X touchwin(old_win); X wrefresh(old_win); X } X XWINDOW *InitScreen() X X { X WINDOW *basic_w; X X SavedFcntl = fcntl(fileno(stdin), F_GETFL, 0); X signal(SIGINT, zap); X signal(SIGQUIT, dumpcore); X signal(SIGPIPE, zap); X initscr(); X noecho(); X crmode(); X basic_w = stdscr; X werase(basic_w); X box(basic_w, 0, 0); X wrefresh(basic_w); X return basic_w; X } X Xvoid EndScreen() X X { X echo(); X nocrmode(); X endwin(); X FixNodelay(); X } X Xint GetString(win, str, max_len) X XWINDOW *win; Xchar *str; Xint max_len; X X { X int y, x; X int len = 0; X int ch; X X noecho(); X getyx(win, y, x); X wrefresh(win); X while ((ch = wgetch(win)) != '\n') X { X switch (ch) X { X case ASCII_BS : X case ASCII_DEL : X if (len > 0) X { X --len; X mvwaddch(win, y, x + len, ' '); X } X else X flash(); X break; X default : X if (len < max_len && isalnum(ch)) X { X str[len] = ch; X mvwaddch(win, y, x + len, ch); X ++len; X } X else X flash(); X break; X } X wmove(win, y, x + len); X wrefresh(win); X } X str[len] = 0; X X return len; X } X Xvoid BlockSignals() X X { X signal(SIGINT, SIG_IGN); X signal(SIGQUIT, SIG_IGN); X } X Xstatic void zap(signo) X Xint signo; X X { X if (! StopIO) X { X endwin(); X if (signo == SIGINT) X fprintf(stderr, "You aborted!\n"); X else X fprintf(stderr, "Your opponent aborted!\n"); X FixNodelay(); X KillChild(); X } X EndFIFO(); X exit(1); X } X Xstatic void dumpcore() X X { X if (StopIO) X return; X endwin(); X FixNodelay(); X signal(SIGQUIT, SIG_DFL); X KillChild(); X kill(getpid(), SIGQUIT); X pause(); X } X Xstatic void KillChild() X X { X if (ChildPid <= 0) X return; X signal(SIGCLD, SIG_IGN); X kill(ChildPid, SIGKILL); X } X Xstatic void FixNodelay() X X { X (void)fcntl(fileno(stdin), F_SETFL, SavedFcntl); X } END_OF_FILE if test 2383 -ne `wc -c <'scr.c'`; then echo shar: \"'scr.c'\" unpacked with wrong size! fi # end of 'scr.c' fi if test -f 'types.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'types.h'\" else echo shar: Extracting \"'types.h'\" \(121 characters\) sed "s/^X//" >'types.h' <<'END_OF_FILE' Xtypedef struct coords_t { X int y; X int x; X int dir; X } coords_t; X Xtypedef struct delta_t { X int dy; X int dx; X } delta_t; END_OF_FILE if test 121 -ne `wc -c <'types.h'`; then echo shar: \"'types.h'\" unpacked with wrong size! fi # end of 'types.h' fi if test -f 'usleep.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usleep.c'\" else echo shar: Extracting \"'usleep.c'\" \(545 characters\) sed "s/^X//" >'usleep.c' <<'END_OF_FILE' X#include <curses.h> X#include "consts.h" X#include "types.h" X#include "funcs.h" X X#ifdef M_XENIX Xvoid MillisecondSleep(ms) X Xint ms; X X { X (void)nap(ms); X } X#else X#ifdef SYS5_3 X X#include <sys/poll.h> X Xvoid MillisecondSleep(ms) X Xint ms; X X { X (void) poll((struct pollfd *)0, 0L, ms); X X return (1); X } X#else X X/* this must be the last resort, single user machines only! */ X XMAKE SURE YOU CHECK THIS WHILE YOU ARE PORTING X Xint MillisecondSleep(ms) X Xint ms; X X { X int start = clock(); X int end = ms * 1000; X X while (clock() - start < end); X } X#endif X#endif END_OF_FILE if test 545 -ne `wc -c <'usleep.c'`; then echo shar: \"'usleep.c'\" unpacked with wrong size! fi # end of 'usleep.c' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. 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