home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v14i089: okbridge2 - computer-mediated bridge game, Part11/14
- Message-ID: <3528@master.CNA.TEK.COM>
- Date: 7 Sep 92 21:42:50 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1822
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: mclegg@cs.UCSD.EDU (Matthew Clegg)
- Posting-number: Volume 14, Issue 89
- Archive-name: okbridge2/Part11
- Supersedes: okbridge: Volume 13, Issue 16-22
- Environment: BSD-derived Unix, NeXT, 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 11 (of 14)."
- # Contents: boards.h parser.c parser.h rc.c types.h
- # Wrapped by billr@saab on Mon Sep 7 14:33:38 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'boards.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'boards.h'\"
- else
- echo shar: Extracting \"'boards.h'\" \(12795 characters\)
- sed "s/^X//" >'boards.h' <<'END_OF_FILE'
- X/* boards.h -- routines for manipulating boards.
- X *
- X ! Copyright (C) 1990-1992 by Matthew Clegg. All Rights Reserved
- X !
- X ! OKbridge is made available as a free service to the Internet.
- X ! Accordingly, the following restrictions are placed on its use:
- X !
- X ! 1. OKbridge may not be modified in any way without the explicit
- X ! permission of Matthew Clegg.
- X !
- X ! 2. OKbridge may not be used in any way for commercial advantage.
- X ! It may not be placed on for-profit networks or on for-profit
- X ! computer systems. It may not be bundled as part of a package
- X ! or service provided by a for-profit organization.
- X !
- X ! If you have questions about restrictions on the use of OKbridge,
- X ! write to mclegg@cs.ucsd.edu.
- X !
- X ! DISCLAIMER: The user of OKbridge accepts full responsibility for any
- X ! damage which may be caused by OKbridge.
- X *
- X */
- X
- X#ifndef CIPHER_INCLUDED
- X#include "cipher.h"
- X#endif
- X
- X#define BOARDS_INCLUDED
- X
- X/* This module provides routines for manipulating the set of boards.
- X Conceptually, the interface to this module is a local database for
- X accessing and updating boards. However, this module also contains
- X routines for reading and writing boards from files and also
- X routines for transmitting and receiving boards over the network.
- X*/
- X
- X/* The following definitions record the information which we will store
- X for each board and for the play of each board. These structures are
- X meant to be robust enough so that the entire state of the game can
- X be reconstructed from them.
- X*/
- X
- Xtypedef struct Board_struct {
- X /* First, we must provide some information describing where this
- X board came from: */
- X char *source; /* A character string identifying the source
- X of this board -- perhaps a filename or an
- X internet name. */
- X int serial_no; /* The number of the board within the file. */
- X char *startup_comment; /* a comment which will be displayed when the
- X hand is first displayed. */
- X
- X /* The following information describes the board itself: */
- X int dealer; /* the dealer for this hand. */
- X int vulnerable [2]; /* boolean flags for each side. */
- X int scoring_mode; /* the scoring mode used when this hand was
- X generated (and played). */
- X int part_score [2]; /* A part score carried over from a previous
- X hand(s), if relevant. */
- X hand deal; /* the cards. */
- X
- X int mps_computed; /* true if the match point scores have been
- X computed for this board. */
- X int imps_computed; /* true if the imp scores have been computed
- X for this board. */
- X
- X /* Then we need info about the people who have played this board: */
- X struct Play_record_struct *play_records;
- X
- X struct Board_struct *next;
- X} Board, *Board_ptr;
- X
- Xtypedef struct Play_record_struct {
- X /* The following provides the minimal amount of information needed to
- X represent a hand. */
- X char *player_names[4]; /* The names of each of the players. */
- X int table; /* The table number where this board was played,
- X or -1 not played locally. */
- X int no_bids; /* The number of actual bids that were made. */
- X bid_list bids; /* The list of bids. */
- X bid_list alerts; /* For each bid, a nonzero value if the bid was
- X alerted. */
- X int no_plays; /* The number of plays. */
- X deal play_list; /* A list of the cards played, in order.
- X The person who played a card play_list[i]
- X can be found as deal[play_list[i]]. In
- X particular, the leader for the k-th trick
- X is deal[play_list[4*k]]. */
- X int bidding_completed; /* A boolean flag indicating that the bidding
- X was completed. (not strictly necessary) */
- X int hand_completed; /* A boolean flag indicating that the play
- X was completed. */
- X
- X int next_player; /* The index of the next person who should make
- X a bid or play. */
- X int result; /* If the contract was made, the number of
- X tricks-6 taken by the declaring side. OW,
- X the negative of the number of tricks down. */
- X int tricks[2]; /* Number of tricks taken by each side. */
- X int below_line[2]; /* Number of points awarded below-the-line to
- X each side. If our scoring mode is other than
- X RUBBER, then this is the score for the hand. */
- X int above_line[2]; /* Number of points awarded above-the-line to
- X each side. If our scoring mode is other than
- X RUBBER, then this is zero. */
- X
- X /* The following information is additional info. which is implied
- X by the above: */
- X int contract; /* The contract, but without doubling info. */
- X int doubled; /* 0=not doubled, 1=doubled, 2=redoubled. */
- X int declarer;
- X int mimp_points [2]; /* 2 * The number of MIMP points awarded. */
- X float match_points[2]; /* 2 * The number of match points awarded. */
- X float imatch_points[2]; /* The number of int'l match points awarded. */
- X
- X struct Play_record_struct *next;
- X} Play_record, *Play_record_ptr;
- X
- X
- X#ifdef _BOARDS_
- X
- X Board *Played_boards = NULL;
- X /* The list of boards which have already been played. */
- X Board *Played_boards_tail = NULL;
- X /* The last element on the list of played boards. */
- X
- X Board *Unplayed_boards = NULL;
- X /* The list of boards which are yet to be played. */
- X
- X#else
- X
- X extern Board *Played_boards, *Played_boards_tail, *Unplayed_boards;
- X
- X#endif
- X
- X/* The following primitives are for manipulating the boards and play
- X records. */
- X
- XBoard *Allocate_board ();
- X/* Returns a pointer to a newly allocated board. Does not fill in any
- X of the fields. */
- X
- Xvoid Deallocate_board ();
- X/* Deallocates the board b. This includes freeing up strings which are
- X part of the structure and de-allocating the play records associated to
- X this board. */
- X
- XPlay_record *Allocate_play_record ();
- X/* Returns a pointer to a newly allocated play record. Does not fill in any
- X of the fields. */
- X
- Xvoid Deallocate_play_record ();
- X/* Deallocates the play record p. This includes freeing up strings
- X which are part of the structure. */
- X
- Xvoid Erase_board_list ();
- X/* Deallocates all of the boards in the list. */
- X
- Xvoid Append_board ();
- X/* Appends the board b to the list of unplayed boards. */
- X
- Xvoid Append_play_record ();
- X/* Appends the play record p to the list of play records associated to the
- X board b. */
- X
- Xvoid Encode_board ();
- X/* Encodes the board in the string array buf1, buf2. This encoding does not
- X include the play records. */
- X
- XBoard *Decode_board ();
- X/* Decodes the string array buf and returns a corresponding board structure. */
- X
- Xvoid Encode_play_record ();
- X/* Encodes the play_record p into buffers buf1 .. buf3. */
- X
- XPlay_record *Decode_play_record ();
- X/* Decodes the strings buf1 .. buf3, returning a corresponding play record
- X structure. Returns NULL if an error occurs in the decoding. */
- X
- X
- X/* Primitives for accessing email duplicate files: */
- X
- Xint Read_Email_Header ();
- X/* Searches the file f until an email header is found. If the header
- X is found, then returns 0. Otherwise, returns 1. */
- X
- Xvoid Write_Email_Header ();
- X/* Writes an email header to the file f. */
- X
- X
- Xint Read_Email_Board ();
- X/* Reads a board from the file f using the cipher descriptor c.
- X Stores in b a pointer to an allocated board record containing the
- X data which has been read. If successful, returns 0. If the end of
- X file is reached, returns 1. If some other error occurs, returns -1.
- X*/
- X
- Xvoid Write_Email_Board ();
- X/* Writes the board b to the file f using the cipher descriptor c. */
- X
- Xint Load_Email_Duplicate_File ();
- X/* First erases all of the current boards.
- X Then, reads an entire email duplicate file, recording each of the hands
- X read from the file into the current list of unplayed boards.
- X If successful, returns 0. If the header could not be found,
- X returns 1. If some other error occurs, returns -1.
- X*/
- X
- Xint Merge_Email_Duplicate_File ();
- X/* Reads an email duplicate file. For each board found in the file,
- X if the same board occurs among the list of boards, then updates
- X the data associated with that board using the data read from the file.
- X Discards boards which do not match those stored in memory.
- X If successful, returns 0. If the header could not be found, returns 1.
- X If some other error occurs, returns -1.
- X*/
- X
- X
- Xvoid Write_Email_Duplicate_File ();
- X/* Writes the list of played and unplayed boards to the file f. */
- X
- X
- X/* Routines for accessing and updating the current set of email
- X duplicate boards. */
- X
- XBoard *Generate_Random_Match_Board ();
- X/* Generates a random match board for the given scoring mode,
- X and returns a pointer to it. If b is non-null, then uses the
- X dealer and vulnerability information in b to determine who the
- X dealer and vulnerabilities in the generated board. This is
- X done by looking up the dealer and vulnerabilities in a table
- X (defined in types.h) and then picking the cyclically next
- X entry in the table.
- X*/
- X
- XBoard *Generate_Random_Rubber_Board ();
- X/* Generates a random rubber board and returns a pointer to it,
- X based upon the part score and result recorded in the previously
- X played board b and play record p. If b or p is NULL, then
- X generates a board with neither side vulnerable and a 0 part score.
- X*/
- X
- XPlay_record *Search_for_play_record ();
- X/* Searches the list of play records associated with the board b for a
- X record of play by the same players as mentioned in p. If such a
- X record is found, then returns a pointer to it. Otherwise, returns
- X NULL. */
- X
- XPlay_record *Locate_play_record_by_foursome
- X ();
- X/* Searches the list of play records associated with the board b for a record
- X where the names of the players exactly match n, e, s, and w, in order.
- X Returns the play record if found, or NULL if no matching record is found.
- X*/
- X
- X
- Xvoid Clear_All_Boards ();
- X/* Clears the list of played and unplayed boards. */
- X
- Xint Board_is_Available ();
- X/* Returns true if there is a board available in the list of unplayed
- X boards. */
- X
- XBoard *Next_Unplayed_Board ();
- X/* If there is a board on the list of unplayed boards, then unlinks it and
- X returns it. Otherwise, returns NULL. */
- X
- Xvoid Record_Played_Board ();
- X/* Appends the board to the list of played boards. */
- X
- X
- X/* Routines for scoring play records: */
- X
- Xint Highcard_points ();
- X/* Returns the number of highcard points held by the partnership 'side'. */
- X
- Xvoid Compute_Matchpoints ();
- X/* Computes the match point totals for the current board. */
- X
- Xvoid Compute_Intl_Matchpoints ();
- X/* Computes the internation match point totals for the current board. */
- X
- Xvoid Compute_MIMP_points ();
- X/* Computes the number of MIMP points for the play record p, based upon
- X the scoring information found in the play record. In addition,
- X we compute simulated match_point and imp values for the play record
- X which are based upon the number of MIMP's.
- X*/
- X
- Xvoid Compute_contract ();
- X/* Computes the contract for the play record p based upon the bids present
- X in the bidding list. */
- X
- Xint Index_of_Last_Bid ();
- X/* Returns the index in the bid list p of the last bid made by the given
- X player, or -1 if the player has not made any bids.
- X*/
- X
- Xvoid Generate_valid_bids ();
- X/* Determines the valid bids for the player, based on the information
- X contained in the play record p. Assumes the declarer, contract
- X and doubled fields of p have been correctly computed from the bid
- X list.
- X*/
- X
- Xvoid Generate_holdings ();
- X/* Records in the hand h the cards held by the given player, based on the
- X deal contained in the board b and on the past no_plays recorded plays.
- X The holdings of the player are recorded as a boolean string in h, so that
- X h[c] == true iff the player holds the card c.
- X*/
- X
- Xvoid Generate_valid_leads ();
- X/* Records in the hand h the set of cards which the player may lead,
- X based upon the plays which have already been recorded in p.
- X The valid plays are stored as a boolean string in h, so that
- X h[c] == true iff it is legal to play card c.
- X*/
- X
- Xvoid Generate_valid_follows
- X ();
- X/* Records in the hand h the set of cards which the player may play to
- X follow the given lead, based upon the plays which have already been
- X recorded in p.
- X
- X The valid plays are stored as a boolean string in h, so that
- X h[c] == true iff it is legal to play card c.
- X*/
- X
- Xint Next_Player ();
- X/* Returns the index of the next person who should play, or -1 if the
- X hand has been completed. If it is the dummy's play, then the
- X index of the declarer is returned.
- X*/
- X
- Xint Winning_card ();
- X/* Returns the index of the player who played the winning card from
- X * the cards c_l, c_lho, c_p, c_rho, based on the given trump suit
- X * and that c_l was the card lead.
- X */
- END_OF_FILE
- if test 12795 -ne `wc -c <'boards.h'`; then
- echo shar: \"'boards.h'\" unpacked with wrong size!
- fi
- # end of 'boards.h'
- fi
- if test -f 'parser.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'parser.c'\"
- else
- echo shar: Extracting \"'parser.c'\" \(12067 characters\)
- sed "s/^X//" >'parser.c' <<'END_OF_FILE'
- X/* parser.c -- implementaton of generalized parser.
- X *
- X ! Copyright (C) 1990-1992 by Matthew Clegg. All Rights Reserved
- X !
- X ! OKbridge is made available as a free service to the Internet.
- X ! Accordingly, the following restrictions are placed on its use:
- X !
- X ! 1. OKbridge may not be modified in any way without the explicit
- X ! permission of Matthew Clegg.
- X !
- X ! 2. OKbridge may not be used in any way for commercial advantage.
- X ! It may not be placed on for-profit networks or on for-profit
- X ! computer systems. It may not be bundled as part of a package
- X ! or service provided by a for-profit organization.
- X !
- X ! If you have questions about restrictions on the use of OKbridge,
- X ! write to mclegg@cs.ucsd.edu.
- X !
- X ! DISCLAIMER: The user of OKbridge accepts full responsibility for any
- X ! damage which may be caused by OKbridge.
- X *
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X
- X#ifdef GCC
- Xextern int atoi ();
- Xextern printf ();
- X#endif
- X
- X#include "types.h"
- X#define PARSER
- X#include "parser.h"
- X
- X#define MAPUPPER(c) ((('a' <= (c)) && ((c) <= 'z'))? ((c) + 'A' - 'a') : (c))
- X
- Xstatic char *input_buffer;
- X /* The current input buffer being examined. */
- Xstatic int buffer_pos;
- X /* The current position in the parser buffer. */
- Xstatic char keyword_buffer[80];
- X /* A buffer used for holding one keyword. */
- X
- Xstatic char command_word [80];
- Xtypedef char parameter_string_element[80];
- Xstatic int *parameter_list[3];
- Xstatic int parameter_keyword [3];
- Xstatic parameter_string_element parameter_string[3];
- Xstatic hand parameter_hand[3];
- X
- X#define NOW input_buffer[buffer_pos]
- X#define NEXT input_buffer[buffer_pos++]
- X#define ADVANCE buffer_pos++;
- X
- X#define IGNORE_CASE 1
- X#define PRESERVE_CASE 0
- X
- Xvoid Lcopy (from, to, len)
- X char *from, *to; int len;
- X/* Copies at most len-1 characters from from to to. */
- X{
- X int i = 0;
- X
- X len -= 1;
- X for (i = 0; i < len; i++) {
- X to [i] = from[i];
- X if (to[i] == '\0') return;
- X }
- X to[len] = '\0';
- X}
- X
- Xstatic void Skip_whitespace ()
- X/* Skips any whitespace characters in the input_buffer. */
- X{
- X while ((NOW == ' ') || (NOW == '\t')) ADVANCE;
- X}
- X
- Xstatic int Parse_Field (dest_buffer, dest_buflen, uppercase)
- X char *dest_buffer; int uppercase, dest_buflen;
- X/* Reads a field from the current input buffer. A field is a sequence
- X of characters delimited by whitespace. Copies the field to the
- X keyword_buffer. Returns the number of characters in the field,
- X or 0 if the end of the input buffer has been reached. If uppercase
- X is true, then the characters in the field are automatically converted
- X to upper case as they are read.
- X*/
- X{
- X int n = 0;
- X int c;
- X
- X Skip_whitespace ();
- X dest_buflen -= 1;
- X while ((NOW != ' ') && (NOW != '\t') && (NOW != '\0')) {
- X c = NEXT;
- X if (n < dest_buflen)
- X dest_buffer[n++] = uppercase? MAPUPPER(c): c;
- X }
- X
- X dest_buffer[n] = '\0';
- X return (n);
- X}
- X
- Xstatic int Parse_keyword (keyword_list)
- X char *keyword_list;
- X/* Reads a keyword from the input buffer and tries to find it in
- X the keyword_list. If no match can be found, then returns -1.
- X Otherwise, returns the index of the keyword in the list of keywords,
- X with the first keyword having index 0.
- X*/
- X{
- X int l, n, keyword_index;
- X
- X n = Parse_Field (keyword_buffer, 80, IGNORE_CASE);
- X keyword_index = 0;
- X while (*keyword_list) {
- X l = 0;
- X while ((keyword_list[l] != '|') && (keyword_list[l] != '\0')) l++;
- X if ((l == 0) && (n == -1))
- X return (keyword_index);
- X else if ((l == n) && !strncmp(keyword_buffer, keyword_list, n))
- X return (keyword_index);
- X keyword_index++;
- X if (keyword_list[l] != '\0')
- X keyword_list += l+1;
- X else
- X return (-1);
- X }
- X return (-1);
- X}
- X
- Xstatic int Parse_bid ()
- X/* Reads a field from the input buffer and interprets it as a bid.
- X Returns the index of the bid in the bid table. If unsuccessful,
- X returns -1.
- X*/
- X{
- X int n = Parse_Field (keyword_buffer, 80, IGNORE_CASE);
- X int i = 0;
- X
- X if (n == 0) return (-1);
- X
- X if (!strcmp(keyword_buffer, "PASS"))
- X return (BID_PASS);
- X else if (!strcmp(keyword_buffer, "DOUBLE"))
- X return (BID_DOUBLE);
- X else if (!strcmp(keyword_buffer, "REDOUBLE"))
- X return (BID_REDOUBLE);
- X
- X if (keyword_buffer[n-1] == 'N') {
- X keyword_buffer[n++] = 'T';
- X keyword_buffer[n] = '\0';
- X }
- X
- X while (bid_names[i] != NULL) {
- X if (!strcmp(keyword_buffer, bid_names[i]))
- X return (i);
- X else
- X i++;
- X }
- X return (-1);
- X}
- X
- Xstatic int Parse_Card ()
- X/* Reads the next field from the input buffer and interprets it as a
- X card name. Returns the index of the card in the card array,
- X or -1 if no match is found.
- X */
- X{
- X int n = Parse_Field (keyword_buffer, 80, IGNORE_CASE);
- X int i = 0;
- X
- X if (n != 2) return (-1);
- X
- X while (card_names[i] != NULL) {
- X if (!strcmp(keyword_buffer, card_names[i]))
- X return (i);
- X else
- X i++;
- X }
- X
- X i = keyword_buffer[0];
- X keyword_buffer[0] = keyword_buffer[1];
- X keyword_buffer[1] = i;
- X i = 0;
- X while (card_names[i] != NULL) {
- X if (!strcmp(keyword_buffer, card_names[i]))
- X return (i);
- X else
- X i++;
- X }
- X
- X return (-1);
- X}
- X
- Xstatic int Parse_int (ivalue)
- X int *ivalue;
- X/* Parses an integer from the input stream. Returns 0 if an integer
- X was found, or -1 if not. The value is placed into ivalue. */
- X{
- X int i = 0, d = 0;
- X
- X Skip_whitespace ();
- X if ((NOW == '+') || (NOW == '-')) {
- X keyword_buffer[i++] = NOW;
- X ADVANCE;
- X }
- X
- X while (('0' <= NOW) && (NOW <= '9')) {
- X keyword_buffer[i++] = NOW;
- X ADVANCE;
- X d++;
- X }
- X keyword_buffer[i] = '\0';
- X
- X if (d == 0) return (-1);
- X *ivalue = atoi (keyword_buffer);
- X return (0);
- X}
- X
- Xstatic int Parse_filename (fn_buffer, buflen)
- X char *fn_buffer; int buflen;
- X/* Reads a filename into the buffer fn_buffer. If a possible
- X filename is found, then returns 0. Otherwise, returns 1.
- X*/
- X{
- X int n = Parse_Field (fn_buffer, buflen, PRESERVE_CASE);
- X return (n == 0);
- X}
- X
- Xstatic int Parse_string (string_buffer)
- X char *string_buffer;
- X/* Simply copies the rest of the input buffer to the string_buffer.
- X Returns 0 if at least one character was copied.
- X*/
- X{
- X int i = 0;
- X
- X Skip_whitespace ();
- X while (NOW != '\0')
- X string_buffer[i++] = NEXT;
- X string_buffer[i] = '\0';
- X return (i == 0);
- X}
- X
- Xstatic int Parse_name (name_buf, name_buflen)
- X char *name_buf; int name_buflen;
- X/* Copies a blank delimited "name" to the buffer. */
- X{
- X int n = Parse_Field (name_buf, name_buflen, PRESERVE_CASE);
- X return (n == 0);
- X}
- X
- Xstatic int Parse_hand (h)
- X hand h;
- X/* Parses a hand from the buffer. If an error occurs, returns -1.
- X Otherwise, returns the hand in h. */
- X{
- X int n = Parse_Field (keyword_buffer, 80, PRESERVE_CASE);
- X int i;
- X
- X if (n != 52) return (-1);
- X
- X for (i = 0; i < 52; i++) {
- X if (('0' <= keyword_buffer[i]) && (keyword_buffer[i] <= '3'))
- X h[i] = keyword_buffer[i] - '0';
- X else
- X return (-1);
- X }
- X return (0);
- X
- X}
- X
- Xstatic int Command_Table_Search (table, length, command)
- X Command_Descriptor *table; int length; char *command;
- X{
- X int b, m, t, r;
- X
- X b = 0;
- X t = length;
- X while (b < t) {
- X m = (b + t) / 2;
- X r = strcmp (command, table[m].command_name);
- X/* printf ("%d %d %d Comparing %s to %s\n", b, m, t,
- X command, table[m].command_name); */
- X if (r < 0)
- X t = m-1;
- X else if (r > 0)
- X b = m+1;
- X else
- X return (m);
- X }
- X if (b == length)
- X return (-1);
- X else if (strcmp(command, table[b].command_name))
- X return (-1);
- X else
- X return (b);
- X}
- X
- Xint Parse_Command (command_table, table_length, buffer)
- X Command_Descriptor *command_table; int table_length; char *buffer;
- X/* int Parse_Command (Command_Descriptor *command_table,
- X int table_length, char *buffer); */
- X/* Reads a command from the buffer and attempts to parse it according
- X to the given table. If successful, then the command specific procedure
- X is called with the parsed parameters. In this case, zero is returned.
- X If unsuccessful, records some error information in Parser_Error_Buf
- X and Parser_Error_Location and returns 1.
- X*/
- X{
- X int i = 0; /* The index of the command in the command table. */
- X int n, error_flag;
- X
- X input_buffer = buffer;
- X buffer_pos = 0;
- X
- X n = Parse_Field (command_word, 80, IGNORE_CASE);
- X i = Command_Table_Search (command_table, table_length, command_word);
- X if (i < 0) {
- X sprintf (Parser_Error_Buf, "UNRECOGNIZED COMMAND NAME: %s",
- X command_word);
- X Parser_Error_Location = 0;
- X return (1);
- X }
- X
- X n = 0;
- X while ((command_table[i].fields[n].field_type != F_END) && (n < 3)) {
- X Skip_whitespace ();
- X Parser_Error_Location = buffer_pos;
- X if ((NOW == '\0') && (command_table[i].fields[n].field_type & F_OPTIONAL))
- X parameter_list[n] = NULL;
- X else {
- X switch (command_table[i].fields[n].field_type & 077) {
- X case F_KEYWORD:
- X parameter_keyword[n] =
- X Parse_keyword(command_table[i].fields[n].field_descriptor);
- X if (parameter_keyword[n] < 0) {
- X sprintf (Parser_Error_Buf, "UNRECOGNIZED KEYWORD -- EXPECTED %s",
- X/* command_word, "COMMAND -- EXPECTED ", */
- X command_table[i].fields[n].field_descriptor);
- X return (1);
- X }
- X parameter_list[n] = ¶meter_keyword[n];
- X break;
- X case F_BID:
- X parameter_keyword[n] = Parse_bid ();
- X if (parameter_keyword[n] < 0) {
- X sprintf (Parser_Error_Buf, "%s %s",
- X "THE FORMAT OF A CORRECT BID IS <LEVEL> <TRUMPSUIT>",
- X " OR P OR X OR XX");
- X return (1);
- X }
- X parameter_list[n] = ¶meter_keyword[n];
- X break;
- X case F_CARD:
- X parameter_keyword[n] = Parse_Card ();
- X if (parameter_keyword[n] < 0) {
- X sprintf (Parser_Error_Buf, "%s",
- X "ERROR - THE FORMAT OF A CORRECT PLAY IS <SUIT> <RANK>");
- X return (1);
- X }
- X parameter_list[n] = parameter_keyword + n;
- X break;
- X case F_INT:
- X error_flag = Parse_int (¶meter_keyword[n]);
- X parameter_list[n] = ¶meter_keyword[n];
- X if (error_flag) {
- X sprintf (Parser_Error_Buf, "%s",
- X "ERROR -- EXPECTED INTEGER VALUE.");
- X return (1);
- X }
- X break;
- X case F_FILENAME:
- X error_flag = Parse_filename (parameter_string[n], 80);
- X parameter_list[n] = (int *) (parameter_string + n);
- X if (error_flag) {
- X sprintf (Parser_Error_Buf, "%s",
- X "ERROR -- EXPECTED FILE NAME.");
- X return (1);
- X }
- X break;
- X case F_STRING:
- X error_flag = Parse_string (parameter_string[n], 80);
- X parameter_list[n] = (int *) (parameter_string + n);
- X if (error_flag) {
- X sprintf (Parser_Error_Buf, "%s %s %s",
- X "ERROR --",
- X command_table[i].fields[n].field_descriptor,
- X "MISSING FROM INPUT");
- X return (1);
- X }
- X break;
- X case F_NAME:
- X error_flag = Parse_name (parameter_string[n], 80);
- X parameter_list[n] = (int *) (parameter_string + n);
- X if (error_flag) {
- X sprintf (Parser_Error_Buf, "%s %s",
- X "ERROR -- EXPECTED ",
- X command_table[i].fields[n].field_descriptor);
- X return (1);
- X }
- X break;
- X case F_DEAL:
- X error_flag = Parse_hand (parameter_hand + n);
- X parameter_list[n] = (int *) (parameter_hand + n);
- X if (error_flag) {
- X sprintf (Parser_Error_Buf, "%s", "ERROR IN DEAL");
- X return (1);
- X }
- X break;
- X default:
- X printf ("Internal Parser Error !!\n");
- X printf ("Input Buffer: %s\n", buffer);
- X printf ("Command Name: %s\n", command_table[i].command_name);
- X printf ("Parameter No: %d\n", n);
- X printf ("Field Type: %d\n",
- X command_table[i].fields[n].field_type);
- X printf ("Field Desc: %s\n",
- X command_table[i].fields[n].field_descriptor);
- X sprintf (Parser_Error_Buf, "Internal Error!");
- X return (1);
- X }
- X }
- X n++;
- X }
- X
- X Skip_whitespace ();
- X if (NOW != '\0') {
- X sprintf (Parser_Error_Buf, "TOO MANY PARAMETERS");
- X return (1);
- X }
- X
- X /* At this point, we have now parsed the command successfully,
- X so we need only call the procedure with the appropriate number
- X of parameters.
- X */
- X switch (n) {
- X case 0:
- X command_table[i].chandler ();
- X break;
- X case 1:
- X command_table[i].chandler (parameter_list[0]);
- X break;
- X case 2:
- X command_table[i].chandler (parameter_list[0],parameter_list[1]);
- X break;
- X case 3:
- X command_table[i].chandler (parameter_list[0], parameter_list[1],
- X parameter_list[2]);
- X break;
- X }
- X return (0);
- X}
- END_OF_FILE
- if test 12067 -ne `wc -c <'parser.c'`; then
- echo shar: \"'parser.c'\" unpacked with wrong size!
- fi
- # end of 'parser.c'
- fi
- if test -f 'parser.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'parser.h'\"
- else
- echo shar: Extracting \"'parser.h'\" \(5817 characters\)
- sed "s/^X//" >'parser.h' <<'END_OF_FILE'
- X/* parser.h -- generalized parser
- X *
- X ! Copyright (C) 1990-1992 by Matthew Clegg. All Rights Reserved
- X !
- X ! OKbridge is made available as a free service to the Internet.
- X ! Accordingly, the following restrictions are placed on its use:
- X !
- X ! 1. OKbridge may not be modified in any way without the explicit
- X ! permission of Matthew Clegg.
- X !
- X ! 2. OKbridge may not be used in any way for commercial advantage.
- X ! It may not be placed on for-profit networks or on for-profit
- X ! computer systems. It may not be bundled as part of a package
- X ! or service provided by a for-profit organization.
- X !
- X ! If you have questions about restrictions on the use of OKbridge,
- X ! write to mclegg@cs.ucsd.edu.
- X !
- X ! DISCLAIMER: The user of OKbridge accepts full responsibility for any
- X ! damage which may be caused by OKbridge.
- X *
- X * This module contains the code which is used for parsing commands
- X * to the okbridge program. There are three command languages which
- X * are used by the program: (1) the language used for communicating
- X * between client and server programs, (2) the language used for
- X * communicating between the server and the tournament director,
- X * and (3) the language used for specifying default values in the
- X * .okbridgerc file. This module contains code which is common to
- X * the handling of all three of these languages.
- X *
- X * The syntax of each of these languages is very simple. Each language
- X * consists of a series of commands. A command begins with a keyword
- X * and then up to three command-specific parameters. The possible
- X * parameter types are also very restricted. Here is a list of the
- X * parameter types:
- X *
- X * F_KEYWORD. The parameter is one of a list of keywords. The keywords
- X * are specified as a list of uppercase words, separated by
- X * vertical bars, e.g., "RUBBER|CHICAGO|DUPLICATE|EMAIL|IMP".
- X * Each keyword is indexed implicitly by its order in the array,
- X *
- X * F_BID. The parameter is the name of a bid.
- X *
- X * F_CARD. The parameter is the name of a card.
- X *
- X * F_INT. The parameter is an integer.
- X *
- X * F_FILENAME. The parameter is the name of a file.
- X *
- X * F_STRING. The file is a string which terminates at the end of the
- X * buffer.
- X *
- X * F_NAME. The parameter is a name of a player. This is currently
- X * treated in the same way as a filename.
- X *
- X * F_DEAL. The parameter is a deal of the cards.
- X *
- X * Consequently, we can encode each command with its keyword, the
- X * parameters it may accept, and a procedure for encoding a data
- X * structure to represent the command. The action of the parser
- X * can then be described as follows. We begin by identifying the
- X * command keyword. Having done this, we attempt to parse the
- X * command specific parameters. If this is successful, then we
- X * call the command specific procedure which creates the data structure
- X * representing the command.
- X *
- X * NOTE: The generalized parser is not re-entrant.
- X *
- X */
- X
- Xtypedef void (*command_handler) ();
- X
- X#define F_KEYWORD 000
- X#define F_BID 001
- X#define F_CARD 002
- X#define F_INT 003
- X#define F_FILENAME 004
- X#define F_STRING 005
- X#define F_NAME 006
- X#define F_DEAL 007
- X#define F_END 010
- X
- X#define F_OPTIONAL 0100
- X
- X
- Xtypedef struct {
- X int field_type;
- X char *field_descriptor;
- X} Field_Descriptor;
- X
- Xtypedef struct Command_Descriptor_Struct {
- X char *command_name;
- X Field_Descriptor fields[3];
- X command_handler chandler;
- X} Command_Descriptor;
- X
- X#define NO_PARAM {F_END, NULL}
- X#define NOP NO_PARAM
- X#define END_PARSE_TABLE {NULL, {NO_PARAM, NO_PARAM, NO_PARAM}, NULL}
- X
- X/* The following macros define commonly used option lists: */
- X
- X#define PARSER_PLAYERS "NORTH|EAST|SOUTH|WEST"
- X#define PARSER_SEATS "NORTH|EAST|SOUTH|WEST|OBS"
- X#define PARSER_ANSWER "NO|YES"
- X#define PARSER_STATE "OFF|ON"
- X#define PARSER_VULN "NONE|EW|NS|BOTH"
- X#define PARSER_SCORE "RUBBER|DUPLICATE|IMP|MP|CLEAR"
- X
- X/* The following macros define commonly used arguments to commands: */
- X#define A_SWITCH {F_KEYWORD, PARSER_ANSWER}
- X#define A_STATE {F_KEYWORD|F_OPTIONAL, PARSER_STATE}
- X#define A_PLAYER {F_KEYWORD, PARSER_PLAYERS}
- X#define A_SEAT {F_KEYWORD, PARSER_SEATS}
- X#define A_VULN {F_KEYWORD, PARSER_VULN}
- X#define A_SCORE {F_KEYWORD, PARSER_SCORE}
- X
- X/* The following macros define command lines where there is only one
- X parameter: */
- X#define C_PARAM(x,y) {{x,y}, NOP, NOP}
- X#define C_EMPTY {NOP, NOP, NOP}
- X#define C_KEY(x) C_PARAM(F_KEYWORD, x)
- X#define C_INT(x) C_PARAM(F_INT, x)
- X#define C_STRING(x) C_PARAM(F_STRING, x)
- X
- X#define C_SWITCH C_PARAM(F_KEYWORD, PARSER_STATE)
- X#define C_STATE C_PARAM(F_KEYWORD|F_OPTIONAL, PARSER_STATE)
- X#define C_PLAYER C_PARAM(F_KEYWORD, PARSER_PLAYERS)
- X#define C_SEAT C_PARAM(F_KEYWORD, PARSER_SEATS)
- X#define C_SCORE C_PARAM(F_KEYWORD, PARSER_SCORE)
- X#define C_VULN C_PARAM(F_KEYWORD, PARSER_VULN)
- X
- X#ifdef PARSER
- X char Parser_Error_Buf [80];
- X /* A buffer where error messages are written if an error is
- X encountered in processing the command. */
- X int Parser_Error_Location;
- X /* The index in the input buffer where trouble began. */
- X
- X#else
- X
- X extern char Parser_Error_Buf [];
- X extern int Parser_Error_Location;
- X
- X#endif
- X
- Xextern int Parse_Command ();
- X/* int Parse_Command (Command_Descriptor *command_table,
- X int table_length, char *buffer); */
- X/* Reads a command from the buffer and attempts to parse it according
- X to the given table. If successful, then the command specific procedure
- X is called with the parsed parameters. In this case, zero is returned.
- X If unsuccessful, records some error information in Parser_Error_Buf
- X and Parser_Error_Location and returns 1.
- X*/
- X
- Xextern void Lcopy ();
- X/* void Lcopy (char *from, char *to, int len); */
- X/* Copies at most len-1 characters from from to to. */
- X
- X
- END_OF_FILE
- if test 5817 -ne `wc -c <'parser.h'`; then
- echo shar: \"'parser.h'\" unpacked with wrong size!
- fi
- # end of 'parser.h'
- fi
- if test -f 'rc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rc.c'\"
- else
- echo shar: Extracting \"'rc.c'\" \(9958 characters\)
- sed "s/^X//" >'rc.c' <<'END_OF_FILE'
- X/* rc.c
- X *
- X ! Copyright (C) 1990-1992 by Matthew Clegg. All Rights Reserved
- X !
- X ! OKbridge is made available as a free service to the Internet.
- X ! Accordingly, the following restrictions are placed on its use:
- X !
- X ! 1. OKbridge may not be modified in any way without the explicit
- X ! permission of Matthew Clegg.
- X !
- X ! 2. OKbridge may not be used in any way for commercial advantage.
- X ! It may not be placed on for-profit networks or on for-profit
- X ! computer systems. It may not be bundled as part of a package
- X ! or service provided by a for-profit organization.
- X !
- X ! If you have questions about restrictions on the use of OKbridge,
- X ! write to mclegg@cs.ucsd.edu.
- X !
- X ! DISCLAIMER: The user of OKbridge accepts full responsibility for any
- X ! damage which may be caused by OKbridge.
- X *
- X */
- X
- X#include <ctype.h>
- X#include <stdio.h>
- X#include <string.h>
- X
- X#include "types.h"
- X#include "state.h"
- X#include "parser.h"
- X
- X#ifdef GCC
- Xextern fprintf (), strcasecmp (), fclose ();
- X#endif
- X
- Xextern char *getenv ();
- Xextern char *strdup ();
- Xextern void exit ();
- Xextern char *Get_CC_Value ();
- Xextern int Define_CC ();
- X
- X#ifndef index
- Xextern char *index ();
- X#endif
- X
- X#define MAX_LENGTH 100
- X
- Xstatic void
- X Autosave_Field (),
- X Bell_Field (),
- X CC_Field (),
- X CCDef_Field (),
- X Default_Field (),
- X Email_Field (),
- X Esckey_Field (),
- X Formal_Field (),
- X Fullname_Field (),
- X GPS_Field (),
- X GPS_IP_Field (),
- X Helpfile_Field (),
- X Load_Field (),
- X Log_Field (),
- X My_IP_Field (),
- X Name_Field (),
- X Position_Field (),
- X Port_Field (),
- X Prompt_Field (),
- X Replay_Field (),
- X Scoring_Field (),
- X Server_Field (),
- X Timer_Field (),
- X Timezone_Field (),
- X Zlog_Field ();
- X
- Xstatic Command_Descriptor Startup_Commands [] = {
- X {"AUTOSAVE", C_SWITCH, Autosave_Field},
- X {"BELL", C_SWITCH, Bell_Field},
- X {"CC", C_PARAM(F_STRING, "<convention-card>"), CC_Field},
- X {"CCDEF", C_PARAM(F_STRING, "<cc-definition>"), CCDef_Field}, /* JAS */
- X {"DEFAULT", C_SWITCH, Default_Field},
- X
- X {"EMAIL", C_PARAM(F_FILENAME, "<your-email-address>"), Email_Field},
- X {"ESCKEY", C_PARAM(F_INT, "<decimal-key-code>"), Esckey_Field},
- X {"FORMAL", C_SWITCH, Formal_Field},
- X {"FULLNAME", C_PARAM(F_STRING, "<player's-full-name>"), Fullname_Field},
- X {"GPS", C_SWITCH, GPS_Field},
- X {"GPS_IP", {{F_FILENAME, "<GPS-server-IP>"},
- X {F_INT | F_OPTIONAL, "<GPS-port>"}, NOP}, GPS_IP_Field},
- X
- X {"HELPFILE", C_PARAM(F_FILENAME, "<helpfile-name>"), Helpfile_Field},
- X {"LOAD", C_PARAM(F_FILENAME, "<email-file>"), Load_Field},
- X {"LOG", C_PARAM(F_FILENAME, "<log-file>"), Log_Field},
- X {"MY_IP", C_PARAM(F_FILENAME, "<local-IP-name-or-number>"), My_IP_Field},
- X {"NAME", C_PARAM(F_NAME, "<player-name>"), Name_Field},
- X
- X {"PORT", C_PARAM(F_INT, "<server-port>"), Port_Field},
- X {"POSITION", C_SEAT, Position_Field},
- X {"PROMPT", C_SWITCH, Prompt_Field},
- X {"REPLAY", C_PARAM(F_FILENAME, "<replay-file>"), Replay_Field},
- X {"SCORING", C_SCORE, Scoring_Field},
- X
- X {"SEAT", C_SEAT, Position_Field},
- X {"SERVER", C_PARAM(F_FILENAME, "<server-name>"), Server_Field},
- X {"TIMER", C_SWITCH, Timer_Field},
- X {"TIMEZONE", C_PARAM(F_STRING, "<local-timezone>"), Timezone_Field},
- X {"ZLOG", C_PARAM(F_FILENAME, "<log-file>"), Zlog_Field},
- X END_PARSE_TABLE
- X};
- X
- X#define STARTUP_TABLE_SIZE ( (sizeof(Startup_Commands) / \
- X sizeof (Command_Descriptor)) - 1) /* changed from 19 5-14-92 JAS */
- X
- X
- Xstatic char line_buffer [MAX_LENGTH];
- Xstatic int line_no;
- Xstatic FILE *init_file;
- Xstatic int error_flag;
- X
- Xextern int errno;
- Xextern char *sys_errlist[];
- X
- Xextern int save_defaults;
- Xextern int bell_is_on;
- Xextern char *help_file_name;
- Xextern FILE *logfile;
- Xextern FILE *zhang_logfile;
- Xextern int local_player;
- Xextern int network_port;
- Xextern int server_mode;
- Xextern int timer_is_on;
- Xextern char *server_name;
- Xextern char *local_player_name;
- Xextern char *autoload_file, *autosave_file;
- Xextern char *local_player_full_name;
- Xextern char *local_player_email;
- Xextern char *local_cc;
- Xextern char *GPS_IP;
- Xextern int GPS_port;
- Xextern int Use_GPS;
- Xextern char *Timezone_name;
- Xextern char Host_IP [];
- Xextern int Host_IP_is_known;
- Xextern int Escape_key;
- X
- X
- Xstatic void Field_Error (error_msg)
- X char *error_msg;
- X/* Prints out the current line from the field file along with an error
- X message.
- X*/
- X{
- X int i;
- X
- X fprintf (stderr, "LINE %2d: %s\n", line_no, line_buffer);
- X for (i = 0; i < Parser_Error_Location + 9; i++)
- X fprintf (stderr, " ");
- X fprintf (stderr, "^ ERROR\n");
- X fprintf (stderr, "ERROR: %s\n", error_msg);
- X error_flag = 1;
- X}
- X
- Xstatic void Autosave_Field (i)
- X int *i;
- X{
- X save_defaults = *i;
- X}
- X
- Xstatic void Bell_Field (i)
- X int *i;
- X{
- X bell_is_on = *i;
- X}
- X
- Xstatic void CC_Field (c)
- X char *c;
- X{
- X local_cc = strdup(Get_CC_Value(c)); /* changed JAS */
- X}
- X
- X/* Ccdef_Field Added JAS */
- Xstatic void CCDef_Field(c)
- X char *c;
- X{
- X
- X if (Define_CC(c, NULL))
- X {
- X char error_buf[80];
- X /* returns true on error */
- X sprintf (error_buf, "Error opening %s: %s", c,
- X sys_errlist[errno]);
- X Field_Error (error_buf);
- X }
- X}
- X
- Xstatic void Default_Field (i)
- X int *i;
- X{
- X default_plays = *i;
- X}
- X
- Xstatic void Email_Field (e)
- X char *e;
- X{
- X local_player_email = strdup(e);
- X}
- X
- Xstatic void Esckey_Field (i)
- X int *i;
- X{
- X Escape_key = *i;
- X}
- X
- Xstatic void Formal_Field (i)
- X int *i;
- X{
- X/* formal_mode = *i; */
- X ;
- X}
- X
- Xstatic void Fullname_Field (f)
- X char *f;
- X{
- X local_player_full_name = strdup(f);
- X}
- X
- Xstatic void GPS_Field (use)
- X int *use;
- X{
- X Use_GPS = *use;
- X}
- X
- Xstatic void GPS_IP_Field (ip, port)
- X char *ip; int *port;
- X{
- X GPS_IP = strdup (ip);
- X if (port != NULL)
- X GPS_port = *port;
- X}
- X
- Xstatic void Helpfile_Field (s)
- X char *s;
- X{
- X help_file_name = strdup (s);
- X}
- X
- Xstatic void Load_Field (s)
- X char *s;
- X{
- X autoload_file = strdup (s);
- X}
- X
- Xstatic void Log_Field (s)
- X char *s;
- X{
- X char error_buf [80];
- X char *filename;
- X
- X if (s[0] == '+') {
- X filename = s + 1;
- X logfile = fopen (filename, "a");
- X } else {
- X filename = s;
- X logfile = fopen (filename, "w");
- X }
- X if (logfile == NULL) {
- X sprintf (error_buf, "Error opening %s: %s", filename,
- X sys_errlist[errno]);
- X Field_Error (error_buf);
- X }
- X}
- X
- Xstatic void My_IP_Field (s)
- X char *s;
- X{
- X sprintf (Host_IP, "%s", s);
- X Host_IP_is_known = 1;
- X}
- X
- Xstatic void Name_Field (s)
- X char *s;
- X{
- X local_player_name = strdup (s);
- X}
- X
- Xstatic void Position_Field (i)
- X int *i;
- X{
- X local_player = *i;
- X}
- X
- Xstatic void Port_Field (i)
- X int *i;
- X{
- X network_port = *i;
- X}
- X
- Xstatic void Prompt_Field (i)
- X int *i;
- X{
- X prompt_dummy = *i;
- X}
- X
- Xstatic void Replay_Field (s)
- X char *s;
- X{
- X autoload_file = strdup (s);
- X autosave_file = strdup (s);
- X}
- X
- Xstatic void Scoring_Field (i)
- X int *i;
- X{
- X scoring_mode = *i;
- X}
- X
- Xstatic void Server_Field (s)
- X char *s;
- X{
- X if (!strcasecmp(s, "ME"))
- X server_mode = 1;
- X else {
- X server_mode = 0;
- X server_name = strdup (s);
- X }
- X}
- X
- Xstatic void Timer_Field (i)
- X int *i;
- X{
- X timer_is_on = *i;
- X}
- X
- Xstatic void Timezone_Field (t)
- X char *t;
- X{
- X Timezone_name = strdup (t);
- X}
- X
- Xstatic void Zlog_Field (s)
- X char *s;
- X{
- X char error_buf [80];
- X char *filename;
- X
- X if (s[0] == '+') {
- X filename = s + 1;
- X zhang_logfile = fopen (filename, "a");
- X } else {
- X filename = s;
- X zhang_logfile = fopen (filename, "w");
- X }
- X if (zhang_logfile == NULL) {
- X sprintf (error_buf, "Error opening %s: %s", filename,
- X sys_errlist[errno]);
- X Field_Error (error_buf);
- X }
- X}
- X
- Xstatic int Read_Field_Line ()
- X/* Reads a line from initialization file init_file and copies it into
- X line_buffer. Returns 1 if data is returned, or 0 if the end of file
- X is reached. Skips comment lines. Strips trailing blanks from the
- X end of the line.
- X*/
- X{
- X int ch;
- X int line_length;
- X
- X do {
- X line_length = 0;
- X ch = getc (init_file);
- X while ((ch != EOF) && (ch != '\n')) {
- X if (line_length < MAX_LENGTH)
- X line_buffer [line_length++] = ch;
- X ch = getc(init_file);
- X }
- X if (ch == EOF)
- X return (0);
- X line_no++;
- X while (line_buffer[line_length-1] == ' ')
- X line_length--;
- X } while ((line_length == 0) || (line_buffer[0] == '#'));
- X
- X line_buffer[line_length] = '\0';
- X return (1);
- X}
- X
- Xvoid Read_Initialization_File (basefilename)
- X char *basefilename;
- X{
- X char *home_dir, filename_buf[128];
- X
- X init_file = fopen (basefilename, "r");
- X home_dir = getenv ("HOME");
- X
- X if ((init_file == NULL) && (home_dir != NULL)) {
- X sprintf (filename_buf, "%s/%s", home_dir, basefilename);
- X init_file = fopen (filename_buf, "r");
- X }
- X
- X if (init_file == NULL) {
- X /* couldn't find an initialization file. */
- X return;
- X }
- X
- X error_flag = 0;
- X while (Read_Field_Line()) {
- X if (Parse_Command (Startup_Commands, STARTUP_TABLE_SIZE,
- X line_buffer))
- X Field_Error (Parser_Error_Buf);
- X }
- X
- X fclose (init_file);
- X
- X if (error_flag) {
- X fprintf (stderr, "\nErrors in %s %s -- %s\n", basefilename,
- X "initialization file", "Program terminating");
- X exit (1);
- X }
- X
- X}
- X
- Xvoid Write_Initialization_File (basefilename)
- X char *basefilename;
- X{
- X char *home_dir, filename_buf[128];
- X
- X home_dir = getenv ("HOME");
- X
- X init_file = NULL;
- X if (home_dir != NULL) {
- X sprintf (filename_buf, "%s/%s", home_dir, basefilename);
- X init_file = fopen (filename_buf, "w");
- X }
- X
- X if (init_file == NULL)
- X init_file = fopen (basefilename, "w");
- X
- X if (init_file == NULL)
- X return;
- X
- X fprintf (init_file, "BELL %s\n", bell_is_on? "ON": "OFF");
- X fprintf (init_file, "DEFAULT %s\n", default_plays? "ON": "OFF");
- X if (local_player_email != NULL)
- X fprintf (init_file, "EMAIL %s\n", local_player_email);
- X/* fprintf (init_file, "FORMAL %s\n", formal_mode? "ON": "OFF"); */
- X if (local_player_full_name != NULL)
- X fprintf (init_file, "FULLNAME %s\n", local_player_full_name);
- X fprintf (init_file, "NAME %s\n", local_player_name);
- X fprintf (init_file, "PROMPT %s\n", prompt_dummy? "ON": "OFF");
- X fprintf (init_file, "SEAT %s\n", seat_names[local_player]);
- X fprintf (init_file, "TIMER %s\n", timer_is_on? "ON": "OFF");
- X fclose (init_file);
- X
- X}
- END_OF_FILE
- if test 9958 -ne `wc -c <'rc.c'`; then
- echo shar: \"'rc.c'\" unpacked with wrong size!
- fi
- # end of 'rc.c'
- fi
- if test -f 'types.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'types.h'\"
- else
- echo shar: Extracting \"'types.h'\" \(10832 characters\)
- sed "s/^X//" >'types.h' <<'END_OF_FILE'
- X/* types.h -- global data values.
- X *
- X ! Copyright (C) 1990-1992 by Matthew Clegg. All Rights Reserved
- X !
- X ! OKbridge is made available as a free service to the Internet.
- X ! Accordingly, the following restrictions are placed on its use:
- X !
- X ! 1. OKbridge may not be modified in any way without the explicit
- X ! permission of Matthew Clegg.
- X !
- X ! 2. OKbridge may not be used in any way for commercial advantage.
- X ! It may not be placed on for-profit networks or on for-profit
- X ! computer systems. It may not be bundled as part of a package
- X ! or service provided by a for-profit organization.
- X !
- X ! If you have questions about restrictions on the use of OKbridge,
- X ! write to mclegg@cs.ucsd.edu.
- X !
- X ! DISCLAIMER: The user of OKbridge accepts full responsibility for any
- X ! damage which may be caused by OKbridge.
- X *
- X * This file defines the common data structures shared by all of the
- X * modules of okbridge.
- X *
- X */
- X
- X#define TYPES_INCLUDED
- X
- X/* The following constants define the various game modes which we may be in.
- X *
- X * The normal mode of operation is CLUB mode. However, the program
- X * also supports a PRACTICE mode and a FORMAL mode. The features of
- X * these modes are as follows:
- X *
- X * PRACTICE mode:
- X * 1. During bidding, the players who are sitting may bid. When it
- X * is time for a bid to be made from an unoccupied seat, the program
- X * automatically supplies a bid of "PASS".
- X * 2. During play, the cards are revealed to everyone, and anyone may
- X * specify the next card to be played.
- X * 3. A hand may be ended with the /claim command. Confirmation is not
- X * requested for claims.
- X *
- X * FORMAL mode:
- X * 1. Alerts are not shown to the partner of the person making the alert.
- X * 2. Talk messages are not transmitted to partner.
- X * 3. The dummy is not displayed to anyone until the opening lead has
- X * been made.
- X * 4. The bidding cannot be reviewed after play has begun.
- X */
- X
- X#define CLUB_PLAYING_MODE 0
- X#define PRACTICE_PLAYING_MODE 1
- X#define FORMAL_PLAYING_MODE 2
- X
- X/* The following constants define the possible states which the program
- X * can be in. The current program state is stored in the variable
- X * game_mode. The meaning of the states are:
- X * STARTUP: This is the initial state of the program, and it is
- X * re-entered at the beginning of each hand. STARTUP mode
- X * is terminated by a READY message, which should only be
- X * issued when the players have taken their seats.
- X * DEAL: In this mode, we receive the board to be played. DEAL
- X * mode is terminated by a BEGIN message.
- X * BIDDING: This state is entered when we are in the bidding phase.
- X * PLAYING: This state is entered when we are in the playing phase.
- X * SCORING: This state is entered when we are displaying the scores
- X * for this hand.
- X */
- X
- X#define STARTUP_MODE 0
- X#define DEALING_MODE 1
- X#define BIDDING_MODE 2
- X#define PLAYING_MODE 3
- X#define SCORING_MODE 4
- X#define SKIP_MODE 5
- X
- X
- X/* The following constants define the various reasons for a reset
- X * (non-local branch to the top of the program).
- X */
- X
- X#define RESET_FULL 1 /* A full reset has been delivered. */
- X#define RESET_CONNECT 2 /* We have connected to a new server. */
- X#define RESET_SERVE 3 /* We are opening a new table. */
- X#define RESET_DISCONNECT 4 /* We have been disconnected from our server. */
- X
- X/* The following constants define the locations on the screen where
- X * user input may occur.
- X */
- X
- X#define PLAY_ROW 16
- X#define PLAY_COL 1
- X#define PLAY_LENGTH 30
- X
- X#define TALK_ROW 17
- X#define TALK_COL 1
- X#define TALK_LENGTH 75
- X
- X/* The following constants define the types of messages which may be
- X * displayed in the talk window:
- X */
- X
- X#define COMMENT_PRIVATE 0
- X#define COMMENT_FORMAL 1
- X#define COMMENT_PUBLIC 2
- X
- X/* The following constants are used to identify the sources of messages.
- X * The possible sources are
- X * NORTH -- the player sitting in the north seat (always the server).
- X * EAST -- east
- X * SOUTH -- south
- X * WEST -- west
- X * OBS -- an observer who is not playing the game.
- X * SERVER -- the person who controls the network connections and also
- X * who controls the flow of the game.
- X */
- X
- X#define PLAYER_NORTH 0
- X#define PLAYER_EAST 1
- X#define PLAYER_SOUTH 2
- X#define PLAYER_WEST 3
- X#define PLAYER_OBS 4
- X#define PLAYER_SERVER 5
- X#define PLAYER_TYPES 6
- X
- X#define IS_OBSERVER(x) ((x) == PLAYER_OBS)
- X#define IS_PLAYER(x) ((0 <= (x)) && ((x) < PLAYER_OBS))
- X
- X#define SIDE_NS 0
- X#define SIDE_EW 1
- X
- X/* Each suit is assigned a index, and each rank is also assigned a index.
- X * This implicitly defines an index for each card, which is defined
- X * as 4 * SUIT + RANK.
- X */
- X
- X/* The following constants identify the suits. No Trump is treated as
- X * a suit because it reduces the number of special cases which must be
- X * handled both in the bidding and the playing.
- X */
- X
- X#define SUIT_CLUBS 0
- X#define SUIT_DIAMONDS 1
- X#define SUIT_HEARTS 2
- X#define SUIT_SPADES 3
- X#define SUIT_NOTRUMP 4
- X#define MAJOR(suit) ((suit == SUIT_HEARTS) || (suit == SUIT_SPADES))
- X#define MINOR(suit) ((suit == SUIT_CLUBS) || (suit == SUIT_DIAMONDS))
- X
- X/* The ranks of the cards. */
- X#define RANK_TWO 0
- X#define RANK_THREE 1
- X#define RANK_FOUR 2
- X#define RANK_FIVE 3
- X#define RANK_SIX 4
- X#define RANK_SEVEN 5
- X#define RANK_EIGHT 6
- X#define RANK_NINE 7
- X#define RANK_TEN 8
- X#define RANK_JACK 9
- X#define RANK_QUEEN 10
- X#define RANK_KING 11
- X#define RANK_ACE 12
- X
- X/* The bids are indexed from 0 to 36. The first three bids are the special
- X * cases: PASS, DOUBLE and REDOUBLE. The remaining bids are ordered as
- X * they should be.
- X */
- X
- X#define BID_PASS 0
- X#define BID_DOUBLE 1
- X#define BID_REDOUBLE 2
- X#define BID_SUIT 3
- X
- X#define side_of(x) (x%2)
- X
- X/* The following scoring modes are supported by okbridge: */
- X
- X#define RUBBER_SCORING 0
- X#define DUPLICATE_SCORING 1
- X#define IMP_SCORING 2
- X#define MP_SCORING 3
- X
- X#define CLEAR_SCORING 4 /* A bogus option used in the /score command
- X to clear the current scores. */
- X
- X/* The following definitions define a few commonly used data types: */
- X
- X#define NAME_LENGTH 10
- X#define MESSAGE_LENGTH 120
- X#define BUFFER_LENGTH 100
- X#define FILENAME_LENGTH 60
- X
- Xtypedef char name_buffer[NAME_LENGTH];
- Xtypedef char message_buffer[MESSAGE_LENGTH];
- Xtypedef char command_buffer[BUFFER_LENGTH];
- Xtypedef char filename_buffer[FILENAME_LENGTH];
- X
- X/* We represent both a deck of cards and a hand by an array of 52 elements,
- X * where the array is indexed by card indices. That is, to each card we
- X * associate a unique integer in the range 0-51, and this "card index"
- X * is used to reference an array representing a deal or a hand. In the
- X * case of a deal, the array contains thirteen elements which are 0,
- X * thirteen which are 1, thirteen which are 2, and thirteen which are 3.
- X * Thus an element of an array refers to the holder of that particular
- X * card. We represent a hand by an array where thirteen elements are 1
- X * and the rest are 0. Thus, an element of an array is TRUE exactly when
- X * that particular card is in the hand.
- X */
- X
- Xtypedef char card_type;
- Xtypedef card_type *suit_type;
- Xtypedef card_type deal [52];
- Xtypedef card_type hand [52];
- Xtypedef int bid_list [100];
- X
- X/* int suit_of (int card_code); */
- X/* Returns the suit index associated to the card with the given card_code. */
- X#define suit_of(cc) ((cc)/13)
- X
- X/* int rank_of (int card_code); */
- X/* Returns the rank index associated to the card with the given card_code. */
- X#define rank_of(cc) ((cc) % 13)
- X
- X/* int card_code (int suit, int rank); */
- X/* Returns the index of the card having the given suit and rank. */
- X#define card_code(suit,rank) (13 * (suit) + (rank))
- X
- X/* int trumpsuit_of (int bid_code); */
- X/* Returns the trump suit determined by a given bid. */
- X#define trumpsuit_of(bc) ((bc) > 2 ? ((bc) - 3) % 5: -1)
- X
- X/* int contract_of (int bid_code); */
- X/* Returns the level of the contract associated to the given bid. */
- X#define level_of(bc) ((bc) > 2 ? (((bc) - 3) / 5) + 1: 0)
- X
- X#define ROTATION_LENGTH 16
- X /* The number of entries in the deal/vulnerabilities rotation sequence. */
- X
- X#ifdef _BRIDGE_
- X
- X /* Character constants: */
- X
- X char *major_revision_level = "1.7"; /* In theory, all copies of the
- X program at a given major
- X revision level should be
- X compatible. */
- X char *minor_revision_level = "C";
- X
- X char *card_names [] = {"C2", "C3", "C4", "C5", "C6", "C7", "C8",
- X "C9", "CT", "CJ", "CQ", "CK", "CA",
- X "D2", "D3", "D4", "D5", "D6", "D7", "D8",
- X "D9", "DT", "DJ", "DQ", "DK", "DA",
- X "H2", "H3", "H4", "H5", "H6", "H7", "H8",
- X "H9", "HT", "HJ", "HQ", "HK", "HA",
- X "S2", "S3", "S4", "S5", "S6", "S7", "S8",
- X "S9", "ST", "SJ", "SQ", "SK", "SA",
- X NULL};
- X char *suit_names [] = {"C", "D", "H", "S", "NT"};
- X char *rank_names [] = {"2", "3", "4", "5", "6", "7", "8", "9",
- X "T", "J", "Q", "K", "A"};
- X char *bid_names [] = {"P" , "X" , "XX",
- X "1C", "1D", "1H", "1S", "1NT",
- X "2C", "2D", "2H", "2S", "2NT",
- X "3C", "3D", "3H", "3S", "3NT",
- X "4C", "4D", "4H", "4S", "4NT",
- X "5C", "5D", "5H", "5S", "5NT",
- X "6C", "6D", "6H", "6S", "6NT",
- X "7C", "7D", "7H", "7S", "7NT",
- X NULL};
- X
- X char *seat_names [] ={"NORTH", "EAST", "SOUTH", "WEST", "OBS",
- X "MOD"};
- X
- X /* Information regarding the positions of the players: */
- X int player_next [] = {1, 2, 3, 0};
- X int player_prev [] = {3, 0, 1, 2};
- X int player_partner [] = {2, 3, 0, 1};
- X
- X /* The rotation of deals and vulnerabilities: */
- X
- X int dealer_list [16] =
- X {PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST,
- X PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST,
- X PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST,
- X PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST};
- X
- X int ns_vulnerability_list [16] =
- X {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0};
- X
- X int ew_vulnerability_list [16] =
- X {0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1};
- X
- X char *month_names [] =
- X { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
- X "Sept", "Oct", "Nov", "Dec"};
- X
- X char *long_suit_names [] =
- X {"CLUB", "DIAMOND", "HEART", "SPADE", "NO TRUMP"};
- X
- X#else
- X
- X /* Character constants: */
- X extern char *major_revision_level, *minor_revision_level;
- X extern char *card_names[],
- X *suit_names[],
- X *rank_names[],
- X *bid_names[],
- X *seat_names[];
- X
- X /* Information regarding the positions of the players: */
- X extern int player_next [],
- X player_prev [],
- X player_partner [];
- X
- X extern int dealer_list [], ns_vulnerability_list [],
- X ew_vulnerability_list [];
- X
- X extern char *month_names [], *long_suit_names [];
- X#endif
- END_OF_FILE
- if test 10832 -ne `wc -c <'types.h'`; then
- echo shar: \"'types.h'\" unpacked with wrong size!
- fi
- # end of 'types.h'
- fi
- echo shar: End of archive 11 \(of 14\).
- cp /dev/null ark11isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 14 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-