home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v13i020: okbridge - computer-mediated bridge game, Part05/07
- Message-ID: <2279@masterCNA.TEK.COM>
- Date: 10 Jan 92 16:45:02 GMT
- Article-I.D.: masterCN.2279
- Sender: news@masterCNA.TEK.COM
- Lines: 1870
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: mclegg@cs.UCSD.EDU (Matthew Clegg)
- Posting-number: Volume 13, Issue 20
- Archive-name: okbridge/Part05
- Environment: BSD-derived Unix, curses, sockets
-
-
-
- #! /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 5 (of 7)."
- # Contents: display.c email.c okbridge.help ps.c
- # Wrapped by billr@saab on Fri Jan 10 08:31:29 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'display.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'display.c'\"
- else
- echo shar: Extracting \"'display.c'\" \(17419 characters\)
- sed "s/^X//" >'display.c' <<'END_OF_FILE'
- X/* display.c -- Display functions for netbridge program.
- X !
- X ! Copyright (C) 1990,1991 by Matthew Clegg
- X !
- X ! This program may be copied and distributed freely. Please do not
- X ! charge money for this program or for any program derived from it.
- X ! If you modify this program, then include a notice stating plainly
- X ! that your program is derived from the okbridge program and is not
- X ! the same as the official okbridge program.
- X !
- X ! I welcome any suggestions for improvement to okbridge, and
- X ! I would be especially happy to receive improved source code.
- X ! If you have comments or suggestions, or if you would like to
- X ! join the okbridge mailing list, then write to
- X !
- X ! mclegg@cs.ucsd.edu
- X !
- X*/
- X
- X#include <stdio.h>
- X#include <string.h>
- X
- X#include "globals.h"
- X#include "terminal.h"
- X
- Xtypedef int window[4];
- X
- X/* Conceptually, we think of the screen as being divided into a number
- X of windows, where each window describes one particular type of activity
- X or aspect of the game. Therefore, we make the following definitions,
- X although these are only guidelines for operation of the display.
- X
- XName of
- XWindow Ymin Xmin Height Width
- X------- ---- ---- ---- ---- */
- Xwindow title = { 1, 1, 6, 25};
- Xwindow top_hand = { 2, 30, 4, 26};
- Xwindow scores = { 1, 59, 6, 26};
- Xwindow left_hand = { 8, 6, 6, 18};
- Xwindow playing_board = { 5, 27, 9, 26};
- Xwindow bidding_board = { 5, 1, 9, 58};
- Xwindow right_hand = { 8, 56, 6, 23};
- Xwindow input = { 13, 1, 6, 26};
- Xwindow status = { 18, 1, 1, 78};
- Xwindow bottom_hand = { 13, 30, 4, 26};
- Xwindow help = { 13, 53, 6, 26};
- Xwindow converse = { 19, 1, 6, 78};
- X
- X#define XMIN(w) w[1]
- X#define YMIN(w) w[0]
- X#define XMAX(w) (w[1] + w[3] - 1)
- X#define YMAX(w) (w[0] + w[2] - 1)
- X#define HEIGHT(w) w[2]
- X#define WIDTH(w) w[3]
- X
- Xstatic int PLAYERHAND_X [4];
- Xstatic int PLAYERHAND_Y [4];
- Xstatic int CARDPOS_X [4];
- Xstatic int CARDPOS_Y [4];
- Xstatic char *position_names [4];
- Xstatic int comments_suspended = 0;
- X
- Xstatic char line_buf [81];
- Xstatic char status_message_buf[81];
- X
- Xstatic underline (ymin, xmin, length)
- X int ymin, xmin, length;
- X/* Prints a line of hyphens BELOW the field beginning at (ymin,xmin),
- X * of given length.
- X */
- X{
- X int i;
- X
- X for (i = 0; i < length; i++)
- X line_buf[i] = '-';
- X line_buf[length] = '\0';
- X print (ymin+1, xmin, line_buf);
- X};
- X
- Xstatic clear_screen_area (ymin, xmin, height, width)
- X int ymin, xmin, height, width;
- X{
- X int i;
- X
- X for (i = 0; i < width; i++) line_buf[i] = ' ';
- X line_buf[width] = '\0';
- X for (i = 0; i < height; i++) print (ymin+i, xmin, line_buf);
- X};
- X
- XReset_Display ()
- X/* Redraws the main features of the screen. Used in the process
- X * of doing a 'refresh'.
- X */
- X{
- X int i;
- X char program_name[20];
- X
- X sprintf (program_name, "OKBRIDGE %s%s", major_revision_level,
- X minor_revision_level);
- X clear_screen ();
- X
- X /* Display the title of the program: */
- X print (YMIN(title), XMIN(title), program_name);
- X/* print (YMIN(title)+1, XMIN(title), "MTC JUNE 90"); */
- X
- X /* Setup the scoreboard: */
- X if (side_of(local_player) == SIDE_NS) {
- X print (YMIN(scores), XMIN(scores) + 8, " WE");
- X print (YMIN(scores), XMIN(scores) + 16, " THEY");
- X } else {
- X print (YMIN(scores), XMIN(scores) + 16, " WE");
- X print (YMIN(scores), XMIN(scores) + 8, " THEY");
- X };
- X underline (YMIN(scores), XMIN(scores) + 8, 5);
- X underline (YMIN(scores), XMIN(scores) + 16, 5);
- X print (YMIN(scores)+2, XMIN(scores), "TRICKS");
- X print (YMIN(scores)+3, XMIN(scores), "VUL");
- X
- X switch (scoring_mode) {
- X case RUBBER_SCORING:
- X print (YMIN(scores)+4, XMIN(scores), "ABOVE");
- X print (YMIN(scores)+5, XMIN(scores), "BELOW");
- X print (YMIN(title)+1, XMIN(title), "HAND");
- X break;
- X case CHICAGO_SCORING:
- X print (YMIN(scores)+4, XMIN(scores), "TOTAL");
- X print (YMIN(scores)+5, XMIN(scores), "PART");
- X print (YMIN(title)+1, XMIN(title), "HAND");
- X break;
- X case DUPLICATE_SCORING:
- X case EMAIL_SCORING:
- X print (YMIN(scores)+4, XMIN(scores), "TOTAL");
- X print (YMIN(scores)+5, XMIN(scores), "PREV");
- X print (YMIN(title)+1, XMIN(title), "BOARD");
- X break;
- X case IMP_SCORING:
- X print (YMIN(scores)+4, XMIN(scores), "TOTAL");
- X print (YMIN(scores)+5, XMIN(scores), "IMP");
- X print (YMIN(title)+1, XMIN(title), "BOARD");
- X break;
- X };
- X sprintf (program_name, "%d", current_deal_no);
- X print (YMIN(title)+1, XMIN(title)+6, program_name);
- X
- X /* Setup the input area: */
- X print (TALK_ROW, TALK_COL, "TALK");
- X
- X
- X /* Setup the conversational area: */
- X for (i = 0; i <= XMAX(converse); i++) line_buf[i] = '-';
- X line_buf[XMAX(converse)+1] = '\0';
- X print (YMIN(converse), XMIN(converse), line_buf);
- X for (i = YMIN(converse)+1; i <= YMAX(converse); i++) {
- X print (i, XMIN(converse), "|");
- X print (i, XMAX(converse)+1, "|");
- X };
- X};
- X
- XInitialize_Display ()
- X/* Should be called once when the program starts up. */
- X{
- X/* Initialize_Terminal (); */
- X Reset_Display ();
- X
- X PLAYERHAND_X [local_player] = XMIN(bottom_hand);
- X PLAYERHAND_Y [local_player] = YMIN(bottom_hand);
- X PLAYERHAND_X [player_next[local_player]] = XMIN(left_hand);
- X PLAYERHAND_Y [player_next[local_player]] = YMIN(left_hand);
- X PLAYERHAND_X [player_partner[local_player]] = XMIN(top_hand);
- X PLAYERHAND_Y [player_partner[local_player]] = YMIN(top_hand);
- X PLAYERHAND_X [player_prev[local_player]] = XMIN(right_hand);
- X PLAYERHAND_Y [player_prev[local_player]] = YMIN(right_hand);
- X
- X CARDPOS_Y[local_player] = YMAX(playing_board) - 2;
- X CARDPOS_X[local_player] = (XMAX(playing_board) +
- X XMIN(playing_board))/2;
- X CARDPOS_Y[player_next[local_player]] = (YMAX(playing_board) +
- X YMIN(playing_board))/2;
- X CARDPOS_X[player_next[local_player]] = XMIN(playing_board) + 3;
- X CARDPOS_Y[player_partner[local_player]] = YMIN(playing_board) + 2;
- X CARDPOS_X[player_partner[local_player]] = (XMAX(playing_board) +
- X XMIN(playing_board))/2;
- X CARDPOS_Y[player_prev[local_player]] = (YMAX(playing_board) +
- X YMIN(playing_board))/2;
- X CARDPOS_X[player_prev[local_player]] = XMAX(playing_board) - 4;
- X
- X position_names[0] = player_names [local_player];
- X position_names[1] = player_names [player_next[local_player]];
- X position_names[2] = player_names [player_partner[local_player]];
- X position_names[3] = player_names [player_prev[local_player]];
- X
- X status_message_buf[0] = '\0';
- X
- X};
- X
- XRefresh_Display ()
- X/* Resets the terminal display and redraws everything. */
- X{
- X int i, j, p;
- X
- X Reset_Display ();
- X Display_Tricks_Taken ();
- X Display_Above_Line_Points ();
- X Display_Below_Line_Points ();
- X Display_Vulnerabilities ();
- X Refresh_Player_Comments ();
- X if (game_mode == STARTUP_MODE) {
- X ;
- X } else if (game_mode == BIDDING_MODE) {
- X Display_Bidding_Board ();
- X Display_Hand_for_Bidding (local_player);
- X p = dealer;
- X for (i = 0; i < no_bids; i++) {
- X Display_Bid (i/4 + 1, p);
- X p = player_next [p];
- X };
- X Display_Bidder (p);
- X print (PLAY_ROW, PLAY_COL, "BID ");
- X } else if (game_mode == PLAYING_MODE) {
- X Display_Contract ();
- X Display_Playing_Board ();
- X Display_Hand (local_player);
- X if ((trick > 1) || (no_plays > 0))
- X Display_Hand (dummy);
- X if (local_player == dummy)
- X Display_Hand (declarer);
- X#ifdef LOOPBACK_MODE
- X Display_Hand (player_next[local_player]); /* DBG */
- X Display_Hand (player_partner[local_player]); /* DBG */
- X Display_Hand (player_prev[local_player]); /* DBG */
- X#endif
- X#ifdef TWOPLAYER_MODE
- X Display_Hand (player_partner[local_player]);
- X#endif
- X
- X p = leader;
- X for (i = 0; i < no_plays; i++) {
- X Display_Play (p, plays[p]);
- X p = player_next[p];
- X };
- X Display_Player (p);
- X print (PLAY_ROW, PLAY_COL, "PLAY");
- X } else if (game_mode == REVIEW_MODE) {
- X Display_Contract ();
- X Display_Playing_Board ();
- X Display_Player (-1);
- X Display_Below_Line_Points ();
- X Display_Above_Line_Points ();
- X for (i = 0; i < 4; i++)
- X Display_Hand (i);
- X/*
- X Display_Status
- X ("REVIEW OF THE HAND -- PRESS RETURN ON A BLANK LINE TO PROCEED");
- X*/
- X };
- X Refresh_Status_Display ();
- X
- X};
- X
- X
- X
- XDisplay_Tricks_Taken ()
- X{
- X sprintf (line_buf,"%5d %5d",tricks[SIDE_NS], tricks[SIDE_EW]);
- X print (YMIN(scores)+2,XMIN(scores)+8, line_buf);
- X};
- X
- XDisplay_Above_Line_Points ()
- X{
- X sprintf (line_buf,"%5d %5d",above_line[SIDE_NS],
- X above_line[SIDE_EW]);
- X print (YMIN(scores)+4,XMIN(scores)+8, line_buf);
- X};
- X
- XDisplay_Below_Line_Points ()
- X{
- X sprintf (line_buf,"%5d %5d",below_line[SIDE_NS],
- X below_line[SIDE_EW]);
- X print (YMIN(scores)+5,XMIN(scores)+8, line_buf);
- X};
- X
- XDisplay_Vulnerabilities ()
- X{
- X char *nsv, *ewv;
- X
- X if (vulnerable[SIDE_NS]) nsv = " YES";
- X else nsv = " NO";
- X if (vulnerable[SIDE_EW]) ewv = " YES";
- X else ewv = " NO";
- X sprintf (line_buf, "%s %s",nsv,ewv);
- X print (YMIN(scores)+3, XMIN(scores)+8, line_buf);
- X};
- X
- XClear_Bidding_Board ()
- X{
- X int x, y, h, w;
- X
- X x = XMIN(bidding_board);
- X y = YMIN(bidding_board);
- X h = HEIGHT(bidding_board);
- X w = WIDTH(bidding_board);
- X clear_screen_area (y, x, h, w);
- X clear_screen_area (PLAY_ROW, 1, 1, 10);
- X
- X};
- X
- XDisplay_Bidding_Board ()
- X/* The bidding display is given as four columns, similar to that found
- X in many bridge books. At the top of each column is printed the
- X corresponding input parameter string to identify the bidder. */
- X{
- X int i;
- X char *first, *second, *third, *fourth, board_no_buf[10];
- X
- X Clear_Bidding_Board ();
- X
- X first = player_names [PLAYER_NORTH];
- X second = player_names [player_next[PLAYER_NORTH]];
- X third = player_names [player_partner[PLAYER_NORTH]];
- X fourth = player_names [player_prev[PLAYER_NORTH]];
- X
- X print(YMIN(bidding_board), XMIN(bidding_board)+05, first);
- X print(YMIN(bidding_board), XMIN(bidding_board)+15, second);
- X print(YMIN(bidding_board), XMIN(bidding_board)+25, third);
- X print(YMIN(bidding_board), XMIN(bidding_board)+35, fourth);
- X
- X underline(YMIN(bidding_board),XMIN(bidding_board)+05,strlen(first));
- X underline(YMIN(bidding_board),XMIN(bidding_board)+15,strlen(second));
- X underline(YMIN(bidding_board),XMIN(bidding_board)+25,strlen(third));
- X underline(YMIN(bidding_board),XMIN(bidding_board)+35,strlen(fourth));
- X
- X sprintf (board_no_buf, "%d", current_deal_no);
- X print (YMIN(title)+1, XMIN(title)+6, board_no_buf);
- X
- X};
- X
- Xstatic Display_suit (y, x, cards)
- X int y, x; suit_type cards;
- X/* Displays the cards in a given suit held by a player. As input,
- X * cards[] is an array of 13 elements, where cards[i] is TRUE if the
- X * player holds the given card. Displays the cards as a string on
- X * the terminal, beginning at coordinates <y,x>.
- X */
- X{
- X int i;
- X
- X for (i = 12; i >= 0; i--)
- X if (cards[i])
- X print (y, x++, rank_names[i]);
- X};
- X
- XDisplay_Hand_for_Bidding (pos)
- Xint pos;
- X{
- X int i, x, y;
- X suit_type h;
- X
- X y = YMIN(bidding_board);
- X x = XMIN(bidding_board) + 45;
- X clear_screen_area (y, x, HEIGHT(bidding_board),
- X XMAX(bidding_board)-x+1);
- X for (i = 0; i < 6; i++)
- X print (y+i, x, "|");
- X
- X x+=1;
- X print (y, x, player_names[pos]);
- X underline (y, x, strlen(player_names[pos]));
- X h = current_hand[pos];
- X print (y+2, x, "S "); Display_suit (y+2, x+2, h+39);
- X print (y+3, x, "H "); Display_suit (y+3, x+2, h+26);
- X print (y+4, x, "D "); Display_suit (y+4, x+2, h+13);
- X print (y+5, x, "C "); Display_suit (y+5, x+2, h);
- X};
- X
- XDisplay_Bidder (player)
- X int player;
- X{
- X char bid_buf[80];
- X
- X sprintf (bid_buf, "%s's BID ", player_names[player]);
- X print (YMIN(title)+2, XMIN(title), bid_buf);
- X};
- X
- XDisplay_Bid (round, player)
- X int round, player;
- X{
- X int x, y, bid, position;
- X char *bid_string;
- X
- X y = YMIN(bidding_board) + round + 1;
- X sprintf (line_buf, " %2d", round);
- X print (y, XMIN(bidding_board), line_buf);
- X
- X/*
- X if (player == dealer) position = 0;
- X else if (player == player_next[dealer]) position = 1;
- X else if (player == player_partner[dealer]) position = 2;
- X else position = 3;
- X*/
- X y++;
- X for (x = dealer; x < 4; x++)
- X if (x == player) y--;
- X
- X position = player;
- X x = XMIN(bidding_board) + 10 * position + 5;
- X bid = bids[player][round-1];
- X if (bid == BID_PASS)
- X bid_string = "--";
- X else
- X bid_string = bid_names[bid];
- X print (y, x, bid_string);
- X};
- X
- XDisplay_Contract ()
- X{
- X char double_buf[40], contract_buf[60];
- X
- X clear_screen_area (YMIN(title)+2, XMIN(title), HEIGHT(title),
- X WIDTH(title));
- X if (redoubled)
- X sprintf (double_buf," REDOUBLED");
- X else if (doubled)
- X sprintf (double_buf, " DOUBLED");
- X else
- X double_buf[0] = '\0';
- X sprintf (contract_buf, "%1d%s (%s)%s",contract,suit_names[trump_suit],
- X player_names[declarer], double_buf);
- X
- X print (YMIN(title)+3, XMIN(title), contract_buf);
- X}
- X
- XClear_Playing_Board ()
- X{
- X clear_screen_area (YMIN(playing_board), XMIN(playing_board),
- X HEIGHT(playing_board), WIDTH(playing_board));
- X clear_screen_area (YMIN(left_hand), XMIN(left_hand),
- X HEIGHT(left_hand), WIDTH(left_hand));
- X clear_screen_area (YMIN(right_hand), XMIN(right_hand),
- X HEIGHT(right_hand), WIDTH(right_hand));
- X clear_screen_area (YMIN(top_hand), XMIN(top_hand),
- X HEIGHT(top_hand), WIDTH(top_hand));
- X clear_screen_area (YMIN(bottom_hand), XMIN(bottom_hand),
- X HEIGHT(bottom_hand), WIDTH(bottom_hand));
- X clear_screen_area (YMIN(title)+3, XMIN(title), 1, WIDTH(title));
- X};
- X
- XDisplay_Playing_Board ()
- X{
- X int i;
- X
- X/* Clear_Playing_Board (); */
- X
- X for (i = 0; i < 4; i++)
- X print (PLAYERHAND_Y[i]+1, PLAYERHAND_X[i]+12 -
- X strlen(player_names[i]), player_names[i]);
- X
- X for (i = 0; i < WIDTH(playing_board)-1; i++) line_buf[i] = '-';
- X line_buf[WIDTH(playing_board)-2] = '\0';
- X print (YMIN(playing_board)+1,XMIN(playing_board)+1,line_buf);
- X print (YMAX(playing_board)-1,XMIN(playing_board)+1,line_buf);
- X
- X for (i = YMIN(playing_board)+2; i < YMAX(playing_board)-1; i++) {
- X print (i, XMIN(playing_board)+1, "|");
- X print (i, XMAX(playing_board)-1, "|");
- X };
- X};
- X
- XDisplay_Player (player)
- X int player;
- X{
- X char play_buf[80];
- X
- X if (player < 0)
- X sprintf (play_buf, " ");
- X else if (player == dummy)
- X sprintf (play_buf, "DUMMY'S PLAY ");
- X else
- X sprintf (play_buf, "%s's PLAY ",
- X player_names[player]);
- X print (YMIN(title)+4, XMIN(title), play_buf);
- X};
- X
- XDisplay_Play (p, card)
- X int p, card;
- X{
- X int x, y, position;
- X
- X y = CARDPOS_Y [p];
- X x = CARDPOS_X [p];
- X if ((0 <= card) && (card < 52))
- X print (y, x, card_names[card]);
- X else
- X print (y, x, " ");
- X};
- X
- XClear_Plays ()
- X{
- X Display_Play (PLAYER_NORTH, -1);
- X Display_Play (PLAYER_EAST, -1);
- X Display_Play (PLAYER_SOUTH, -1);
- X Display_Play (PLAYER_WEST, -1);
- X};
- X
- XDisplay_Hand (p)
- X int p;
- X{
- X int y, x, i;
- X suit_type h;
- X
- X y = PLAYERHAND_Y [p];
- X x = PLAYERHAND_X [p];
- X for (i = 0; i < 4; i++)
- X print (y+i, x, " ");
- X
- X h = current_hand[p];
- X print (y, x+5-strlen(player_names[p]), player_names[p]);
- X if (p == dummy)
- X print (y+1, x+5-7, "(DUMMY)");
- X print (y, x+7, "S "); Display_suit (y, x+10, h+39);
- X print (y+1, x+7, "H "); Display_suit (y+1, x+10, h+26);
- X print (y+2, x+7, "D "); Display_suit (y+2, x+10, h+13);
- X print (y+3, x+7, "C "); Display_suit (y+3, x+10, h);
- X};
- X
- XClear_Hand (p)
- X int p;
- X{
- X int y, x, i;
- X
- X y = PLAYERHAND_Y [p];
- X x = PLAYERHAND_X [p];
- X for (i = 0; i < 4; i++)
- X print (y+i, x, " ");
- X
- X print (y, x+5-strlen(player_names[p]), player_names[p]);
- X if (p == dummy)
- X print (y+1, x+5-7, "(DUMMY)");
- X};
- X
- XDisplay_Status (message)
- X char *message;
- X{
- X Clear_Status_Display ();
- X print (YMIN(status), XMIN(status), message);
- X sprintf (status_message_buf, "%s", message);
- X set_cursor (YMIN(status), XMIN(status) + strlen(message) + 1);
- X};
- X
- XClear_Status_Display ()
- X{
- X clear_screen_area (YMIN(status), XMIN(status), 1, WIDTH(status));
- X status_message_buf [0] = '\0';
- X};
- X
- XRefresh_Status_Display ()
- X{
- X clear_screen_area (YMIN(status), XMIN(status), 1, WIDTH(status));
- X print (YMIN(status), XMIN(status), status_message_buf);
- X set_cursor (YMIN(status),
- X XMIN(status) + strlen(status_message_buf) + 1);
- X};
- X
- X/* The bottom part of the screen is used for the exchange of comments
- X between the players. The following procedures are used for managing
- X this part of the display. */
- X
- X#define COMMENT_LENGTH 78
- X#define COMMENT_BUF_SIZE 5
- X
- Xtypedef char comment_line [COMMENT_LENGTH];
- Xtypedef comment_line comment_buf [COMMENT_BUF_SIZE];
- Xstatic comment_buf player_comments;
- X
- Xstatic blank_out_comment (c)
- X comment_line c;
- X{
- X int i;
- X
- X for (i = 0; i < COMMENT_LENGTH-1; i++) c[i] = ' ';
- X c[COMMENT_LENGTH-1] = '\0';
- X};
- X
- Xstatic copy_string_to_comment (c, s)
- X comment_line c; char *s;
- X{
- X int i;
- X
- X blank_out_comment(c);
- X i = 0;
- X while ((s[i] != '\0') && (i < COMMENT_LENGTH-1)) {
- X c[i] = s[i]; i++; }
- X
- X};
- X
- Xstatic scroll_player_comments ()
- X{
- X int i, j;
- X
- X for (i = 0; i < COMMENT_BUF_SIZE - 1; i++)
- X for (j = 0; j < COMMENT_LENGTH; j++) {
- X player_comments[i][j] =
- X player_comments[i+1][j];
- X };
- X};
- X
- XRefresh_Player_Comments ()
- X{
- X int i, x, y;
- X
- X if (comments_suspended)
- X return;
- X
- X x = XMIN(converse) + 1;
- X y = YMIN(converse) + 1;
- X
- X for (i = 0; i < COMMENT_BUF_SIZE; i++)
- X print (y+i, x, player_comments[i]);
- X};
- X
- XInitialize_Player_Comments ()
- X{
- X int i;
- X
- X for (i = 0; i < COMMENT_BUF_SIZE; i++)
- X blank_out_comment (player_comments[i]);
- X Refresh_Player_Comments ();
- X};
- X
- XDisplay_Player_Comment (player_name, comment)
- X char *player_name, *comment;
- X{
- X char message_buf [80];
- X
- X sprintf (message_buf, "%s: %s", player_name, comment);
- X scroll_player_comments ();
- X copy_string_to_comment (player_comments[COMMENT_BUF_SIZE-1],
- X message_buf);
- X Refresh_Player_Comments ();
- X};
- X
- X
- Xvoid Suspend_Comment_Display ()
- X{
- X comments_suspended = 1;
- X};
- X
- Xvoid Continue_Comment_Display ()
- X{
- X comments_suspended = 0;
- X};
- X
- X
- END_OF_FILE
- if test 17419 -ne `wc -c <'display.c'`; then
- echo shar: \"'display.c'\" unpacked with wrong size!
- fi
- # end of 'display.c'
- fi
- if test -f 'email.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'email.c'\"
- else
- echo shar: Extracting \"'email.c'\" \(18931 characters\)
- sed "s/^X//" >'email.c' <<'END_OF_FILE'
- X/* email.c
- X !
- X ! Copyright (C) 1990,1991 by Matthew Clegg
- X !
- X ! This program may be copied and distributed freely. Please do not
- X ! charge money for this program or for any program derived from it.
- X ! If you modify this program, then include a notice stating plainly
- X ! that your program is derived from the okbridge program and is not
- X ! the same as the official okbridge program.
- X !
- X ! I welcome any suggestions for improvement to okbridge, and
- X ! I would be especially happy to receive improved source code.
- X ! If you have comments or suggestions, or if you would like to
- X ! join the okbridge mailing list, then write to
- X !
- X ! mclegg@cs.ucsd.edu
- X !
- X *
- X * Implementation of procedures for reading and writing email
- X * duplicate files.
- X *
- X */
- X
- X#include <stdio.h>
- X#include <string.h>
- X
- Xextern char *malloc ();
- X
- X#ifdef HPUX
- X#define index(X,Y) strchr(X,Y)
- X#else
- X#ifndef index
- Xextern char *index ();
- X#endif
- X#endif
- X
- X#include "globals.h"
- X#include "code.h"
- X#include "email.h"
- X
- Xextern char *strdup ();
- X
- Xchar *email_error_message = NULL;
- X
- Xstatic char *okbridge_check_string = NULL;
- Xstatic char *Unexpected_EOF_message = "Unexpected end of file";
- X
- Xstatic char *Position_Names [] = {"NORTH", "EAST", "SOUTH", "WEST"};
- Xstatic char *Full_Suit_Names [] = {"CLUBS", "DIAMONDS", "HEARTS", "SPADES"};
- X
- X
- X#ifdef NO_STRCASECMP
- Xint strcasecmp (s1, s2)
- X char *s1, *s2;
- X{
- X char c1, c2;
- X
- X c1 = *(s1++); c2 = *(s2++);
- X while (c1 && c2) {
- X if (('a' <= c1) && (c1 <= 'z')) c1 = c1 - 'a' + 'A';
- X if (('a' <= c2) && (c2 <= 'z')) c2 = c2 - 'a' + 'A';
- X if (c1 < c2)
- X return (-1);
- X else if (c2 < c1)
- X return (1);
- X c1 = *(s1++); c2 = *(s2++);
- X };
- X if ((c1 == 0) && (c2 == 0))
- X return (0);
- X else if (c1 == 0)
- X return (-1);
- X else
- X return (1);
- X
- X};
- X
- Xint strncasecmp (s1, s2, count)
- X char *s1, *s2; int count;
- X{
- X int i, c1, c2;
- X
- X for (i = 0; i < count; i++) {
- X c1 = *(s1++); c2 = *(s2++);
- X if ((c1 == 0) && (c2 == 0))
- X return (0);
- X else if (c1 == 0)
- X return (-1);
- X else if (c2 == 0)
- X return (1);
- X if (('a' <= c1) && (c1 <= 'z')) c1 = c1 - 'a' + 'A';
- X if (('a' <= c2) && (c2 <= 'z')) c2 = c2 - 'a' + 'A';
- X if (c1 < c2)
- X return (-1);
- X else if (c2 < c1)
- X return (1);
- X };
- X return (0);
- X};
- X#endif
- X
- Xstatic void Initialize_Check_String ()
- X{
- X char check_buf [100];
- X
- X if (okbridge_check_string != NULL) return;
- X
- X sprintf (check_buf, "%s %s",
- X "This is an email duplicate file for Okbridge version",
- X major_revision_level);
- X okbridge_check_string = strdup (check_buf);
- X
- X};
- X
- Xstatic int Read_Email_Line (cfile, buffer, buflen)
- X Encoded_File *cfile; char *buffer; int buflen;
- X{
- X int log;
- X
- X do {
- X log = Read_Encoded_Line (cfile, buffer, buflen);
- X if (log < 0) return (log);
- X while ((log > 0) && (buffer[log-1] == ' '))
- X buffer[--log] = '\0';
- X } while ((log == 0) || (buffer[0] == '#'));
- X return (log);
- X};
- X
- Xstatic void fill_buffer (buf, fill_to, fill_char)
- X char *buf; int fill_to; char fill_char;
- X{
- X int i;
- X
- X for (i = strlen(buf); i < fill_to; i++)
- X buf[i] = fill_char;
- X buf[fill_to] = '\0';
- X};
- X
- Xstatic void unfill_buffer (buf, fill_char)
- X char *buf; char fill_char;
- X{
- X int n = strlen(buf);
- X
- X while ((n > 0) && (buf[n-1] == fill_char))
- X buf[--n] = '\0';
- X};
- X
- Xint Read_Email_Duplicate_File (filename, email_struct)
- X char *filename; struct Email_Duplicate_struct **email_struct;
- X/* Reads an email duplicate file. If successful, then allocates a
- X structure to represent the file and returns a pointer to that
- X structure in email_struct. Returns 0 in this case. If an error
- X occurred opening the file, then returns -1 with the system error
- X code in errno. If an error is detected in the format of the file,
- X then returns 1.
- X*/
- X#define EREAD(cfile,buf,buflen) if (Read_Email_Line(cfile,buf,buflen) == -1) return (1);
- X/* #define FORMAT_ERROR(s) do{email_error_message=strdup(s); return (1);}while(0) */
- X#define FORMAT_ERROR(s) {email_error_message=strdup(s); return (1);}
- X{
- X int error_code, i, j, pair_no, n;
- X float ns_mp, ew_mp;
- X char line_buffer[100], ne_name[20], sw_name[20], bid_buf[20],
- X contractor_buf[20], dealer_buf[20], vuln_buf[20];
- X struct Email_Duplicate_struct *e;
- X Encoded_File *ef;
- X Email_Board *bhead, *btail;
- X Email_Score *shead, *stail;
- X Email_Comment *chead, *ctail;
- X char *player_string = "NESW";
- X char *d;
- X
- X email_error_message = Unexpected_EOF_message;
- X
- X Initialize_Check_String ();
- X error_code = Reset_Encoded_File (filename, okbridge_check_string, &ef);
- X if (error_code < 0)
- X return (error_code);
- X else if (error_code > 0)
- X FORMAT_ERROR ("Could not find Okbridge check string");
- X
- X e = (struct Email_Duplicate_struct *)
- X malloc (sizeof (struct Email_Duplicate_struct));
- X
- X EREAD(ef, line_buffer, 100);
- X sscanf (line_buffer, "%d %d", &e->nboards, &e->npairs);
- X
- X e->player_list = (Email_Pair *)
- X malloc (sizeof(Email_Pair) * (e->npairs + 1));
- X
- X for (i = 0; i < e->npairs; i++) {
- X EREAD(ef, line_buffer, 100);
- X sscanf (line_buffer, "%d %s %s", &pair_no, ne_name, sw_name);
- X if (pair_no == 0)
- X FORMAT_ERROR ("Error in list of player pairs");
- X e->player_list[pair_no].ne = strdup(ne_name);
- X e->player_list[pair_no].sw = strdup(sw_name);
- X e->player_list[pair_no].match_points = 0;
- X };
- X
- X bhead = btail = (Email_Board *) malloc (sizeof(Email_Board));
- X shead = (Email_Score *) malloc (sizeof(Email_Score));
- X chead = (Email_Comment *) malloc(sizeof(Email_Comment));
- X for (i = 0; i < e->nboards; i++) {
- X EREAD (ef, line_buffer, 100);
- X btail->next = (Email_Board *) malloc(sizeof(Email_Board));
- X btail = btail->next;
- X ctail = chead;
- X while (line_buffer[0] == '*') {
- X ctail->next = (Email_Comment *)
- X malloc(sizeof(Email_Comment));
- X ctail = ctail->next;
- X ctail->comment = strdup (line_buffer+1);
- X EREAD (ef, line_buffer, 100);
- X };
- X ctail->next = NULL;
- X btail->pre_script = chead->next;
- X
- X btail->ns_vulnerable = btail->ew_vulnerable = 0;
- X sscanf (line_buffer, "%s %s", dealer_buf, vuln_buf);
- X
- X if (!strcasecmp(dealer_buf, "NORTH"))
- X btail->dealer = PLAYER_NORTH;
- X else if (!strcasecmp(dealer_buf, "EAST"))
- X btail->dealer = PLAYER_EAST;
- X else if (!strcasecmp(dealer_buf, "SOUTH"))
- X btail->dealer = PLAYER_SOUTH;
- X else if (!strcasecmp(dealer_buf, "WEST"))
- X btail->dealer = PLAYER_WEST;
- X else
- X FORMAT_ERROR ("Error in dealer");
- X
- X if (!strcasecmp(vuln_buf, "BOTH"))
- X btail->ns_vulnerable = btail->ew_vulnerable = 1;
- X else if (!strcasecmp(vuln_buf, "NS"))
- X btail->ns_vulnerable = 1;
- X else if (!strcasecmp(vuln_buf, "EW"))
- X btail->ew_vulnerable = 1;
- X else if (strcasecmp(vuln_buf, "NONE"))
- X FORMAT_ERROR ("Error in vulnerabilities");
- X
- X EREAD (ef, line_buffer, 100);
- X for (j = 0; j < 52; j++) {
- X d = index (player_string, line_buffer[j]);
- X if (d == 0)
- X FORMAT_ERROR ("Error in deal.");
- X btail->deal[j] = d - player_string;
- X };
- X stail = shead;
- X EREAD (ef, line_buffer, 100);
- X ctail = chead;
- X while (line_buffer[0] == '*') {
- X ctail->next = (Email_Comment *)
- X malloc(sizeof(Email_Comment));
- X ctail = ctail->next;
- X ctail->comment = strdup (line_buffer+1);
- X EREAD (ef, line_buffer, 100);
- X };
- X ctail->next = NULL;
- X btail->post_script = chead->next;
- X while (strcmp(line_buffer, "--")) {
- X stail->next = (Email_Score *)
- X malloc(sizeof(Email_Score));
- X stail = stail->next;
- X sscanf (line_buffer,
- X "%d %d %s %s %d %d %f %f",
- X &(stail->ns_pair), &(stail->ew_pair),
- X bid_buf, contractor_buf, &(stail->result),
- X &(stail->ns_score), &ns_mp, &ew_mp);
- X if ((stail->ns_pair == 0) || (stail->ew_pair == 0))
- X FORMAT_ERROR
- X ("Erroneous pair number in score record");
- X unfill_buffer (bid_buf, 'Z');
- X n = strlen (bid_buf);
- X stail->doubled = 0;
- X if (n >= 3) {
- X if (!strcmp(bid_buf+n-2, "-X")) {
- X stail->doubled = BID_DOUBLE;
- X bid_buf[n-2] = '\0';
- X } else if (!strcmp(bid_buf+n-3, "-XX")){
- X stail->doubled = BID_REDOUBLE;
- X bid_buf[n-3] = '\0';
- X };
- X };
- X n = 0;
- X for (n = 0; (bid_names[n] != NULL) &&
- X strcmp(bid_names[n], bid_buf); n++);
- X if (bid_names[n] == NULL)
- X FORMAT_ERROR ("Error in bid in score record");
- X stail->bid = n;
- X if (!strcmp(contractor_buf, "N"))
- X stail->contractor = PLAYER_NORTH;
- X else if (!strcmp(contractor_buf, "E"))
- X stail->contractor = PLAYER_EAST;
- X else if (!strcmp(contractor_buf, "S"))
- X stail->contractor = PLAYER_SOUTH;
- X else if (!strcmp(contractor_buf, "W"))
- X stail->contractor = PLAYER_WEST;
- X else
- X FORMAT_ERROR
- X ("Error in declarer in score record");
- X EREAD (ef, line_buffer, 100);
- X };
- X stail->next = NULL;
- X btail->score_list = shead->next;
- X };
- X e->board_list = bhead->next;
- X btail->next = NULL;
- X Close_Encoded_File (ef);
- X
- X free (bhead);
- X free (shead);
- X free (chead);
- X *email_struct = e;
- X return (0);
- X};
- X
- Xint Write_Email_Duplicate_File (filename, encode_flag, email_struct)
- X char *filename; int encode_flag;
- X struct Email_Duplicate_struct *email_struct;
- X/* Writes an email duplicate file to filename. If encode_flag is true,
- X then encodes critical parts of the file. If no errors, returns 0.
- X Otherwise, returns -1 with the system error code in errno.
- X*/
- X#define UPRINT(e,s) if (Write_Unencoded_Line(e,s)) return (-1);
- X#define EPRINT(e,s) if (encode_flag? Write_Encoded_Line(e,s): Write_Unencoded_Line(e,s)) return (-1);
- X{
- X int error_code, i, j, k, board_number, name_printed, some_name_printed;
- X char line_buffer[100], bid_buf[20], contractor_buf[20], double_buf [20];
- X Encoded_File *ef;
- X struct Email_Duplicate_struct *e;
- X Email_Board *blist;
- X Email_Score *slist;
- X Email_Comment *clist;
- X char *player_string = "NESW";
- X char *dealer_name;
- X
- X Initialize_Check_String ();
- X error_code = Rewrite_Encoded_File (filename, okbridge_check_string,
- X &ef);
- X if (error_code) return (error_code);
- X
- X e = email_struct;
- X sprintf (line_buffer, "%d %d", e->nboards, e->npairs);
- X UPRINT (ef, "# nboards npairs");
- X UPRINT (ef, line_buffer);
- X
- X for (blist = e->board_list; blist != NULL; blist = blist->next)
- X Compute_Board_Match_Points (blist);
- X for (i = 1; i <= e->npairs; i++)
- X e->player_list[i].match_points = 0;
- X for (blist = e->board_list; blist != NULL; blist = blist->next) {
- X for (slist=blist->score_list; slist!=NULL; slist=slist->next) {
- X e->player_list[slist->ns_pair].match_points +=
- X slist->ns_match_points;
- X e->player_list[slist->ew_pair].match_points +=
- X slist->ew_match_points;
- X };
- X };
- X
- X if (e->npairs > 0) {
- X UPRINT (ef, "");
- X sprintf (line_buffer, "# %4s %10s %10s %s",
- X "pair", "north/east", "south/west", "match points");
- X UPRINT (ef, line_buffer);
- X };
- X for (i = 1; i <= e->npairs; i++) {
- X sprintf (line_buffer, " %4d %-10s %-10s %6.1f", i,
- X e->player_list[i].ne, e->player_list[i].sw,
- X 0.5 * ((float) e->player_list[i].match_points));
- X UPRINT (ef, line_buffer);
- X };
- X
- X UPRINT (ef, "");
- X board_number = 1;
- X for (blist = e->board_list; blist != NULL; blist = blist->next) {
- X sprintf (line_buffer, "# board %d", board_number++);
- X UPRINT (ef, line_buffer);
- X for (clist=blist->pre_script; clist!=NULL; clist=clist->next) {
- X sprintf (line_buffer, "* %s", clist->comment);
- X UPRINT (ef, line_buffer);
- X };
- X
- X if (!encode_flag) {
- X for (i = 0; i < 4; i++) {
- X some_name_printed = 0;
- X sprintf (line_buffer, "# %-5s ", Position_Names[i]);
- X for (j = 0; j < 4; j++) {
- X name_printed = 0;
- X for (k = 12; k >= 0; k--) {
- X if (blist->deal[13*j + k] == i) {
- X if (!name_printed) {
- X if (some_name_printed) {
- X sprintf (line_buffer+strlen(line_buffer),
- X ", ");
- X } else
- X some_name_printed = 1;
- X sprintf (line_buffer+strlen(line_buffer),
- X "%s:", Full_Suit_Names[j]);
- X name_printed = 1;
- X };
- X sprintf (line_buffer+strlen(line_buffer),
- X " %s", rank_names[k]);
- X };
- X };
- X };
- X UPRINT (ef, line_buffer);
- X };
- X };
- X
- X UPRINT (ef, "# Dealer Vulnerabilities");
- X dealer_name = Position_Names[blist->dealer];
- X if (blist->ns_vulnerable && blist->ew_vulnerable)
- X sprintf (line_buffer, "%-6s BOTH", dealer_name);
- X else if (blist->ns_vulnerable)
- X sprintf (line_buffer, "%-6s NS", dealer_name);
- X else if (blist->ew_vulnerable)
- X sprintf (line_buffer, "%-6s EW", dealer_name);
- X else
- X sprintf (line_buffer, "%-6s NONE", dealer_name);
- X UPRINT (ef, line_buffer);
- X
- X for (i = 0; i < 52; i++)
- X line_buffer[i] = player_string[blist->deal[i]];
- X line_buffer[52] = '\0';
- X EPRINT (ef, line_buffer);
- X for (clist=blist->post_script;clist!=NULL;clist=clist->next) {
- X sprintf (line_buffer, "* %s", clist->comment);
- X EPRINT (ef, line_buffer);
- X };
- X sprintf (line_buffer,
- X "#%s%3s %3s %-9s %2s %6s %8s %6s %6s",
- X (encode_flag? " ": ""),
- X "ns", "ew", "bid", "by", "result",
- X "score", "ns-mp", "ew-mp");
- X UPRINT (ef, line_buffer);
- X for (slist = blist->score_list; slist != NULL;
- X slist = slist->next) {
- X switch (slist->doubled) {
- X case 0:
- X double_buf[0] = '\0';
- X break;
- X case BID_DOUBLE:
- X sprintf (double_buf, "-X");
- X break;
- X case BID_REDOUBLE:
- X sprintf (double_buf, "-XX");
- X break;
- X };
- X sprintf (bid_buf, "%s%s", bid_names[slist->bid],
- X double_buf);
- X if (encode_flag)
- X fill_buffer (bid_buf, 7, 'Z');
- X switch (slist->contractor) {
- X case PLAYER_NORTH:
- X sprintf (contractor_buf, "N");
- X break;
- X case PLAYER_EAST:
- X sprintf (contractor_buf, "E");
- X break;
- X case PLAYER_SOUTH:
- X sprintf (contractor_buf, "S");
- X break;
- X case PLAYER_WEST:
- X sprintf (contractor_buf, "W");
- X break;
- X };
- X if (encode_flag)
- X sprintf (line_buffer,
- X " %3d %3d %-9s %-2s %06d %08d %6.1f %6.1f",
- X slist->ns_pair, slist->ew_pair,
- X bid_buf, contractor_buf, slist->result,
- X slist->ns_score,
- X 0.5 * ((float) slist->ns_match_points),
- X 0.5 * ((float) slist->ew_match_points));
- X else
- X sprintf (line_buffer,
- X " %3d %3d %-9s %-2s %+6d %8d %6.1f %6.1f",
- X slist->ns_pair, slist->ew_pair,
- X bid_buf, contractor_buf, slist->result,
- X slist->ns_score,
- X 0.5 * ((float) slist->ns_match_points),
- X 0.5 * ((float) slist->ew_match_points));
- X EPRINT (ef, line_buffer);
- X };
- X UPRINT (ef, "--");
- X };
- X
- X Close_Encoded_File (ef);
- X return (0);
- X
- X};
- X
- Xvoid Free_Email_Duplicate_Struct (email_struct)
- X struct Email_Duplicate_struct *email_struct;
- X/* Simply de-allocates email_struct and its substructures. */
- X{
- X Email_Board *blist;
- X Email_Score *slist;
- X Email_Comment *clist;
- X int i;
- X
- X if (email_struct == NULL) return;
- X
- X if (email_struct->player_list != NULL) {
- X for (i = 1; i <= email_struct->npairs; i++) {
- X free (email_struct->player_list[i].ne);
- X free (email_struct->player_list[i].sw);
- X };
- X free (email_struct->player_list);
- X };
- X
- X while (email_struct->board_list != NULL) {
- X blist = email_struct->board_list;
- X while (blist->pre_script != NULL) {
- X clist = blist->pre_script;
- X blist->pre_script = clist->next;
- X free (clist);
- X };
- X while (blist->post_script != NULL) {
- X clist = blist->post_script;
- X blist->post_script = clist->next;
- X free (clist);
- X };
- X while (blist->score_list != NULL) {
- X slist = blist->score_list;
- X blist->score_list = slist->next;
- X free (slist);
- X };
- X email_struct->board_list = blist->next;
- X free (blist);
- X };
- X free (email_struct);
- X
- X};
- X
- Xstruct Email_Duplicate_struct *New_Email_Duplicate_Struct ()
- X/* Allocates an empty email duplicate structure to be used for
- X recording email duplicate hands.
- X*/
- X{
- X struct Email_Duplicate_struct *e;
- X
- X e = (struct Email_Duplicate_struct *)
- X malloc (sizeof(struct Email_Duplicate_struct));
- X e->nboards = e->npairs = 0;
- X e->player_list = (Email_Pair *) malloc(sizeof(Email_Pair));
- X e->board_list = NULL;
- X return (e);
- X};
- X
- Xint Add_Email_Pair (email_struct, ne_name, sw_name)
- X struct Email_Duplicate_struct *email_struct;
- X char *ne_name, *sw_name;
- X/* Appends a new player-pair to the list of players in email_struct.
- X Returns the pair number assigned to them.
- X*/
- X{
- X Email_Pair *p;
- X
- X email_struct->npairs += 1;
- X email_struct->player_list = (Email_Pair *)
- X realloc(email_struct->player_list,
- X sizeof(Email_Pair) * (email_struct->npairs + 1));
- X p = email_struct->player_list + email_struct->npairs;
- X p->ne = strdup (ne_name);
- X p->sw = strdup (sw_name);
- X p->match_points = 0;
- X return (email_struct->npairs);
- X};
- X
- XEmail_Board *Add_Email_Board (email_struct, new_deal)
- X struct Email_Duplicate_struct *email_struct;
- X hand new_deal;
- X/* Appends the given hand to the list of boards in email_struct.
- X Returns a pointer to the newly allocated board.
- X*/
- X{
- X int i;
- X Email_Board *b;
- X
- X if (email_struct->nboards++) {
- X b = email_struct->board_list;
- X while (b->next != NULL) b = b->next;
- X b->next = (Email_Board *) malloc(sizeof(Email_Board));
- X b = b->next;
- X } else
- X b = email_struct->board_list =
- X (Email_Board *) malloc(sizeof(Email_Board));
- X
- X b->score_list = NULL;
- X b->pre_script = b->post_script = NULL;
- X b->next = NULL;
- X for (i = 0; i < 52; i++)
- X b->deal[i] = new_deal[i];
- X return (b);
- X};
- X
- Xvoid Record_Email_Score (email_board,
- X ns_pair, ew_pair, bid, doubled, contractor, result, ns_score)
- X Email_Board *email_board;
- X int ns_pair, ew_pair, bid, contractor, result, ns_score;
- X/* Constructs a new score record containing the information
- X ns_pair, ew_pair, bid, contractor, result and ns_score.
- X Links this into the list of score records associated to email_board.
- X The list is maintained in ascending order according to ns_score.
- X*/
- X{
- X Email_Score *s, *p;
- X
- X s = (Email_Score *) malloc (sizeof(Email_Score));
- X
- X s->ns_pair = ns_pair;
- X s->ew_pair = ew_pair;
- X s->bid = bid;
- X s->doubled = doubled;
- X s->contractor = contractor;
- X s->result = result;
- X s->ns_score = ns_score;
- X s->ns_match_points = 0;
- X s->ew_match_points = 0;
- X
- X if (email_board->score_list == NULL) {
- X email_board->score_list = s;
- X s->next = NULL;
- X } else if (email_board->score_list->ns_score >= s->ns_score) {
- X s->next = email_board->score_list;
- X email_board->score_list = s;
- X } else {
- X p = email_board->score_list;
- X while ((p->next != NULL) && (p->next->ns_score < s->ns_score))
- X p = p->next;
- X s->next = p->next;
- X p->next = s;
- X };
- X};
- X
- Xvoid Compute_Board_Match_Points (email_board)
- X Email_Board *email_board;
- X/* Computes the ns_match_points and ew_match_points fields for each of
- X the records in the score list of email_board. The number recorded
- X is actually twice the number of match points awarded.
- X*/
- X{
- X int rank, ties, top_board;
- X Email_Score *s, *p;
- X
- X rank = 0;
- X s = email_board->score_list;
- X while (s != NULL) {
- X /* Count the number of ties at the current rank. */
- X p = s->next;
- X ties = 0;
- X while ((p != NULL) && (p->ns_score == s->ns_score)) {
- X ties++;
- X p = p->next;
- X };
- X /* Award ns match points for each pair at current rank. */
- X top_board = rank + rank + ties;
- X p = s;
- X while ((p != NULL) && (p->ns_score == s->ns_score)) {
- X p->ns_match_points = top_board;
- X p = p->next;
- X };
- X s = p;
- X rank += 1 + ties;
- X };
- X
- X /* Award ew match points for each pair. */
- X rank = (rank-1)*2;
- X for (s = email_board->score_list; s != NULL; s = s->next)
- X s->ew_match_points = rank - s->ns_match_points;
- X
- X};
- END_OF_FILE
- if test 18931 -ne `wc -c <'email.c'`; then
- echo shar: \"'email.c'\" unpacked with wrong size!
- fi
- # end of 'email.c'
- fi
- if test -f 'okbridge.help' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'okbridge.help'\"
- else
- echo shar: Extracting \"'okbridge.help'\" \(10765 characters\)
- sed "s/^X//" >'okbridge.help' <<'END_OF_FILE'
- X# okbridge.help -- help file for the okbridge program
- X#
- X# Copyright (C) 1990,1991 by Matthew Clegg
- X#
- X# This program may be copied and distributed freely. Please do not
- X# charge money for this program or for any program derived from it.
- X# If you modify this program, then include a notice stating plainly
- X# that your program is derived from the okbridge program and is not
- X# the same as the official okbridge program.
- X#
- X# I welcome any suggestions for improvement to okbridge, and
- X# I would be especially happy to receive improved source code.
- X# If you have comments or suggestions, or if you would like to
- X# join the okbridge mailing list, then write to
- X#
- X# mclegg@cs.ucsd.edu
- X#
- X#
- X# The help information in this file is organized as a series of topics.
- X# The first entry in the file is interpreted to be the main topic,
- X# i.e., it is the entry which is displayed if no particular keyword
- X# is given. Each topic entry has a header line which contains an
- X# identifying keyword and a descriptive phrase. This is followed
- X# by the body of the entry and is terminated by an end-of-entry line.
- X#
- X# The format of an entry is
- X#
- X# <keyword> <phrase>
- X# help text
- X# more help text
- X# ...
- X# last help text
- X# --
- X#
- X# Comment lines such as this one are not printed in the help display.
- X# A page break is given by placing the '^' character on a line by itself.
- X#
- Xmain A general description of the program
- X
- X Welcome to OKBRIDGE, version 1.3
- X
- X
- X This is a computer-moderated bridge program. It allows four
- Xpeople at different locations on the Internet to play bridge together.
- XThe computer shuffles the cards and communicates bids and plays between
- Xthe players.
- X
- X
- X The help system is organized as a series of topics, each
- Xidentified by a keyword. To obtain information on a particular topic,
- Xjust type '/HELP topic'. The information displayed on the screen
- Xreflects the current state of the game and is meant to be
- Xself-explanatory. The input to the program is command-oriented. See
- Xthe topic '/help input' for more information on this subject.
- X
- X
- X Good luck at the bridge table!
- X
- X--
- Xbidding information on how to enter a bid
- X
- X Information about Bidding
- X ----------- ----- -------
- X
- XThe format of a bid is one of the following:
- X
- X <level> <trump>
- X DOUBLE (or X)
- X REDOUBLE (or XX)
- X PASS (or P)
- X
- Xwhere
- X <level> is either 1, 2, 3, 4, 5, 6, or 7
- X
- X <suit> is one of
- X NOTRUMP (or NT or N)
- X SPADES (or SPADE or S)
- X HEARTS (or HEART or H)
- X DIAMONDS (or DIAMOND or D)
- X CLUBS (or CLUB or C)
- Xexamples
- X P, 1C, 1 CLUB, 1N, 1NT, 1 NOTRUMP, 2H, 2 HEARTS, X, DOUBLE, XX
- X--
- Xcommands Commands for controlling the program
- X
- X /BELL [ON|OFF]
- X By default, the okbridge program rings the terminal's bell whenever
- X it requests input from you. However, this can be disabled by
- X typing '/BELL OFF'. The state of the bell can be toggled with ^G.
- X
- X /CLAIM [n]
- X This command 'claims' n additional tricks for the declarer.
- X If n is omitted, then all remaining tricks are claimed.
- X The other players are shown the declarer's hand and are
- X asked whether or not they agree to the declarer's request.
- X If both agree, then the hand is ended early. This command can
- X be used only by the declarer and only when it is declarer's or
- X dummy's turn to play.
- X
- X /DEFAULT [ON | OFF]
- X This command controls whether or not defaults will be provided
- X for bids, plays and questions. This mode can be toggled with ^D.
- X
- X^
- X /HELP [topic]
- X Type '/HELP' alone to obtain general help, or type
- X '/HELP topic' to obtain help about a particular topic.
- X
- X /LOG [filename]
- X Typing '/LOG filename' causes this hand and subsequent hands
- X to be written to the file with name 'filename'. Omitting
- X 'filename' causes the current log file to be closed.
- X
- X /PING
- X Sends an invisible message to each of the other players, which is
- X automatically echoed. Reports the round-trip communication time.
- X
- X /PROMPT [ON|OFF]
- X By default, the dummy is asked to press RETURN after the end
- X of each trick. This allows the dummy to see each trick as
- X it is played. This prompting can be disabled by typing
- X '/PROMPT OFF' (convenient if you need to run to the wc :-)
- X The prompt mode can be toggled with ^P.
- X
- X^
- X /QUIT
- X Terminates the program.
- X
- X /REVIEW
- X Displays the bidding for review. This is intended to be used
- X during the playing mode. This command can be abbreviated with ^B.
- X
- X /TALK message
- X Sends a short message to the other players. This command can be used
- X when the program is waiting for you to enter a bid or a play.
- X Not needed if the word 'TALK' is displayed to the left of the cursor.
- X
- X--
- Xcontrols Special control characters recognized by the program
- XSpecial control characters recognized by the program
- X------- ------- ---------- ---------- -- --- -------
- X
- X ^B When used during the play of a hand, the bidding is displayed
- X for review.
- X
- X ^C Quits the program. (The program requests confirmation first.)
- X
- X ^D Toggles the default input mode. See the /DEFAULT command.
- X
- X ^G Toggles the bell. See the /BELL command.
- X
- X ^P Toggles the prompt. See the /PROMPT command.
- X
- X ^R Refreshes the screen.
- X
- X ^T Returns to talk mode if you have been asked to bid or play.
- X
- X ESC Erases the input which has been typed so far.
- X
- XIn addition, if you press RETURN without typing anything, the program will
- Xsupply a default input, which can then be entered by pressing RETURN again.
- X
- X--
- Xcopyright Copyright notice for the program
- X Copyright Notice
- X --------- ------
- X
- XCopyright (C) 1990,1991 by Matthew Clegg
- X
- XThis program may be copied and distributed freely. Please do not
- Xcharge money for this program or for any program derived from it.
- XIf you modify this program, then include a notice stating plainly
- Xthat your program is derived from the okbridge program and is not
- Xthe same as the official okbridge program.
- X
- XI welcome any suggestions for improvement to okbridge, and I would be
- Xespecially happy to receive improved source code. If you have
- Xcomments or suggestions, or if you would like to join the okbridge
- Xmailing list, then write to
- X
- X mclegg@cs.ucsd.edu
- X
- X--
- Xemail Commands specific to email duplicate bridge
- X /DEAL [nhands]
- X This command can only be used by north when playing Email
- X duplicate bridge. It causes nhands boards to be dealt and
- X played. After they have been played, the results can be
- X /SAVEd and emailed to another foursome for play.
- X
- X /LOAD filename
- X This command can only be used by north when playing Email
- X duplicate bridge. It causes a series of boards to be read
- X from the file "filename".
- X
- X /SAVE filename
- X This command causes the set of boards which have been played
- X so far to be saved to the file with name filename. These
- X boards can then be emailed to another foursome for competitive
- X play. Note that the /SAVE command can be used by any player
- X at any time. However, the previous results of play by other
- X foursomes will only be recorded if /SAVE is used by north.
- X
- X /REPLAY filename
- X First /LOAD's "filename". After the boards have been played,
- X automatically saves them along with the results back to "filename".
- X--
- Xinput General info about entering input
- X
- X How to Enter Input
- X --- -- ----- -----
- X
- XDuring normal operation, the bridge program is always in one of
- Xthree 'input modes'. The input which you type is interpreted according
- Xto the input mode, which is displayed at the beginning of the line
- Xcontaining the cursor. The input modes are
- X
- XMode Interpretation
- X---- --------------
- XBID The program is expecting you to enter your bid.
- XPLAY The program is expecting you to enter the card you wish to play.
- XTALK Any text that you enter will be transmitted to the other players.
- X
- XAs you type your text, you may use the backspace key to erase the last
- Xcharacter. The ESC key will erase all of the text you have typed.
- X
- XThere are number of commands which can be given to the program in any
- Xinput mode. For information on these commands, type '/help commands'.
- X
- XAlso, there are a number of special control-characters which are
- Xrecognized by the program. For information about these, type
- X'/help controls.'
- X
- X--
- Xmaillist Information about the okbridge mailing lists
- X
- X The Okbridge Mailing Lists
- X --- -------- ------- -----
- X
- Xokbridge@cs.ucsd.edu
- X This list is intended for arranging bridge games.
- X
- Xokbridge-pgm@cs.ucsd.edu
- X This list is intended for announcing new bridge playing software and
- X updates to old bridge software and for discussing issues in computer
- X moderated bridge.
- X
- XTo join either list, send a message to the corresponding email address
- Xwhose body contains the single line
- X
- X ADD <list-name>
- X
- Xwhere <list-name> is okbridge or okbridge-pgm, as appropriate.
- X
- X--
- Xnetwork Setting up the network communications
- X
- X Network Information
- X ------- -----------
- X
- XBefore the game can begin, the players must agree that one person will
- Xact as the 'server'. All messages transmitted by the program are then
- Xmediated through this server. When starting the program, the internet
- Xname of the server must be specified on the command line.
- X
- XIf you usually play with the same four people, then you may want to
- Xput the name of the server and your usual position into the .okbridgerc
- Xfile. The .okbridgerc file contains default information which is read
- Xby the program before it starts.
- X
- X
- X--
- Xplaying Information about how to enter a play
- X Information about Playing
- X ----------- ----- -------
- X
- XA card is played by writing
- X <suit> <rank>
- X
- Xwhere
- X <suit> is one of
- X SPADES (or SPADE or S)
- X HEARTS (or HEART or H)
- X DIAMONDS (or DIAMOND or D)
- X CLUBS (or CLUB or C)
- X
- X <rank> is one of
- X 2, 3, ..., 9, TEN (or T), JACK (or J), QUEEN (or Q),
- X KING (or K), ACE (or A)
- X
- XSome examples of cards are
- X CT, C T, C TEN, CLUB T, CLUB TEN, S3, SPADE3, SPADE 3
- X
- XNote that the order <suit> <rank> used in playing is reversed
- Xfrom the order <level> <trumpsuit> used in bidding.
- X--
- Xslam A special message when a slam is made
- X
- X
- X
- X
- X Oh, what a beautiful mornin'!
- X Oh, what a beautiful day!
- X I got a beautiful feelin'
- X Ev'rything's goin' my way.
- X Oh, what a beautiful day.
- X
- X ...
- X
- X
- X words by Oscar Hammerstein II
- X from the musical, _Oklahoma_
- X
- END_OF_FILE
- if test 10765 -ne `wc -c <'okbridge.help'`; then
- echo shar: \"'okbridge.help'\" unpacked with wrong size!
- fi
- # end of 'okbridge.help'
- fi
- if test -f 'ps.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ps.c'\"
- else
- echo shar: Extracting \"'ps.c'\" \(3779 characters\)
- sed "s/^X//" >'ps.c' <<'END_OF_FILE'
- X/* ps.c -- "parse-string" data structure.
- X !
- X ! Copyright (C) 1990,1991 by Matthew Clegg
- X !
- X ! This program may be copied and distributed freely. Please do not
- X ! charge money for this program or for any program derived from it.
- X ! If you modify this program, then include a notice stating plainly
- X ! that your program is derived from the okbridge program and is not
- X ! the same as the official okbridge program.
- X !
- X ! I welcome any suggestions for improvement to okbridge, and
- X ! I would be especially happy to receive improved source code.
- X ! If you have comments or suggestions, or if you would like to
- X ! join the okbridge mailing list, then write to
- X !
- X ! mclegg@cs.ucsd.edu
- X !
- X */
- X
- X#ifdef __TURBOC__
- X#include <alloc.h>
- X#endif
- X
- X/* #include <ctype.h> */
- X#include <stdio.h>
- X#include "ps.h"
- X
- Xparse_string ps_alloc (n)
- X int n;
- X/* Returns a parse_string which can hold up to n bytes of text. */
- X{
- X parse_string ps;
- X
- X ps = (parse_string) malloc (n + PS_OFFSET + 1);
- X ps[PS_SIZE] = n;
- X return (ps);
- X};
- X
- X/* void ps_reset(parse_string ps); */
- X/* Clears a parse_string so that new data can be copied into it. */
- X
- Xps_put (ps, ch)
- Xparse_string ps; char ch;
- X/* void ps_put (parse_string ps, char ch) */
- X/* Adds the character ch to the parse_string ps. */
- X{
- X if (ps[PS_LENGTH] < ps[PS_SIZE])
- X ps[PS_OFFSET + ps[PS_LENGTH]++] = ch;
- X};
- X
- Xps_copy (ps, s)
- Xparse_string ps; char *s;
- X/* void ps_copy (parse_string ps, char *s) */
- X/* Copies the string s to the parse_string ps.
- X * Resets ps before doing the copy.
- X */
- X{
- X ps[PS_POS] = ps[PS_LENGTH] = 0;
- X while ((*s != '\0') && (ps[PS_LENGTH] < ps[PS_SIZE]))
- X ps[PS_OFFSET + ps[PS_LENGTH]++] = *(s++);
- X};
- X
- Xps_read (ps, fp)
- Xparse_string ps; FILE *fp;
- X/* void ps_read (parse_string ps, FILE *fp) */
- X/* Copies the next text line from the file fp to the parse_string ps.
- X * Resets ps before doing the copy.
- X */
- X{
- X char ch;
- X
- X ps[PS_POS] = ps[PS_LENGTH] = 0;
- X ch = getc(fp);
- X while ((ch != '\n') && (ch != EOF)) {
- X if (ps[PS_LENGTH] < ps[PS_SIZE])
- X ps[PS_OFFSET + ps[PS_LENGTH]++] = ch;
- X ch = getc (fp);
- X };
- X};
- X
- X/* char ps_scan (parse_string ps); */
- X/* Returns the current character in the parse_string ps.
- X * Does not advance the pointer in ps.
- X */
- X
- Xint ps_matches (ps, key)
- Xparse_string ps; char *key;
- X/* int ps_matches (parse_string ps, char *key) */
- X/* Returns TRUE if the next sequence of characters in the parse string
- X * matches key. If so, then advances the pointer in the parse string
- X * past key. Otherwise, returns FALSE.
- X */
- X{
- X int i;
- X char *text;
- X
- X ps[PS_OFFSET + ps[PS_LENGTH]] = '\0';
- X text = ps + PS_OFFSET + ps[PS_POS];
- X for (i=0; key[i] != '\0'; i++)
- X if (key[i] != text[i])
- X return (0);
- X ps[PS_POS] += i;
- X return (1);
- X};
- X
- Xint upper (ch)
- Xint ch;
- X{
- X if (('a' <= ch) && (ch <= 'z'))
- X return (ch - 'a' + 'A');
- X else
- X return (ch);
- X};
- X
- Xint ps_matches_ic (ps, key)
- Xparse_string ps; char *key;
- X/* int ps_matches_ic (parse_string ps, char *key) */
- X/* Returns TRUE if the next sequence of characters in the parse string
- X * matches key, after both are converted to upper case. If so, then
- X * advances the pointer in the parse string past key.
- X */
- X{
- X int i;
- X char *text;
- X
- X ps[PS_OFFSET + ps[PS_LENGTH]] = '\0';
- X text = ps + PS_OFFSET + ps[PS_POS];
- X for (i=0; key[i] != '\0'; i++)
- X if (upper(key[i]) != upper(text[i]))
- X return (0);
- X ps[PS_POS] += i;
- X return (1);
- X};
- X
- X/* void ps_next (parse_string ps); */
- X/* Advances the pointer in the parse_string ps to the next character. */
- X
- X/* int ps_size (parse_string ps); */
- X/* Returns the number of characters allocated for text in ps. */
- X
- X/* int ps_length (parse_string ps); */
- X/* Returns the number of characters of text currently used in ps. */
- X
- X/* int ps_pos (parse_string ps); */
- X/* Returns the index of the current character in ps. */
- X
- X
- X
- X
- X
- X
- END_OF_FILE
- if test 3779 -ne `wc -c <'ps.c'`; then
- echo shar: \"'ps.c'\" unpacked with wrong size!
- fi
- # end of 'ps.c'
- fi
- echo shar: End of archive 5 \(of 7\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 7 archives.
- rm -f ark[1-9]isdone
- echo creating input.c from input.c.aa and input.c.ab
- cat input.c.aa input.c.ab >input.c
- rm -f input.c.aa input.c.ab
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-