17872Sarnold # include <curses.h> 27872Sarnold # include <ctype.h> 37872Sarnold # include <unctrl.h> 47872Sarnold # include "deck.h" 57872Sarnold # include "cribbage.h" 67709Sarnold 77872Sarnold # define LINESIZE 128 87709Sarnold 97872Sarnold # define CTRL(X) ('X' - 'A' + 1) 107709Sarnold 117872Sarnold # ifndef attron 127872Sarnold # define erasechar() _tty.sg_erase 137872Sarnold # define killchar() _tty.sg_kill 147872Sarnold # endif attron 157872Sarnold 167709Sarnold char linebuf[ LINESIZE ]; 177709Sarnold 187709Sarnold char *rankname[ RANKS ] = { "ACE", "TWO", "THREE", "FOUR", 197872Sarnold "FIVE", "SIX", "SEVEN", "EIGHT", 207872Sarnold "NINE", "TEN", "JACK", "QUEEN", 217872Sarnold "KING" }; 227709Sarnold 237709Sarnold char *rankchar[ RANKS ] = { "A", "2", "3", "4", "5", "6", "7", 247872Sarnold "8", "9", "T", "J", "Q", "K" }; 257709Sarnold 267709Sarnold char *suitname[ SUITS ] = { "SPADES", "HEARTS", "DIAMONDS", 277872Sarnold "CLUBS" }; 287709Sarnold 297709Sarnold char *suitchar[ SUITS ] = { "S", "H", "D", "C" }; 307709Sarnold 317709Sarnold 327709Sarnold 337709Sarnold /* 347872Sarnold * msgcard: 357872Sarnold * Call msgcrd in one of two forms 367709Sarnold */ 377872Sarnold msgcard(c, brief) 387872Sarnold CARD c; 397872Sarnold BOOLEAN brief; 407709Sarnold { 417872Sarnold if (brief) 427872Sarnold return msgcrd(c, TRUE, (char *) NULL, TRUE); 437872Sarnold else 447872Sarnold return msgcrd(c, FALSE, " of ", FALSE); 457709Sarnold } 467709Sarnold 477709Sarnold 487709Sarnold 497709Sarnold /* 507872Sarnold * msgcrd: 517872Sarnold * Print the value of a card in ascii 527709Sarnold */ 537872Sarnold msgcrd(c, brfrank, mid, brfsuit) 547872Sarnold CARD c; 557872Sarnold char *mid; 567872Sarnold BOOLEAN brfrank, brfsuit; 577872Sarnold { 587872Sarnold if (c.rank == EMPTY || c.suit == EMPTY) 597872Sarnold return FALSE; 607872Sarnold if (brfrank) 617872Sarnold addmsg("%1.1s", rankchar[c.rank]); 627872Sarnold else 637872Sarnold addmsg(rankname[c.rank]); 647872Sarnold if (mid != NULL) 657872Sarnold addmsg(mid); 667872Sarnold if (brfsuit) 677872Sarnold addmsg("%1.1s", suitchar[c.suit]); 687872Sarnold else 697872Sarnold addmsg(suitname[c.suit]); 707872Sarnold return TRUE; 717872Sarnold } 727709Sarnold 737872Sarnold /* 747872Sarnold * printcard: 757872Sarnold * Print out a card. 767872Sarnold */ 777872Sarnold printcard(win, cardno, c) 787872Sarnold WINDOW *win; 797872Sarnold int cardno; 807872Sarnold CARD c; 817872Sarnold { 82*7946Sarnold prcard(win, cardno * 2, cardno, c, FALSE); 837872Sarnold } 847709Sarnold 857872Sarnold /* 867872Sarnold * prcard: 877872Sarnold * Print out a card on the window at the specified location 887872Sarnold */ 89*7946Sarnold prcard(win, y, x, c, blank) 907872Sarnold WINDOW *win; 917872Sarnold int y, x; 927872Sarnold CARD c; 93*7946Sarnold BOOLEAN blank; 947709Sarnold { 957872Sarnold if (c.rank == EMPTY) 967872Sarnold return; 977872Sarnold mvwaddstr(win, y + 0, x, "+-----+"); 987872Sarnold mvwaddstr(win, y + 1, x, "| |"); 997872Sarnold mvwaddstr(win, y + 2, x, "| |"); 1007872Sarnold mvwaddstr(win, y + 3, x, "| |"); 1017872Sarnold mvwaddstr(win, y + 4, x, "+-----+"); 102*7946Sarnold if (!blank) { 103*7946Sarnold mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]); 104*7946Sarnold waddch(win, suitchar[c.suit][0]); 105*7946Sarnold mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]); 106*7946Sarnold waddch(win, suitchar[c.suit][0]); 107*7946Sarnold } 1087709Sarnold } 1097709Sarnold 1107709Sarnold /* 1117872Sarnold * prhand: 1127872Sarnold * Print a hand of n cards 1137709Sarnold */ 1147872Sarnold prhand(h, n, win) 1157872Sarnold CARD h[]; 1167872Sarnold int n; 1177872Sarnold WINDOW *win; 1187709Sarnold { 1197872Sarnold register int i; 1207709Sarnold 1217872Sarnold werase(win); 1227872Sarnold for (i = 0; i < n; i++) 1237872Sarnold printcard(win, i, h[i]); 1247872Sarnold wrefresh(win); 1257709Sarnold } 1267709Sarnold 1277709Sarnold 1287709Sarnold 1297709Sarnold /* 1307872Sarnold * infrom: 1317872Sarnold * reads a card, supposedly in hand, accepting unambigous brief 1327872Sarnold * input, returns the index of the card found... 1337709Sarnold */ 1347872Sarnold infrom(hand, n, prompt) 1357872Sarnold CARD hand[]; 1367872Sarnold int n; 1377872Sarnold char *prompt; 1387709Sarnold { 1397872Sarnold register int i, j; 1407872Sarnold CARD crd; 1417709Sarnold 1427872Sarnold if (n < 1) { 1437872Sarnold printf("\nINFROM: %d = n < 1!!\n", n); 1447872Sarnold exit(74); 1457872Sarnold } 1467872Sarnold for (;;) { 1477872Sarnold if (incard(&crd)) { /* if card is full card */ 1487872Sarnold if (!isone(crd, hand, n)) 1497872Sarnold msg("That's not in your hand"); 1507872Sarnold else { 1517872Sarnold for (i = 0; i < n; i++) 1527872Sarnold if (hand[i].rank == crd.rank && 1537872Sarnold hand[i].suit == crd.suit) 1547872Sarnold break; 1557872Sarnold if (i >= n) { 1567872Sarnold printf("\nINFROM: isone or something messed up\n"); 1577872Sarnold exit(77); 1587872Sarnold } 1597872Sarnold return i; 1607872Sarnold } 1617872Sarnold } 1627872Sarnold else /* if not full card... */ 1637872Sarnold if (crd.rank != EMPTY) { 1647872Sarnold for (i = 0; i < n; i++) 1657872Sarnold if (hand[i].rank == crd.rank) 1667872Sarnold break; 1677872Sarnold if (i >= n) 1687872Sarnold msg("No such rank in your hand"); 1697872Sarnold else { 1707872Sarnold for (j = i + 1; j < n; j++) 1717872Sarnold if (hand[j].rank == crd.rank) 1727872Sarnold break; 1737872Sarnold if (j < n) 1747872Sarnold msg("Ambiguous rank"); 1757872Sarnold else 1767872Sarnold return i; 1777872Sarnold } 1787872Sarnold } 1797872Sarnold else 1807872Sarnold msg("Sorry, I missed that"); 1817872Sarnold msg(prompt); 1827872Sarnold } 1837872Sarnold /* NOTREACHED */ 1847709Sarnold } 1857709Sarnold 1867709Sarnold 1877709Sarnold 1887709Sarnold /* 1897872Sarnold * incard: 1907872Sarnold * Inputs a card in any format. It reads a line ending with a CR 1917872Sarnold * and then parses it. 1927709Sarnold */ 1937872Sarnold incard(crd) 1947872Sarnold CARD *crd; 1957709Sarnold { 1967872Sarnold char *getline(); 1977872Sarnold register int i; 1987872Sarnold int rnk, sut; 1997872Sarnold char *line, *p, *p1; 2007872Sarnold BOOLEAN retval; 2017709Sarnold 2027872Sarnold retval = FALSE; 2037872Sarnold rnk = sut = EMPTY; 2047872Sarnold if (!(line = getline())) 2057872Sarnold goto gotit; 2067872Sarnold p = p1 = line; 2077872Sarnold while( *p1 != ' ' && *p1 != NULL ) ++p1; 2087872Sarnold *p1++ = NULL; 2097872Sarnold if( *p == NULL ) goto gotit; 2107872Sarnold /* IMPORTANT: no real card has 2 char first name */ 2117872Sarnold if( strlen(p) == 2 ) { /* check for short form */ 2127872Sarnold rnk = EMPTY; 2137872Sarnold for( i = 0; i < RANKS; i++ ) { 2147872Sarnold if( *p == *rankchar[i] ) { 2157872Sarnold rnk = i; 2167872Sarnold break; 2177872Sarnold } 2187872Sarnold } 2197872Sarnold if( rnk == EMPTY ) goto gotit; /* it's nothing... */ 2207872Sarnold ++p; /* advance to next char */ 2217872Sarnold sut = EMPTY; 2227872Sarnold for( i = 0; i < SUITS; i++ ) { 2237872Sarnold if( *p == *suitchar[i] ) { 2247872Sarnold sut = i; 2257872Sarnold break; 2267872Sarnold } 2277872Sarnold } 2287872Sarnold if( sut != EMPTY ) retval = TRUE; 2297872Sarnold goto gotit; 2307872Sarnold } 2317872Sarnold rnk = EMPTY; 2327872Sarnold for( i = 0; i < RANKS; i++ ) { 2337872Sarnold if( !strcmp( p, rankname[i] ) || !strcmp( p, rankchar[i] ) ) { 2347872Sarnold rnk = i; 2357872Sarnold break; 2367872Sarnold } 2377872Sarnold } 2387872Sarnold if( rnk == EMPTY ) goto gotit; 2397872Sarnold p = p1; 2407872Sarnold while( *p1 != ' ' && *p1 != NULL ) ++p1; 2417872Sarnold *p1++ = NULL; 2427872Sarnold if( *p == NULL ) goto gotit; 2437872Sarnold if( !strcmp( "OF", p ) ) { 2447872Sarnold p = p1; 2457872Sarnold while( *p1 != ' ' && *p1 != NULL ) ++p1; 2467872Sarnold *p1++ = NULL; 2477872Sarnold if( *p == NULL ) goto gotit; 2487872Sarnold } 2497872Sarnold sut = EMPTY; 2507872Sarnold for( i = 0; i < SUITS; i++ ) { 2517872Sarnold if( !strcmp( p, suitname[i] ) || !strcmp( p, suitchar[i] ) ) { 2527872Sarnold sut = i; 2537872Sarnold break; 2547872Sarnold } 2557872Sarnold } 2567872Sarnold if( sut != EMPTY ) retval = TRUE; 2577709Sarnold gotit: 2587872Sarnold (*crd).rank = rnk; 2597872Sarnold (*crd).suit = sut; 2607872Sarnold return( retval ); 2617709Sarnold } 2627709Sarnold 2637709Sarnold 2647709Sarnold 2657709Sarnold /* 2667872Sarnold * getuchar: 2677872Sarnold * Reads and converts to upper case 2687709Sarnold */ 2697709Sarnold getuchar() 2707709Sarnold { 2717872Sarnold register int c; 2727709Sarnold 2737872Sarnold c = readchar(); 2747872Sarnold if (islower(c)) 2757872Sarnold c = toupper(c); 2767872Sarnold addch(c); 2777872Sarnold return c; 2787709Sarnold } 2797709Sarnold 2807709Sarnold /* 2817934Sarnold * number: 2827934Sarnold * Reads in a decimal number and makes sure it is between "lo" and 2837934Sarnold * "hi" inclusive. 2847709Sarnold */ 2857934Sarnold number(lo, hi, prompt) 2867934Sarnold int lo, hi; 2877934Sarnold char *prompt; 2887709Sarnold { 2897934Sarnold char *getline(); 2907934Sarnold register char *p; 2917934Sarnold register int sum; 2927709Sarnold 2937872Sarnold sum = 0; 2947934Sarnold for (;;) { 2957934Sarnold msg(prompt); 2967934Sarnold if(!(p = getline()) || *p == NULL) { 2977934Sarnold msg(quiet ? "Not a number" : "That doesn't look like a number"); 2987934Sarnold continue; 2997934Sarnold } 3007872Sarnold sum = 0; 3017934Sarnold 3027934Sarnold if (!isdigit(*p)) 3037872Sarnold sum = lo - 1; 3047934Sarnold else 3057934Sarnold while (isdigit(*p)) { 3067934Sarnold sum = 10 * sum + (*p - '0'); 3077872Sarnold ++p; 3087934Sarnold } 3097934Sarnold 3107934Sarnold if (*p != ' ' && *p != '\t' && *p != NULL) 3117934Sarnold sum = lo - 1; 3127934Sarnold if (sum >= lo && sum <= hi) 3137934Sarnold return sum; 3147934Sarnold if (sum == lo - 1) 3157934Sarnold msg("that doesn't look like a number, try again --> "); 3167934Sarnold else 3177934Sarnold msg("%d is not between %d and %d inclusive, try again --> ", 3187934Sarnold sum, lo, hi); 3197934Sarnold } 3207709Sarnold } 3217709Sarnold 3227872Sarnold /* 3237872Sarnold * msg: 3247872Sarnold * Display a message at the top of the screen. 3257872Sarnold */ 3267872Sarnold char Msgbuf[BUFSIZ] = ""; 3277709Sarnold 3287872Sarnold int Mpos = 0; 3297709Sarnold 3307872Sarnold static int Newpos = 0; 3317872Sarnold 3327872Sarnold /* VARARGS1 */ 3337872Sarnold msg(fmt, args) 3347872Sarnold char *fmt; 3357872Sarnold int args; 3367872Sarnold { 3377872Sarnold /* 3387872Sarnold * if the string is "", just clear the line 3397872Sarnold */ 3407872Sarnold if (*fmt == '\0') { 3417872Sarnold move(LINES - 1, 0); 3427872Sarnold clrtoeol(); 3437872Sarnold Mpos = 0; 3447872Sarnold Hasread = TRUE; 3457872Sarnold return; 3467872Sarnold } 3477872Sarnold /* 3487872Sarnold * otherwise add to the message and flush it out 3497872Sarnold */ 3507872Sarnold doadd(fmt, &args); 3517872Sarnold endmsg(); 3527872Sarnold } 3537872Sarnold 3547709Sarnold /* 3557872Sarnold * addmsg: 3567872Sarnold * Add things to the current message 3577709Sarnold */ 3587872Sarnold /* VARARGS1 */ 3597872Sarnold addmsg(fmt, args) 3607872Sarnold char *fmt; 3617872Sarnold int args; 3627872Sarnold { 3637872Sarnold doadd(fmt, &args); 3647872Sarnold } 3657709Sarnold 3667872Sarnold /* 3677872Sarnold * endmsg: 3687872Sarnold * Display a new msg (giving him a chance to see the previous one 3697872Sarnold * if it is up there with the --More--) 3707872Sarnold */ 3717872Sarnold endmsg() 3727709Sarnold { 3737872Sarnold if (!Hasread) { 3747872Sarnold move(LINES - 1, Mpos); 3757872Sarnold addstr("--More--"); 3767872Sarnold refresh(); 3777872Sarnold wait_for(' '); 3787872Sarnold } 3797872Sarnold /* 3807872Sarnold * All messages should start with uppercase, except ones that 3817872Sarnold * start with a pack addressing character 3827872Sarnold */ 3837872Sarnold if (islower(Msgbuf[0]) && Msgbuf[1] != ')') 3847872Sarnold Msgbuf[0] = toupper(Msgbuf[0]); 3857872Sarnold mvaddstr(LINES - 1, 0, Msgbuf); 3867872Sarnold clrtoeol(); 3877872Sarnold Mpos = Newpos; 3887872Sarnold Newpos = 0; 3897872Sarnold refresh(); 3907872Sarnold Hasread = FALSE; 3917872Sarnold } 3927709Sarnold 3937872Sarnold /* 3947872Sarnold * doadd: 3957872Sarnold * Perform an add onto the message buffer 3967872Sarnold */ 3977872Sarnold doadd(fmt, args) 3987872Sarnold char *fmt; 3997872Sarnold int *args; 4007872Sarnold { 4017872Sarnold static FILE junk; 4027872Sarnold 4037872Sarnold /* 4047872Sarnold * Do the printf into Msgbuf 4057872Sarnold */ 4067872Sarnold junk._flag = _IOWRT + _IOSTRG; 4077872Sarnold junk._ptr = &Msgbuf[Newpos]; 4087872Sarnold junk._cnt = 32767; 4097872Sarnold _doprnt(fmt, args, &junk); 4107872Sarnold putc('\0', &junk); 4117872Sarnold Newpos = strlen(Msgbuf); 4127709Sarnold } 4137709Sarnold 4147872Sarnold /* 4157872Sarnold * wait_for 4167872Sarnold * Sit around until the guy types the right key 4177872Sarnold */ 4187872Sarnold wait_for(ch) 4197872Sarnold register char ch; 4207872Sarnold { 4217872Sarnold register char c; 4227709Sarnold 4237872Sarnold if (ch == '\n') 4247872Sarnold while ((c = readchar()) != '\n') 4257872Sarnold continue; 4267872Sarnold else 4277872Sarnold while (readchar() != ch) 4287872Sarnold continue; 4297872Sarnold } 4307709Sarnold 4317872Sarnold /* 4327872Sarnold * readchar: 4337872Sarnold * Reads and returns a character, checking for gross input errors 4347872Sarnold */ 4357872Sarnold readchar() 4367872Sarnold { 4377872Sarnold register int cnt, y, x; 4387872Sarnold auto char c; 4397709Sarnold 4407872Sarnold over: 4417872Sarnold cnt = 0; 4427872Sarnold while (read(0, &c, 1) <= 0) 4437872Sarnold if (cnt++ > 100) /* if we are getting infinite EOFs */ 4447872Sarnold bye(); /* quit the game */ 4457872Sarnold if (c == CTRL(L)) { 4467872Sarnold wrefresh(curscr); 4477872Sarnold goto over; 4487872Sarnold } 4497872Sarnold Hasread = TRUE; 4507872Sarnold if (c == '\r') 4517872Sarnold return '\n'; 4527872Sarnold else 4537872Sarnold return c; 4547872Sarnold } 4557872Sarnold 4567872Sarnold /* 4577872Sarnold * getline: 4587872Sarnold * Reads the next line up to '\n' or EOF. Multiple spaces are 4597872Sarnold * compressed to one space; a space is inserted before a ',' 4607872Sarnold */ 4617872Sarnold char * 4627872Sarnold getline() 4637872Sarnold { 4647872Sarnold register char *sp; 4657872Sarnold register int c, oy, ox; 4667872Sarnold 4677872Sarnold getyx(stdscr, oy, ox); 4687872Sarnold refresh(); 4697872Sarnold /* 4707872Sarnold * loop reading in the string, and put it in a temporary buffer 4717872Sarnold */ 4727872Sarnold for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) { 4737872Sarnold if (c == -1) 4747872Sarnold continue; 4757872Sarnold else if (c == erasechar()) { /* process erase character */ 4767872Sarnold if (sp > linebuf) { 4777872Sarnold register int i; 4787872Sarnold 4797872Sarnold sp--; 4807872Sarnold for (i = strlen(unctrl(*sp)); i; i--) 4817872Sarnold addch('\b'); 4827872Sarnold } 4837872Sarnold continue; 4847872Sarnold } 4857872Sarnold else if (c == killchar()) { /* process kill character */ 4867872Sarnold sp = linebuf; 4877872Sarnold move(oy, ox); 4887872Sarnold continue; 4897872Sarnold } 4907872Sarnold else if (sp == linebuf && c == ' ') 4917872Sarnold continue; 4927872Sarnold if (sp >= &linebuf[LINESIZE-1] || !(isprint(c) || c == ' ')) 4937872Sarnold putchar(CTRL(G)); 4947872Sarnold else { 4957872Sarnold if (islower(c)) 4967872Sarnold c = toupper(c); 4977872Sarnold *sp++ = c; 4987872Sarnold addstr(unctrl(c)); 4997872Sarnold /*###366 [cc] Mpos undefined %%%*/ 5007872Sarnold Mpos++; 5017872Sarnold } 5027872Sarnold } 5037872Sarnold *sp = '\0'; 5047872Sarnold return linebuf; 5057872Sarnold } 506