home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume14 / okbrdge2 / part11 < prev    next >
Encoding:
Internet Message Format  |  1993-01-26  |  55.1 KB

  1. Path: uunet!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v14i089:  okbridge2 - computer-mediated bridge game, Part11/14
  5. Message-ID: <3528@master.CNA.TEK.COM>
  6. Date: 7 Sep 92 21:42:50 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1822
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: mclegg@cs.UCSD.EDU (Matthew Clegg)
  12. Posting-number: Volume 14, Issue 89
  13. Archive-name: okbridge2/Part11
  14. Supersedes: okbridge: Volume 13, Issue 16-22
  15. Environment: BSD-derived Unix, NeXT, curses, sockets
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 11 (of 14)."
  26. # Contents:  boards.h parser.c parser.h rc.c types.h
  27. # Wrapped by billr@saab on Mon Sep  7 14:33:38 1992
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'boards.h' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'boards.h'\"
  31. else
  32. echo shar: Extracting \"'boards.h'\" \(12795 characters\)
  33. sed "s/^X//" >'boards.h' <<'END_OF_FILE'
  34. X/* boards.h -- routines for manipulating boards.
  35. X *
  36. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  37. X ! 
  38. X ! OKbridge is made available as a free service to the Internet.
  39. X ! Accordingly, the following restrictions are placed on its use:
  40. X ! 
  41. X ! 1.  OKbridge may not be modified in any way without the explicit 
  42. X !     permission of Matthew Clegg.  
  43. X ! 
  44. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  45. X !     It may not be placed on for-profit networks or on for-profit
  46. X !     computer systems.  It may not be bundled as part of a package
  47. X !     or service provided by a for-profit organization.
  48. X ! 
  49. X ! If you have questions about restrictions on the use of OKbridge,
  50. X ! write to mclegg@cs.ucsd.edu.
  51. X ! 
  52. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  53. X ! damage which may be caused by OKbridge.
  54. X *
  55. X */
  56. X
  57. X#ifndef CIPHER_INCLUDED
  58. X#include "cipher.h"
  59. X#endif
  60. X
  61. X#define BOARDS_INCLUDED
  62. X
  63. X/* This module provides routines for manipulating the set of boards.
  64. X   Conceptually, the interface to this module is a local database for
  65. X   accessing and updating boards.  However, this module also contains
  66. X   routines for reading and writing boards from files and also
  67. X   routines for transmitting and receiving boards over the network.
  68. X*/
  69. X
  70. X/* The following definitions record the information which we will store
  71. X   for each board and for the play of each board.  These structures are
  72. X   meant to be robust enough so that the entire state of the game can
  73. X   be reconstructed from them.
  74. X*/
  75. X
  76. Xtypedef struct Board_struct {
  77. X  /* First, we must provide some information describing where this
  78. X     board came from: */
  79. X  char *source;           /* A character string identifying the source
  80. X                 of this board -- perhaps a filename or an
  81. X                 internet name. */
  82. X  int  serial_no;         /* The number of the board within the file. */
  83. X  char *startup_comment;  /* a comment which will be displayed when the
  84. X                 hand is first displayed. */
  85. X
  86. X  /* The following information describes the board itself: */
  87. X  int  dealer;             /* the dealer for this hand. */
  88. X  int  vulnerable [2];     /* boolean flags for each side. */
  89. X  int  scoring_mode;       /* the scoring mode used when this hand was
  90. X                  generated (and played). */
  91. X  int  part_score [2];     /* A part score carried over from a previous
  92. X                  hand(s), if relevant. */
  93. X  hand deal;               /* the cards. */
  94. X
  95. X  int  mps_computed;       /* true if the match point scores have been
  96. X                  computed for this board. */
  97. X  int  imps_computed;      /* true if the imp scores have been computed
  98. X                  for this board. */
  99. X
  100. X  /* Then we need info about the people who have played this board: */
  101. X  struct Play_record_struct *play_records;
  102. X
  103. X  struct Board_struct *next;
  104. X} Board, *Board_ptr;
  105. X
  106. Xtypedef struct Play_record_struct {
  107. X  /* The following provides the minimal amount of information needed to
  108. X     represent a hand. */
  109. X  char *player_names[4];   /* The names of each of the players. */
  110. X  int  table;              /* The table number where this board was played,
  111. X                  or -1 not played locally. */
  112. X  int  no_bids;            /* The number of actual bids that were made. */
  113. X  bid_list bids;           /* The list of bids. */
  114. X  bid_list alerts;         /* For each bid, a nonzero value if the bid was
  115. X                  alerted. */
  116. X  int  no_plays;           /* The number of plays. */
  117. X  deal play_list;          /* A list of the cards played, in order.
  118. X                  The person who played a card play_list[i]
  119. X                  can be found as deal[play_list[i]].  In
  120. X                  particular, the leader for the k-th trick
  121. X                  is deal[play_list[4*k]]. */
  122. X  int  bidding_completed;  /* A boolean flag indicating that the bidding
  123. X                  was completed. (not strictly necessary) */
  124. X  int  hand_completed;     /* A boolean flag indicating that the play
  125. X                  was completed. */
  126. X
  127. X  int  next_player;        /* The index of the next person who should make
  128. X                  a bid or play. */
  129. X  int  result;             /* If the contract was made, the number of
  130. X                  tricks-6 taken by the declaring side. OW,
  131. X                  the negative of the number of tricks down. */
  132. X  int  tricks[2];          /* Number of tricks taken by each side. */
  133. X  int  below_line[2];      /* Number of points awarded below-the-line to
  134. X                  each side.  If our scoring mode is other than
  135. X                  RUBBER, then this is the score for the hand. */
  136. X  int  above_line[2];      /* Number of points awarded above-the-line to
  137. X                  each side.  If our scoring mode is other than
  138. X                  RUBBER, then this is zero. */
  139. X
  140. X  /* The following information is additional info. which is implied
  141. X     by the above: */
  142. X  int  contract;           /* The contract, but without doubling info. */
  143. X  int  doubled;            /* 0=not doubled, 1=doubled, 2=redoubled. */
  144. X  int  declarer;
  145. X  int  mimp_points [2];    /* 2 * The number of MIMP points awarded. */
  146. X  float match_points[2];   /* 2 * The number of match points awarded.  */
  147. X  float imatch_points[2];  /* The number of int'l match points awarded. */
  148. X  
  149. X  struct Play_record_struct *next;
  150. X} Play_record, *Play_record_ptr;
  151. X
  152. X  
  153. X#ifdef _BOARDS_
  154. X
  155. X  Board *Played_boards = NULL;
  156. X    /* The list of boards which have already been played. */
  157. X  Board *Played_boards_tail = NULL;
  158. X    /* The last element on the list of played boards. */
  159. X
  160. X  Board *Unplayed_boards = NULL;
  161. X    /* The list of boards which are yet to be played. */
  162. X
  163. X#else
  164. X
  165. X  extern Board *Played_boards, *Played_boards_tail, *Unplayed_boards;
  166. X
  167. X#endif
  168. X
  169. X/* The following primitives are for manipulating the boards and play
  170. X   records. */
  171. X
  172. XBoard *Allocate_board ();
  173. X/* Returns a pointer to a newly allocated board.  Does not fill in any
  174. X   of the fields. */
  175. X
  176. Xvoid Deallocate_board ();
  177. X/* Deallocates the board b.  This includes freeing up strings which are
  178. X   part of the structure and de-allocating the play records associated to
  179. X   this board. */
  180. X
  181. XPlay_record *Allocate_play_record ();
  182. X/* Returns a pointer to a newly allocated play record.  Does not fill in any
  183. X   of the fields. */
  184. X
  185. Xvoid Deallocate_play_record ();
  186. X/* Deallocates the play record p.  This includes freeing up strings
  187. X   which are part of the structure. */
  188. X
  189. Xvoid Erase_board_list ();
  190. X/* Deallocates all of the boards in the list. */
  191. X
  192. Xvoid Append_board ();
  193. X/* Appends the board b to the list of unplayed boards. */
  194. X
  195. Xvoid Append_play_record ();
  196. X/* Appends the play record p to the list of play records associated to the
  197. X   board b. */
  198. X
  199. Xvoid Encode_board ();
  200. X/* Encodes the board in the string array buf1, buf2.  This encoding does not 
  201. X   include the play records. */
  202. X
  203. XBoard *Decode_board ();
  204. X/* Decodes the string array buf and returns a corresponding board structure. */
  205. X
  206. Xvoid Encode_play_record ();
  207. X/* Encodes the play_record p into buffers buf1 .. buf3. */
  208. X
  209. XPlay_record *Decode_play_record ();
  210. X/* Decodes the strings buf1 .. buf3, returning a corresponding play record
  211. X   structure.  Returns NULL if an error occurs in the decoding.  */
  212. X
  213. X
  214. X/* Primitives for accessing email duplicate files: */
  215. X
  216. Xint Read_Email_Header ();
  217. X/* Searches the file f until an email header is found.  If the header
  218. X   is found, then returns 0.  Otherwise, returns 1. */
  219. X
  220. Xvoid Write_Email_Header ();
  221. X/* Writes an email header to the file f. */
  222. X
  223. X
  224. Xint Read_Email_Board ();
  225. X/* Reads a board from the file f using the cipher descriptor c.
  226. X   Stores in b a pointer to an allocated board record containing the
  227. X   data which has been read.  If successful, returns 0.  If the end of 
  228. X   file is reached, returns 1.  If some other error occurs, returns -1.
  229. X*/
  230. X
  231. Xvoid Write_Email_Board ();
  232. X/* Writes the board b to the file f using the cipher descriptor c. */
  233. X
  234. Xint Load_Email_Duplicate_File ();
  235. X/* First erases all of the current boards.
  236. X   Then, reads an entire email duplicate file, recording each of the hands 
  237. X   read from the file into the current list of unplayed boards. 
  238. X   If successful, returns 0.  If the header could not be found,
  239. X   returns 1.  If some other error occurs, returns -1.
  240. X*/
  241. X
  242. Xint Merge_Email_Duplicate_File ();
  243. X/* Reads an email duplicate file.  For each board found in the file,
  244. X   if the same board occurs among the list of boards, then updates
  245. X   the data associated with that board using the data read from the file.
  246. X   Discards boards which do not match those stored in memory.
  247. X   If successful, returns 0.  If the header could not be found, returns 1.
  248. X   If some other error occurs, returns -1.
  249. X*/
  250. X
  251. X
  252. Xvoid Write_Email_Duplicate_File ();
  253. X/* Writes the list of played and unplayed boards to the file f. */
  254. X
  255. X
  256. X/* Routines for accessing and updating the current set of email 
  257. X   duplicate boards. */
  258. X
  259. XBoard *Generate_Random_Match_Board ();
  260. X/* Generates a random match board for the given scoring mode,
  261. X   and returns a pointer to it.  If b is non-null, then uses the
  262. X   dealer and vulnerability information in b to determine who the
  263. X   dealer and vulnerabilities in the generated board.  This is
  264. X   done by looking up the dealer and vulnerabilities in a table
  265. X   (defined in types.h) and then picking the cyclically next
  266. X   entry in the table.
  267. X*/
  268. X
  269. XBoard *Generate_Random_Rubber_Board ();
  270. X/* Generates a random rubber board and returns a pointer to it,
  271. X   based upon the part score and result recorded in the previously
  272. X   played board b and play record p.  If b or p is NULL, then
  273. X   generates a board with neither side vulnerable and a 0 part score.
  274. X*/
  275. X
  276. XPlay_record *Search_for_play_record ();
  277. X/* Searches the list of play records associated with the board b for a
  278. X   record of play by the same players as mentioned in p.  If such a
  279. X   record is found, then returns a pointer to it.  Otherwise, returns
  280. X   NULL. */
  281. X
  282. XPlay_record *Locate_play_record_by_foursome 
  283. X  ();
  284. X/* Searches the list of play records associated with the board b for a record
  285. X   where the names of the players exactly match n, e, s, and w, in order.
  286. X   Returns the play record if found, or NULL if no matching record is found. 
  287. X*/
  288. X
  289. X
  290. Xvoid Clear_All_Boards ();
  291. X/* Clears the list of played and unplayed boards. */
  292. X
  293. Xint Board_is_Available ();
  294. X/* Returns true if there is a board available in the list of unplayed
  295. X   boards. */
  296. X
  297. XBoard *Next_Unplayed_Board ();
  298. X/* If there is a board on the list of unplayed boards, then unlinks it and
  299. X   returns it.  Otherwise, returns NULL. */
  300. X
  301. Xvoid Record_Played_Board ();
  302. X/* Appends the board to the list of played boards. */
  303. X
  304. X
  305. X/* Routines for scoring play records: */
  306. X
  307. Xint Highcard_points ();
  308. X/* Returns the number of highcard points held by the partnership 'side'. */
  309. X
  310. Xvoid Compute_Matchpoints ();
  311. X/* Computes the match point totals for the current board. */
  312. X
  313. Xvoid Compute_Intl_Matchpoints ();
  314. X/* Computes the internation match point totals for the current board. */
  315. X
  316. Xvoid Compute_MIMP_points ();
  317. X/* Computes the number of MIMP points for the play record p, based upon
  318. X   the scoring information found in the play record.  In addition,
  319. X   we compute simulated match_point and imp values for the play record
  320. X   which are based upon the number of MIMP's.
  321. X*/
  322. X
  323. Xvoid Compute_contract ();
  324. X/* Computes the contract for the play record p based upon the bids present
  325. X   in the bidding list. */
  326. X
  327. Xint Index_of_Last_Bid ();
  328. X/* Returns the index in the bid list p of the last bid made by the given
  329. X   player, or -1 if the player has not made any bids.
  330. X*/
  331. X
  332. Xvoid Generate_valid_bids ();
  333. X/* Determines the valid bids for the player, based on the information
  334. X   contained in the play record p.  Assumes the declarer, contract
  335. X   and doubled fields of p have been correctly computed from the bid
  336. X   list.
  337. X*/
  338. X
  339. Xvoid Generate_holdings ();
  340. X/* Records in the hand h the cards held by the given player, based on the
  341. X   deal contained in the board b and on the past no_plays recorded plays. 
  342. X   The holdings of the player are recorded as a boolean string in h, so that
  343. X     h[c] == true iff the player holds the card c.
  344. X*/
  345. X
  346. Xvoid Generate_valid_leads ();
  347. X/* Records in the hand h the set of cards which the player may lead,
  348. X   based upon the plays which have already been recorded in p.
  349. X   The valid plays are stored as a boolean string in h, so that
  350. X     h[c] == true iff it is legal to play card c.
  351. X*/
  352. X
  353. Xvoid Generate_valid_follows 
  354. X  ();
  355. X/* Records in the hand h the set of cards which the player may play to
  356. X   follow the given lead, based upon the plays which have already been
  357. X   recorded in p.
  358. X
  359. X   The valid plays are stored as a boolean string in h, so that
  360. X     h[c] == true iff it is legal to play card c.
  361. X*/
  362. X
  363. Xint Next_Player ();
  364. X/* Returns the index of the next person who should play, or -1 if the
  365. X   hand has been completed.  If it is the dummy's play, then the
  366. X   index of the declarer is returned.
  367. X*/
  368. X
  369. Xint Winning_card ();
  370. X/* Returns the index of the player who played the winning card from
  371. X * the cards c_l, c_lho, c_p, c_rho, based on the given trump suit
  372. X * and that c_l was the card lead.
  373. X */
  374. END_OF_FILE
  375. if test 12795 -ne `wc -c <'boards.h'`; then
  376.     echo shar: \"'boards.h'\" unpacked with wrong size!
  377. fi
  378. # end of 'boards.h'
  379. fi
  380. if test -f 'parser.c' -a "${1}" != "-c" ; then 
  381.   echo shar: Will not clobber existing file \"'parser.c'\"
  382. else
  383. echo shar: Extracting \"'parser.c'\" \(12067 characters\)
  384. sed "s/^X//" >'parser.c' <<'END_OF_FILE'
  385. X/* parser.c -- implementaton of generalized parser.
  386. X *
  387. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  388. X ! 
  389. X ! OKbridge is made available as a free service to the Internet.
  390. X ! Accordingly, the following restrictions are placed on its use:
  391. X ! 
  392. X ! 1.  OKbridge may not be modified in any way without the explicit 
  393. X !     permission of Matthew Clegg.  
  394. X ! 
  395. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  396. X !     It may not be placed on for-profit networks or on for-profit
  397. X !     computer systems.  It may not be bundled as part of a package
  398. X !     or service provided by a for-profit organization.
  399. X ! 
  400. X ! If you have questions about restrictions on the use of OKbridge,
  401. X ! write to mclegg@cs.ucsd.edu.
  402. X ! 
  403. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  404. X ! damage which may be caused by OKbridge.
  405. X *
  406. X */
  407. X
  408. X#include <stdio.h>
  409. X#include <ctype.h>
  410. X#include <string.h>
  411. X
  412. X#ifdef GCC
  413. Xextern int atoi ();
  414. Xextern printf ();
  415. X#endif
  416. X
  417. X#include "types.h"
  418. X#define PARSER
  419. X#include "parser.h"
  420. X
  421. X#define MAPUPPER(c) ((('a' <= (c)) && ((c) <= 'z'))? ((c) + 'A' - 'a') : (c))
  422. X
  423. Xstatic char *input_buffer;
  424. X  /* The current input buffer being examined. */
  425. Xstatic int   buffer_pos;
  426. X  /* The current position in the parser buffer. */
  427. Xstatic char  keyword_buffer[80];
  428. X  /* A buffer used for holding one keyword. */
  429. X
  430. Xstatic char command_word [80];
  431. Xtypedef char parameter_string_element[80];
  432. Xstatic int *parameter_list[3];
  433. Xstatic int parameter_keyword [3];
  434. Xstatic parameter_string_element parameter_string[3];
  435. Xstatic hand parameter_hand[3];
  436. X
  437. X#define NOW     input_buffer[buffer_pos]
  438. X#define NEXT    input_buffer[buffer_pos++]
  439. X#define ADVANCE buffer_pos++;
  440. X
  441. X#define IGNORE_CASE   1
  442. X#define PRESERVE_CASE 0
  443. X
  444. Xvoid Lcopy (from, to, len)
  445. X     char *from, *to; int len;
  446. X/* Copies at most len-1 characters from from to to. */
  447. X{
  448. X  int i = 0;
  449. X
  450. X  len -= 1;
  451. X  for (i = 0; i < len; i++) {
  452. X    to [i] = from[i];
  453. X    if (to[i] == '\0') return;
  454. X  }
  455. X  to[len] = '\0';
  456. X}
  457. X
  458. Xstatic void Skip_whitespace ()
  459. X/* Skips any whitespace characters in the input_buffer. */
  460. X{
  461. X  while ((NOW == ' ') || (NOW == '\t')) ADVANCE;
  462. X}
  463. X
  464. Xstatic int Parse_Field (dest_buffer, dest_buflen, uppercase)
  465. X     char *dest_buffer; int uppercase, dest_buflen;
  466. X/* Reads a field from the current input buffer.  A field is a sequence
  467. X   of characters delimited by whitespace.  Copies the field to the
  468. X   keyword_buffer.  Returns the number of characters in the field,
  469. X   or 0 if the end of the input buffer has been reached.  If uppercase
  470. X   is true, then the characters in the field are automatically converted
  471. X   to upper case as they are read.
  472. X*/
  473. X{
  474. X  int n = 0;
  475. X  int c;
  476. X
  477. X  Skip_whitespace ();
  478. X  dest_buflen -= 1;
  479. X  while ((NOW != ' ') && (NOW != '\t') && (NOW != '\0')) {
  480. X    c = NEXT;
  481. X    if (n < dest_buflen)
  482. X      dest_buffer[n++] = uppercase? MAPUPPER(c): c;
  483. X  }
  484. X
  485. X  dest_buffer[n] = '\0';
  486. X  return (n);
  487. X}
  488. X
  489. Xstatic int Parse_keyword (keyword_list)
  490. X     char *keyword_list;
  491. X/* Reads a keyword from the input buffer and tries to find it in
  492. X   the keyword_list.  If no match can be found, then returns -1.
  493. X   Otherwise, returns the index of the keyword in the list of keywords,
  494. X   with the first keyword having index 0.
  495. X*/
  496. X{
  497. X  int l, n, keyword_index;
  498. X
  499. X  n = Parse_Field (keyword_buffer, 80, IGNORE_CASE);
  500. X  keyword_index = 0;
  501. X  while (*keyword_list) {
  502. X    l = 0;
  503. X    while ((keyword_list[l] != '|') && (keyword_list[l] != '\0')) l++;
  504. X    if ((l == 0) && (n == -1))
  505. X      return (keyword_index);
  506. X    else if ((l == n) && !strncmp(keyword_buffer, keyword_list, n))
  507. X      return (keyword_index);
  508. X    keyword_index++;
  509. X    if (keyword_list[l] != '\0')
  510. X      keyword_list += l+1;
  511. X    else
  512. X      return (-1);
  513. X  }
  514. X  return (-1);
  515. X}
  516. X
  517. Xstatic int Parse_bid ()
  518. X/* Reads a field from the input buffer and interprets it as a bid.
  519. X   Returns the index of the bid in the bid table.  If unsuccessful,
  520. X   returns -1.
  521. X*/
  522. X{
  523. X  int n = Parse_Field (keyword_buffer, 80, IGNORE_CASE);
  524. X  int i = 0;
  525. X
  526. X  if (n == 0) return (-1);
  527. X
  528. X  if (!strcmp(keyword_buffer, "PASS"))
  529. X    return (BID_PASS);
  530. X  else if (!strcmp(keyword_buffer, "DOUBLE"))
  531. X    return (BID_DOUBLE);
  532. X  else if (!strcmp(keyword_buffer, "REDOUBLE"))
  533. X    return (BID_REDOUBLE);
  534. X
  535. X  if (keyword_buffer[n-1] == 'N') {
  536. X    keyword_buffer[n++] = 'T';
  537. X    keyword_buffer[n] = '\0';
  538. X  }
  539. X
  540. X  while (bid_names[i] != NULL) {
  541. X    if (!strcmp(keyword_buffer, bid_names[i]))
  542. X      return (i);
  543. X    else
  544. X      i++;
  545. X  }
  546. X  return (-1);
  547. X}
  548. X
  549. Xstatic int Parse_Card ()
  550. X/* Reads the next field from the input buffer and interprets it as a
  551. X   card name.  Returns the index of the card in the card array,
  552. X   or -1 if no match is found.
  553. X */
  554. X{
  555. X  int n = Parse_Field (keyword_buffer, 80, IGNORE_CASE);
  556. X  int i = 0;
  557. X
  558. X  if (n != 2) return (-1);
  559. X
  560. X  while (card_names[i] != NULL) {
  561. X    if (!strcmp(keyword_buffer, card_names[i]))
  562. X      return (i);
  563. X    else
  564. X      i++;
  565. X  }
  566. X
  567. X  i = keyword_buffer[0];
  568. X  keyword_buffer[0] = keyword_buffer[1];
  569. X  keyword_buffer[1] = i;
  570. X  i = 0;
  571. X  while (card_names[i] != NULL) {
  572. X    if (!strcmp(keyword_buffer, card_names[i]))
  573. X      return (i);
  574. X    else
  575. X      i++;
  576. X  }
  577. X
  578. X  return (-1);
  579. X}
  580. X
  581. Xstatic int Parse_int (ivalue)
  582. X     int *ivalue;
  583. X/* Parses an integer from the input stream.  Returns 0 if an integer
  584. X   was found, or -1 if not.  The value is placed into ivalue. */
  585. X{
  586. X  int i = 0, d = 0;
  587. X
  588. X  Skip_whitespace ();
  589. X  if ((NOW == '+') || (NOW == '-')) {
  590. X    keyword_buffer[i++] = NOW;
  591. X    ADVANCE;
  592. X  }
  593. X
  594. X  while (('0' <= NOW) && (NOW <= '9')) {
  595. X    keyword_buffer[i++] = NOW;
  596. X    ADVANCE;
  597. X    d++;
  598. X  }
  599. X  keyword_buffer[i] = '\0';
  600. X
  601. X  if (d == 0) return (-1);
  602. X  *ivalue = atoi (keyword_buffer);
  603. X  return (0);
  604. X}
  605. X
  606. Xstatic int Parse_filename (fn_buffer, buflen)
  607. X     char *fn_buffer; int buflen;
  608. X/* Reads a filename into the buffer fn_buffer.  If a possible
  609. X   filename is found, then returns 0.  Otherwise, returns 1.
  610. X*/
  611. X{
  612. X  int n = Parse_Field (fn_buffer, buflen, PRESERVE_CASE);
  613. X  return (n == 0);
  614. X}
  615. X
  616. Xstatic int Parse_string (string_buffer)
  617. X     char *string_buffer;
  618. X/* Simply copies the rest of the input buffer to the string_buffer. 
  619. X   Returns 0 if at least one character was copied.
  620. X*/
  621. X{
  622. X  int i = 0;
  623. X
  624. X  Skip_whitespace ();
  625. X  while (NOW != '\0')
  626. X    string_buffer[i++] = NEXT;
  627. X  string_buffer[i] = '\0';
  628. X  return (i == 0);
  629. X}
  630. X
  631. Xstatic int Parse_name (name_buf, name_buflen)
  632. X     char *name_buf; int name_buflen;
  633. X/* Copies a blank delimited "name" to the buffer. */
  634. X{
  635. X  int n = Parse_Field (name_buf, name_buflen, PRESERVE_CASE);
  636. X  return (n == 0);
  637. X}
  638. X
  639. Xstatic int Parse_hand (h)
  640. X     hand h;
  641. X/* Parses a hand from the buffer.  If an error occurs, returns -1.
  642. X   Otherwise, returns the hand in h. */
  643. X{
  644. X  int n = Parse_Field (keyword_buffer, 80, PRESERVE_CASE);
  645. X  int i;
  646. X
  647. X  if (n != 52) return (-1);
  648. X
  649. X  for (i = 0; i < 52; i++) {
  650. X    if (('0' <= keyword_buffer[i]) && (keyword_buffer[i] <= '3'))
  651. X      h[i] = keyword_buffer[i] - '0';
  652. X    else
  653. X      return (-1);
  654. X  }
  655. X  return (0);
  656. X
  657. X}
  658. X
  659. Xstatic int Command_Table_Search (table, length, command)
  660. X     Command_Descriptor *table; int length; char *command;
  661. X{
  662. X  int b, m, t, r;
  663. X
  664. X  b = 0;
  665. X  t = length;
  666. X  while (b < t) {
  667. X    m = (b + t) / 2;
  668. X    r = strcmp (command, table[m].command_name);
  669. X/*    printf ("%d %d %d Comparing %s to %s\n", b, m, t,
  670. X        command, table[m].command_name); */
  671. X    if (r < 0)
  672. X      t = m-1;
  673. X    else if (r > 0)
  674. X      b = m+1;
  675. X    else
  676. X      return (m);
  677. X  }
  678. X  if (b == length)
  679. X    return (-1);
  680. X  else if (strcmp(command, table[b].command_name))
  681. X    return (-1);
  682. X  else
  683. X    return (b);
  684. X}
  685. X
  686. Xint Parse_Command (command_table, table_length, buffer)
  687. X     Command_Descriptor *command_table; int table_length; char *buffer;
  688. X/* int Parse_Command (Command_Descriptor *command_table, 
  689. X   int table_length, char *buffer); */
  690. X/* Reads a command from the buffer and attempts to parse it according
  691. X   to the given table.  If successful, then the command specific procedure
  692. X   is called with the parsed parameters.  In this case, zero is returned.
  693. X   If unsuccessful, records some error information in Parser_Error_Buf
  694. X   and Parser_Error_Location and returns 1.
  695. X*/
  696. X{
  697. X  int i = 0;  /* The index of the command in the command table. */
  698. X  int n, error_flag;
  699. X
  700. X  input_buffer = buffer;
  701. X  buffer_pos = 0;
  702. X
  703. X  n = Parse_Field (command_word, 80, IGNORE_CASE);
  704. X  i = Command_Table_Search (command_table, table_length, command_word);
  705. X  if (i < 0) {
  706. X    sprintf (Parser_Error_Buf, "UNRECOGNIZED COMMAND NAME: %s",
  707. X         command_word);
  708. X    Parser_Error_Location = 0;
  709. X    return (1);
  710. X  }
  711. X
  712. X  n = 0;
  713. X  while ((command_table[i].fields[n].field_type != F_END) && (n < 3)) {
  714. X    Skip_whitespace ();
  715. X    Parser_Error_Location = buffer_pos;
  716. X    if ((NOW == '\0') && (command_table[i].fields[n].field_type & F_OPTIONAL))
  717. X      parameter_list[n] = NULL;
  718. X    else {
  719. X      switch (command_table[i].fields[n].field_type & 077) {
  720. X      case F_KEYWORD:
  721. X    parameter_keyword[n] = 
  722. X      Parse_keyword(command_table[i].fields[n].field_descriptor);
  723. X    if (parameter_keyword[n] < 0) {
  724. X      sprintf (Parser_Error_Buf, "UNRECOGNIZED KEYWORD -- EXPECTED %s",
  725. X/*           command_word, "COMMAND -- EXPECTED ", */
  726. X           command_table[i].fields[n].field_descriptor);
  727. X      return (1);
  728. X    }
  729. X    parameter_list[n] = ¶meter_keyword[n];
  730. X    break;
  731. X      case F_BID:
  732. X    parameter_keyword[n] = Parse_bid ();
  733. X    if (parameter_keyword[n] < 0) {
  734. X      sprintf (Parser_Error_Buf, "%s %s",
  735. X           "THE FORMAT OF A CORRECT BID IS <LEVEL> <TRUMPSUIT>", 
  736. X           " OR P OR X OR XX");
  737. X      return (1);
  738. X    }
  739. X    parameter_list[n] = ¶meter_keyword[n];
  740. X    break;
  741. X      case F_CARD:
  742. X    parameter_keyword[n] = Parse_Card ();
  743. X    if (parameter_keyword[n] < 0) {
  744. X      sprintf (Parser_Error_Buf, "%s",
  745. X           "ERROR - THE FORMAT OF A CORRECT PLAY IS <SUIT> <RANK>");
  746. X      return (1);
  747. X    }
  748. X    parameter_list[n] = parameter_keyword + n;
  749. X    break;
  750. X      case F_INT:
  751. X    error_flag = Parse_int (¶meter_keyword[n]);
  752. X    parameter_list[n] = ¶meter_keyword[n];
  753. X    if (error_flag) {
  754. X      sprintf (Parser_Error_Buf, "%s",
  755. X           "ERROR -- EXPECTED INTEGER VALUE.");
  756. X      return (1);
  757. X    }
  758. X    break;
  759. X      case F_FILENAME:
  760. X    error_flag = Parse_filename (parameter_string[n], 80);
  761. X    parameter_list[n] = (int *) (parameter_string + n);
  762. X    if (error_flag) {
  763. X      sprintf (Parser_Error_Buf, "%s",
  764. X           "ERROR -- EXPECTED FILE NAME.");
  765. X      return (1);
  766. X    }
  767. X    break;
  768. X      case F_STRING:
  769. X    error_flag = Parse_string (parameter_string[n], 80);
  770. X    parameter_list[n] = (int *) (parameter_string + n);
  771. X    if (error_flag) {
  772. X      sprintf (Parser_Error_Buf, "%s %s %s",
  773. X           "ERROR --",
  774. X           command_table[i].fields[n].field_descriptor,
  775. X           "MISSING FROM INPUT");
  776. X      return (1);
  777. X    }
  778. X    break;
  779. X      case F_NAME:
  780. X    error_flag = Parse_name (parameter_string[n], 80);
  781. X    parameter_list[n] = (int *) (parameter_string + n);
  782. X    if (error_flag) {
  783. X      sprintf (Parser_Error_Buf, "%s %s",
  784. X           "ERROR -- EXPECTED ",
  785. X           command_table[i].fields[n].field_descriptor);
  786. X      return (1);
  787. X    }
  788. X    break;
  789. X      case F_DEAL:
  790. X    error_flag = Parse_hand (parameter_hand + n);
  791. X    parameter_list[n] = (int *) (parameter_hand + n);
  792. X    if (error_flag) {
  793. X      sprintf (Parser_Error_Buf, "%s", "ERROR IN DEAL");
  794. X      return (1);
  795. X    }
  796. X    break;
  797. X      default:
  798. X    printf ("Internal Parser Error !!\n");
  799. X    printf ("Input Buffer: %s\n", buffer);
  800. X    printf ("Command Name: %s\n", command_table[i].command_name);
  801. X    printf ("Parameter No: %d\n", n);
  802. X    printf ("Field Type:   %d\n", 
  803. X        command_table[i].fields[n].field_type);
  804. X    printf ("Field Desc:   %s\n",
  805. X        command_table[i].fields[n].field_descriptor);
  806. X    sprintf (Parser_Error_Buf, "Internal Error!");
  807. X    return (1);
  808. X      }
  809. X    }
  810. X    n++;
  811. X  }
  812. X
  813. X  Skip_whitespace ();
  814. X  if (NOW != '\0') {
  815. X    sprintf (Parser_Error_Buf, "TOO MANY PARAMETERS");
  816. X    return (1);
  817. X  }
  818. X
  819. X  /* At this point, we have now parsed the command successfully,
  820. X     so we need only call the procedure with the appropriate number
  821. X     of parameters. 
  822. X  */
  823. X  switch (n) {
  824. X  case 0: 
  825. X    command_table[i].chandler ();
  826. X    break;
  827. X  case 1:
  828. X    command_table[i].chandler (parameter_list[0]);
  829. X    break;
  830. X  case 2:
  831. X    command_table[i].chandler (parameter_list[0],parameter_list[1]);
  832. X    break;
  833. X  case 3:
  834. X    command_table[i].chandler (parameter_list[0], parameter_list[1],
  835. X                   parameter_list[2]);
  836. X    break;
  837. X  }
  838. X  return (0);
  839. X}
  840. END_OF_FILE
  841. if test 12067 -ne `wc -c <'parser.c'`; then
  842.     echo shar: \"'parser.c'\" unpacked with wrong size!
  843. fi
  844. # end of 'parser.c'
  845. fi
  846. if test -f 'parser.h' -a "${1}" != "-c" ; then 
  847.   echo shar: Will not clobber existing file \"'parser.h'\"
  848. else
  849. echo shar: Extracting \"'parser.h'\" \(5817 characters\)
  850. sed "s/^X//" >'parser.h' <<'END_OF_FILE'
  851. X/* parser.h -- generalized parser
  852. X *
  853. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  854. X ! 
  855. X ! OKbridge is made available as a free service to the Internet.
  856. X ! Accordingly, the following restrictions are placed on its use:
  857. X ! 
  858. X ! 1.  OKbridge may not be modified in any way without the explicit 
  859. X !     permission of Matthew Clegg.  
  860. X ! 
  861. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  862. X !     It may not be placed on for-profit networks or on for-profit
  863. X !     computer systems.  It may not be bundled as part of a package
  864. X !     or service provided by a for-profit organization.
  865. X ! 
  866. X ! If you have questions about restrictions on the use of OKbridge,
  867. X ! write to mclegg@cs.ucsd.edu.
  868. X ! 
  869. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  870. X ! damage which may be caused by OKbridge.
  871. X *
  872. X * This module contains the code which is used for parsing commands
  873. X * to the okbridge program.  There are three command languages which
  874. X * are used by the program: (1) the language used for communicating
  875. X * between client and server programs, (2) the language used for
  876. X * communicating between the server and the tournament director,
  877. X * and (3) the language used for specifying default values in the
  878. X * .okbridgerc file.  This module contains code which is common to
  879. X * the handling of all three of these languages.
  880. X *
  881. X * The syntax of each of these languages is very simple.  Each language
  882. X * consists of a series of commands.  A command begins with a keyword
  883. X * and then up to three command-specific parameters.  The possible
  884. X * parameter types are also very restricted.  Here is a list of the
  885. X * parameter types:
  886. X *
  887. X *  F_KEYWORD.  The parameter is one of a list of keywords.  The keywords
  888. X *    are specified as a list of uppercase words, separated by
  889. X *    vertical bars, e.g., "RUBBER|CHICAGO|DUPLICATE|EMAIL|IMP".
  890. X *    Each keyword is indexed implicitly by its order in the array,
  891. X *   
  892. X *  F_BID.  The parameter is the name of a bid.
  893. X *
  894. X *  F_CARD.  The parameter is the name of a card.
  895. X *
  896. X *  F_INT.  The parameter is an integer.
  897. X *
  898. X *  F_FILENAME.  The parameter is the name of a file.
  899. X *
  900. X *  F_STRING.  The file is a string which terminates at the end of the
  901. X *    buffer.
  902. X *
  903. X *  F_NAME.  The parameter is a name of a player.  This is currently
  904. X *    treated in the same way as a filename.
  905. X *
  906. X *  F_DEAL.  The parameter is a deal of the cards.
  907. X *
  908. X * Consequently, we can encode each command with its keyword, the
  909. X * parameters it may accept, and a procedure for encoding a data
  910. X * structure to represent the command.  The action of the parser
  911. X * can then be described as follows.  We begin by identifying the
  912. X * command keyword.  Having done this, we attempt to parse the
  913. X * command specific parameters.  If this is successful, then we
  914. X * call the command specific procedure which creates the data structure
  915. X * representing the command.
  916. X *
  917. X * NOTE: The generalized parser is not re-entrant.
  918. X *
  919. X */
  920. X
  921. Xtypedef void (*command_handler) ();
  922. X
  923. X#define F_KEYWORD   000
  924. X#define F_BID       001
  925. X#define F_CARD      002
  926. X#define F_INT       003
  927. X#define F_FILENAME  004
  928. X#define F_STRING    005
  929. X#define F_NAME      006
  930. X#define F_DEAL      007
  931. X#define F_END       010
  932. X
  933. X#define F_OPTIONAL 0100
  934. X
  935. X
  936. Xtypedef struct {
  937. X  int    field_type;
  938. X  char   *field_descriptor;
  939. X} Field_Descriptor;
  940. X
  941. Xtypedef struct Command_Descriptor_Struct {
  942. X  char *command_name;
  943. X  Field_Descriptor fields[3];
  944. X  command_handler chandler;
  945. X} Command_Descriptor;
  946. X
  947. X#define NO_PARAM {F_END, NULL}
  948. X#define NOP NO_PARAM
  949. X#define END_PARSE_TABLE {NULL, {NO_PARAM, NO_PARAM, NO_PARAM}, NULL}
  950. X
  951. X/* The following macros define commonly used option lists: */
  952. X
  953. X#define PARSER_PLAYERS "NORTH|EAST|SOUTH|WEST"
  954. X#define PARSER_SEATS   "NORTH|EAST|SOUTH|WEST|OBS"
  955. X#define PARSER_ANSWER  "NO|YES"
  956. X#define PARSER_STATE   "OFF|ON"
  957. X#define PARSER_VULN    "NONE|EW|NS|BOTH"
  958. X#define PARSER_SCORE   "RUBBER|DUPLICATE|IMP|MP|CLEAR"
  959. X
  960. X/* The following macros define commonly used arguments to commands: */
  961. X#define A_SWITCH  {F_KEYWORD, PARSER_ANSWER}
  962. X#define A_STATE   {F_KEYWORD|F_OPTIONAL, PARSER_STATE}
  963. X#define A_PLAYER  {F_KEYWORD, PARSER_PLAYERS}
  964. X#define A_SEAT    {F_KEYWORD, PARSER_SEATS}
  965. X#define A_VULN    {F_KEYWORD, PARSER_VULN}
  966. X#define A_SCORE   {F_KEYWORD, PARSER_SCORE}
  967. X
  968. X/* The following macros define command lines where there is only one
  969. X   parameter: */
  970. X#define C_PARAM(x,y) {{x,y}, NOP, NOP}
  971. X#define C_EMPTY      {NOP, NOP, NOP}
  972. X#define C_KEY(x)     C_PARAM(F_KEYWORD, x)
  973. X#define C_INT(x)     C_PARAM(F_INT, x)
  974. X#define C_STRING(x)  C_PARAM(F_STRING, x)
  975. X
  976. X#define C_SWITCH     C_PARAM(F_KEYWORD, PARSER_STATE)
  977. X#define C_STATE      C_PARAM(F_KEYWORD|F_OPTIONAL, PARSER_STATE)
  978. X#define C_PLAYER     C_PARAM(F_KEYWORD, PARSER_PLAYERS)
  979. X#define C_SEAT       C_PARAM(F_KEYWORD, PARSER_SEATS)
  980. X#define C_SCORE      C_PARAM(F_KEYWORD, PARSER_SCORE)
  981. X#define C_VULN       C_PARAM(F_KEYWORD, PARSER_VULN)
  982. X
  983. X#ifdef PARSER
  984. X  char Parser_Error_Buf [80];
  985. X    /* A buffer where error messages are written if an error is
  986. X       encountered in processing the command. */
  987. X  int Parser_Error_Location;
  988. X    /* The index in the input buffer where trouble began. */
  989. X
  990. X#else
  991. X
  992. X  extern char Parser_Error_Buf [];
  993. X  extern int  Parser_Error_Location;
  994. X
  995. X#endif
  996. X
  997. Xextern int Parse_Command ();
  998. X/* int Parse_Command (Command_Descriptor *command_table, 
  999. X   int table_length, char *buffer); */
  1000. X/* Reads a command from the buffer and attempts to parse it according
  1001. X   to the given table.  If successful, then the command specific procedure
  1002. X   is called with the parsed parameters.  In this case, zero is returned.
  1003. X   If unsuccessful, records some error information in Parser_Error_Buf
  1004. X   and Parser_Error_Location and returns 1.
  1005. X*/
  1006. X
  1007. Xextern void Lcopy ();
  1008. X/* void Lcopy (char *from, char *to, int len); */
  1009. X/* Copies at most len-1 characters from from to to. */
  1010. X
  1011. X   
  1012. END_OF_FILE
  1013. if test 5817 -ne `wc -c <'parser.h'`; then
  1014.     echo shar: \"'parser.h'\" unpacked with wrong size!
  1015. fi
  1016. # end of 'parser.h'
  1017. fi
  1018. if test -f 'rc.c' -a "${1}" != "-c" ; then 
  1019.   echo shar: Will not clobber existing file \"'rc.c'\"
  1020. else
  1021. echo shar: Extracting \"'rc.c'\" \(9958 characters\)
  1022. sed "s/^X//" >'rc.c' <<'END_OF_FILE'
  1023. X/* rc.c
  1024. X *
  1025. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  1026. X ! 
  1027. X ! OKbridge is made available as a free service to the Internet.
  1028. X ! Accordingly, the following restrictions are placed on its use:
  1029. X ! 
  1030. X ! 1.  OKbridge may not be modified in any way without the explicit 
  1031. X !     permission of Matthew Clegg.  
  1032. X ! 
  1033. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  1034. X !     It may not be placed on for-profit networks or on for-profit
  1035. X !     computer systems.  It may not be bundled as part of a package
  1036. X !     or service provided by a for-profit organization.
  1037. X ! 
  1038. X ! If you have questions about restrictions on the use of OKbridge,
  1039. X ! write to mclegg@cs.ucsd.edu.
  1040. X ! 
  1041. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  1042. X ! damage which may be caused by OKbridge.
  1043. X *
  1044. X */
  1045. X
  1046. X#include <ctype.h>
  1047. X#include <stdio.h>
  1048. X#include <string.h>
  1049. X
  1050. X#include "types.h"
  1051. X#include "state.h"
  1052. X#include "parser.h"
  1053. X
  1054. X#ifdef GCC
  1055. Xextern fprintf (), strcasecmp (), fclose ();
  1056. X#endif
  1057. X
  1058. Xextern char *getenv ();
  1059. Xextern char *strdup ();
  1060. Xextern void exit ();
  1061. Xextern char *Get_CC_Value ();
  1062. Xextern int  Define_CC ();
  1063. X
  1064. X#ifndef index
  1065. Xextern char *index ();
  1066. X#endif
  1067. X
  1068. X#define    MAX_LENGTH    100
  1069. X
  1070. Xstatic void 
  1071. X  Autosave_Field (),
  1072. X  Bell_Field (), 
  1073. X  CC_Field (), 
  1074. X  CCDef_Field (),
  1075. X  Default_Field (), 
  1076. X  Email_Field (), 
  1077. X  Esckey_Field (),
  1078. X  Formal_Field (),
  1079. X  Fullname_Field (),
  1080. X  GPS_Field (),
  1081. X  GPS_IP_Field (),
  1082. X  Helpfile_Field (), 
  1083. X  Load_Field (), 
  1084. X  Log_Field (), 
  1085. X  My_IP_Field (),
  1086. X  Name_Field (), 
  1087. X  Position_Field (), 
  1088. X  Port_Field (), 
  1089. X  Prompt_Field (), 
  1090. X  Replay_Field (), 
  1091. X  Scoring_Field (), 
  1092. X  Server_Field (),
  1093. X  Timer_Field (),
  1094. X  Timezone_Field (),
  1095. X  Zlog_Field ();
  1096. X
  1097. Xstatic Command_Descriptor Startup_Commands [] = {
  1098. X  {"AUTOSAVE",  C_SWITCH, Autosave_Field},
  1099. X  {"BELL",      C_SWITCH, Bell_Field},
  1100. X  {"CC",        C_PARAM(F_STRING, "<convention-card>"), CC_Field},
  1101. X  {"CCDEF",     C_PARAM(F_STRING, "<cc-definition>"), CCDef_Field}, /* JAS */
  1102. X  {"DEFAULT",   C_SWITCH, Default_Field},
  1103. X
  1104. X  {"EMAIL",     C_PARAM(F_FILENAME, "<your-email-address>"), Email_Field},
  1105. X  {"ESCKEY",    C_PARAM(F_INT, "<decimal-key-code>"), Esckey_Field},
  1106. X  {"FORMAL",    C_SWITCH, Formal_Field},
  1107. X  {"FULLNAME",  C_PARAM(F_STRING, "<player's-full-name>"), Fullname_Field},
  1108. X  {"GPS",       C_SWITCH, GPS_Field},
  1109. X  {"GPS_IP",    {{F_FILENAME, "<GPS-server-IP>"}, 
  1110. X     {F_INT | F_OPTIONAL, "<GPS-port>"}, NOP}, GPS_IP_Field},
  1111. X
  1112. X  {"HELPFILE",  C_PARAM(F_FILENAME, "<helpfile-name>"), Helpfile_Field},
  1113. X  {"LOAD",      C_PARAM(F_FILENAME, "<email-file>"), Load_Field},
  1114. X  {"LOG",       C_PARAM(F_FILENAME, "<log-file>"), Log_Field},
  1115. X  {"MY_IP",     C_PARAM(F_FILENAME, "<local-IP-name-or-number>"), My_IP_Field},
  1116. X  {"NAME",      C_PARAM(F_NAME, "<player-name>"), Name_Field},
  1117. X
  1118. X  {"PORT",      C_PARAM(F_INT, "<server-port>"), Port_Field},
  1119. X  {"POSITION",  C_SEAT, Position_Field},
  1120. X  {"PROMPT",    C_SWITCH, Prompt_Field},
  1121. X  {"REPLAY",    C_PARAM(F_FILENAME, "<replay-file>"), Replay_Field},
  1122. X  {"SCORING",   C_SCORE, Scoring_Field},
  1123. X
  1124. X  {"SEAT",      C_SEAT, Position_Field},
  1125. X  {"SERVER",    C_PARAM(F_FILENAME, "<server-name>"), Server_Field},
  1126. X  {"TIMER",     C_SWITCH, Timer_Field},
  1127. X  {"TIMEZONE",  C_PARAM(F_STRING, "<local-timezone>"), Timezone_Field},
  1128. X  {"ZLOG",      C_PARAM(F_FILENAME, "<log-file>"), Zlog_Field},
  1129. X  END_PARSE_TABLE
  1130. X};
  1131. X
  1132. X#define STARTUP_TABLE_SIZE ( (sizeof(Startup_Commands) /  \
  1133. X         sizeof (Command_Descriptor)) - 1)    /* changed from 19 5-14-92 JAS */
  1134. X
  1135. X
  1136. Xstatic char line_buffer [MAX_LENGTH];
  1137. Xstatic int  line_no;
  1138. Xstatic FILE *init_file;
  1139. Xstatic int  error_flag;
  1140. X
  1141. Xextern int errno;
  1142. Xextern char *sys_errlist[];
  1143. X
  1144. Xextern int save_defaults;
  1145. Xextern int bell_is_on;
  1146. Xextern char *help_file_name;
  1147. Xextern FILE *logfile;
  1148. Xextern FILE *zhang_logfile;
  1149. Xextern int local_player;
  1150. Xextern int network_port;
  1151. Xextern int server_mode;
  1152. Xextern int timer_is_on;
  1153. Xextern char *server_name;
  1154. Xextern char *local_player_name;
  1155. Xextern char *autoload_file, *autosave_file;
  1156. Xextern char *local_player_full_name;
  1157. Xextern char *local_player_email;
  1158. Xextern char *local_cc;
  1159. Xextern char *GPS_IP;
  1160. Xextern int  GPS_port;
  1161. Xextern int  Use_GPS;
  1162. Xextern char *Timezone_name;
  1163. Xextern char Host_IP [];
  1164. Xextern int  Host_IP_is_known;
  1165. Xextern int  Escape_key;
  1166. X
  1167. X
  1168. Xstatic void Field_Error (error_msg)
  1169. X    char *error_msg;
  1170. X/* Prints out the current line from the field file along with an error
  1171. X   message.
  1172. X*/
  1173. X{
  1174. X        int i;
  1175. X
  1176. X    fprintf (stderr, "LINE %2d: %s\n", line_no, line_buffer);
  1177. X    for (i = 0; i < Parser_Error_Location + 9; i++)
  1178. X      fprintf (stderr, " ");
  1179. X    fprintf (stderr, "^ ERROR\n");
  1180. X    fprintf (stderr, "ERROR:  %s\n", error_msg);
  1181. X    error_flag = 1;
  1182. X}
  1183. X
  1184. Xstatic void Autosave_Field (i)
  1185. X     int *i;
  1186. X{
  1187. X  save_defaults = *i;
  1188. X}
  1189. X
  1190. Xstatic void Bell_Field (i)
  1191. X    int *i;
  1192. X{
  1193. X    bell_is_on = *i;
  1194. X}
  1195. X
  1196. Xstatic void CC_Field (c)
  1197. X     char *c;
  1198. X{
  1199. X  local_cc = strdup(Get_CC_Value(c));                         /* changed JAS */
  1200. X}
  1201. X
  1202. X/* Ccdef_Field Added JAS */
  1203. Xstatic void CCDef_Field(c)
  1204. X     char *c;
  1205. X{
  1206. X  
  1207. X  if (Define_CC(c, NULL))
  1208. X  {
  1209. X    char error_buf[80];
  1210. X    /* returns true on error */
  1211. X    sprintf (error_buf, "Error opening %s: %s", c,
  1212. X             sys_errlist[errno]);
  1213. X    Field_Error (error_buf);
  1214. X  }
  1215. X}
  1216. X
  1217. Xstatic void Default_Field (i)
  1218. X     int *i;
  1219. X{
  1220. X  default_plays = *i;
  1221. X}
  1222. X
  1223. Xstatic void Email_Field (e)
  1224. X     char *e;
  1225. X{
  1226. X  local_player_email = strdup(e);
  1227. X}
  1228. X
  1229. Xstatic void Esckey_Field (i)
  1230. X     int *i;
  1231. X{
  1232. X  Escape_key = *i;
  1233. X}
  1234. X
  1235. Xstatic void Formal_Field (i)
  1236. X     int *i;
  1237. X{
  1238. X/*  formal_mode = *i; */
  1239. X  ;
  1240. X}
  1241. X
  1242. Xstatic void Fullname_Field (f)
  1243. X     char *f;
  1244. X{
  1245. X  local_player_full_name = strdup(f);
  1246. X}
  1247. X
  1248. Xstatic void GPS_Field (use)
  1249. X     int *use;
  1250. X{
  1251. X  Use_GPS = *use;
  1252. X}
  1253. X
  1254. Xstatic void GPS_IP_Field (ip, port)
  1255. X     char *ip; int *port;
  1256. X{
  1257. X  GPS_IP = strdup (ip);
  1258. X  if (port != NULL)
  1259. X    GPS_port = *port;
  1260. X}
  1261. X
  1262. Xstatic void Helpfile_Field (s)
  1263. X    char *s;
  1264. X{
  1265. X    help_file_name = strdup (s);
  1266. X}
  1267. X
  1268. Xstatic void Load_Field (s)
  1269. X     char *s;
  1270. X{
  1271. X  autoload_file = strdup (s);
  1272. X}
  1273. X
  1274. Xstatic void Log_Field (s)
  1275. X    char *s;
  1276. X{
  1277. X    char error_buf [80];
  1278. X    char *filename;
  1279. X
  1280. X    if (s[0] == '+') {
  1281. X      filename = s + 1;
  1282. X      logfile = fopen (filename, "a");
  1283. X    } else {
  1284. X      filename = s;
  1285. X      logfile = fopen (filename, "w");
  1286. X    }
  1287. X    if (logfile == NULL) {
  1288. X        sprintf (error_buf, "Error opening %s: %s", filename,
  1289. X            sys_errlist[errno]);
  1290. X        Field_Error (error_buf);
  1291. X    }
  1292. X}
  1293. X
  1294. Xstatic void My_IP_Field (s)
  1295. X     char *s;
  1296. X{
  1297. X  sprintf (Host_IP, "%s", s);
  1298. X  Host_IP_is_known = 1;
  1299. X}
  1300. X
  1301. Xstatic void Name_Field (s)
  1302. X    char *s;
  1303. X{
  1304. X    local_player_name = strdup (s);
  1305. X}
  1306. X
  1307. Xstatic void Position_Field (i)
  1308. X    int *i;
  1309. X{
  1310. X    local_player = *i;
  1311. X}
  1312. X
  1313. Xstatic void Port_Field (i)
  1314. X    int *i;
  1315. X{
  1316. X    network_port = *i;
  1317. X}
  1318. X
  1319. Xstatic void Prompt_Field (i)
  1320. X    int *i;
  1321. X{
  1322. X    prompt_dummy = *i;
  1323. X}
  1324. X
  1325. Xstatic void Replay_Field (s)
  1326. X     char *s;
  1327. X{
  1328. X  autoload_file = strdup (s);
  1329. X  autosave_file = strdup (s);
  1330. X}
  1331. X
  1332. Xstatic void Scoring_Field (i)
  1333. X    int *i;
  1334. X{
  1335. X    scoring_mode = *i;
  1336. X}
  1337. X
  1338. Xstatic void Server_Field (s)
  1339. X    char *s;
  1340. X{
  1341. X    if (!strcasecmp(s, "ME"))
  1342. X        server_mode = 1;
  1343. X    else {
  1344. X        server_mode = 0;
  1345. X        server_name = strdup (s);
  1346. X    }
  1347. X}
  1348. X
  1349. Xstatic void Timer_Field (i)
  1350. X     int *i;
  1351. X{
  1352. X  timer_is_on = *i;
  1353. X}
  1354. X
  1355. Xstatic void Timezone_Field (t)
  1356. X     char *t;
  1357. X{
  1358. X  Timezone_name = strdup (t);
  1359. X}
  1360. X
  1361. Xstatic void Zlog_Field (s)
  1362. X    char *s;
  1363. X{
  1364. X    char error_buf [80];
  1365. X    char *filename;
  1366. X
  1367. X    if (s[0] == '+') {
  1368. X      filename = s + 1;
  1369. X      zhang_logfile = fopen (filename, "a");
  1370. X    } else {
  1371. X      filename = s;
  1372. X      zhang_logfile = fopen (filename, "w");
  1373. X    }
  1374. X    if (zhang_logfile == NULL) {
  1375. X        sprintf (error_buf, "Error opening %s: %s", filename,
  1376. X            sys_errlist[errno]);
  1377. X        Field_Error (error_buf);
  1378. X    }
  1379. X}
  1380. X
  1381. Xstatic int Read_Field_Line ()
  1382. X/* Reads a line from initialization file init_file and copies it into
  1383. X   line_buffer.  Returns 1 if data is returned, or 0 if the end of file
  1384. X   is reached.  Skips comment lines.  Strips trailing blanks from the
  1385. X   end of the line.
  1386. X*/
  1387. X{
  1388. X    int ch;
  1389. X    int line_length;
  1390. X
  1391. X    do {
  1392. X            line_length = 0;
  1393. X        ch = getc (init_file);
  1394. X        while ((ch != EOF) && (ch != '\n')) {
  1395. X            if (line_length < MAX_LENGTH)
  1396. X                line_buffer [line_length++] = ch;
  1397. X            ch = getc(init_file);
  1398. X        }
  1399. X        if (ch == EOF)
  1400. X            return (0);
  1401. X        line_no++;
  1402. X        while (line_buffer[line_length-1] == ' ')
  1403. X            line_length--;
  1404. X    } while ((line_length == 0) || (line_buffer[0] == '#'));
  1405. X
  1406. X    line_buffer[line_length] = '\0';
  1407. X    return (1);
  1408. X}
  1409. X
  1410. Xvoid Read_Initialization_File (basefilename)
  1411. X     char *basefilename;
  1412. X{
  1413. X    char *home_dir, filename_buf[128];
  1414. X
  1415. X    init_file = fopen (basefilename, "r");
  1416. X    home_dir = getenv ("HOME");
  1417. X
  1418. X    if ((init_file == NULL) && (home_dir != NULL)) {
  1419. X        sprintf (filename_buf, "%s/%s", home_dir, basefilename);
  1420. X        init_file = fopen (filename_buf, "r");
  1421. X    }
  1422. X
  1423. X    if (init_file == NULL) {
  1424. X        /* couldn't find an initialization file. */
  1425. X        return;
  1426. X    }
  1427. X
  1428. X    error_flag = 0;
  1429. X    while (Read_Field_Line()) {
  1430. X      if (Parse_Command (Startup_Commands, STARTUP_TABLE_SIZE, 
  1431. X                 line_buffer))
  1432. X        Field_Error (Parser_Error_Buf);
  1433. X    }
  1434. X
  1435. X    fclose (init_file);
  1436. X
  1437. X    if (error_flag) {
  1438. X        fprintf (stderr, "\nErrors in %s %s -- %s\n", basefilename,
  1439. X            "initialization file", "Program terminating");
  1440. X        exit (1);
  1441. X    }
  1442. X
  1443. X}
  1444. X
  1445. Xvoid Write_Initialization_File (basefilename)
  1446. X     char *basefilename;
  1447. X{
  1448. X    char *home_dir, filename_buf[128];
  1449. X
  1450. X    home_dir = getenv ("HOME");
  1451. X
  1452. X    init_file = NULL;
  1453. X    if (home_dir != NULL) {
  1454. X      sprintf (filename_buf, "%s/%s", home_dir, basefilename);
  1455. X      init_file = fopen (filename_buf, "w");
  1456. X    }
  1457. X
  1458. X    if (init_file == NULL)
  1459. X      init_file = fopen (basefilename, "w");
  1460. X
  1461. X    if (init_file == NULL)
  1462. X      return;
  1463. X
  1464. X    fprintf (init_file, "BELL %s\n", bell_is_on? "ON": "OFF");
  1465. X    fprintf (init_file, "DEFAULT %s\n", default_plays? "ON": "OFF");
  1466. X    if (local_player_email != NULL)
  1467. X      fprintf (init_file, "EMAIL %s\n", local_player_email);
  1468. X/*    fprintf (init_file, "FORMAL %s\n", formal_mode? "ON": "OFF"); */
  1469. X    if (local_player_full_name != NULL)
  1470. X      fprintf (init_file, "FULLNAME %s\n", local_player_full_name);
  1471. X    fprintf (init_file, "NAME %s\n", local_player_name);
  1472. X    fprintf (init_file, "PROMPT %s\n", prompt_dummy? "ON": "OFF");
  1473. X    fprintf (init_file, "SEAT %s\n", seat_names[local_player]);
  1474. X    fprintf (init_file, "TIMER %s\n", timer_is_on? "ON": "OFF");
  1475. X    fclose (init_file);
  1476. X
  1477. X}
  1478. END_OF_FILE
  1479. if test 9958 -ne `wc -c <'rc.c'`; then
  1480.     echo shar: \"'rc.c'\" unpacked with wrong size!
  1481. fi
  1482. # end of 'rc.c'
  1483. fi
  1484. if test -f 'types.h' -a "${1}" != "-c" ; then 
  1485.   echo shar: Will not clobber existing file \"'types.h'\"
  1486. else
  1487. echo shar: Extracting \"'types.h'\" \(10832 characters\)
  1488. sed "s/^X//" >'types.h' <<'END_OF_FILE'
  1489. X/* types.h -- global data values.
  1490. X *
  1491. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  1492. X ! 
  1493. X ! OKbridge is made available as a free service to the Internet.
  1494. X ! Accordingly, the following restrictions are placed on its use:
  1495. X ! 
  1496. X ! 1.  OKbridge may not be modified in any way without the explicit 
  1497. X !     permission of Matthew Clegg.  
  1498. X ! 
  1499. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  1500. X !     It may not be placed on for-profit networks or on for-profit
  1501. X !     computer systems.  It may not be bundled as part of a package
  1502. X !     or service provided by a for-profit organization.
  1503. X ! 
  1504. X ! If you have questions about restrictions on the use of OKbridge,
  1505. X ! write to mclegg@cs.ucsd.edu.
  1506. X ! 
  1507. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  1508. X ! damage which may be caused by OKbridge.
  1509. X *
  1510. X * This file defines the common data structures shared by all of the
  1511. X * modules of okbridge.
  1512. X *
  1513. X */
  1514. X
  1515. X#define TYPES_INCLUDED
  1516. X/* The following constants define the various game modes which we may be in.
  1517. X *  
  1518. X * The normal mode of operation is CLUB mode.  However, the program
  1519. X * also supports a PRACTICE mode and a FORMAL mode.  The features of
  1520. X * these modes are as follows:
  1521. X *
  1522. X * PRACTICE mode:
  1523. X *   1. During bidding, the players who are sitting may bid.  When it
  1524. X *      is time for a bid to be made from an unoccupied seat, the program
  1525. X *      automatically supplies a bid of "PASS".
  1526. X *   2. During play, the cards are revealed to everyone, and anyone may
  1527. X *      specify the next card to be played.
  1528. X *   3. A hand may be ended with the /claim command.  Confirmation is not
  1529. X *      requested for claims.
  1530. X *
  1531. X * FORMAL mode:
  1532. X *   1. Alerts are not shown to the partner of the person making the alert.
  1533. X *   2. Talk messages are not transmitted to partner.
  1534. X *   3. The dummy is not displayed to anyone until the opening lead has
  1535. X *      been made.
  1536. X *   4. The bidding cannot be reviewed after play has begun.
  1537. X */ 
  1538. X
  1539. X#define CLUB_PLAYING_MODE      0
  1540. X#define PRACTICE_PLAYING_MODE  1
  1541. X#define FORMAL_PLAYING_MODE    2
  1542. X
  1543. X/* The following constants define the possible states which the program
  1544. X * can be in.  The current program state is stored in the variable
  1545. X * game_mode.  The meaning of the states are:
  1546. X *  STARTUP:  This is the initial state of the program, and it is
  1547. X *            re-entered at the beginning of each hand.  STARTUP mode
  1548. X *            is terminated by a READY message, which should only be
  1549. X *            issued when the players have taken their seats.
  1550. X *  DEAL:     In this mode, we receive the board to be played.  DEAL
  1551. X *            mode is terminated by a BEGIN message.
  1552. X *  BIDDING:  This state is entered when we are in the bidding phase.
  1553. X *  PLAYING:  This state is entered when we are in the playing phase.
  1554. X *  SCORING:  This state is entered when we are displaying the scores
  1555. X *            for this hand.
  1556. X */
  1557. X#define STARTUP_MODE    0
  1558. X#define DEALING_MODE    1
  1559. X#define BIDDING_MODE    2
  1560. X#define PLAYING_MODE    3
  1561. X#define SCORING_MODE    4
  1562. X#define SKIP_MODE       5
  1563. X
  1564. X
  1565. X/* The following constants define the various reasons for a reset
  1566. X * (non-local branch to the top of the program).
  1567. X */
  1568. X
  1569. X#define RESET_FULL        1  /* A full reset has been delivered. */
  1570. X#define RESET_CONNECT     2  /* We have connected to a new server. */
  1571. X#define RESET_SERVE       3  /* We are opening a new table. */
  1572. X#define RESET_DISCONNECT  4  /* We have been disconnected from our server. */
  1573. X
  1574. X/* The following constants define the locations on the screen where
  1575. X * user input may occur.
  1576. X */
  1577. X#define PLAY_ROW    16
  1578. X#define PLAY_COL    1
  1579. X#define PLAY_LENGTH    30
  1580. X#define TALK_ROW    17
  1581. X#define TALK_COL    1
  1582. X#define TALK_LENGTH    75
  1583. X
  1584. X/* The following constants define the types of messages which may be
  1585. X * displayed in the talk window:
  1586. X */
  1587. X
  1588. X#define COMMENT_PRIVATE 0
  1589. X#define COMMENT_FORMAL  1
  1590. X#define COMMENT_PUBLIC  2
  1591. X/* The following constants are used to identify the sources of messages.
  1592. X * The possible sources are
  1593. X *   NORTH   -- the player sitting in the north seat (always the server).
  1594. X *   EAST    -- east
  1595. X *   SOUTH   -- south
  1596. X *   WEST    -- west
  1597. X *   OBS     -- an observer who is not playing the game.
  1598. X *   SERVER  -- the person who controls the network connections and also
  1599. X *              who controls the flow of the game.
  1600. X */
  1601. X
  1602. X#define PLAYER_NORTH    0
  1603. X#define PLAYER_EAST     1
  1604. X#define PLAYER_SOUTH    2
  1605. X#define PLAYER_WEST     3
  1606. X#define PLAYER_OBS      4
  1607. X#define PLAYER_SERVER   5
  1608. X#define PLAYER_TYPES    6
  1609. X
  1610. X#define IS_OBSERVER(x)  ((x) == PLAYER_OBS)
  1611. X#define IS_PLAYER(x)    ((0 <= (x)) && ((x) < PLAYER_OBS))
  1612. X
  1613. X#define SIDE_NS         0
  1614. X#define SIDE_EW         1
  1615. X
  1616. X/* Each suit is assigned a index, and each rank is also assigned a index.
  1617. X * This implicitly defines an index for each card, which is defined
  1618. X * as 4 * SUIT + RANK.
  1619. X */
  1620. X
  1621. X/* The following constants identify the suits.  No Trump is treated as
  1622. X * a suit because it reduces the number of special cases which must be
  1623. X * handled both in the bidding and the playing.
  1624. X */
  1625. X#define SUIT_CLUBS    0
  1626. X#define SUIT_DIAMONDS    1
  1627. X#define SUIT_HEARTS    2
  1628. X#define SUIT_SPADES    3
  1629. X#define SUIT_NOTRUMP    4
  1630. X#define MAJOR(suit)     ((suit == SUIT_HEARTS) || (suit == SUIT_SPADES))
  1631. X#define MINOR(suit)     ((suit == SUIT_CLUBS)  || (suit == SUIT_DIAMONDS))
  1632. X
  1633. X/* The ranks of the cards. */
  1634. X#define RANK_TWO    0
  1635. X#define RANK_THREE    1
  1636. X#define RANK_FOUR    2
  1637. X#define RANK_FIVE    3
  1638. X#define RANK_SIX    4
  1639. X#define RANK_SEVEN    5
  1640. X#define RANK_EIGHT    6
  1641. X#define RANK_NINE    7
  1642. X#define RANK_TEN    8
  1643. X#define RANK_JACK    9
  1644. X#define RANK_QUEEN    10
  1645. X#define RANK_KING    11
  1646. X#define RANK_ACE    12
  1647. X
  1648. X/* The bids are indexed from 0 to 36.  The first three bids are the special
  1649. X * cases: PASS, DOUBLE and REDOUBLE.  The remaining bids are ordered as
  1650. X * they should be. 
  1651. X */
  1652. X#define BID_PASS    0
  1653. X#define BID_DOUBLE    1
  1654. X#define BID_REDOUBLE    2
  1655. X#define BID_SUIT    3
  1656. X
  1657. X#define side_of(x)     (x%2)
  1658. X
  1659. X/* The following scoring modes are supported by okbridge:  */
  1660. X
  1661. X#define RUBBER_SCORING      0
  1662. X#define DUPLICATE_SCORING   1
  1663. X#define IMP_SCORING         2
  1664. X#define MP_SCORING          3
  1665. X
  1666. X#define CLEAR_SCORING       4  /* A bogus option used in the /score command
  1667. X                  to clear the current scores. */
  1668. X
  1669. X/* The following definitions define a few commonly used data types: */
  1670. X
  1671. X#define NAME_LENGTH     10
  1672. X#define MESSAGE_LENGTH  120
  1673. X#define BUFFER_LENGTH   100
  1674. X#define FILENAME_LENGTH 60
  1675. X
  1676. Xtypedef char name_buffer[NAME_LENGTH];
  1677. Xtypedef char message_buffer[MESSAGE_LENGTH];
  1678. Xtypedef char command_buffer[BUFFER_LENGTH];
  1679. Xtypedef char filename_buffer[FILENAME_LENGTH];
  1680. X
  1681. X/* We represent both a deck of cards and a hand by an array of 52 elements,
  1682. X * where the array is indexed by card indices.  That is, to each card we
  1683. X * associate a unique integer in the range 0-51, and this "card index"
  1684. X * is used to reference an array representing a deal or a hand.  In the
  1685. X * case of a deal, the array contains thirteen elements which are 0,
  1686. X * thirteen which are 1, thirteen which are 2, and thirteen which are 3.
  1687. X * Thus an element of an array refers to the holder of that particular
  1688. X * card.  We represent a hand by an array where thirteen elements are 1
  1689. X * and the rest are 0.  Thus, an element of an array is TRUE exactly when
  1690. X * that particular card is in the hand.
  1691. X */
  1692. X
  1693. Xtypedef char card_type;
  1694. Xtypedef card_type *suit_type;
  1695. Xtypedef card_type deal [52];
  1696. Xtypedef card_type hand [52];
  1697. Xtypedef int  bid_list [100];
  1698. X/* int suit_of (int card_code); */
  1699. X/* Returns the suit index associated to the card with the given card_code. */
  1700. X#define suit_of(cc)    ((cc)/13)
  1701. X/* int rank_of (int card_code); */
  1702. X/* Returns the rank index associated to the card with the given card_code. */
  1703. X#define rank_of(cc)    ((cc) % 13)
  1704. X
  1705. X/* int card_code (int suit, int rank); */
  1706. X/* Returns the index of the card having the given suit and rank. */
  1707. X#define card_code(suit,rank)  (13 * (suit) + (rank)) 
  1708. X
  1709. X/* int trumpsuit_of (int bid_code); */
  1710. X/* Returns the trump suit determined by a given bid. */
  1711. X#define trumpsuit_of(bc)    ((bc) > 2 ?  ((bc) - 3) % 5: -1)
  1712. X/* int contract_of (int bid_code); */
  1713. X/* Returns the level of the contract associated to the given bid. */
  1714. X#define level_of(bc)        ((bc) > 2 ?  (((bc) - 3) / 5) + 1: 0)
  1715. X
  1716. X#define ROTATION_LENGTH 16
  1717. X  /* The number of entries in the deal/vulnerabilities rotation sequence. */
  1718. X
  1719. X#ifdef _BRIDGE_
  1720. X    /* Character constants: */
  1721. X
  1722. X        char *major_revision_level = "1.7";  /* In theory, all copies of the
  1723. X                             program at a given major 
  1724. X                        revision level should be 
  1725. X                        compatible. */
  1726. X        char *minor_revision_level = "C";
  1727. X
  1728. X    char *card_names [] =  {"C2", "C3", "C4", "C5", "C6", "C7", "C8",
  1729. X                "C9", "CT", "CJ", "CQ", "CK", "CA",
  1730. X                "D2", "D3", "D4", "D5", "D6", "D7", "D8",
  1731. X                "D9", "DT", "DJ", "DQ", "DK", "DA",
  1732. X                "H2", "H3", "H4", "H5", "H6", "H7", "H8",
  1733. X                "H9", "HT", "HJ", "HQ", "HK", "HA",
  1734. X                "S2", "S3", "S4", "S5", "S6", "S7", "S8",
  1735. X                "S9", "ST", "SJ", "SQ", "SK", "SA",
  1736. X                NULL};
  1737. X    char *suit_names [] =  {"C", "D", "H", "S", "NT"};
  1738. X    char *rank_names [] =  {"2", "3", "4", "5", "6", "7", "8", "9",
  1739. X                "T", "J", "Q", "K", "A"};
  1740. X    char *bid_names  [] =  {"P" , "X" , "XX",
  1741. X                "1C", "1D", "1H", "1S", "1NT",
  1742. X                "2C", "2D", "2H", "2S", "2NT",
  1743. X                "3C", "3D", "3H", "3S", "3NT",
  1744. X                "4C", "4D", "4H", "4S", "4NT",
  1745. X                "5C", "5D", "5H", "5S", "5NT",
  1746. X                "6C", "6D", "6H", "6S", "6NT",
  1747. X                "7C", "7D", "7H", "7S", "7NT",
  1748. X                NULL};
  1749. X    char *seat_names [] ={"NORTH", "EAST", "SOUTH", "WEST", "OBS",
  1750. X                  "MOD"};
  1751. X    /* Information regarding the positions of the players: */
  1752. X    int player_next [] = {1, 2, 3, 0};
  1753. X    int player_prev [] = {3, 0, 1, 2};
  1754. X    int player_partner [] = {2, 3, 0, 1};
  1755. X
  1756. X        /* The rotation of deals and vulnerabilities: */
  1757. X
  1758. X        int dealer_list [16] =
  1759. X          {PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST,
  1760. X       PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST,
  1761. X       PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST,
  1762. X           PLAYER_NORTH, PLAYER_EAST, PLAYER_SOUTH, PLAYER_WEST};
  1763. X
  1764. X        int ns_vulnerability_list [16] =
  1765. X          {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0};
  1766. X
  1767. X        int ew_vulnerability_list [16] =
  1768. X          {0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1};
  1769. X
  1770. X        char *month_names [] =
  1771. X          { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", 
  1772. X            "Sept", "Oct", "Nov", "Dec"};
  1773. X
  1774. X        char *long_suit_names [] = 
  1775. X          {"CLUB", "DIAMOND", "HEART", "SPADE", "NO TRUMP"};
  1776. X
  1777. X#else
  1778. X    /* Character constants: */
  1779. X        extern char *major_revision_level, *minor_revision_level;
  1780. X          extern char *card_names[],
  1781. X            *suit_names[],
  1782. X            *rank_names[],
  1783. X            *bid_names[],
  1784. X            *seat_names[];
  1785. X
  1786. X    /* Information regarding the positions of the players: */
  1787. X    extern int  player_next [],
  1788. X            player_prev [],
  1789. X            player_partner [];
  1790. X        extern int dealer_list [], ns_vulnerability_list [], 
  1791. X          ew_vulnerability_list [];
  1792. X
  1793. X        extern char *month_names [], *long_suit_names [];
  1794. X#endif
  1795. END_OF_FILE
  1796. if test 10832 -ne `wc -c <'types.h'`; then
  1797.     echo shar: \"'types.h'\" unpacked with wrong size!
  1798. fi
  1799. # end of 'types.h'
  1800. fi
  1801. echo shar: End of archive 11 \(of 14\).
  1802. cp /dev/null ark11isdone
  1803. MISSING=""
  1804. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  1805.     if test ! -f ark${I}isdone ; then
  1806.     MISSING="${MISSING} ${I}"
  1807.     fi
  1808. done
  1809. if test "${MISSING}" = "" ; then
  1810.     echo You have unpacked all 14 archives.
  1811.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1812. else
  1813.     echo You still need to unpack the following archives:
  1814.     echo "        " ${MISSING}
  1815. fi
  1816. ##  End of shell archive.
  1817. exit 0
  1818.