home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume13 / okbridge / part06 < prev    next >
Encoding:
Internet Message Format  |  1992-01-12  |  54.8 KB

  1. Path: uunet!spool.mu.edu!uwm.edu!ogicse!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v13i021:  okbridge - computer-mediated bridge game, Part06/07
  5. Message-ID: <2280@masterCNA.TEK.COM>
  6. Date: 10 Jan 92 16:45:15 GMT
  7. Article-I.D.: masterCN.2280
  8. Sender: news@masterCNA.TEK.COM
  9. Lines: 1832
  10. Approved: billr@saab.CNA.TEK.COM
  11.  
  12. Submitted-by: mclegg@cs.UCSD.EDU (Matthew Clegg)
  13. Posting-number: Volume 13, Issue 21
  14. Archive-name: okbridge/Part06
  15. Environment: BSD-derived Unix, 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 6 (of 7)."
  26. # Contents:  code.c email.h globals.h help.c input.h oktally.c
  27. #   scoring.c
  28. # Wrapped by billr@saab on Fri Jan 10 08:31:29 1992
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'code.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'code.c'\"
  32. else
  33. echo shar: Extracting \"'code.c'\" \(8947 characters\)
  34. sed "s/^X//" >'code.c' <<'END_OF_FILE'
  35. X/* code.c
  36. X ! 
  37. X ! Copyright (C) 1990,1991 by Matthew Clegg
  38. X ! 
  39. X ! This program may be copied and distributed freely.  Please do not
  40. X ! charge money for this program or for any program derived from it.
  41. X ! If you modify this program, then include a notice stating plainly
  42. X ! that your program is derived from the okbridge program and is not
  43. X ! the same as the official okbridge program.
  44. X !
  45. X ! I welcome any suggestions for improvement to okbridge, and 
  46. X ! I would be especially happy to receive improved source code.
  47. X ! If you have comments or suggestions, or if you would like to
  48. X ! join the okbridge mailing list, then write to
  49. X !
  50. X !   mclegg@cs.ucsd.edu
  51. X !
  52. X *
  53. X * This file implements procedures for a very simple cipher which
  54. X * is used to encode crucial parts of the files which contain
  55. X * email duplicate hands.
  56. X *
  57. X * The intention of this cipher is to make the contents
  58. X * of an email duplicate file non-obvious.  This cipher is certainly
  59. X * not intended to be difficult to break -- it is simply intended to
  60. X * allow email duplicate files to be manipulated (e.g., mailed, copied,
  61. X * etc.) without having their contents revealed.
  62. X *
  63. X * The cipher that we use is based upon the following principles:
  64. X *    1.  Only the 64 characters a-zA-Z0-9+- are encoded.
  65. X *        This defines a function h(c) for characters c which is 0
  66. X *        if c is not coded and which is a unique integer in the
  67. X *        range [1,64] if c is coded.
  68. X *    2.  An initial permutation p the integers [1,64] is chosen.
  69. X *    3.  Given a string s, a permuted string s' is computed according
  70. X *        to the following formula:
  71. X *
  72. X *      s'[i] =  s[i]                  if h[s[i]] = 0,
  73. X *           h^-1 [ p[ (h[s[i]] + i) mod 64 ]]    otherwise.
  74. X *
  75. X *        In other words, the encoding of a character is determined
  76. X *        by a fixed permutation and by its index in the string.
  77. X *
  78. X * An email duplicate file begins with a header line identifying the
  79. X * fact that it is an email duplicate file.  The following line contains
  80. X * the permutation which has been used to encode the file.  The
  81. X * succeeding lines are a mixture of plain-text and coded lines.
  82. X * Coded lines begin with an exclamation point '!'.
  83. X */
  84. X
  85. X#include <stdio.h>
  86. X
  87. X
  88. Xextern char *malloc ();
  89. X
  90. X/* extern long random (); */
  91. Xextern int rand ();
  92. X#define random(n) ((rand () / 64) % n)
  93. X
  94. Xint codefile_line_no;
  95. X    /* The number of lines that have been read from the current
  96. X           coded file. */
  97. X
  98. X#define CIPHER_SIZE    64
  99. X#define CIPHER_SIZE1    65
  100. X
  101. Xstatic  int cipher_mapping [128];    /* the function h above. */
  102. Xstatic  int cipher_unmapping [128];    /* h^-1, where defined  */
  103. Xstatic  int mapping_is_initialized = 0;
  104. X
  105. Xtypedef int cipher_encoding [128];    /* the function p above. */
  106. Xtypedef int cipher_decoding [128];    /* p^-1 */
  107. X
  108. Xtypedef struct Encoded_File_Struct {
  109. X    cipher_encoding        encoding;
  110. X    cipher_decoding        decoding;
  111. X    FILE            *cf;
  112. X} Encoded_File;
  113. X
  114. Xstatic void Initialize_Cipher_Mapping ()
  115. X{
  116. X    int i;
  117. X
  118. X    for (i = 0; i < 128; i++)
  119. X        cipher_mapping[i] = cipher_unmapping[i] = 0;
  120. X    for (i = 'A'; i <= 'Z'; i++)
  121. X        cipher_mapping[i] = i - 'A' + 1;
  122. X    for (i = 'a'; i <= 'z'; i++)
  123. X        cipher_mapping[i] = i - 'a' + 26 + 1;
  124. X    for (i = '0'; i <= '9'; i++)
  125. X        cipher_mapping[i] = i - '0' + 52 + 1;
  126. X    cipher_mapping['+'] = 63;
  127. X    cipher_mapping['-'] = 64;
  128. X
  129. X    for (i = 0; i < 128; i++)
  130. X        if (cipher_mapping[i])
  131. X            cipher_unmapping[cipher_mapping[i]] = i;
  132. X};
  133. X
  134. Xstatic int Read_Line (f, buf, buflen)
  135. X    FILE *f; char *buf; int buflen;
  136. X/* Reads a line of up to buflen characters from the file f into
  137. X   the buffer buf.  Returns the number of characters read, or -1
  138. X   if EOF reached.
  139. X*/
  140. X{
  141. X    int i, ch;
  142. X
  143. X    i = 0;
  144. X    while ((ch = getc(f)) != '\n') {
  145. X        if (ch == EOF)
  146. X            return (-1);
  147. X        if ((i < buflen - 1) && (ch != '\015'))
  148. X            buf[i++] = ch;
  149. X    };
  150. X    buf[i] = '\0';
  151. X    codefile_line_no++;
  152. X    return (i);
  153. X};
  154. X
  155. Xint Reset_Encoded_File (filename, check_string, ef)
  156. X    char *filename, *check_string; Encoded_File **ef;
  157. X/* Opens the named file for input.  Returns a pointer to a structure
  158. X   describing the opened file.  If an error occurs in opening the
  159. X   file, returns -1, in which case the system error code is stored
  160. X   in errno.  Reads lines from the file until a line is found which
  161. X   matches check_string.  If the check_string is not found, then
  162. X   returns 1.  Else, reads the cipher_encoding from the following line.
  163. X   Allocates a new Encoded_File structure and stores its location in ef.
  164. X   Returns 0 on success.
  165. X*/
  166. X{
  167. X    FILE *code_file;
  168. X    char *check_buffer, code_buffer [CIPHER_SIZE1];
  169. X    int buflen, read_code, i;
  170. X
  171. X    if (!mapping_is_initialized)
  172. X        Initialize_Cipher_Mapping ();
  173. X
  174. X    if (strcmp(filename, "-"))
  175. X      code_file = fopen (filename, "r");
  176. X    else
  177. X      code_file = stdin;
  178. X
  179. X    if (code_file == NULL)
  180. X        return (-1);
  181. X    codefile_line_no = 0;
  182. X
  183. X    buflen = strlen (check_string);
  184. X    check_buffer = malloc (buflen + 1);
  185. X    do {
  186. X        read_code = Read_Line (code_file, check_buffer, buflen+1);
  187. X    } while ((read_code >= 0) && strcmp (check_string, check_buffer));
  188. X    free (check_buffer);
  189. X    if (read_code < 0) {
  190. X        fclose (code_file);
  191. X        return (1);
  192. X    };
  193. X
  194. X    read_code = Read_Line (code_file, code_buffer, CIPHER_SIZE1);
  195. X    if (read_code < 0) {
  196. X        fclose (code_file);
  197. X        return (1);
  198. X    };
  199. X
  200. X    *ef = (Encoded_File *) malloc(sizeof(Encoded_File));
  201. X    for (i = 0; i < CIPHER_SIZE; i++)
  202. X        (*ef)->encoding[i+1] = cipher_mapping[code_buffer[i]];
  203. X    for (i = 1; i < CIPHER_SIZE1; i++)
  204. X        (*ef)->decoding[(*ef)->encoding[i]] = i;
  205. X    (*ef)->cf = code_file;
  206. X    return (0);
  207. X};
  208. X
  209. Xstatic void Encode_Line (ef, buf)
  210. X    Encoded_File *ef; char *buf;
  211. X{
  212. X    int i, base_code;
  213. X
  214. X    for (i = 0; buf[i] != '\0'; i++)
  215. X        if ((base_code = cipher_mapping[buf[i]]) != 0)
  216. X            buf[i] = cipher_unmapping [ef->encoding[
  217. X                    (base_code + 3*i) % CIPHER_SIZE + 1]];
  218. X};
  219. X
  220. Xstatic void Decode_Line (ef, buf)
  221. X    Encoded_File *ef; char *buf;
  222. X{
  223. X    int i, p, base_code;
  224. X
  225. X    for (i = 0; buf[i] != '\0'; i++)
  226. X        if ((base_code = cipher_mapping[buf[i]]) != 0) {
  227. X            p = (ef->decoding[base_code] + 3*CIPHER_SIZE - 3*i)
  228. X                % CIPHER_SIZE - 1;
  229. X            if (p == 0) p = CIPHER_SIZE;
  230. X            buf[i] = cipher_unmapping[p];
  231. X        };
  232. X            
  233. X
  234. X};
  235. X
  236. Xint Read_Encoded_Line (ef, buf, buflen)
  237. X    Encoded_File *ef; char *buf; int buflen;
  238. X/* Reads a line of up to buflen characters from the encoded file ef
  239. X   into buf.  If the first character of the line is '!', then strips
  240. X   that character and applies the decoding algorithm to the remainder
  241. X   of the line.  Otherwise, just copies the line from the input file
  242. X   to the buffer.  Returns the number of characters read or -1 if
  243. X   the end of file is reached.
  244. X*/
  245. X{
  246. X    int i, read_code, base_mapping;
  247. X
  248. X    read_code = Read_Line (ef->cf, buf, buflen);
  249. X    if ((read_code <= 0) || (buf[0] != '!'))
  250. X        return (read_code);
  251. X
  252. X    for (i = 0; i < read_code; i++)
  253. X        buf[i] = buf[i+1];
  254. X    read_code -= 1;
  255. X
  256. X    Decode_Line (ef, buf);
  257. X    return (read_code);
  258. X    
  259. X};
  260. X
  261. Xint Rewrite_Encoded_File (filename, check_string, ef)
  262. X    char *filename, *check_string; Encoded_File **ef;
  263. X/* Opens the named file for output.  Returns a pointer to a structure
  264. X   describing the opened file.  If an error occurs in opening the file,
  265. X   then returns -1, in which case the system error code is stored
  266. X   in errno.  Invents a permutation for the new encoded file.
  267. X   Writes the check_string as the first line of the new file,
  268. X   and the permutation as the second line.  Returns 0 to indicate
  269. X   success.
  270. X*/
  271. X{
  272. X    FILE *code_file;
  273. X    char code_buffer [CIPHER_SIZE1];
  274. X    int read_code, i, t, c;
  275. X
  276. X    if (!mapping_is_initialized)
  277. X        Initialize_Cipher_Mapping ();
  278. X
  279. X    if (strcmp(filename, "-"))
  280. X      code_file = fopen (filename, "w");
  281. X    else
  282. X      code_file = stdout;
  283. X
  284. X    if (code_file == NULL)
  285. X        return (-1);
  286. X
  287. X    *ef = (Encoded_File *) malloc(sizeof(Encoded_File));
  288. X
  289. X    for (i = 1; i < CIPHER_SIZE1; i++) 
  290. X        (*ef)->encoding [i] = i;
  291. X    for (i = 1; i < CIPHER_SIZE; i++) {
  292. X        c = random (CIPHER_SIZE + 1 - i);
  293. X        t = (*ef)->encoding[i+c]; 
  294. X        (*ef)->encoding[i+c] = (*ef)->encoding[i];
  295. X        (*ef)->encoding[i] = t;
  296. X    };
  297. X
  298. X    for (i = 1; i < CIPHER_SIZE1; i++)
  299. X        (*ef)->decoding[(*ef)->encoding[i]] = i;
  300. X
  301. X    (*ef)->cf = code_file;
  302. X
  303. X    fprintf ((*ef)->cf, "%s\n", check_string);
  304. X    
  305. X    for (i = 0; i < CIPHER_SIZE; i++)
  306. X        code_buffer[i] = cipher_unmapping[(*ef)->encoding[i+1]];
  307. X    code_buffer[CIPHER_SIZE] = '\0';
  308. X    fprintf ((*ef)->cf, "%s\n", code_buffer);
  309. X
  310. X    return (0);
  311. X        
  312. X};
  313. Xint Write_Encoded_Line (ef, buf)
  314. X    Encoded_File *ef; char *buf;
  315. X/* Writes the encoded version of the string from buf to the encoded
  316. X   file ef.  Returns 0 on success or 1 if the system reports an error.
  317. X*/
  318. X{
  319. X    Encode_Line (ef, buf);
  320. X    fprintf (ef->cf, "!%s\n", buf);
  321. X    fflush (ef->cf);
  322. X    Decode_Line (ef, buf);
  323. X    return (0);
  324. X};
  325. X
  326. Xint Write_Unencoded_Line (ef, buf)
  327. X    Encoded_File *ef; char *buf;
  328. X/* Writes the unencoded line in buf to the file ef. */
  329. X{
  330. X    if (buf[0] == '!')
  331. X        fprintf (ef->cf, " %s\n", buf);
  332. X    else
  333. X        fprintf (ef->cf, "%s\n", buf);
  334. X    return (0);
  335. X};
  336. X
  337. Xvoid Close_Encoded_File (ef)
  338. X    Encoded_File *ef;
  339. X/* Closes the file associated to ef and disposes of the memory
  340. X   associated to ef. */
  341. X{
  342. X        if ((ef->cf != stdout) && (ef->cf != stdin)) {
  343. X      fflush (ef->cf);
  344. X      fclose (ef->cf);
  345. X    };
  346. X    free (ef);
  347. X};
  348. END_OF_FILE
  349. if test 8947 -ne `wc -c <'code.c'`; then
  350.     echo shar: \"'code.c'\" unpacked with wrong size!
  351. fi
  352. # end of 'code.c'
  353. fi
  354. if test -f 'email.h' -a "${1}" != "-c" ; then 
  355.   echo shar: Will not clobber existing file \"'email.h'\"
  356. else
  357. echo shar: Extracting \"'email.h'\" \(5047 characters\)
  358. sed "s/^X//" >'email.h' <<'END_OF_FILE'
  359. X/* email.h
  360. X ! 
  361. X ! Copyright (C) 1990,1991 by Matthew Clegg
  362. X ! 
  363. X ! This program may be copied and distributed freely.  Please do not
  364. X ! charge money for this program or for any program derived from it.
  365. X ! If you modify this program, then include a notice stating plainly
  366. X ! that your program is derived from the okbridge program and is not
  367. X ! the same as the official okbridge program.
  368. X !
  369. X ! I welcome any suggestions for improvement to okbridge, and 
  370. X ! I would be especially happy to receive improved source code.
  371. X ! If you have comments or suggestions, or if you would like to
  372. X ! join the okbridge mailing list, then write to
  373. X !
  374. X !   mclegg@cs.ucsd.edu
  375. X !
  376. X *
  377. X * This file defines the data structures associated with reading
  378. X * and writing email duplicate files.  An email duplicate file
  379. X * has the following information:
  380. X *
  381. X *  1.  Some header information, including the encryption key,
  382. X *      the number of boards played, and the number of player pairs.
  383. X *
  384. X *  2.  A list of player-pairs.
  385. X *
  386. X *  3.  A list of boards.  This includes the deal of the cards and
  387. X *      also a series of scores.
  388. X *
  389. X * The email duplicate structure mirrors the contents of an email
  390. X * duplicate file more or less directly.
  391. X *
  392. X */
  393. X
  394. Xtypedef struct Email_Comment_struct {
  395. X    char     *comment;
  396. X    struct Email_Comment_struct *next;
  397. X} Email_Comment;
  398. X
  399. Xtypedef struct Email_Pair_struct {
  400. X    char    *ne;    /* The north/east player's name. */
  401. X    char    *sw;    /* The south/west player's name. */
  402. X    int    match_points;
  403. X} Email_Pair;
  404. X
  405. Xtypedef struct Email_Score_struct {
  406. X    int    ns_pair;    /* The north-south pair number. */
  407. X    int     ew_pair;    /* The east-west pair number. */
  408. X    int    bid;        /* Index of bid in bid_names. */
  409. X    int    doubled;    /* 0, BID_DOUBLE or BID_REDOUBLE. */
  410. X    int    contractor;    /* PLAYER_NORTH ... PLAYER_WEST. */
  411. X    int    result;
  412. X    int    ns_score;    /* +score for contract made, -score for down.*/
  413. X    int    ns_match_points;
  414. X    int    ew_match_points;
  415. X    struct Email_Score_struct *next;
  416. X} Email_Score;
  417. X
  418. Xtypedef struct Email_Board_struct {
  419. X    hand    deal;
  420. X    int     dealer;
  421. X    int    ns_vulnerable, ew_vulnerable;
  422. X    Email_Comment *pre_script, *post_script;
  423. X    Email_Score *score_list;
  424. X    struct Email_Board_struct *next;
  425. X} Email_Board;
  426. X
  427. Xstruct Email_Duplicate_struct {
  428. X    int    nboards;    /* The number of boards played. */
  429. X    int     npairs;        /* The number of player-pairs. */
  430. X    Email_Pair  *player_list;
  431. X    Email_Board *board_list;
  432. X};
  433. X
  434. X
  435. Xextern int Read_Email_Duplicate_File ();
  436. X/*
  437. Xint Read_Email_Duplicate_File (filename, email_struct)
  438. X    char *filename; struct Email_Duplicate_Struct **email_struct; */
  439. X/* Reads an email duplicate file.  If successful, then allocates a
  440. X   structure to represent the file and returns a pointer to that
  441. X   structure in email_struct.  Returns 0 in this case.  If an error
  442. X   occurred opening the file, then returns -1 with the system error
  443. X   code in errno.  If an error is detected in the format of the file,
  444. X   then returns 1.
  445. X*/
  446. X
  447. Xextern int Write_Email_Duplicate_File ();
  448. X/*
  449. Xint Write_Email_Duplicate_File (filename, encode_flag, email_struct)
  450. X    char *email_file; int encode_flag;
  451. X    struct Email_Duplicate_Struct *email_struct; 
  452. X*/
  453. X/* Writes an email duplicate file to filename.  If encode_flag is true,
  454. X   then encodes critical parts of the file.  If no errors, returns 0.
  455. X   Otherwise, returns -1 with the system error code in errno.
  456. X*/
  457. X
  458. Xextern void Free_Email_Duplicate_Struct ();
  459. X/*
  460. Xvoid Free_Email_Duplicate_Struct (email_struct)
  461. X    struct Email_Duplicate_struct *email_struct; */
  462. X/* Simply de-allocates email_struct and its substructures. */
  463. X
  464. Xextern struct Email_Duplicate_struct *New_Email_Duplicate_Struct ();
  465. X/* Allocates an empty email duplicate structure to be used for
  466. X   recording email duplicate hands.
  467. X*/
  468. X
  469. Xextern int Add_Email_Pair ();
  470. X/*
  471. Xint Add_Email_Pair (email_struct, ne_name, sw_name)
  472. X    struct Email_Duplicate_struct *email_struct;
  473. X    char *ne_name, *sw_name;
  474. X*/
  475. X/* Appends a new player-pair to the list of players in email_struct.
  476. X   Returns the pair number assigned to them.
  477. X*/
  478. X
  479. Xextern Email_Board *Add_Email_Board ();
  480. X/*
  481. XEmail_Board *Add_Email_Board (email_struct, new_deal)
  482. X    struct Email_Duplicate_struct *email_struct;
  483. X    hand new_deal;
  484. X*/
  485. X/* Appends the given hand to the list of boards in email_struct. 
  486. X   Returns a pointer to the newly allocated board.
  487. X*/
  488. X
  489. Xextern void Record_Email_Score ();
  490. X/*
  491. Xvoid Record_Email_Score (email_board,
  492. X    ns_pair, ew_pair, bid, doubled, contractor, result, ns_score)
  493. X    struct Email_Board *email_board;
  494. X    int ns_pair, ew_pair, bid, contractor, result, ns_score;
  495. X*/
  496. X/* Constructs a new score record containing the information
  497. X   ns_pair, ew_pair, bid, contractor, result and ns_score.
  498. X   Links this into the list of score records associated to email_board.
  499. X   The list is maintained in ascending order according to ns_score.
  500. X*/
  501. X
  502. Xextern void Compute_Board_Match_Points ();
  503. X/*
  504. Xvoid Compute_Board_Match_Points (email_board)
  505. X    struct Email_Board *email_board;
  506. X*/
  507. X/* Computes the ns_match_points and ew_match_points fields for each of
  508. X   the records in the score list of email_board.  The number recorded
  509. X   is actually twice the number of match points awarded.  
  510. X*/
  511. X
  512. END_OF_FILE
  513. if test 5047 -ne `wc -c <'email.h'`; then
  514.     echo shar: \"'email.h'\" unpacked with wrong size!
  515. fi
  516. # end of 'email.h'
  517. fi
  518. if test -f 'globals.h' -a "${1}" != "-c" ; then 
  519.   echo shar: Will not clobber existing file \"'globals.h'\"
  520. else
  521. echo shar: Extracting \"'globals.h'\" \(9551 characters\)
  522. sed "s/^X//" >'globals.h' <<'END_OF_FILE'
  523. X/* globals.h -- global data values.
  524. X ! 
  525. X ! Copyright (C) 1990,1991 by Matthew Clegg
  526. X ! 
  527. X ! This program may be copied and distributed freely.  Please do not
  528. X ! charge money for this program or for any program derived from it.
  529. X ! If you modify this program, then include a notice stating plainly
  530. X ! that your program is derived from the okbridge program and is not
  531. X ! the same as the official okbridge program.
  532. X !
  533. X ! I welcome any suggestions for improvement to okbridge, and 
  534. X ! I would be especially happy to receive improved source code.
  535. X ! If you have comments or suggestions, or if you would like to
  536. X ! join the okbridge mailing list, then write to
  537. X !
  538. X !   mclegg@cs.ucsd.edu
  539. X !
  540. X * This file contains the definitions of all of the global variables.
  541. X * These variables represent the state of the current game.  It seems
  542. X * to be more convenient to make them global variables than to store
  543. X * them locally and pass them as parameters to various procedures.
  544. X *
  545. X * The definition _BRIDGE_ is used to distinguish the external
  546. X * references to these variables from the actual definitions.  The module
  547. X * which defines these variables should give a definition to _BRIDGE_
  548. X * before including this file.
  549. X */
  550. X/* #define LOOPBACK_MODE */
  551. X/* #define TWOPLAYER_MODE */
  552. X/* The following constants define the possible states which the program
  553. X * can be in.  The current program state is stored in the variable
  554. X * game_mode.
  555. X */
  556. X#define STARTUP_MODE    0
  557. X#define DEALING_MODE    1
  558. X#define BIDDING_MODE    2
  559. X#define PLAYING_MODE    3
  560. X#define REVIEW_MODE     4
  561. X/* The following constants define the locations on the screen where
  562. X * user input may occur.
  563. X */
  564. X#define PLAY_ROW    16
  565. X#define PLAY_COL    1
  566. X#define PLAY_LENGTH    30
  567. X#define TALK_ROW    17
  568. X#define TALK_COL    1
  569. X#define TALK_LENGTH    75
  570. X/* The following constants are used to refer to the positions of various
  571. X * players.  The players are named NORTH, SOUTH, EAST and WEST.
  572. X * However, the assignment of these positions to the screen display
  573. X * may vary from game to game.  And the position of the declarer may
  574. X * vary from hand to hand.
  575. X */
  576. X#define PLAYER_NORTH    0
  577. X#define PLAYER_EAST    1
  578. X#define PLAYER_SOUTH    2
  579. X#define PLAYER_WEST    3
  580. X#define POS_TOP        0
  581. X#define POS_RIGHT    1
  582. X#define POS_BOTTOM    2
  583. X#define POS_LEFT    3
  584. X#define GAME_DECLARER    0
  585. X#define GAME_OPPL    1
  586. X#define GAME_DUMMY    2
  587. X#define GAME_OPPR    3
  588. X#define SUIT_CLUBS    0
  589. X#define SUIT_DIAMONDS    1
  590. X#define SUIT_HEARTS    2
  591. X#define SUIT_SPADES    3
  592. X#define SUIT_NOTRUMP    4
  593. X#define MAJOR(suit)     ((suit == SUIT_HEARTS) || (suit == SUIT_SPADES))
  594. X#define MINOR(suit)     ((suit == SUIT_CLUBS)  || (suit == SUIT_DIAMONDS))
  595. X
  596. X#define RANK_TWO    0
  597. X#define RANK_THREE    1
  598. X#define RANK_FOUR    2
  599. X#define RANK_FIVE    3
  600. X#define RANK_SIX    4
  601. X#define RANK_SEVEN    5
  602. X#define RANK_EIGHT    6
  603. X#define RANK_NINE    7
  604. X#define RANK_TEN    8
  605. X#define RANK_JACK    9
  606. X#define RANK_QUEEN    10
  607. X#define RANK_KING    11
  608. X#define RANK_ACE    12
  609. X#define BID_PASS    0
  610. X#define BID_DOUBLE    1
  611. X#define BID_REDOUBLE    2
  612. X#define BID_SUIT    3
  613. X
  614. X#define SIDE_NS        0
  615. X#define SIDE_EW        1
  616. X#define side_of(x)     (x%2)
  617. X
  618. X#define RUBBER_SCORING    0
  619. X#define CHICAGO_SCORING   1
  620. X#define DUPLICATE_SCORING 2 
  621. X#define EMAIL_SCORING      3
  622. X#define IMP_SCORING       4
  623. X
  624. X/* We represent both a deck of cards and a hand by an array of 52 elements,
  625. X * where the array is indexed by card indices.  That is, to each card we
  626. X * associate a unique integer in the range 0-51, and this "card index"
  627. X * is used to reference an array representing a deal or a hand.  In the
  628. X * case of a deal, the array contains thirteen elements which are 0,
  629. X * thirteen which are 1, thirteen which are 2, and thirteen which are 3.
  630. X * Thus an element of an array refers to the holder of that particular
  631. X * card.  We represent a hand by an array where thirteen elements are 1
  632. X * and the rest are 0.  Thus, an element of an array is TRUE exactly when
  633. X * that particular card is in the hand.
  634. X */
  635. X
  636. Xtypedef char card_type;
  637. Xtypedef card_type *suit_type;
  638. Xtypedef card_type deal [52];
  639. Xtypedef card_type hand [52];
  640. Xtypedef int  bid_list [10];
  641. X#ifdef _BRIDGE_
  642. X    /* Character constants: */
  643. X
  644. X        char *major_revision_level = "1.5";  /* In theory, all copies of the
  645. X                             program at a given major 
  646. X                        revision level should be 
  647. X                        compatible. */
  648. X        char *minor_revision_level = "Q";
  649. X
  650. X    char *card_names [] =  {"C2", "C3", "C4", "C5", "C6", "C7", "C8",
  651. X                "C9", "CT", "CJ", "CQ", "CK", "CA",
  652. X                "D2", "D3", "D4", "D5", "D6", "D7", "D8",
  653. X                "D9", "DT", "DJ", "DQ", "DK", "DA",
  654. X                "H2", "H3", "H4", "H5", "H6", "H7", "H8",
  655. X                "H9", "HT", "HJ", "HQ", "HK", "HA",
  656. X                "S2", "S3", "S4", "S5", "S6", "S7", "S8",
  657. X                "S9", "ST", "SJ", "SQ", "SK", "SA"};
  658. X    char *suit_names [] =  {"C", "D", "H", "S", "NT"};
  659. X    char *rank_names [] =  {"2", "3", "4", "5", "6", "7", "8", "9",
  660. X                "T", "J", "Q", "K", "A"};
  661. X    char *bid_names  [] =  {"P" , "X" , "XX",
  662. X                "1C", "1D", "1H", "1S", "1NT",
  663. X                "2C", "2D", "2H", "2S", "2NT",
  664. X                "3C", "3D", "3H", "3S", "3NT",
  665. X                "4C", "4D", "4H", "4S", "4NT",
  666. X                "5C", "5D", "5H", "5S", "5NT",
  667. X                "6C", "6D", "6H", "6S", "6NT",
  668. X                "7C", "7D", "7H", "7S", "7NT",
  669. X                NULL};
  670. X    char *player_names [] ={"NORTH", "EAST", "SOUTH", "WEST"};
  671. X    /* Information regarding the positions of the players: */
  672. X    int player_next [] = {1, 2, 3, 0};
  673. X    int player_prev [] = {3, 0, 1, 2};
  674. X    int player_partner [] = {2, 3, 0, 1};
  675. X    int local_player;            /* the local player */
  676. X        int scoring_mode;            
  677. X        int prompt_dummy = 1;                   /* true if the dummy should
  678. X                           be prompted after each 
  679. X                           play. */
  680. X        int default_plays=1;                    /* true if default plays
  681. X                           are allowed. */
  682. X
  683. X    /* Information regarding the current hand: */
  684. X    int  dealer,
  685. X         game_mode;        /* whether we are bidding or playing. */
  686. X    deal current_deal;
  687. X    hand current_hand [4];  /* indexed by player position. */
  688. X        int trick;              /* number of tricks played in current hand */
  689. X    /* Information regarding the current trick being played: */
  690. X    int leader;        /* Which player leads the current trick? */
  691. X    int no_plays;        /* The number of cards played in this trick. */
  692. X    int plays[4];        /* The cards played so far in this trick,
  693. X                   indexed by the position of the player. */
  694. X    /* Information about the bidding: */
  695. X    int trump_suit;        /* trump suit for current hand. */
  696. X    int contract;        /* (rank of) contract in current hand. */
  697. X    int declarer;        /* declarer in current hand. */
  698. X        int dummy;              /* dummy in current hand. */
  699. X    int doubled, redoubled; /* boolean flags. */
  700. X    bid_list bids [4];    /* index by player position */
  701. X    int no_bids;
  702. X    /* Scoring information: */
  703. X    int tricks [2];        /* no. tricks won by each side in this hand. */
  704. X    int above_line [2];    /* 'above-the-line' points for each side. */
  705. X    int below_line [2];    /* 'below-the-line' points for each side. */
  706. X    int vulnerable [2];    /* number of games won by each side in this
  707. X                   rubber */
  708. X    int hands_played;    /* the number of hands that have been
  709. X                   played so far. */
  710. X    /* Information used for email duplicate scoring: */
  711. X    int total_no_deals;    /* the total number of deals to make
  712. X                   before querying for further action. */
  713. X    int current_deal_no;    /* the current deal number. */
  714. X    int replaying_mode;    /* true if we are "replaying" hands that have
  715. X                   been read from a file. */
  716. X    int ns_pair_no;        /* the pair number assigned to north-south */
  717. X    int ew_pair_no;        /* the pair number assigned to east-west */
  718. X    struct Email_Duplicate_struct *email_record;
  719. X                /* record of the email duplicate hands. */
  720. X    struct Email_Board_struct *current_board;    
  721. X                /* the current board being played. */
  722. X
  723. X#else
  724. X    /* Character constants: */
  725. X        extern char *major_revision_level, *minor_revision_level;
  726. X          extern char *card_names[],
  727. X            *suit_names[],
  728. X            *rank_names[],
  729. X            *bid_names[],
  730. X            *player_names[];
  731. X
  732. X    /* Information regarding the positions of the players: */
  733. X    extern int  player_next [],
  734. X            player_prev [],
  735. X            player_partner [],
  736. X            local_player;
  737. X        extern int scoring_mode;
  738. X        extern int prompt_dummy;
  739. X        extern int default_plays;
  740. X    /* Information regarding the current hand: */
  741. X    extern int  dealer,
  742. X            game_mode;
  743. X    extern deal current_deal;
  744. X    extern hand current_hand [4];
  745. X        extern int  trick;
  746. X    /* Information about the bidding: */
  747. X    extern int  trump_suit,
  748. X            contract,
  749. X            declarer,
  750. X                    dummy,
  751. X            doubled, redoubled;
  752. X    extern bid_list bids [4];
  753. X    extern int  no_bids;
  754. X    /* Information regarding the current trick being played: */
  755. X    extern int  leader,
  756. X            no_plays,
  757. X            plays [];
  758. X    /* Scoring information: */
  759. X    extern int  tricks[],
  760. X            above_line [],
  761. X            below_line [],
  762. X            vulnerable [],
  763. X            hands_played;
  764. X    /* Information used for email duplicate scoring: */
  765. X    extern int total_no_deals,
  766. X           current_deal_no,
  767. X           replaying_mode,
  768. X           ns_pair_no,
  769. X           ew_pair_no;
  770. X    extern struct Email_Duplicate_struct *email_record;
  771. X    extern struct Email_Board_struct *current_board;    
  772. X#endif
  773. X/* int suit_of (int card_code); */
  774. X/* Returns the suit index associated to the card with the given card_code. */
  775. X#define suit_of(cc)    (cc/13)
  776. X/* int rank_of (int card_code); */
  777. X/* Returns the rank index associated to the card with the given card_code. */
  778. X#define rank_of(cc)    (cc % 13)
  779. X/* int trumpsuit_of (int bid_code); */
  780. X/* Returns the trump suit determined by a given bid. */
  781. X#define trumpsuit_of(bc)    ((bc) > 2 ?  ((bc) - 3) % 5: -1)
  782. X/* int contract_of (int bid_code); */
  783. X/* Returns the level of the contract associated to the given bid. */
  784. X#define contract_of(bc)        ((bc) > 2 ?  (((bc) - 3) / 5) + 1: 0)
  785. X
  786. END_OF_FILE
  787. if test 9551 -ne `wc -c <'globals.h'`; then
  788.     echo shar: \"'globals.h'\" unpacked with wrong size!
  789. fi
  790. # end of 'globals.h'
  791. fi
  792. if test -f 'help.c' -a "${1}" != "-c" ; then 
  793.   echo shar: Will not clobber existing file \"'help.c'\"
  794. else
  795. echo shar: Extracting \"'help.c'\" \(6323 characters\)
  796. sed "s/^X//" >'help.c' <<'END_OF_FILE'
  797. X/* help.c -- help functions for the bridge program.
  798. X ! 
  799. X ! Copyright (C) 1990,1991 by Matthew Clegg
  800. X ! 
  801. X ! This program may be copied and distributed freely.  Please do not
  802. X ! charge money for this program or for any program derived from it.
  803. X ! If you modify this program, then include a notice stating plainly
  804. X ! that your program is derived from the okbridge program and is not
  805. X ! the same as the official okbridge program.
  806. X !
  807. X ! I welcome any suggestions for improvement to okbridge, and 
  808. X ! I would be especially happy to receive improved source code.
  809. X ! If you have comments or suggestions, or if you would like to
  810. X ! join the okbridge mailing list, then write to
  811. X !
  812. X !   mclegg@cs.ucsd.edu
  813. X !
  814. X *
  815. X */
  816. X#include <stdio.h>
  817. X#include <string.h>
  818. X#include <ctype.h>
  819. X
  820. X#ifndef SEEK_SET
  821. X#define SEEK_SET  0
  822. X#endif
  823. X#include "globals.h"
  824. X#include "ps.h"
  825. X#include "input.h"
  826. X#include "terminal.h"
  827. X/* char *help_file_name = "okbridge.help"; */
  828. X#include "helpfile.h"
  829. Xextern int errno;
  830. Xextern char *sys_errlist[];
  831. Xextern char *strdup();
  832. Xextern char *getenv ();
  833. X
  834. Xtypedef struct help_entry_struct {
  835. X    char    *topic;
  836. X    char    *description;
  837. X    long int file_offset;
  838. X    struct help_entry_struct *next;
  839. X} *help_entry;
  840. Xstatic help_entry main_topic = NULL;
  841. XFILE *help_file = NULL;
  842. X
  843. Xstatic display_topics (message)
  844. X    char *message;
  845. X/* Displays the list of topics, with the given message as the top line.
  846. X . Does not display the main topic.
  847. X */
  848. X{
  849. X    int i;
  850. X    help_entry e;
  851. X    char msg_buf[80];
  852. X    clear_screen ();
  853. X    print (1,1,message);
  854. X    if (main_topic == NULL) {
  855. X        print (3,1,"The help system is empty.");
  856. X    } else {
  857. X        i = 3;
  858. X        for (e = main_topic->next; e != NULL; e = e->next) {
  859. X          if (strcasecmp(e->topic, "slam")) {
  860. X            sprintf (msg_buf, "%-10s -- %s",e->topic,
  861. X                e->description);
  862. X            print (i++, 1, msg_buf);
  863. X              };
  864. X        };
  865. X    };
  866. X    input_acknowledgment (24);
  867. X};
  868. Xstatic int read_help_line (buf, buflen)
  869. X    char *buf;
  870. X/* Reads a line from the help file.  Returns the number of characters
  871. X   read of -1 if EOF is encountered.  Skips lines beginning with a '#'. 
  872. X*/
  873. X{
  874. X    int i, ch;
  875. X    do {
  876. X        ch = getc(help_file);
  877. X        i = 0;
  878. X        while ((ch != '\n') && (ch != EOF)) {
  879. X            if (i < buflen-1) buf[i++] = ch;
  880. X            ch = getc(help_file);
  881. X        };
  882. X        buf[i] = '\0';
  883. X        if (ch == EOF) return (-1);
  884. X        while ((i > 0) && isspace(buf[i-1])) buf[--i] = '\0';
  885. X    } while (buf[0] == '#');
  886. X    return (i);
  887. X};
  888. Xstatic display_help_entry (e)
  889. X    help_entry e;
  890. X/* Displays the help_entry e. */
  891. X{
  892. X    char line[81];
  893. X    int lines_on_page, log;
  894. X
  895. X    lines_on_page = 0;
  896. X/*
  897. X    sprintf (line, "%s -- %s", e->topic, e->description);
  898. X    print(++lines_on_page, 1, line);
  899. X    lines_on_page += 1;
  900. X*/
  901. X
  902. X    fseek (help_file, e->file_offset, SEEK_SET);
  903. X    log = read_help_line (line, 81);
  904. X    while ((log >= 0) && strcmp(line, "--")) {
  905. X        if ((lines_on_page > 22) || (line[0] == '^')) {
  906. X            input_acknowledgment (24);
  907. X            clear_screen ();
  908. X            lines_on_page = 0;
  909. X            if (line[0] == '^') line[0] = ' ';
  910. X        };
  911. X        print (++lines_on_page, 1, line);
  912. X        log = read_help_line (line, 81);
  913. X    };
  914. X    input_acknowledgment (24);
  915. X        
  916. X};
  917. X
  918. Xstatic FILE *open_helpfile ()
  919. X/* Tries to open the helpfile with given name from the help_directory.
  920. X * If an error, prints an error message and returns NULL.  Otherwise,
  921. X * returns a pointer to the opened file.
  922. X */
  923. X{
  924. X    char filename_buf [80], msg_buf[80], *envhelpdir;
  925. X    FILE *fp;
  926. X    if ((envhelpdir = getenv("OKBRIDGE_HELPFILE")) != NULL)
  927. X        sprintf (filename_buf, "%s", envhelpdir);
  928. X    else
  929. X        sprintf (filename_buf, "%s", help_file_name);
  930. X
  931. X    fp = fopen (filename_buf, "r");
  932. X    if (fp == NULL)
  933. X        fp = fopen ("okbridge.help", "r");
  934. X
  935. X    if (fp == NULL) {
  936. X        sprintf (msg_buf, "Error opening helpfile %s", filename_buf);
  937. X        print (3, 1, msg_buf);
  938. X        sprintf (msg_buf, "System reports error: %s",
  939. X                sys_errlist[errno]);
  940. X        print (4, 1, msg_buf);
  941. X        input_acknowledgment (24);
  942. X    };
  943. X    return (fp);
  944. X};
  945. Xstatic help_entry find_help_topic (topic)
  946. X    char *topic;
  947. X/* Looks for the help entry with the associated topic.  If it is found,
  948. X * returns a pointer to the corresponding record.  Otherwise, returns NULL.
  949. X */
  950. X{
  951. X    help_entry e;
  952. X    e = main_topic;
  953. X    while (e != NULL) {
  954. X        if (!strcasecmp(e->topic, topic))
  955. X            return (e);
  956. X        e = e->next;
  957. X    };
  958. X    return (e);
  959. X};
  960. Xstatic help_entry read_new_help_entry ()
  961. X/* Reads a help entry from the help_file.  Allocates a help_entry record
  962. X . and records the pertinent information in that record.  Returns the
  963. X . allocated record or NULL if the end of file is reached.
  964. X */
  965. X{
  966. X    char line_buf[81], keyword_buf[80];
  967. X    help_entry e;
  968. X    char *curpos, *keypos, *descpos, ch;
  969. X    int log;
  970. X
  971. X    log = read_help_line (line_buf, 81);
  972. X    if (log < 0)
  973. X        return (NULL);
  974. X
  975. X    for (keypos = line_buf; isspace(*keypos); keypos++);
  976. X    for (curpos = keypos;(*curpos != '\0') && !isspace(*curpos);curpos++);
  977. X    for (descpos = curpos; isspace(*descpos); descpos++);
  978. X
  979. X    e = (help_entry) malloc(sizeof(struct help_entry_struct));
  980. X    *curpos = '\0';
  981. X    e->topic = strdup (keypos);
  982. X    e->description = strdup (descpos);
  983. X    e->file_offset = ftell (help_file);
  984. X    e->next = NULL;
  985. X
  986. X    do
  987. X        log = read_help_line (line_buf, 81);
  988. X    while 
  989. X        ((log >= 0) && strcmp(line_buf, "--"));
  990. X
  991. X    return (e);
  992. X
  993. X};
  994. X
  995. Xinitialize_help_system ()
  996. X/* Called once at the beginning of the program to read the file of help
  997. X * topics.
  998. X */
  999. X{
  1000. X    help_entry e;
  1001. X    help_file = open_helpfile ();
  1002. X    if (help_file == NULL) return;
  1003. X    e = main_topic = read_new_help_entry ();
  1004. X    while (e != NULL) {
  1005. X        e->next = read_new_help_entry ();
  1006. X        e = e->next;
  1007. X    };
  1008. X
  1009. X};
  1010. Xdisplay_help (topic)
  1011. X    char *topic;
  1012. X/* Displays help on the given topic.  This consists of looking up the
  1013. X * help file associated to this topic and displaying the contents of this
  1014. X * file on the screen.  If the topic string is empty, then displays first
  1015. X * the contents of the main topic file, and then displays a list of the
  1016. X * topics.  If there is no help on the given topic, then displays a list
  1017. X * of topics.
  1018. X */
  1019. X{
  1020. X    help_entry he;
  1021. X    char line_buf[81];
  1022. X    if (main_topic == NULL)
  1023. X        return;
  1024. X    Suspend_Comment_Display ();
  1025. X        clear_screen ();
  1026. X    if (strlen(topic) == 0) {
  1027. X        display_help_entry (main_topic);
  1028. X                display_topics ("Here is a list of available topics: ");
  1029. X    } else if ((he = find_help_topic(topic)) != NULL)
  1030. X        display_help_entry (he);
  1031. X    else {
  1032. X        sprintf (line_buf, "%s  %s",
  1033. X         "There is no help for this topic.",
  1034. X         "The available topics are");
  1035. X        display_topics (line_buf);
  1036. X    };
  1037. X    Continue_Comment_Display ();
  1038. X};
  1039. END_OF_FILE
  1040. if test 6323 -ne `wc -c <'help.c'`; then
  1041.     echo shar: \"'help.c'\" unpacked with wrong size!
  1042. fi
  1043. # end of 'help.c'
  1044. fi
  1045. if test -f 'input.h' -a "${1}" != "-c" ; then 
  1046.   echo shar: Will not clobber existing file \"'input.h'\"
  1047. else
  1048. echo shar: Extracting \"'input.h'\" \(7783 characters\)
  1049. sed "s/^X//" >'input.h' <<'END_OF_FILE'
  1050. X/* input.h -- interface for input module of bridge game.
  1051. X ! 
  1052. X ! Copyright (C) 1990,1991 by Matthew Clegg
  1053. X ! 
  1054. X ! This program may be copied and distributed freely.  Please do not
  1055. X ! charge money for this program or for any program derived from it.
  1056. X ! If you modify this program, then include a notice stating plainly
  1057. X ! that your program is derived from the okbridge program and is not
  1058. X ! the same as the official okbridge program.
  1059. X !
  1060. X ! I welcome any suggestions for improvement to okbridge, and 
  1061. X ! I would be especially happy to receive improved source code.
  1062. X ! If you have comments or suggestions, or if you would like to
  1063. X ! join the okbridge mailing list, then write to
  1064. X !
  1065. X !   mclegg@cs.ucsd.edu
  1066. X !
  1067. X *
  1068. X * This file defines the routines for handling the player-input
  1069. X * in the bridge game.
  1070. X *
  1071. X */
  1072. X/* The main job of the input module is to return a record indicating
  1073. X . a player's input.  However, the input module also controls 
  1074. X . some of the bookkeeping and communications aspects of the game.  The
  1075. X . commands having index 100 or greater are handled internally to the
  1076. X . input module and are not ever passed back to the calling routines.
  1077. X */
  1078. X#define CMD_ERROR    000
  1079. X#define CMD_VULN    001
  1080. X#define CMD_RDEAL    002
  1081. X#define CMD_BID        004
  1082. X#define CMD_PLAY    010
  1083. X#define CMD_FINISH    020
  1084. X#define CMD_HELLO    0000000100
  1085. X#define CMD_ACK        0000000200
  1086. X#define CMD_TALK    0000000400
  1087. X#define CMD_HELP    0000001000
  1088. X#define CMD_QUIT    0000002000
  1089. X#define CMD_BELL    0000004000
  1090. X#define CMD_PING    0000010000
  1091. X#define CMD_ECHO    0000020000
  1092. X#define CMD_PROMPT      0000040000
  1093. X#define CMD_CLAIM    0000100000
  1094. X#define CMD_RESP    0000200000
  1095. X#define CMD_SCORE       0000400000
  1096. X#define CMD_LOG         0001000000
  1097. X#define CMD_DEAL    0002000000
  1098. X#define CMD_LOAD    0004000000
  1099. X#define CMD_SAVE    0010000000
  1100. X#define CMD_REPLAY      0020000000
  1101. X#define CMD_COMMENT    0040000000
  1102. X#define CMD_DEFAULT     0100000000
  1103. X#define CMD_REVIEW      0200000000
  1104. X/* #define MAX_COMMANDS    25 */
  1105. X
  1106. X#define VERSION_LENGTH    10
  1107. X#define VERSION_NAME_LENGTH 20
  1108. X#define MESSAGE_LENGTH    75
  1109. X#define TOPIC_LENGTH    20
  1110. X#define FILENAME_LENGTH 60
  1111. Xtypedef struct player_command_struct {
  1112. X    long    command;
  1113. X    int    player_no;
  1114. X    union  {
  1115. X        int     bid;
  1116. X        int     card;
  1117. X        char     deal [52];
  1118. X        char     version_name [VERSION_NAME_LENGTH];
  1119. X        char    message [MESSAGE_LENGTH];
  1120. X        char    topic [TOPIC_LENGTH];
  1121. X        char    filename [FILENAME_LENGTH];
  1122. X        int    bell;
  1123. X        int    ping_source;
  1124. X        int     prompt;
  1125. X        int     tricks;
  1126. X        int    response;
  1127. X        int     scoring;
  1128. X        int    nhands;
  1129. X        int    vulnerable;
  1130. X        int     defaalt;
  1131. X    } data;
  1132. X} *player_command;
  1133. Xtypedef struct input_buffer_struct {
  1134. X    char    buf[91];
  1135. X    int    row, col, length;    /* aspects of the screen display. */
  1136. X    int    pos;            /* cursor position in buffer. */
  1137. X    int     defaulted;              /* true if input buffer contains the
  1138. X                       default input. */
  1139. X} *input_buffer;
  1140. X#ifndef _INPUT_
  1141. Xextern parse_player_command ();
  1142. X/* void parse_player_command (parse_string ps, player_command pc); */
  1143. X/* parse the string ps into a player command, which is stored in pc.
  1144. X * If an error is encountered, then an error message is stored in the
  1145. X * global variable parsing_errmsg.
  1146. X *
  1147. X * The syntax of a player command is as follows:
  1148. X *
  1149. X * 0.  VULN  NONE | EW | NS | BOTH
  1150. X * 1.  RDEAL <cards>
  1151. X * 2.  BID  (<level> (<suit> | <notrump>)) | <pass> | <double> | <redouble>
  1152. X * 3.  PLAY <suit> <card>
  1153. X * 4.  CLAIM <ntricks>
  1154. X * 5.  FINISH YES | NO
  1155. X * 6.  TALK message
  1156. X * 7.  HELLO version name
  1157. X * 8.  ACK   version name
  1158. X * 9.  HELP [topic]
  1159. X * 10. BELL [ON | OFF]
  1160. X * 11. PROMPT [ON | OFF]
  1161. X * 12. PING
  1162. X * 13. ECHO [player]
  1163. X * 14. SCORE mode
  1164. X * 15. LOG <log-file>
  1165. X * 16. DEAL [nhands]
  1166. X * 17. LOAD filename
  1167. X * 18. SAVE filename
  1168. X * 19. REPLAY filename
  1169. X * 20. COMMENT broadcast-message
  1170. X * 21. QUIT
  1171. X *
  1172. X * where:
  1173. X *  <cards> = A string over the alphabet {0,1,2,3} containing exactly
  1174. X *            thirteen occurrences of each symbol.
  1175. X *  <level> = 1 | 2 | 3 | 4 | 5 | 6 | 7
  1176. X *  <suit>  = C | D | H | S | CLUB[S] | DIAMOND[S] | HEART[S] | SPADE[S]
  1177. X *  <notrump> = N | NT | NOTRUMP
  1178. X *  <pass> = P | PASS
  1179. X *  <double> = X | DOUBLE
  1180. X *  <redouble> = XX | REDOUBLE
  1181. X *  <card> = <suit> <rank>
  1182. X *  <rank> = 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | T | J | Q | K
  1183. X *             | JACK | KING | QUEEN
  1184. X *  <tricks>  = an integer in the range 0 - 13.
  1185. X *  <version> = a string indicating the revision level of the program
  1186. X *  <name>    = the name of a player
  1187. X *  <player>  = NORTH | EAST | SOUTH | WEST
  1188. X *  <mode>    = RUBBER | CHICAGO
  1189. X */
  1190. Xextern clear_input_buffer ();
  1191. X/* void clear_input_buffer (input_buffer ib); */
  1192. X/* Clears the screen display representing the input buffer, and
  1193. X * resets the cursor position to the beginning of the buffer.
  1194. X */
  1195. Xextern int update_input_buffer ();
  1196. X/* int update_input_buffer (input_buffer ib, int ch); */
  1197. X/* Adds the character ch to the input buffer, or if it is a control
  1198. X * character, then modifies the cursor position or buffer appropriately.
  1199. X * If the user has indicated he is through entering input, by entering
  1200. X * i.e. <^J> or <^M>, then TRUE is returned.  Otherwise, FALSE is
  1201. X * returned.  The other control characters which are accepted at this
  1202. X * point are:
  1203. X *    <^H>    causes last character in buffer to be erased.
  1204. X *     <^R>    causes the screen to be refreshed.
  1205. X *    <DEL>    causes last character in buffer to be erased.
  1206. X *    <ESC>    causes entire buffer to be erased.
  1207. X * Printable characters are entered into the buffer if there is room.
  1208. X * All other characters are ignored.
  1209. X */
  1210. Xextern Initialize_Input ();
  1211. X/* void Initialize_Input (void); */
  1212. X/* This routine should be called once when the program first begins,
  1213. X *  in order to set up the input buffers correctly.
  1214. X */
  1215. Xextern input_hand ();
  1216. X/* void input_hand (deal new_deal); */
  1217. X/* Inputs a new deal into the data structure 'new_deal'.  If the dealer
  1218. X * is the local_player, then the deck is shuffled locally and the deal
  1219. X * is messaged to the other players.  Otherwise, we wait for the other
  1220. X * players to send us the new deal.
  1221. X */
  1222. Xextern int input_bid ();
  1223. X/* int input_bid (int rmt_player, int minimum_bid, int double_ok,
  1224. X     int redouble_ok); */
  1225. X/* Inputs a bid from the player 'rmt_player'.  If rmt_player is the
  1226. X * local player, then we only accept a contract bid which is at least as
  1227. X * high as minimum_bid, and we only accept a double or redouble bid if
  1228. X * respectively double_ok and redouble_ok is true.  However, if rmt_player
  1229. X * is not the local player, then we wait for the bid to come from the
  1230. X * network.  In this case, we assume that the bid we receive is legal.
  1231. X */
  1232. Xextern int input_play ();
  1233. X/* int input_play (int rmt_player, hand legal_plays); */
  1234. X/* Inputs a play from the player 'rmt_player'.  If rmt_player is the
  1235. X * local player, then we only accept a play which is listed as one of the
  1236. X * cards in 'legal_plays'.  However, if rmt_player is not the local player,
  1237. X * then we wait for the play to come from the network.  In this case, we
  1238. X * assume that the play is legal.  If the return value is non-negative,
  1239. X * then it indicates the card which has been played.  Otherwise,
  1240. X * the return value is of the form -k-1, where k is the number of
  1241. X * additional tricks conceded to the declaring team in this hand.
  1242. X */
  1243. Xextern input_acknowledgement ();
  1244. X/* void input_acknowledgment (int line); */
  1245. X/* Displays the message "PRESS RETURN TO CONTINUE" on the given screen line,
  1246. X * unless line == -1, in which case the message is displayed on the
  1247. X * status line.  Then waits for the user to press, RETURN.
  1248. X */
  1249. Xextern send_player_message (); 
  1250. X/* send_player_message (char *message); */
  1251. X/* Transmits the message to the other players through the network. 
  1252. X * Prepends the name of the player to the message before transmitting.
  1253. X */
  1254. Xextern Broadcast_Comment ();
  1255. X/* Broadcase_Comment (char *message); */
  1256. X/* Transmits the message to the other players as a comment which is
  1257. X * displayed in the talk window.
  1258. X */
  1259. X
  1260. X#endif
  1261. END_OF_FILE
  1262. if test 7783 -ne `wc -c <'input.h'`; then
  1263.     echo shar: \"'input.h'\" unpacked with wrong size!
  1264. fi
  1265. # end of 'input.h'
  1266. fi
  1267. if test -f 'oktally.c' -a "${1}" != "-c" ; then 
  1268.   echo shar: Will not clobber existing file \"'oktally.c'\"
  1269. else
  1270. echo shar: Extracting \"'oktally.c'\" \(6530 characters\)
  1271. sed "s/^X//" >'oktally.c' <<'END_OF_FILE'
  1272. X/* tally.c
  1273. X ! 
  1274. X ! Copyright (C) 1991 by Matthew Clegg
  1275. X ! 
  1276. X ! This program may be copied and distributed freely.  Please do not
  1277. X ! charge money for this program or for any program derived from it.
  1278. X ! If you modify this program, then include a notice stating plainly
  1279. X ! that your program is derived from the okbridge program and is not
  1280. X ! the same as the official okbridge program.
  1281. X !
  1282. X ! I welcome any suggestions for improvement to okbridge, and 
  1283. X ! I would be especially happy to receive improved source code.
  1284. X ! If you have comments or suggestions, or if you would like to
  1285. X ! join the okbridge mailing list, then write to
  1286. X !
  1287. X !   mclegg@cs.ucsd.edu
  1288. X !
  1289. X * This program merges email duplicate files, totaling the match
  1290. X * points for corresponding pairs in each file.
  1291. X *
  1292. X * Usage:
  1293. X *
  1294. X *   tally [-c] [-sn] file_1 file_2 ... file_n
  1295. X *
  1296. X * Reads each of file_1, file_2, ..., file_n.  Merges the boards
  1297. X * from these files and totals the match points for each pair.
  1298. X * Writes the merged set of boards to standard output.  If the
  1299. X * -c flag is given, then the output is written in encoded format.
  1300. X * If the "-sn" parameter is given, then "n" is interpreted to be
  1301. X * some positive integer which determines the number of hands to
  1302. X * skip before writing the first hand to output.  If a filename is
  1303. X * given simply as "-", then the hands are read from standard input.
  1304. X */
  1305. X
  1306. X#include <stdio.h>
  1307. X#include <string.h>
  1308. X
  1309. X#define _BRIDGE_
  1310. X
  1311. X#include "globals.h"
  1312. X#include "email.h"
  1313. X
  1314. Xextern int errno;
  1315. Xextern char *sys_errlist [];
  1316. Xextern char *email_error_message;
  1317. Xextern char *malloc ();
  1318. X
  1319. Xchar **filename;
  1320. X  /* The list of files from which we are to read email duplicate hands. */
  1321. Xint no_files;
  1322. X  /* The number of entries in the filename array. */
  1323. Xint coded_format;
  1324. X  /* A boolean variable which is true if the output should be written
  1325. X     in coded format. */
  1326. X
  1327. Xstruct Email_Duplicate_struct *merged_email_boards;
  1328. X  /* The set of merged email boards. */
  1329. X
  1330. Xstruct Email_Duplicate_struct *current_email_boards;
  1331. X  /* The set of email boards that we are currently merging. */
  1332. X
  1333. Xint *Pair_Translation = NULL;
  1334. X  /* An array mapping pair numbers in the current email board list to
  1335. X     corresponding pair numbers in the merged board list.
  1336. X  */
  1337. X
  1338. Xchar *strdup (s)
  1339. X     char *s;
  1340. X{
  1341. X  char *p, *q;
  1342. X
  1343. X  p = q = malloc (strlen(s) + 1);
  1344. X  while (*s)
  1345. X    *(q++) = *(s++);
  1346. X  *q = '\0';
  1347. X  return (p);
  1348. X};
  1349. X
  1350. Xint Lookup_Pair (e, ne, sw)
  1351. X     struct Email_Duplicate_struct *e; char *ne, *sw;
  1352. X/* Looks for the pair (ne, sw) in the pair list of the email duplicate
  1353. X   struct e.  If found, returns the index of the pair.  Otherwise,
  1354. X   returns -1.
  1355. X*/
  1356. X{
  1357. X  int i;
  1358. X
  1359. X  for (i = 1; i <= e->npairs; i++)
  1360. X    if (!strcmp(e->player_list[i].ne, ne) && !strcmp(e->player_list[i].sw, sw))
  1361. X      return (i);
  1362. X  return (-1);
  1363. X};
  1364. X
  1365. Xvoid Create_Pair_Mapping ()
  1366. X/* Creates a mapping between pair numbers for the current_email_boards and
  1367. X   the pair numbers for the merged_email_boards.  Records new pairs into
  1368. X   merged_email_boards if necessary.
  1369. X*/
  1370. X{
  1371. X  int i, p;
  1372. X  char *ne, *sw;
  1373. X
  1374. X  if (Pair_Translation != NULL)
  1375. X    free (Pair_Translation);
  1376. X  Pair_Translation = (int *) malloc (sizeof(int) * 
  1377. X                     (current_email_boards->npairs + 1));
  1378. X
  1379. X  for (i = 1; i <= current_email_boards->npairs; i++) {
  1380. X    ne = current_email_boards->player_list[i].ne;
  1381. X    sw = current_email_boards->player_list[i].sw;
  1382. X    if ((p = Lookup_Pair(merged_email_boards, ne, sw)) < 0)
  1383. X      p = Add_Email_Pair (merged_email_boards, ne, sw);
  1384. X    Pair_Translation[i] = p;
  1385. X  };
  1386. X};
  1387. X
  1388. Xint Equal_Hand (h1, h2)
  1389. X     hand h1, h2;
  1390. X/* Returns true if the hands h1 and h2 are equal. */
  1391. X{
  1392. X  int i;
  1393. X
  1394. X  for (i = 0; i < 52; i++)
  1395. X    if (h1[i] != h2[i])
  1396. X      return (0);
  1397. X
  1398. X  return (1);
  1399. X};
  1400. X
  1401. Xvoid Tally_Board (b)
  1402. X     Email_Board *b;
  1403. X/* Records the scores from the board b into the list of merged email duplicate
  1404. X   boards. */
  1405. X{
  1406. X  Email_Board *c;
  1407. X  Email_Score *s;
  1408. X  int ns, ew;
  1409. X
  1410. X  c = merged_email_boards->board_list;
  1411. X  while ((c != NULL) && !Equal_Hand (b->deal, c->deal)) c = c->next;
  1412. X  if (c == NULL) {
  1413. X    c = Add_Email_Board (merged_email_boards, b->deal);
  1414. X    c->ns_vulnerable = b->ns_vulnerable;
  1415. X    c->ew_vulnerable = b->ew_vulnerable;
  1416. X    c->pre_script = b->pre_script;
  1417. X    c->post_script = b->post_script;
  1418. X    c->dealer = b->dealer;
  1419. X  };
  1420. X
  1421. X  s = b->score_list;
  1422. X  for (s = b->score_list; s != NULL; s = s->next) {
  1423. X    ns = Pair_Translation [s->ns_pair];
  1424. X    ew = Pair_Translation [s->ew_pair];
  1425. X    Record_Email_Score (c, ns, ew, s->bid, s->doubled, s->contractor, 
  1426. X            s->result, s->ns_score);
  1427. X  };
  1428. X
  1429. X};
  1430. X
  1431. Xvoid Abort (m)
  1432. X     char *m;
  1433. X{
  1434. X  fprintf (stderr, "tally: %s\n", m);
  1435. X  exit (1);
  1436. X};
  1437. X
  1438. Xmain (argc, argv)
  1439. X     int argc; char *argv[];
  1440. X{
  1441. X  int i, status, skip_count;
  1442. X  char error_buf [80];
  1443. X  Email_Board *b;
  1444. X
  1445. X  no_files = 0;
  1446. X  skip_count = 0;
  1447. X  filename = (char **) malloc ((argc - 1) * sizeof(char *));
  1448. X  for (i = 1; i < argc; i++) {
  1449. X    if (*argv[i] == '-') {
  1450. X      if(argv[i][1] == '\0')
  1451. X    filename[no_files++] = argv[i];
  1452. X      else if (argv[i][1] == 's') {
  1453. X    skip_count = atoi (argv[i]+2);
  1454. X    if (skip_count == 0) {
  1455. X      sprintf (error_buf, "Error in skip count: %s", argv[i]+2);
  1456. X      Abort (error_buf);
  1457. X    };
  1458. X      } else if (!strcmp(argv[i], "-c"))
  1459. X    coded_format = 1;
  1460. X      else
  1461. X    Abort ("Error in parameters");
  1462. X    } else
  1463. X      filename[no_files++] = argv[i];
  1464. X  };
  1465. X
  1466. X  if (no_files < 1)
  1467. X    Abort ("At least one email file name must be given.");
  1468. X
  1469. X  status = Read_Email_Duplicate_File (filename[0], &merged_email_boards);
  1470. X  if (status < 0) {
  1471. X    sprintf (error_buf, "Error opening file %s: %s", filename[0],
  1472. X         sys_errlist[errno]);
  1473. X    Abort (error_buf);
  1474. X  } else if (status > 0) {
  1475. X    sprintf (error_buf, "Error in format of file %s: %s", filename[0],
  1476. X         email_error_message);
  1477. X    Abort (error_buf);
  1478. X  };
  1479. X
  1480. X  for (i = 1; i < no_files; i++) {
  1481. X    status = Read_Email_Duplicate_File (filename[i], ¤t_email_boards);
  1482. X    if (status < 0) {
  1483. X      sprintf (error_buf, "Error opening file %s: %s", filename[0],
  1484. X           sys_errlist[errno]);
  1485. X      Abort (error_buf);
  1486. X    } else if (status > 0) {
  1487. X      sprintf (error_buf, "Error in format of file %s: %s", filename[0],
  1488. X           email_error_message);
  1489. X      Abort (error_buf);
  1490. X    };
  1491. X
  1492. X    Create_Pair_Mapping ();
  1493. X
  1494. X    for (b = current_email_boards->board_list; b != NULL; b = b->next)
  1495. X      Tally_Board (b);
  1496. X  };
  1497. X
  1498. X  for(i=0; (i < skip_count) && (merged_email_boards->board_list != NULL); i++){
  1499. X    merged_email_boards->board_list =
  1500. X      merged_email_boards->board_list->next;
  1501. X    merged_email_boards->nboards--;
  1502. X  };
  1503. X
  1504. X  Write_Email_Duplicate_File ("-", coded_format, merged_email_boards);
  1505. X
  1506. X};
  1507. END_OF_FILE
  1508. if test 6530 -ne `wc -c <'oktally.c'`; then
  1509.     echo shar: \"'oktally.c'\" unpacked with wrong size!
  1510. fi
  1511. # end of 'oktally.c'
  1512. fi
  1513. if test -f 'scoring.c' -a "${1}" != "-c" ; then 
  1514.   echo shar: Will not clobber existing file \"'scoring.c'\"
  1515. else
  1516. echo shar: Extracting \"'scoring.c'\" \(6200 characters\)
  1517. sed "s/^X//" >'scoring.c' <<'END_OF_FILE'
  1518. X/* scoring.c -- scoring functions for the bridge program.
  1519. X ! 
  1520. X ! Copyright (C) 1990,1991 by Matthew Clegg
  1521. X ! 
  1522. X ! This program may be copied and distributed freely.  Please do not
  1523. X ! charge money for this program or for any program derived from it.
  1524. X ! If you modify this program, then include a notice stating plainly
  1525. X ! that your program is derived from the okbridge program and is not
  1526. X ! the same as the official okbridge program.
  1527. X !
  1528. X ! I welcome any suggestions for improvement to okbridge, and 
  1529. X ! I would be especially happy to receive improved source code.
  1530. X ! If you have comments or suggestions, or if you would like to
  1531. X ! join the okbridge mailing list, then write to
  1532. X !
  1533. X !   mclegg@cs.ucsd.edu
  1534. X !
  1535. X *
  1536. X * This file defines the functions used for computing scores.
  1537. X * We provide functions for scoring according to the rules of
  1538. X * rubber bridge as well as according to the rules of Chicago style
  1539. X * bridge.  Instead of being passed parameters, these functions
  1540. X * obtain most of their information from the global variables
  1541. X * defined in globals.h.
  1542. X *
  1543. X * I would like to thank Tom Kronmiller for supplying the code
  1544. X * for scoring according to the Chicago rules.  Thanks Tom!
  1545. X */
  1546. X#include "globals.h"
  1547. X
  1548. Xstatic int  first_trick   [] = {20, 20, 30, 30, 40};
  1549. Xstatic int  subseq_tricks [] = {20, 20, 30, 30, 30};
  1550. X
  1551. X
  1552. Xint Rubber_score_above (extra)
  1553. X     int extra;
  1554. X/* int Rubber_score_above (int extra, int vulnerable); */
  1555. X/* Computes the above-the-line score for the current contract assuming
  1556. X * that 'extra' many tricks below the required number were taken.
  1557. X * Returns the computed above-the-line score.
  1558. X */
  1559. X{
  1560. X  int above = 0;  /* computed above-the-line points. */
  1561. X  int vul;        /* true if contracting team is vulnerable. */
  1562. X
  1563. X  vul = vulnerable[side_of(declarer)];
  1564. X  if (doubled || redoubled) {
  1565. X    above = 100 * extra;
  1566. X    if (vul)       above *= 2;
  1567. X    if (redoubled) above *= 2;
  1568. X    above += 50;
  1569. X  } else
  1570. X    above = subseq_tricks[trump_suit] * extra;
  1571. X
  1572. X  if (contract == 6)
  1573. X    above += vul? 750: 500;
  1574. X  else if (contract == 7)
  1575. X    above += vul? 1500: 1000;
  1576. X  return (above);
  1577. X    
  1578. X};
  1579. X
  1580. Xint Rubber_score_below ()
  1581. X/* int Rubber_score_below (void); */
  1582. X/* Computes the below-the-line score for the current contract,
  1583. X * assuming that it was made.
  1584. X */
  1585. X{
  1586. X  int below = 0;  /* computed below-the-line points. */
  1587. X
  1588. X  below  = first_trick[trump_suit] + 
  1589. X    (contract - 1) * subseq_tricks[trump_suit];
  1590. X  if (redoubled)
  1591. X    below *= 4;
  1592. X  else if (doubled)
  1593. X    below *= 2;
  1594. X  return (below);
  1595. X};
  1596. X
  1597. X
  1598. Xint Rubber_score_set (down)
  1599. X     int down;
  1600. X/* int Rubber_score_set (int down); */
  1601. X/* Computes the penalty score for the current contract assuming that
  1602. X * 'down' too few tricks were taken.  Returns the score.
  1603. X */
  1604. X{
  1605. X  int penalty = 0;  /* computed penalty points. */
  1606. X  int vul;          /* true if contracting team is vulnerable. */
  1607. X
  1608. X  vul = vulnerable[side_of(declarer)];
  1609. X  down -= 1;
  1610. X  if (doubled || redoubled) {
  1611. X    if (vul) penalty = 200 + 300 * down;
  1612. X    else     penalty = 100 + 200 * down;
  1613. X    if (redoubled) penalty *= 2;
  1614. X  } else {
  1615. X    if (vul) penalty = 100 + 100 * down;
  1616. X    else     penalty =  50 +  50 * down;
  1617. X  };
  1618. X  return (penalty);
  1619. X};
  1620. X
  1621. X
  1622. Xint Chicago_score_made (extra, vulnerable)
  1623. X     int extra, vulnerable;
  1624. X/* int Chicago_score_made (int extra, int vulnerable); */
  1625. X/* Computes the score for the current contract assuming that it was made
  1626. X * and that an additional 'extra' tricks were taken.  'vulnerable' is a
  1627. X * boolean flag which indicates whether the declaring team was
  1628. X * vulnerable.  Returns the score.
  1629. X */
  1630. X{
  1631. X    int result = 0, perTrick;
  1632. X
  1633. X
  1634. X    /* How much is making the bid worth? */
  1635. X    perTrick = (MINOR(trump_suit))? 20:30;
  1636. X    result = perTrick * contract;
  1637. X    if (trump_suit == SUIT_NOTRUMP)    result += 10;
  1638. X    if (redoubled)                  result *= 4;
  1639. X    else if (doubled)               result *= 2;
  1640. X      
  1641. X    /* Was it a game we made? */
  1642. X    if (result >= 100)        result += (!vulnerable)? 300:500;
  1643. X/*    else                    result += 50; */
  1644. X
  1645. X    /* Was it a slam we made? */
  1646. X    if (contract == 6)        result += (!vulnerable)? 500:750;
  1647. X    if (contract == 7)        result += (!vulnerable)? 1000:1500;
  1648. X
  1649. X    /* Were we insulted by a double? */
  1650. X    if (redoubled)                  result += 100;
  1651. X    else if (doubled)               result += 50;
  1652. X
  1653. X    /* How much do we get for overtricks? */
  1654. X    if (redoubled)
  1655. X            result += (extra * 100) * (vulnerable? 4: 2);
  1656. X    else if (doubled)
  1657. X            result += (extra * 100) * (vulnerable? 2: 1);
  1658. X    else
  1659. X        result += extra * perTrick;
  1660. X
  1661. X    return (result);
  1662. X}
  1663. X
  1664. X
  1665. Xint Chicago_score_set (down, vulnerable)
  1666. X     int down, vulnerable;
  1667. X/* int Chicago_score_set (int down, int vulnerable); */
  1668. X/* Computes the score for the current contract assuming that it was
  1669. X * set and that 'down' too few tricks were taken.  'vulnerable' is
  1670. X * a boolean flag which indicates whether the declaring team was
  1671. X * vulnerable.  Returns the score.
  1672. X *
  1673. X * written by Tom Kronmiller
  1674. X */
  1675. X{
  1676. X    int result = 0;
  1677. X
  1678. X    if (!doubled)
  1679. X    {
  1680. X        result = 50 * down;
  1681. X        if (vulnerable) result *= 2;
  1682. X    }
  1683. X    else
  1684. X    {
  1685. X        switch (down)
  1686. X        {
  1687. X            case 1:
  1688. X                result = (!vulnerable)? 100:200;
  1689. X                break;
  1690. X            case 2:
  1691. X                result = (!vulnerable)? 300:500;
  1692. X                break;
  1693. X            case 3:
  1694. X                result = (!vulnerable)? 500:800;
  1695. X                break;
  1696. X            default:
  1697. X                result = 500 + (300*(down-3)) 
  1698. X                  + ((!vulnerable)? 0:300);
  1699. X                break;
  1700. X        }
  1701. X        if (redoubled) result *= 2;
  1702. X    }
  1703. X    return (result);
  1704. X}
  1705. X
  1706. X
  1707. Xint Duplicate_score_made (extra, vulnerable)
  1708. X     int extra, vulnerable;
  1709. X/* int Duplicate_score_made (int extra, int vulnerable); */
  1710. X/* Computes the score for the current contract assuming that it was made
  1711. X * and that an additional 'extra' tricks were taken.  'vulnerable' is a
  1712. X * boolean flag which indicates whether the declaring team was
  1713. X * vulnerable.  Returns the score.
  1714. X */
  1715. X{
  1716. X    int score;
  1717. X
  1718. X    score = Chicago_score_made (extra, vulnerable);
  1719. X    if (score < 300)
  1720. X        score += 50;
  1721. X    return (score);
  1722. X    
  1723. X}
  1724. X
  1725. Xint Duplicate_score_set (down, vulnerable)
  1726. X     int down, vulnerable;
  1727. X/* int Duplicate_score_set (int down, int vulnerable); */
  1728. X/* Computes the score for the current contract assuming that it was
  1729. X * set and that 'down' too few tricks were taken.  'vulnerable' is
  1730. X * a boolean flag which indicates whether the declaring team was
  1731. X * vulnerable.  Returns the score.
  1732. X */
  1733. X{
  1734. X    return (Chicago_score_set(down, vulnerable));
  1735. X};
  1736. X
  1737. END_OF_FILE
  1738. if test 6200 -ne `wc -c <'scoring.c'`; then
  1739.     echo shar: \"'scoring.c'\" unpacked with wrong size!
  1740. fi
  1741. # end of 'scoring.c'
  1742. fi
  1743. echo shar: End of archive 6 \(of 7\).
  1744. cp /dev/null ark6isdone
  1745. MISSING=""
  1746. for I in 1 2 3 4 5 6 7 ; do
  1747.     if test ! -f ark${I}isdone ; then
  1748.     MISSING="${MISSING} ${I}"
  1749.     fi
  1750. done
  1751. if test "${MISSING}" = "" ; then
  1752.     echo You have unpacked all 7 archives.
  1753.     rm -f ark[1-9]isdone
  1754.     echo creating input.c from input.c.aa and input.c.ab
  1755.     cat input.c.aa input.c.ab >input.c
  1756.     rm -f input.c.aa input.c.ab
  1757. else
  1758.     echo You still need to unpack the following archives:
  1759.     echo "        " ${MISSING}
  1760. fi
  1761. ##  End of shell archive.
  1762. exit 0
  1763.