jjv3345@ritcv.UUCP (Jeff Van Epps) (11/21/85)
: Run this script with sh, not with csh
echo x payoff.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > payoff.c
X/*
X** Add current pot to winners available cash. Tell everyone who won.
X*/
X
X# include "players.h"
X# include "tellall.h"
X
Xvoid payoff( player, n_players, winner, pot )
X
XPLAYER player[]; /* player information */
Xint n_players; /* number of players */
Xint winner; /* which player won */
Xint pot; /* how much $ was won */
X
X{
Xchar temp[80];
X
Xplayer[winner].cash += pot;
Xsprintf( temp, "W%s", player[winner].name );
Xtellall( player, n_players, temp );
X}
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l payoff.c
echo x payoff.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > payoff.h
X/*
X** Pay the pot to the winner.
X*/
X
Xextern void payoff();
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l payoff.h
echo x players.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > players.c
X/*
X** Routines to handle players joining game and quitting.
X*/
X
X# include "players.h"
X# include "util.h"
X# include "port.h"
X# include "scores.h"
X# include <errno.h>
X# include <sys/types.h>
X# include <sys/socket.h>
X# ifdef MASSCOMP
X# include <net/in.h>
X typedef unsigned long u_long;
X# include <net/misc.h>
X# else
X# include <netinet/in.h>
X# include <sys/time.h>
X# endif
X# include <stdio.h>
X# include <netdb.h>
X# ifdef MASSCOMP
X extern char *index();
X# else
X# include <strings.h>
X# endif
X
X# define TRUE 1
X# define FALSE 0
X# define ERROR -1
X
X# define START_CASH 200 /* amount new player starts with */
X# define MAX_PLAYERS 5 /* max # concurrent players */
X
XPLAYER player[MAX_PLAYERS]; /* player information */
Xint n_players=1; /* computer is playing */
Xstatic int main_socket=ERROR; /* socket to accept connections on */
X
Xvoid new_players( player, n_players, block )
X
XPLAYER player[]; /* array of player info structures */
Xint *n_players; /* number of players (incl comp) */
Xint block; /* if nobody wants to join, wait on socket
X until somebody does. */
X
X{
Xint readfds; /* for select() call */
Xchar temp[80]; /* to read player's name*/
Xint s; /* temp holder for new socket */
Xint rc; /* # ready selected sockets */
Xint open_sock(); /* to open main socket */
X# ifdef MASSCOMP
Xint free_socket(); /* gets a free socket */
Xint new_socket; /* file descriptor of socket gotten */
X# endif
Xstruct sockaddr_in from; /* connection acceptor */
Xint fromlen = sizeof(from);
X# ifndef MASSCOMP
Xstruct timeval t; /* don't let select() run forever */
X# endif
Xint i;
X
Xif (main_socket == ERROR)
X main_socket = open_sock();
X/* set up 1 second timeout for use on all select() calls */
X# ifndef MASSCOMP
Xt.tv_sec = 1L;
Xt.tv_usec = 0L;
X# endif
X/* see if people who were sitting out want to rejoin yet */
Xfor( i=1; i<*n_players; i++ )
X {
X if ( player[i].sittingout )
X {
X readfds = 1 << player[i].socket;
X# ifdef MASSCOMP
X if ( select( 32, &readfds, 0, 1000 ) > 0 ) /* 1000 ms */
X# else
X if ( select( 32, &readfds, 0, 0, &t ) > 0 )
X# endif
X {
X readln( player[i].socket, temp );
X if ( temp[0] == 'S' )
X player[i].sittingout = FALSE;
X }
X }
X }
Xfor (;;)
X {
X readfds = 1 << main_socket;
X# ifdef MASSCOMP
X rc = select( 32, &readfds, 0, 1000 );
X# else
X rc = select( 32, &readfds, 0, 0, &t );
X# endif
X if (rc > 0 || block)
X {
X# ifdef MASSCOMP
X if ((s = accept( main_socket, &from )) < 0 )
X# else
X if ((s = accept( main_socket, &from, &fromlen)) < 0)
X# endif
X {
X perror("accept");
Xfflush(stdout);
X break;
X }
X if ( *n_players >= MAX_PLAYERS )
X {
X writeln( s, "TOOMANY" );
X close( s );
X }
X else
X {
X block = FALSE;
X printf("accepted connection from ");
X# ifdef MASSCOMP
X new_socket = free_socket();
X socketaddr( new_socket, &from );
X sprintf( temp, "%d", ntohs( from.sin_port ) );
X writeln( main_socket, temp );
X accept( new_socket, &from );
X read( main_socket, temp, 1 ); /* eat the EOF ????? */
X close( main_socket );
X sleep(5);
X main_socket = open_sock();
X s = new_socket;
X# else
X writeln( s, "OK" );
X# endif
X player[*n_players].socket = s;
X player[*n_players].cash = START_CASH;
X player[*n_players].in = FALSE;
X player[*n_players].wantsout = FALSE;
X player[*n_players].sittingout = FALSE;
X player[*n_players].lonehands = 0;
X readln( s, temp );
X temp[strlen( temp ) - 1] = NULL;
X /* don't allow colons in name because of format of score file */
X if ( index( temp, ':' ) != NULL )
X *index( temp, ':' ) = NULL;
X if ( strlen( temp ) > 25 )
X temp[25] = NULL;
X player[*n_players].name = strsave( temp );
X printf("%s\n",temp);
X fflush(stdout);
X readln( s, temp );
X player[*n_players].userid = atoi( temp );
X if ( played_before( player[*n_players].name, player[*n_players].userid ) )
X player[*n_players].cash = get_cash();
X (*n_players)++;
X break;
X }
X }
X else
X break;
X }
X}
X
Xvoid leave( player, n_players )
X
XPLAYER player[];
Xint *n_players;
X
X{
Xregister int i;
X
Xfor( i=1; i<*n_players; i++)
X if (player[i].wantsout)
X {
X writeln( player[i].socket, "Q" );
X put_cash( player[i].name, player[i].userid, player[i].cash );
X high_score_list( player[i].socket );
X close( player[i].socket );
X free( player[i].name );
X player[i] = player[*n_players - 1];
X (*n_players)--;
X --i; /* since this entry is new, test again */
X }
X}
X/* Open the main socket. */
X
Xint open_sock()
X
X{
Xint s;
Xstruct sockaddr_in sockaddr;
Xstruct hostent *host;
X
X# ifdef MASSCOMP
X sockaddr.sin_family = AF_INET;
X sockaddr.sin_port = htons( PORT );
X if ((host = gethostbyname( HOST )) == NULL)
X {
X perror( "gethostbyname" );
X exit(1);
X }
X sockaddr.sin_addr.s_addr = *(u_long *) host->h_addr;
X s = socket( SOCK_STREAM, 0, &sockaddr, SO_ACCEPTCONN );
X# else
X s = socket( AF_INET, SOCK_STREAM, 0 );
X# endif
Xif (s < 0)
X {
X perror("open_sock");
X exit(1);
X }
X# ifndef MASSCOMP
Xsockaddr.sin_family = AF_INET;
Xsockaddr.sin_port = htons( PORT );
Xif (bind( s, &sockaddr, sizeof(sockaddr)) < 0)
X {
X perror("bind");
X exit(1);
X }
Xif (listen( s, 0 ) < 0)
X {
X perror("listen");
X exit(1);
X }
X# endif
Xreturn( s );
X}
X
Xvoid crash()
X
X{
Xint i;
X
Xfor(i=0; i<32; i++)
X close(i);
Xexit(9);
X}
X
X# ifdef MASSCOMP
X
X/* accept() does not allocate a new socket on the Masscomps. Therefore we
X** have to grab our own new socket and tell the client where it is.
X*/
X
Xfree_socket()
X
X{
Xint s;
X
Xif ( ( s = socket( SOCK_STREAM, 0, 0, SO_ACCEPTCONN ) ) < 0 )
X {
X perror( "free_socket" );
X crash();
X }
Xreturn( s );
X}
X
X# endif
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l players.c
echo x players.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > players.h
X/*
X** A structure is maintained with information on each player.
X*/
X
Xtypedef struct _player {
X char *name; /* Player's name */
X int userid; /* player's user id number */
X int cash; /* Amount of money player currently has */
X int cards[5]; /* Player's current hand (indexes into deck[]) */
X int score; /* PAIR, THREE, FLUSH, etc. */
X int count[13]; /* counters used to determine score */
X int in; /* Still in current hand? */
X int wantsout; /* Quit after this hand? */
X int sittingout; /* Sit out after this hand? */
X int bet; /* How much bet into current pot*/
X int lonehands; /* # hands played against only computer */
X int socket; /* To communicate with player on*/
X } PLAYER;
X
Xextern PLAYER player[];
X
Xextern int n_players; /* current number of players (including computer) */
X
Xextern void new_players(),leave(),crash();
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l players.h
echo x poker.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > poker.c
X# include "util.h"
X# include "port.h"
X# include "limits.h"
X# include <sys/types.h>
X# include <sys/socket.h>
X# ifdef MASSCOMP
X# include <net/in.h>
X typedef unsigned long u_long;
X# include <net/misc.h>
X# else
X# include <netinet/in.h>
X# endif
X# include <netdb.h>
X# include <stdio.h>
X# include <curses.h>
X# include <ctype.h>
X# include <signal.h>
X
Xint s; /* the socket */
X
Xmain( argc, argv, envp )
X
Xint argc;
Xchar **argv;
Xchar **envp;
X
X{
Xstruct sockaddr_in sockaddr;
Xstruct hostent *host;
Xchar *getenv();
Xchar *name;
Xchar temp[80];
Xextern int getuid();
Xvoid closem();
X
X# ifdef MASSCOMP
X s = socket( SOCK_STREAM, 0, 0, 0 );
X# else
X s = socket( AF_INET, SOCK_STREAM, 0 );
X# endif
Xif (s < 0)
X {
X perror( "socket" );
X exit(1);
X }
Xif ((host = gethostbyname( (argc > 1) ? argv[1] : HOST )) == NULL)
X {
X perror( "gethostbyname" );
X exit(1);
X }
Xsockaddr.sin_family = AF_INET;
Xsockaddr.sin_port = htons( PORT );
Xsockaddr.sin_addr.s_addr = *(u_long *) host->h_addr;
Xprintf( "Waiting for last hand to finish ... " );
Xfflush(stdout);
Xsignal( SIGINT, closem );
Xsignal( SIGQUIT, closem );
X# ifdef MASSCOMP
Xif ( connect( s, &sockaddr ) < 0 )
X# else
Xif ( connect( s, &sockaddr, sizeof(sockaddr) ) < 0)
X# endif
X {
X perror( "connect" );
X exit(1);
X }
Xreadln( s, temp );
Xif ( strcmp( temp, "TOOMANY\n" ) == 0 )
X printf( "Table Full!\n" );
Xelse
X {
X if ( strcmp( temp, "OK\n" ) != 0 ) /* must go to another socket */
X {
X close( s );
X sockaddr.sin_port = htons( atoi( temp ) );
X# ifdef MASSCOMP
X s = socket( SOCK_STREAM, 0, 0, 0 );
X if ( s < 0 )
X perror("damn socket");
X if ( connect( s, &sockaddr ) < 0 )
X# else
X s = socket( AF_INET, SOCK_STREAM, 0 );
X if ( connect( s, &sockaddr, sizeof(sockaddr) ) < 0 )
X# endif
X {
X perror( "second connect" );
X exit( 1 );
X }
X }
X signal( SIGINT, SIG_IGN );
X signal( SIGQUIT, SIG_IGN );
X if ( ( name = getenv( "POKER" ) ) == NULL )
X if ( ( name = getenv( "NAME" ) ) == NULL )
X name = getenv( "USER" );
X writeln( s, name );
X sprintf( temp, "%d", getuid() );
X writeln( s, temp );
X play( s );
X readln( s, temp );
X while( temp[0] != ':' )
X {
X printf( "%s", temp );
X readln( s, temp );
X }
X }
Xclose(s);
Xexit(0);
X}
X
X
X/*
X** Listen to poker daemon and update the screen as it says. These are the
X** commands from the daemon to this program:
X**
X** Nn name of player n
X** Cn cards for player n
X** P pot value
X** U update screen
X** X clear screen
X** Hn action for player n (fold, raise, call, etc.)
X** Rn result for player n (straight, two pair, --fold--, etc.)
X** Bn total amount bet by player n this hand
X** $n amount of cash player n has
X** D get discards from this player
X** ? get bet from this player - amount to call follows
X** Q player has quit; cleanup & terminate
X** W player name following has won this hand
X** T tells which player's turn it is; cursor is put next to his name
X** M message to print on bottom of screen
X**
X**
X** These are the commands from this program to the daemon:
X**
X** Q quit after this hand is finished
X** F fold
X** Dxxxxx discard these cards (k=keep,d=discard)
X** C call
X** Rxx raise by this amount
X** P pass - not allowed if player has to call someone else's raise
X** S toggles sitting out switch
X**
X*/
X
Xplay( s )
X
Xint s; /* socket we communicate upon */
X
X{
Xchar temp[80]; /* buffer to read command into */
Xchar temp2[80]; /* outgoing commands are sometimes built here */
Xint n; /* determine which player we're talking about */
Xint minimum; /* minimum bet to stay in */
Xchar c; /* player's command */
Xint done; /* get commands until something valid */
Xint quit=FALSE; /* has player quit yet? */
Xint out=FALSE; /* is player sitting out? */
Xchar cards[20]; /* hold player's current hand */
Xvoid mygetstr(); /* because curses getstr() doesn't work */
Xint i,x;
Xint oldx=0,oldy=0; /* markers for current player cursor */
X
Xinitscr();
Xnoecho(); crmode();
Xleaveok( stdscr, FALSE );
Xwhile ( !quit )
X {
X readln( s, temp );
X n = temp[1] - '0'; /* which player? */
X switch ( temp[0] ) {
X case 'M' :
X mvaddstr( 15, 40, temp+1 );
X refresh();
X break;
X case 'N' :
X mvaddstr( n*2, 4, temp+2 );
X break;
X case 'T' :
X mvaddstr( oldy, oldx, " " );
X mvaddstr( n*2, 0, "--> " );
X oldy = n * 2;
X oldx = 0;
X refresh();
X break;
X case 'C' :
X mvaddstr( n*2, 35, temp+2 );
X strcpy( cards, temp+2 );
X break;
X case 'U' :
X move( 0, 0 );
X refresh();
X break;
X case 'X' :
X clear();
X mvaddstr( 14, 4, "C) Call last raise" );
X mvaddstr( 15, 4, "F) Fold this hand" );
X mvaddstr( 16, 4, "P) Pass (Check)" );
X mvaddstr( 17, 4, "Q) Quit after this hand" );
X mvaddstr( 18, 4, "R) Raise last bet" );
X mvaddstr( 19, 4, "S) Sit out for a while" );
X break;
X case 'P' :
X move( LINES-1, 4 );
X printw( "Pot: %-6d ", atoi( temp + 1 ) );
X break;
X case 'B' :
X move( n*2+1, 6 );
X printw( "Bet: %-6d ", atoi( temp + 2 ) );
X break;
X case 'H' :
X mvaddstr( n*2+1, 35, temp+2 );
X break;
X case 'R' :
X mvaddstr( n*2, 60, temp+2 );
X break;
X case '$' :
X move( n*2+1, 18 );
X printw( "Cash: %-6d ", atoi( temp + 2 ) );
X break;
X case 'Q' :
X endwin();
X quit = TRUE;
X break;
X case 'W' :
X move( LINES-2, 20 );
X temp[strlen( temp ) - 1] = NULL; /* strip newline */
X printw( "%s wins this hand! --more-- ", temp+1 );
X refresh();
X while( getch() != ' ' ) ;
X if ( out )
X {
X move( LINES-2, 20 );
X clrtoeol();
X printw( "Hit space to come back--" );
X refresh();
X while( getch() != ' ' ) ;
X printw( "waiting..." );
X refresh();
X writeln( s, "S" );
X out = FALSE;
X }
X break;
X case 'D' :
X /* find out what player wants to discard */
X move( 14, 25 );
X clrtoeol();
X mvaddstr( 14, 40, "Discard: " );
X refresh();
X mygetstr( temp );
X i = 0;
X strcpy( temp2, "Dkkkkk" );
X while( temp[i] != NULL )
X {
X if ( isdigit( temp[i] ) )
X {
X x = temp[i] - '0';
X if ( x > 0 && x < 6 )
X temp2[x] = 'd';
X }
X i++;
X }
X writeln( s, temp2 );
X break;
X case '?' :
X /* time to let player bet on this hand */
X minimum = atoi( temp + 1 );
X done = FALSE;
X move( 14, 25 );
X clrtoeol();
X while ( !done )
X {
X mvaddstr( 14, 25, "Bet: " );
X refresh();
X while( (c = getch()) == '\014' )
X wrefresh( curscr );
X if ( islower( c ) )
X c = toupper( c );
X done = TRUE;
X switch (c) {
X case 'Q' :
X done = FALSE;
X mvaddstr( LINES-1, 50, "Quitting." );
X case 'C' :
X if ( c == 'C' && minimum == 0 )
X {
X mvaddstr( 14, 35, "No raise to call; pass or raise." );
X refresh();
X done = FALSE;
X break;
X }
X case 'F' :
X sprintf( temp, "%c", c );
X writeln( s, temp );
X break;
X case 'S' :
X done = FALSE;
X out = TRUE;
X writeln( s, "S" );
X mvaddstr( LINES-1, 30, "Sitting out." );
X break;
X case 'P' :
X if ( minimum > 0 )
X {
X mvaddstr( 14, 35, "Can't pass; meet last raise or fold." );
X refresh();
X done = FALSE;
X }
X else
X writeln( s, "P" );
X break;
X case 'R' :
X strcpy( temp, "0" );
X while ( atoi( temp ) <= 0 )
X {
X move( 15, 25 );
X printw( "%15.15s", " " );
X mvaddstr( 15, 25, "Raise: " );
X refresh();
X mygetstr( temp );
X if ( atoi( temp ) > RAISE_LIMIT )
X {
X move( 15, 40 );
X printw( "Raise limit = %d.", RAISE_LIMIT );
X strcpy( temp, "0" );
X }
X }
X minimum = atoi( temp );
X sprintf( temp, "R%d", minimum );
X writeln( s, temp );
X break;
X default:
X done = FALSE;
X /* try again */
X break;
X }
X }
X break;
X default:
X /* ignore unknown commands */
X break;
X }
X }
Xprintf("\n\n\n");
X}
X
Xvoid mygetstr( str )
X
Xchar *str;
X
X{
Xint i=0,x,y;
Xchar c;
X
Xgetyx( stdscr, y, x );
Xwhile ( ( c = getch() ) != '\n' )
X if ( c == '\b' && i > 0 )
X {
X move( y, --x );
X refresh();
X --i;
X }
X else if ( c == '\014' )
X wrefresh( curscr );
X else
X {
X str[i++] = c;
X addch( c );
X refresh();
X x++;
X }
Xstr[i] = NULL;
X}
X
Xvoid closem()
X
X{
Xclose( s );
Xexit( 1 );
X}
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l poker.c
echo x port.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > port.h
X/*
X** Port for POKER.
X*/
X
X# define PORT 55142
X# define HOST "ritcv"
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l port.h
echo x scores.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > scores.c
X/*
X** Maintain players' cash from one play to the next.
X** Money is stored according to NAME. Thus if a player plays on different
X** systems, he's still playing with the same cash. Also note that if a
X** player changes his name, he starts anew with START_CASH.
X** Userid is also now included, so that someone can not "steal" another
X** player's cash by usurping his name temporarily.
X*/
X
X# include "scores.h"
X# include <stdio.h>
X# ifdef MASSCOMP
X# include <sys/types.h>
X char *index();
X# else
X# include <strings.h>
X# endif
X# ifdef MASSCOMP
X# include <fcntl.h>
X# else
X# include <sys/file.h>
X# endif
X
X# define SCORE_FILE "/a2/s11/jjv3345/POKERSCORES"
X# define TRUE 1
X# define FALSE 0
X
Xstatic int scores=(-1); /* file channel for scores */
Xstatic char temp[81];
X
Xplayed_before( name, id )
X
Xchar *name; /* player's name to search for */
Xint id;
X
X{
Xint found=FALSE;
Xchar *p;
X
Xif ( scores == -1 )
X if ( ( scores = open( SCORE_FILE, O_RDWR, 0 ) ) == -1 )
X {
X perror( SCORE_FILE );
X return( FALSE );
X }
Xlseek( scores, 0, 0 );
Xwhile( read( scores, temp, 80 ) == 80 )
X if ( strncmp( temp, name, (p = index( temp, ':' )) - temp ) == 0 && atoi( p + 1 ) == id )
X {
X found = TRUE;
X break;
X }
Xreturn( found );
X}
X
X
Xget_cash()
X
X{
Xreturn( atoi( index( index( temp, ':' ) + 1, ':' ) + 1 ) );
X}
X
X
Xvoid put_cash( name, id, cash )
X
Xchar *name; /* player's name */
Xint id; /* player's userid */
Xint cash; /* how much dough he had*/
X
X{
Xint found=FALSE;
Xchar *p;
Xchar idstr[10];
X
Xlseek( scores, 0, 0 );
Xwhile( read( scores, temp, 80 ) == 80 )
X if ( strncmp( temp, name, (p = index( temp, ':' )) - temp ) == 0 && atoi( p + 1 ) == id )
X {
X found = TRUE;
X break;
X }
Xif ( found )
X lseek( scores, -80, 1 );
Xsprintf( idstr, "%d", id );
Xsprintf( temp, "%s:%s:%-*d\n", name, idstr, 77 - strlen( name ) - strlen( idstr) , cash );
Xwrite( scores, temp, 80 );
X}
X
Xvoid high_score_list( s )
X
Xint s; /* player's socket */
X
X{
Xstruct stuff {
X char name[30];
X int score;
X struct stuff *next;
X } *head, *ptr, *tempptr, *last;
Xint l;
Xint num;
Xint score;
Xchar name[30];
Xchar output[80];
X
Xhead = NULL;
Xlseek( scores, 0, 0 );
Xwriteln( s, "HIGH SCORE LIST" );
Xwriteln( s, "=====================================" );
Xwhile( read( scores, temp, 80 ) == 80 )
X {
X strncpy( name, temp, l = ( index( temp, ':' ) - temp ) );
X name[l] = NULL;
X score = get_cash();
X ptr = head;
X last = NULL;
X while( ptr != NULL && ptr->score > score )
X {
X last = ptr;
X ptr = ptr->next;
X }
X if ( head == NULL )
X {
X head = (struct stuff *) malloc( sizeof(struct stuff) );
X ptr = head;
X ptr->next = NULL;
X }
X else if ( ptr == head )
X {
X head = (struct stuff *) malloc( sizeof(struct stuff) );
X head->next = ptr;
X ptr = head;
X }
X else
X {
X tempptr = ptr;
X ptr = last;
X ptr->next = (struct stuff *) malloc( sizeof(struct stuff) );
X ptr->next->next = tempptr;
X ptr = ptr->next;
X }
X strcpy( ptr->name, name );
X ptr->score = score;
X }
Xnum = 0;
Xptr = head;
Xwhile( num++ < 10 && ptr != NULL )
X {
X sprintf( output, "%6d %-30s", ptr->score, ptr->name );
X writeln( s, output );
X ptr = ptr->next;
X }
Xwriteln( s, ":" ); /* tell client that we are truly finished */
Xptr = head;
Xwhile( ptr != NULL )
X {
X tempptr = ptr->next;
X free( ptr );
X ptr = tempptr;
X }
X}
X
X# ifdef MASSCOMP /* should be in library somewhere, but where? */
X
Xchar *index( str, ch )
X
Xchar *str; /* string to search in */
Xchar ch; /* character to look for */
X
X{
Xwhile( *str != NULL && *str != ch )
X str++;
Xreturn( (*str == NULL) ? NULL : str );
X}
X
X# endif
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l scores.c
echo x scores.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > scores.h
X/*
X** Maintain players' cash from one play to the next.
X*/
X
Xextern int played_before(), get_cash();
Xextern void put_cash(), high_score_list();
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l scores.h
echo x showcards.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > showcards.c
X/*
X** Tell each player everybody's name. Show each player only his own cards.
X*/
X
X# include "showcards.h"
X# include "players.h"
X# include "cards.h"
X# include "util.h"
X
Xvoid show_cards( player, n_players, all, test )
X
XPLAYER player[]; /* all player info */
Xint n_players; /* # active players */
Xint all; /* TRUE=show everybody's cards who is still in
X FALSE=show only player's cards to himself */
Xint test; /* show all cards whether in or out */
X /* only used if 'all' is TRUE */
X
X{
Xint i,j,k;
Xchar temp[10];
Xvoid show();
X
Xfor(i=1; i<n_players; i++) /* don't show cards to computer */
X if ( player[i].bet >= 0 ) /* if sitting out, be quiet */
X {
X for( j=0; j<n_players; j++ ) /* tell player everyone's name */
X {
X sprintf( temp, "N%d", j );
X write( player[i].socket, temp, 2 );
X writeln( player[i].socket, player[j].name );
X }
X if ( all )
X {
X for( k=0; k<n_players; k++ )
X if ( test || player[k].in )
X show( player, temp, k, i );
X }
X else
X show( player, temp, i, i );
X writeln( player[i].socket, "U" ); /* update screen command */
X }
X}
X
Xvoid show( player, temp, i, j )
X
XPLAYER player[];
Xchar temp[];
Xint i; /* whose cards to show */
Xint j; /* who to show them to */
X
X{
Xint c;
X
Xsprintf( temp, "C%d", i ); /* cards for player i */
Xwrite( player[j].socket, temp, 2 );
Xfor(c=0; c<5; c++)
X {
X sprintf( temp, "%c%c ", rank(player[i].cards[c]), color(player[i].cards[c]));
X write( player[j].socket, temp, 3 );
X }
Xwrite( player[j].socket, "\n", 1 );
X}
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l showcards.c
echo x showcards.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > showcards.h
X/*
X** Routine which shows each player his or everybody's cards.
X*/
X
Xextern void show_cards();
Xextern void show();
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l showcards.h
echo x tellall.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > tellall.c
X/*
X** Send everyone a message.
X*/
X
X# include "tellall.h"
X# include "util.h"
X# include "players.h"
X
Xvoid tellall( player, n_players, msg )
X
XPLAYER player[]; /* all player info */
Xint n_players; /* # of players */
Xchar *msg; /* message to send */
X
X{
Xint i;
X
Xfor( i=1; i<n_players; i++ ) /* don't send any messages to the computer */
X if ( player[i].bet != -1 ) /* no messages to anyone sitting out */
X writeln( player[i].socket, msg );
X}
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l tellall.c
echo x tellall.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > tellall.h
X/*
X** Send everyone a message.
X*/
X
Xextern void tellall();
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l tellall.h
echo x util.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > util.c
X/*
X** Various utility routines.
X*/
X
X# include <stdio.h>
X# include "util.h"
X
Xchar *strsave( temp )
X
Xchar *temp;
X
X{
Xchar *p;
Xextern char *malloc();
X
Xp = malloc( strlen(temp) + 1 );
Xstrcpy( p, temp );
Xreturn( p );
X}
X
Xint readln( s, temp )
X
Xint s; /* fd to read from */
Xchar *temp; /* area to read into */
X
X{
Xdo {
X if (read( s, temp, 1) < 1)
X return(0);
X }
Xwhile( *temp++ != '\n');
X*temp = NULL;
X}
X
Xwriteln( s, temp )
X
Xint s; /* channel to write on */
Xchar *temp; /* what to write */
X
X{
Xwrite( s, temp, strlen( temp ) );
Xwrite( s, "\n", 1 );
X}
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l util.c
echo x util.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > util.h
X/*
X** Various utility routines.
X*/
X
Xextern char *strsave();
Xextern int readln();
Xextern int writeln();
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l util.h
echo x whowon.c
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > whowon.c
X/*
X** Figure out who wins.
X*/
X
X# include <stdio.h>
X# include "whowon.h"
X# include "players.h"
X# include "cards.h"
X# include "showcards.h"
X# include "tellall.h"
X
X# define TRUE 1
X# define FALSE 0
X
Xstatic char *scores[] = {
X "Nothing", "Pair", "Two Pair", "Three of a kind", "Straight", "Flush",
X "Full House", "Four of a kind", "Straight Flush", "Royal Flush" };
X
Xint whowon( player, n_players, test )
X
XPLAYER player[]; /* all player information */
Xint n_players; /* number of players */
Xint test; /* show all cards regardless */
X
X{
Xint i;
Xint max=(-1); /* highest score */
Xint winner=0; /* which player won */
Xchar temp[80]; /* tell everybody what everybody has */
Xvoid evaluate(),tie();
X
Xshow_cards( player, n_players, TRUE, test ); /* show all hands everywhere */
Xfor( i=0; i<n_players; i++ )
X if ( test || player[i].in )
X {
X evaluate( player, i );
X sprintf( temp, "R%d%s", i, scores[player[i].score] );
X tellall( player, n_players, temp );
X if ( player[i].in && player[i].score > max )
X {
X max = player[i].score;
X winner = i;
X }
X else if ( player[i].in && player[i].score == max )
X {
X tie( player, &winner, i );
X }
X }
Xreturn( winner );
X}
X
Xstatic void tie( player, winner, which )
X
XPLAYER player[]; /* all hands on deck */
Xint *winner; /* may have to set new winner */
Xint which; /* which player is challenging the winner */
X
X{
Xint top1,top2;
Xint i;
Xint done=FALSE;
Xint oldwinner;
X
Xoldwinner = *winner;
Xwhile( !done )
X {
X top1 = top2 = -1;
X for( i=12; i>=0; i-- )
X {
X if ( top1 == -1 || player[which].count[i] > player[which].count[top1] )
X top1 = i;
X if ( top2 == -1 || player[*winner].count[i] > player[*winner].count[top2] )
X top2 = i;
X }
X if ( top1 != top2 )
X {
X if ( top1 > top2 )
X *winner = which;
X done = TRUE;
X }
X else if ( player[which].count[top1] == 0 ) /* OH, NO! */
X {
X printf( "tie() failed to resolve - details follow\n" );
X for( i=0; i<5; i++ )
X printf( "%c%c ", rank(player[which].cards[i]), color(player[which].cards[i]) );
X for( i=0; i<5; i++ )
X printf( "%c%c ", rank(player[*winner].cards[i]), color(player[*winner].cards[i]) );
X fflush( stdout );
X done = TRUE;
X }
X else
X {
X player[which].count[top1] = 0;
X player[*winner].count[top2] = 0;
X }
X }
X/* re-evaluate hands because counts have been messed ... */
Xevaluate( player, oldwinner );
Xevaluate( player, which );
X}
X
Xvoid evaluate( player, which )
X
XPLAYER player[];
Xint which; /* which player's hand to evaluate */
X
X{
Xint kind[6];
Xint i,j;
X
Xfor( i=0; i<13; i++ )
X player[which].count[i] = 0;
Xfor( i=0; i<5; i++ )
X player[which].count[card(player[which].cards[i])] ++ ;
Xfor( i=0; i<6; i++ )
X kind[i] = 0;
Xfor( i=0; i<13; i++ )
X kind[player[which].count[i]] ++ ;
Xif ( kind[4] )
X player[which].score = FOUR;
Xelse if ( kind[3] && kind[2] )
X player[which].score = FULL;
Xelse if ( kind[3] )
X player[which].score = THREE;
Xelse if ( kind[2] == 2 )
X player[which].score = TWOPAIR;
Xelse if ( kind[2] )
X player[which].score = PAIR;
Xelse
X player[which].score = NOTHING;
Xif ( player[which].score == NOTHING )
X {
X for( i=1; i<5; i++ )
X if ( suit(player[which].cards[i]) != suit(player[which].cards[0] ) )
X break;
X if ( i == 5 )
X player[which].score = FLUSH;
X i = -1;
X while( player[which].count[++i] == 0 ) ;
X j = i;
X while( ++i < 13 && player[which].count[i] == 1 ) ;
X /* trash below is for A-5 straights */
X if ( i - j == 5 || ((i == 4) && (j == 0) && (player[which].count[12] == 1)) )
X if ( player[which].score == FLUSH )
X player[which].score = STRAIGHT_FLUSH;
X else
X player[which].score = STRAIGHT;
X if ( player[which].score == STRAIGHT_FLUSH && i == 13 )
X player[which].score = ROYAL_FLUSH;
X }
X}
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l whowon.c
echo x whowon.h
sed -e 's/^X//' << 'PaRtIcUlAtEmAtTeR' > whowon.h
X/*
X** Evaluate the hands of everyone who is still in, then return winner.
X*/
X
Xextern int whowon();
Xextern void evaluate();
X
X# define NOTHING 0
X# define PAIR 1
X# define TWOPAIR 2
X# define THREE 3
X# define STRAIGHT 4
X# define FLUSH 5
X# define FULL 6
X# define FOUR 7
X# define STRAIGHT_FLUSH 8
X# define ROYAL_FLUSH 9
X
PaRtIcUlAtEmAtTeR
echo -n ' '
ls -l whowon.h