home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume14 / okbrdge2 / part12 < prev    next >
Encoding:
Internet Message Format  |  1993-01-26  |  54.4 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: v14i090:  okbridge2 - computer-mediated bridge game, Part12/14
  5. Message-ID: <3529@master.CNA.TEK.COM>
  6. Date: 7 Sep 92 21:43:04 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1919
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: mclegg@cs.UCSD.EDU (Matthew Clegg)
  12. Posting-number: Volume 14, Issue 90
  13. Archive-name: okbridge2/Part12
  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 12 (of 14)."
  26. # Contents:  Makefile ccdef.c cipher.c display.h help.c scoring.c
  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 'Makefile' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'Makefile'\"
  31. else
  32. echo shar: Extracting \"'Makefile'\" \(7691 characters\)
  33. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  34. X# makefile for Okbridge 1.7
  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# In general the okbridge program can be compiled simply by
  58. X# typing 'make'.  If you are planning to install okbridge in
  59. X# a public directory, then you may want to first change the
  60. X# values of the variables OKBRIDGE_DIR and OKBRIDGE_HELPFILE.
  61. X# Then, type 'make install'.
  62. X
  63. XOKBRIDGE_DIR = /usr/local/games
  64. XOKBRIDGE_HELPFILE = /usr/local/games/okbridge.help
  65. XINSTALL = /usr/bin/install
  66. X
  67. X# Thanks to George Ferguson of the University of Rochester, we now have
  68. X# a set of manual pages for okbridge.  To install these, change the
  69. X# following definitions as appropriate and type "make install.man"
  70. XMANDIR = /usr/local/man/man6
  71. XMANEXT = 6
  72. X
  73. X# MACHINE SPECIFIC INFORMATION:
  74. X#
  75. X# Okbridge has been compiled and run successfully on the following systems:
  76. X#
  77. X#   Machine              OS                 Changes to Makefile
  78. X#   -------              --                 -------------------
  79. X#   Decstation 3100,5000 ULTRIX V4.0 & 4.2  none
  80. X#   HP 400 apollo        4.3 bsd            PWCOMMENT = -DNO_PWCOMMENT
  81. X#   IBM RS/6000          AIX 3.1            MACHINE_FLAGS = -DAIX
  82. X#   IBM RT               Modified BSD       none
  83. X#   NeXTStation          NextStep 2.1       none
  84. X#   Sun Sparcstation     SunOS 4.1.x        none
  85. X#   Vax 2000 & 3100      BSD UNIX 4.3       none
  86. X#
  87. X#
  88. X# If you are compiling with SunOS (version 4.0 or later), then you may wish
  89. X# to uncomment the following two lines.  This slightly alters the behavior
  90. X# of the curses interface.
  91. X#MACHINE_FLAGS = -DSUNOS
  92. X#CC = /usr/5bin/cc
  93. X#
  94. X# If you are compiling this program on a machine which is
  95. X# running IBM's AIX operating system, then uncomment the
  96. X# next line:
  97. X#MACHINE_FLAGS = -DAIX
  98. X#
  99. X# If you are running on an HP/UX system, you may need to uncomment
  100. X# the following line:
  101. X#MACHINE_FLAGS = -DHPUX
  102. X#
  103. X# If you are compiling this program on a machine which does not
  104. X# have strcasecmp and strncasecmp, then you will need to uncomment
  105. X# the following line (this is not necessary if you are using
  106. X# SunOS or a recent version of Ultrix):
  107. X#STRCASECMP = -DNO_STRCASECMP
  108. X#
  109. X# A few machines do not provide the name of the time zone when returning
  110. X# the system time through the localtime() call.  Typically, this will
  111. X# cause a compile time error in network.c near line 600.  If you have such 
  112. X# a machine, then you will want to uncomment the following line:
  113. X#TIMEZONE = -DNO_TM_ZONE
  114. X#
  115. X# Some other machines do not store the 'gecos' field in the password file
  116. X# file entry.  If the player has not specified his/her name using the
  117. X# FULLNAME field in the .okbridgerc file, then we try to extract his
  118. X# name from the gecos field.  This is used in listing the current bridge
  119. X# players in the GPS.  If your machine cannot compile this code, then
  120. X# you will get a compile time error in network.c near line 500.  You
  121. X# should then uncomment the following line:
  122. X#PWCOMMENT = -DNO_PWCOMMENT
  123. X#
  124. X
  125. XFLAGS = $(STRCASECMP) $(TIMEZONE) $(MACHINE_FLAGS) $(PW_COMMENT)
  126. X
  127. X# The following flags may be useful if you have modified the okbridge
  128. X# program and you need assistance debugging it:
  129. X#
  130. X# CFLAGS = -g -DDEBUG -DLOGFILE -DMDEBUG
  131. X# MFLAGS = /usr/lib/debug/malloc.o
  132. X#
  133. X# CFLAGS = $(FLAGS) -g -DDEBUG -DLOGFILE
  134. X# CFLAGS = $(FLAGS) -g -DDEBUG
  135. X# CFLAGS = -g
  136. X# CC = gcc
  137. XCFLAGS = -O $(FLAGS)
  138. X
  139. X# Sun people might like to define this to get pure executables.
  140. X#  pure = all code is in the binary
  141. X#  non-pure = code may use shared libs, and be demand-paged
  142. X# The advatages about pure code, is that you needn't worry about having the
  143. X# right version of the shared libs (important if run different versions 
  144. X# of the os), and if you store the binary on NFS, you aren't swapping
  145. X# code over the network.  Disadvantages is that the size of pure code is
  146. X# bigger, and might use more virtual mem (not using shared libs).
  147. X#
  148. X# For gcc on SunOS
  149. X# LDFLAGS= -static -n
  150. X# For cc on SunOS
  151. X# LDFLAGS= -Bstatic -n
  152. X
  153. XOBJ =     bridge.o input.o display.o terminal.o network.o help.o scoring.o\
  154. X     boards.o cipher.o rc.o protocol.o parser.o nonstd.o socket.o\
  155. X    gps.o ccdef.o commands.o conversation.o cs.o log.o
  156. X
  157. XSHUFFLEOBJ = okshuffle.o nonstd.o boards.o cipher.o scoring.o
  158. X
  159. XTALLYOBJ = oktally.o nonstd.o boards.o cipher.o scoring.o log.o
  160. X
  161. XGPSOBJ = gps_server.o socket.o boards.o nonstd.o cipher.o scoring.o
  162. XGPSSRC = ../gps-1.1/gps_server.c
  163. XGPS    = ../gps-1.1/gps_server
  164. X
  165. Xall:    okbridge okshuffle oktally
  166. X
  167. Xokbridge:    $(OBJ)
  168. X    $(CC) $(LDFLAGS) -o okbridge $(OBJ) -lcurses -ltermcap $(MFLAGS)
  169. X
  170. Xokshuffle:    $(SHUFFLEOBJ) types.h boards.h
  171. X    $(CC) $(LDFLAGS) -o okshuffle $(SHUFFLEOBJ)
  172. X
  173. Xoktally:    $(TALLYOBJ) types.h
  174. X    $(CC) $(LDFLAGS) -o oktally $(TALLYOBJ)
  175. X
  176. Xgps_server:    $(GPSOBJ) $(GPSSRC)
  177. X    $(CC) $(LDFLAGS) -o gps_server $(GPSOBJ) 
  178. X    cp gps_server $(GPS)
  179. X
  180. Xinstall: install.bin install.help
  181. X
  182. Xinstall.bin:    okbridge okshuffle oktally
  183. X    strip okbridge
  184. X    strip okshuffle
  185. X    strip oktally
  186. X    $(INSTALL) okbridge $(OKBRIDGE_DIR)/okbridge
  187. X    $(INSTALL) okshuffle $(OKBRIDGE_DIR)
  188. X    $(INSTALL) oktally $(OKBRIDGE_DIR)
  189. X
  190. Xinstall.help:
  191. X    $(INSTALL) -c -m 644 okbridge.help $(OKBRIDGE_HELPFILE)
  192. X
  193. Xinstall.man:
  194. X    install -c -m 0644 okbridge.man $(MANDIR)/okbridge.$(MANEXT)
  195. X    install -c -m 0644 okshuffle.man $(MANDIR)/okshuffle.$(MANEXT)
  196. X    install -c -m 0644 oktally.man $(MANDIR)/oktally.$(MANEXT)
  197. X
  198. Xclean:
  199. X    rm -f *.o 
  200. X    rm -f *~
  201. X    rm -f tmp*
  202. X    rm -f *.log
  203. X    rm -f *.zlog
  204. X    rm -f *.orig
  205. X
  206. Xveryclean:    clean
  207. X    rm -f okbridge okshuffle oktally gps_server helpfile.h core tags TAGS
  208. X
  209. Xdistrib:    veryclean
  210. X        csh -f < MkDistrib
  211. X
  212. Xbridge.o:    bridge.c state.h types.h network.h protocol.h\
  213. X                display.h input.h terminal.h help.h scoring.h parser.h\
  214. X        conversation.h
  215. X
  216. Xboards.o:    boards.c boards.h types.h cipher.h boards.h socket.h\
  217. X        parser.h protocol.h network.h scoring.h
  218. X
  219. Xccdef.o:    ccdef.c
  220. X
  221. Xcipher.o:    cipher.h cipher.c
  222. X
  223. Xcommands.o:    commands.h commands.c types.h parser.h state.h terminal.h \
  224. X        display.h input.h gps.h network.h
  225. X
  226. Xconversation.o:    conversation.h conversation.c types.h protocol.h network.h
  227. X
  228. Xcs.o:        cs.h cs.c socket.h state.h types.h network.h protocol.h gps.h
  229. X
  230. Xdisplay.o:    display.h display.c terminal.h types.h state.h
  231. X
  232. Xgps.o:        gps.h gps_info.h parser.h gps.c conversation.h
  233. X
  234. Xgps_server.o:   $(GPSSRC) types.h boards.h gps_info.h socket.h
  235. X            cp $(GPSSRC) gps_server.c
  236. X            $(CC) -c $(CFLAGS) gps_server.c
  237. X            rm gps_server.c
  238. X
  239. Xhelp.o:        help.h help.c types.h input.h terminal.h helpfile.h
  240. X
  241. Xinput.o:    input.h input.c network.h terminal.h display.h\
  242. X        help.h input.h protocol.h state.h types.h conversation.h
  243. X
  244. Xlog.o:        log.h log.c boards.h
  245. X
  246. Xnetwork.o:    network.h network.c state.h types.h protocol.h socket.h
  247. X
  248. Xnonstd.o:    nonstd.c
  249. X
  250. Xparser.o:    parser.h parser.c
  251. X
  252. Xprotocol.o:     protocol.h parser.h protocol.c types.h
  253. X
  254. Xrc.o:        rc.h rc.c types.h parser.h state.h network.h
  255. X
  256. Xscoring.o:    scoring.h scoring.c state.h types.h
  257. X
  258. Xsocket.o:    socket.h socket.c
  259. X
  260. Xstartup.o:    state.h types.h parser.h
  261. X
  262. Xterminal.o:    terminal.h terminal.c
  263. X
  264. Xhelpfile.h:
  265. X        echo 'char *help_file_name="'$(OKBRIDGE_HELPFILE)'";' \
  266. X        > helpfile.h
  267. X
  268. END_OF_FILE
  269. if test 7691 -ne `wc -c <'Makefile'`; then
  270.     echo shar: \"'Makefile'\" unpacked with wrong size!
  271. fi
  272. # end of 'Makefile'
  273. fi
  274. if test -f 'ccdef.c' -a "${1}" != "-c" ; then 
  275.   echo shar: Will not clobber existing file \"'ccdef.c'\"
  276. else
  277. echo shar: Extracting \"'ccdef.c'\" \(7370 characters\)
  278. sed "s/^X//" >'ccdef.c' <<'END_OF_FILE'
  279. X/*
  280. X * ccfile.c  Routines to support the file of convention cards for use with
  281. X * okbridge.
  282. X *
  283. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  284. X ! 
  285. X ! OKbridge is made available as a free service to the Internet.
  286. X ! Accordingly, the following restrictions are placed on its use:
  287. X ! 
  288. X ! 1.  OKbridge may not be modified in any way without the explicit 
  289. X !     permission of Matthew Clegg.  
  290. X ! 
  291. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  292. X !     It may not be placed on for-profit networks or on for-profit
  293. X !     computer systems.  It may not be bundled as part of a package
  294. X !     or service provided by a for-profit organization.
  295. X ! 
  296. X ! If you have questions about restrictions on the use of OKbridge,
  297. X ! write to mclegg@cs.ucsd.edu.
  298. X ! 
  299. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  300. X ! damage which may be caused by OKbridge.
  301. X *
  302. X * This module written by Jonathan Segal, and is donated to the okbridge
  303. X * elder (i.e. Matt Clegg) to do with as he will.
  304. X *
  305. X *
  306. X * This is quite simple, actually- it is a simple name-value pair table.
  307. X *
  308. X * Since this is fused onto an existing system, it uses global variables.
  309. X *  
  310. X */
  311. X
  312. X#include <ctype.h>
  313. X#include <stdio.h>
  314. X#include <string.h>
  315. X/* #include <malloc.h> */
  316. X
  317. Xextern char *strdup ();
  318. Xextern void free ();
  319. Xextern char *realloc (), *malloc ();
  320. X
  321. X#define    MAX_LENGTH    256
  322. X
  323. Xtypedef struct cc_el
  324. X{
  325. X  char *ccname;
  326. X  char *ccvalue;
  327. X} cc_el;
  328. X
  329. X#define NEW_CC_BLOCK_SIZE  5
  330. X
  331. X/*
  332. X  The convention card table is a NULL-terminated array of cc_els
  333. X  */
  334. X
  335. Xstatic cc_el *cc = 0;                                  /* base table pointer */
  336. Xstatic int max_num_ccs = 0;                /* referent for memory allocation */
  337. Xstatic int num_ccs = 0;                        /* current number of used ccs */
  338. X
  339. X
  340. X/*
  341. X  forward declarations */
  342. Xvoid Free_CCs(/*_ void _*/);
  343. Xstatic int Get_Some_CCs(/*_ void _*/);
  344. Xstatic cc_el *Find_CC(/*_ char *name _*/);
  345. Xstatic int Add_CC_Definition(/*_ char *n, char *v _*/);
  346. Xstatic void Display_CC(/*_ char *ccname, void (*display_cc)() _*/);
  347. X
  348. X/*------------------------------Get_CC_Value---------------------------------*/
  349. Xchar *Get_CC_Value(/*_ char *c _*/);
  350. X/*
  351. X  This functions is passed a cc candidate.  If this string only contains one
  352. X  word, and this word is a name in the cc table, the value of the cc will be
  353. X  returned (note the value is from the table, so may need to be strduped.
  354. X  Otherwise, it will simply return its parameter.
  355. X
  356. X*/
  357. X
  358. Xchar *Get_CC_Value( c )
  359. Xchar *c;
  360. X{
  361. X  char *n;
  362. X  cc_el *cp;
  363. X
  364. X  for (n = c; *n && !isspace(*n); ++n);                 /* check if one word */
  365. X  if (*n)                                              /* more than one word */
  366. X    return (c);
  367. X  
  368. X  cp = Find_CC(c);
  369. X
  370. X  if (!cp)                                             /* named CC not found */
  371. X  {
  372. X    return (c);
  373. X  }
  374. X  
  375. X  else
  376. X  {
  377. X    return (cp->ccvalue);
  378. X  }
  379. X}
  380. X
  381. X/*---------------------------------Define_CC---------------------------------*/
  382. Xint Define_CC(/*_ char *ccdef, void (*display_cc)() _*/);
  383. X/*
  384. X  this will parse the ccdef string -- if the
  385. X*/
  386. X
  387. Xint Define_CC( ccdef, display_cc )
  388. Xchar *ccdef;
  389. Xvoid (*display_cc)();
  390. X{
  391. X  char *n, *v;
  392. X  char buf[MAX_LENGTH];
  393. X  
  394. X  for (n = ccdef; *n && isspace(*n); ++n)
  395. X    ;                                             /* skip to first non-white */
  396. X  if (!*n)
  397. X  {
  398. X    return (1);
  399. X  }
  400. X
  401. X  for(v = n; *v && !isspace(*v) ; ++v)
  402. X    ;                                               /* skip to first white */
  403. X  if (!*v)
  404. X  {
  405. X    Display_CC(n, display_cc);
  406. X    return(0);
  407. X  }
  408. X  
  409. X  *v = '\0';                                        /* null terminate name */
  410. X  for (++v; *v && isspace(*v); ++v)
  411. X    ;
  412. X  if (!*v)
  413. X  {
  414. X    Display_CC(n, display_cc);
  415. X    return (0);
  416. X  }
  417. X  if (Add_CC_Definition(n,v))
  418. X  {
  419. X    return (1);
  420. X  }
  421. X  else
  422. X  {
  423. X    if (display_cc)
  424. X    {
  425. X      sprintf(buf,"CC defined: %s",n);
  426. X      (*display_cc)(buf);
  427. X    }
  428. X    return (0);
  429. X  }
  430. X}
  431. X
  432. X/*--------------------------------Display_CC---------------------------------*/
  433. X/*
  434. X  Display the CC with the specified name
  435. X*/
  436. X
  437. Xstatic void Display_CC( n, display_cc )
  438. Xchar  *n;
  439. Xvoid (*display_cc)();
  440. X{
  441. X  cc_el *cp;
  442. X  char linebuf[MAX_LENGTH];
  443. X
  444. X  if (!display_cc)
  445. X    return;                           /* do nothing with no display function */
  446. X  /* display the cc */
  447. X  if (cp = Find_CC(n))
  448. X  {
  449. X    sprintf(linebuf,"%s = %s",cp->ccname, cp->ccvalue);
  450. X    (*display_cc)(linebuf);
  451. X  }
  452. X  else
  453. X  {
  454. X    sprintf(linebuf, "%s IS UNDEFINED AS A CONVENTION CARD", n);
  455. X    (*display_cc)(linebuf);
  456. X  }
  457. X}    
  458. X
  459. X/*-----------------------------Add_CC_Definition-----------------------------*/
  460. X/*
  461. X  Add a new cc definition to the CC table
  462. X*/
  463. X
  464. Xstatic int Add_CC_Definition( n, v )
  465. Xchar *n;
  466. Xchar *v;
  467. X{
  468. X  cc_el *cp;
  469. X  /* first see if we have a redefinition */
  470. X
  471. X  if (cp = Find_CC(n))
  472. X  {
  473. X    char *old_val = cp->ccvalue;
  474. X    if (!(cp->ccvalue = strdup(v)))
  475. X    {
  476. X      cp->ccvalue = old_val;
  477. X      return (1);
  478. X    }
  479. X    free(old_val);
  480. X    return (0);
  481. X  }
  482. X
  483. X  /* we're adding a new one */
  484. X  if (num_ccs >= max_num_ccs &&  Get_Some_CCs())
  485. X  {
  486. X    return (1);                                /* we're out of room for more */
  487. X  }
  488. X    
  489. X  /* now n is pointing to name, v is pointing to value */
  490. X  
  491. X  if (!(cc[num_ccs].ccname = strdup(n)))
  492. X    return (1);                                             /* no more room! */
  493. X  if (!(cc[num_ccs].ccvalue = strdup(v)))
  494. X  {
  495. X    free(cc[num_ccs].ccname);                               /* no more room! */
  496. X    cc[num_ccs].ccname = (char *) NULL;
  497. X    return (1);
  498. X  }
  499. X  ++num_ccs;
  500. X  return (0);
  501. X}
  502. X
  503. X/*------------------------------Display_All_CCs------------------------------*/
  504. Xvoid Display_All_CCs(/*_ void (*display)() _*/);
  505. X/*
  506. XEnter function description here
  507. X*/
  508. X
  509. Xvoid Display_All_CCs( display )
  510. Xvoid (*display)();
  511. X{
  512. X  cc_el *cp;
  513. X  char   linebuf[MAX_LENGTH];
  514. X
  515. X  if (!cc)
  516. X  {
  517. X    (*display) ("NO NAMED CONVENTION CARDS HAVE BEEN DEFINED.");
  518. X    return;
  519. X  }
  520. X  for (cp = cc; cp->ccname; ++cp)
  521. X  {
  522. X    sprintf(linebuf,"%s = %s",cp->ccname, cp->ccvalue);
  523. X    (*display)(linebuf);
  524. X  }
  525. X}
  526. X
  527. X
  528. X
  529. X/*---------------------------------Free_CCs----------------------------------*/
  530. X/*
  531. X  Empty the CC table, freeing the memory each CC.
  532. X*/
  533. X
  534. Xvoid Free_CCs()
  535. X{
  536. X  cc_el *cp = cc;
  537. X
  538. X  if (!cc)
  539. X    return;
  540. X  while (cp->ccname)
  541. X  {
  542. X    free(cp->ccname);
  543. X    free(cp->ccvalue);
  544. X  }
  545. X
  546. X  cc->ccname = cc->ccvalue = (char *) NULL;
  547. X  num_ccs = 0;
  548. X  
  549. X}
  550. X
  551. X/*-------------------------------Get_Some_CCs--------------------------------*/
  552. X/*
  553. X  Increase the CC table size.  Returns 1 on success, 0 on failure.
  554. X*/
  555. X
  556. Xstatic int Get_Some_CCs()
  557. X{
  558. X  cc_el *newcc;
  559. X
  560. X  max_num_ccs += NEW_CC_BLOCK_SIZE;
  561. X
  562. X  if (cc)
  563. X  {
  564. X    newcc = (cc_el *) realloc(cc, sizeof(cc_el) * (max_num_ccs + 1));
  565. X                                         /* add one for the null termination */
  566. X  }
  567. X  else
  568. X  {
  569. X    newcc = (cc_el *) malloc(sizeof(cc_el) * (max_num_ccs + 1));
  570. X  }
  571. X  if (!newcc)
  572. X  {
  573. X    max_num_ccs -= NEW_CC_BLOCK_SIZE;
  574. X    return (1);
  575. X  }
  576. X  else
  577. X  {
  578. X    cc = newcc;
  579. X    return (0);
  580. X  }
  581. X}
  582. X
  583. X/*----------------------------------Find_CC----------------------------------*/
  584. X/*
  585. X  Search the cc table for a CC named name
  586. X
  587. X  return the element found, NULL if none.
  588. X*/
  589. X
  590. Xstatic cc_el *Find_CC( name )
  591. Xchar *name;
  592. X{
  593. X  cc_el *cp;
  594. X  if (!cc)
  595. X  {
  596. X    return (NULL);
  597. X  }
  598. X  
  599. X  for (cp = cc; cp->ccname; ++cp)
  600. X  {
  601. X    if (!strcmp(cp->ccname, name))
  602. X    {
  603. X      /* a match! */
  604. X      return (cp);
  605. X    }
  606. X  }
  607. X  /* no match */
  608. X  return (NULL);
  609. X  
  610. X}
  611. X
  612. END_OF_FILE
  613. if test 7370 -ne `wc -c <'ccdef.c'`; then
  614.     echo shar: \"'ccdef.c'\" unpacked with wrong size!
  615. fi
  616. # end of 'ccdef.c'
  617. fi
  618. if test -f 'cipher.c' -a "${1}" != "-c" ; then 
  619.   echo shar: Will not clobber existing file \"'cipher.c'\"
  620. else
  621. echo shar: Extracting \"'cipher.c'\" \(7397 characters\)
  622. sed "s/^X//" >'cipher.c' <<'END_OF_FILE'
  623. X/* cipher.c
  624. X *
  625. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  626. X ! 
  627. X ! OKbridge is made available as a free service to the Internet.
  628. X ! Accordingly, the following restrictions are placed on its use:
  629. X ! 
  630. X ! 1.  OKbridge may not be modified in any way without the explicit 
  631. X !     permission of Matthew Clegg.  
  632. X ! 
  633. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  634. X !     It may not be placed on for-profit networks or on for-profit
  635. X !     computer systems.  It may not be bundled as part of a package
  636. X !     or service provided by a for-profit organization.
  637. X ! 
  638. X ! If you have questions about restrictions on the use of OKbridge,
  639. X ! write to mclegg@cs.ucsd.edu.
  640. X ! 
  641. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  642. X ! damage which may be caused by OKbridge.
  643. X *
  644. X * This file implements procedures for a very simple cipher which
  645. X * is used to encode crucial parts of the files which contain
  646. X * email duplicate hands.
  647. X *
  648. X * The intention of this cipher is to make the contents
  649. X * of an email duplicate file non-obvious.  This cipher is certainly
  650. X * not intended to be difficult to break -- it is simply intended to
  651. X * allow email duplicate files to be manipulated (e.g., mailed, copied,
  652. X * etc.) without having their contents revealed.
  653. X *
  654. X * The cipher that we use is based upon the following principles:
  655. X *    1.  Only the 64 characters a-zA-Z0-9+- are encoded.
  656. X *        This defines a function h(c) for characters c which is 0
  657. X *        if c is not coded and which is a unique integer in the
  658. X *        range [1,64] if c is coded.
  659. X *    2.  An initial permutation p the integers [1,64] is chosen.
  660. X *    3.  Given a string s, a permuted string s' is computed according
  661. X *        to the following formula:
  662. X *
  663. X *      s'[i] =  s[i]                  if h[s[i]] = 0,
  664. X *           h^-1 [ p[ (h[s[i]] + i) mod 64 ]]    otherwise.
  665. X *
  666. X *        In other words, the encoding of a character is determined
  667. X *        by a fixed permutation and by its index in the string.
  668. X *
  669. X * An email duplicate file begins with a header line identifying the
  670. X * fact that it is an email duplicate file.  The following line contains
  671. X * the permutation which has been used to encode the file.  The
  672. X * succeeding lines are a mixture of plain-text and coded lines.
  673. X * Coded lines begin with an exclamation point '!'.
  674. X */
  675. X
  676. X#include <stdio.h>
  677. X#include <string.h>
  678. X
  679. X#include "cipher.h"
  680. X
  681. Xextern char *malloc ();
  682. X
  683. X#ifdef GCC
  684. Xextern int  fgetc ();
  685. Xextern fprintf ();
  686. X#endif
  687. X
  688. X/* extern long random (); */
  689. Xextern int rand ();
  690. X#define random(n) ((rand () / 64) % n)
  691. X
  692. Xstatic  int cipher_mapping [128];    /* the function h above. */
  693. Xstatic  int cipher_unmapping [128];    /* h^-1, where defined  */
  694. Xstatic  int mapping_is_initialized = 0;
  695. X
  696. X#define LINEBUF_SIZE  128
  697. Xstatic char line_buf[LINEBUF_SIZE];
  698. X
  699. Xstatic void Initialize_Cipher_Mapping ()
  700. X{
  701. X    int i;
  702. X
  703. X    for (i = 0; i < 128; i++)
  704. X      cipher_mapping[i] = 0;
  705. X    for (i = 0; i < CIPHER_SIZE1; i++)
  706. X      cipher_unmapping[i] = 0;
  707. X
  708. X    for (i = 'A'; i <= 'Z'; i++)
  709. X        cipher_mapping[i] = i - 'A' + 1;
  710. X    for (i = 'a'; i <= 'z'; i++)
  711. X        cipher_mapping[i] = i - 'a' + 26 + 1;
  712. X    for (i = '0'; i <= '9'; i++)
  713. X        cipher_mapping[i] = i - '0' + 52 + 1;
  714. X    cipher_mapping['+'] = 63;
  715. X    cipher_mapping['-'] = 64;
  716. X
  717. X    for (i = 0; i < 128; i++)
  718. X        if (cipher_mapping[i])
  719. X            cipher_unmapping[cipher_mapping[i]] = i;
  720. X}
  721. X
  722. Xstatic int Read_Line (f, buf, buflen)
  723. X    FILE *f; char *buf; int buflen;
  724. X/* Reads a line of up to buflen characters from the file f into
  725. X   the buffer buf.  Returns the number of characters read, or -1
  726. X   if EOF reached.
  727. X*/
  728. X{
  729. X    int n, ch;
  730. X
  731. X    if (fgets(buf, buflen, f) == NULL)
  732. X      return (-1);
  733. X
  734. X    n = strlen(buf);
  735. X    if ((n >= buflen) && (buf[n-1] != '\n'))
  736. X      do
  737. X        { ch = fgetc (f); }
  738. X      while ((ch != '\n') && (ch != EOF));
  739. X    else
  740. X      buf[--n] = '\0';
  741. X
  742. X    return (n);
  743. X}
  744. X
  745. Xint Read_Cipher_Descriptor (f, c)
  746. X     FILE *f;
  747. X     Cipher *c;
  748. X/*  Reads a cipher descriptor from the file f.  Returns 0 if successful
  749. X    or 1 if an error occurred. */
  750. X{
  751. X  char code_buffer[80];
  752. X  int i, n;
  753. X
  754. X  if (!mapping_is_initialized)
  755. X    Initialize_Cipher_Mapping ();
  756. X
  757. X  n = Read_Line (f, code_buffer, 80);
  758. X  if (n < CIPHER_SIZE)
  759. X    return (1);
  760. X
  761. X  for (i = 0; i < CIPHER_SIZE; i++)
  762. X    c->encoding[i+1] = cipher_mapping[(int) code_buffer[i]];
  763. X  for (i = 1; i < CIPHER_SIZE1; i++)
  764. X    c->decoding[c->encoding[i]] = i;
  765. X  return (0);
  766. X}
  767. X
  768. Xvoid Write_Cipher_Descriptor (f, c)
  769. X     FILE *f;
  770. X     Cipher *c;
  771. X/* Writes the cipher descriptor c to the file f. */
  772. X{
  773. X  char code_buffer[CIPHER_SIZE1];
  774. X  int i;
  775. X
  776. X  for (i = 0; i < CIPHER_SIZE; i++)
  777. X    code_buffer[i] = cipher_unmapping[c->encoding[i+1]];
  778. X  code_buffer[CIPHER_SIZE] = '\0';
  779. X  fprintf (f, "%s\n", code_buffer);
  780. X}
  781. X
  782. Xvoid Create_Cipher_Descriptor (f, c)
  783. X     FILE *f;
  784. X     Cipher *c;
  785. X/* Fills the structure c with a randomly generated cipher descriptor. */
  786. X{
  787. X  int i, t, r;
  788. X
  789. X  if (!mapping_is_initialized)
  790. X    Initialize_Cipher_Mapping ();
  791. X
  792. X  c->encoding[0] = c->decoding[0] = 0;
  793. X
  794. X  for (i = 1; i < CIPHER_SIZE1; i++) 
  795. X    c->encoding [i] = i;
  796. X  for (i = 1; i < CIPHER_SIZE; i++) {
  797. X    r = random (CIPHER_SIZE + 1 - i);
  798. X    t = c->encoding[i+r]; 
  799. X    c->encoding[i+r] = c->encoding[i];
  800. X    c->encoding[i] = t;
  801. X  };
  802. X  
  803. X  for (i = 1; i < CIPHER_SIZE1; i++)
  804. X    c->decoding[c->encoding[i]] = i;
  805. X
  806. X}
  807. X
  808. Xvoid Encode_String (c, source, dest)
  809. X     Cipher *c;
  810. X     char *source;
  811. X     char *dest;
  812. X/* Encodes the string in source, placing the result in dest.
  813. X   If c == NULL, then simply copies source to dest. */
  814. X{
  815. X  int i, base_code;
  816. X  
  817. X  if (c == NULL) {
  818. X    strcpy (dest, source);
  819. X    return;
  820. X  }
  821. X    
  822. X  for (i = 0; source[i] != '\0'; i++)
  823. X    if ((base_code = cipher_mapping[(int) (source[i])]) != 0)
  824. X      dest[i] = cipher_unmapping 
  825. X    [c->encoding [(base_code + 3*i) % CIPHER_SIZE + 1]];
  826. X    else
  827. X      dest[i] = source[i];
  828. X  dest[i] = '\0';
  829. X  
  830. X}
  831. X
  832. Xvoid Decode_String (c, source, dest)
  833. X     Cipher *c;
  834. X     char *source;
  835. X     char *dest;
  836. X/* Decodes the string in source, placing the result in dest.
  837. X   If c == NULL, then simply copies source to dest. */
  838. X{
  839. X  int i, p, base_code;
  840. X
  841. X  if (c == NULL) {
  842. X    strcpy (dest, source);
  843. X    return;
  844. X  }
  845. X
  846. X  for (i = 0; source[i] != '\0'; i++)
  847. X    if ((base_code = cipher_mapping[(int) (source[i])]) != 0) {
  848. X      p = (c->decoding[base_code] + 3*CIPHER_SIZE - 3*i)
  849. X    % CIPHER_SIZE - 1;
  850. X      if (p == 0) p = CIPHER_SIZE;
  851. X      dest[i] = cipher_unmapping[p];
  852. X    } else
  853. X      dest[i] = source[i];
  854. X
  855. X  dest[i] = '\0';
  856. X}
  857. X
  858. Xvoid Write_Ciphered_Line (f, c, buf)
  859. X     FILE *f;
  860. X     Cipher *c;
  861. X     char *buf;
  862. X/* Encodes buf using the cipher c and writes it to the file f. 
  863. X   The first character written to the file is an exclamation point '!' */
  864. X{
  865. X  if (c == NULL)
  866. X    fprintf (f, "%s\n", buf);
  867. X  else {
  868. X    Encode_String (c, buf, line_buf);
  869. X    fprintf (f, "!%s\n", line_buf);
  870. X  }
  871. X}
  872. X
  873. Xint Read_Ciphered_Line (f, c, buf, buflen)
  874. X     FILE *f;
  875. X     Cipher *c;
  876. X     char *buf;
  877. X     int buflen;
  878. X/* Reads a line of up to buflen characters from the file f and decodes
  879. X   the line using the cipher c.  If the first character of the line
  880. X   is not an exclamation point '!', then the line is assumed to be
  881. X   in plain text.  Returns the number of characters read or -1 if
  882. X   end of file reached.
  883. X*/
  884. X{
  885. X  int n;
  886. X
  887. X  buf[0] = '\0';
  888. X  n = Read_Line (f, line_buf, buflen);
  889. X  if (n <= 0)
  890. X    return (n);
  891. X
  892. X  if (line_buf[0] == '!') {
  893. X    Decode_String (c, line_buf+1, buf);
  894. X    return (n-1);
  895. X  } else {
  896. X    strcpy (buf, line_buf);
  897. X    return (n);
  898. X  }
  899. X  
  900. X}
  901. END_OF_FILE
  902. if test 7397 -ne `wc -c <'cipher.c'`; then
  903.     echo shar: \"'cipher.c'\" unpacked with wrong size!
  904. fi
  905. # end of 'cipher.c'
  906. fi
  907. if test -f 'display.h' -a "${1}" != "-c" ; then 
  908.   echo shar: Will not clobber existing file \"'display.h'\"
  909. else
  910. echo shar: Extracting \"'display.h'\" \(9932 characters\)
  911. sed "s/^X//" >'display.h' <<'END_OF_FILE'
  912. X/* display.h
  913. X *
  914. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  915. X ! 
  916. X ! OKbridge is made available as a free service to the Internet.
  917. X ! Accordingly, the following restrictions are placed on its use:
  918. X ! 
  919. X ! 1.  OKbridge may not be modified in any way without the explicit 
  920. X !     permission of Matthew Clegg.  
  921. X ! 
  922. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  923. X !     It may not be placed on for-profit networks or on for-profit
  924. X !     computer systems.  It may not be bundled as part of a package
  925. X !     or service provided by a for-profit organization.
  926. X ! 
  927. X ! If you have questions about restrictions on the use of OKbridge,
  928. X ! write to mclegg@cs.ucsd.edu.
  929. X ! 
  930. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  931. X ! damage which may be caused by OKbridge.
  932. X *
  933. X * The DISPLAY module for the bridge program is responsible for
  934. X * presenting the information regarding various aspects of the
  935. X * game to the screen.  The organization of the screen is embedded
  936. X * within this module, and there are entry points for giving
  937. X * updates to the screen at each step of the game.
  938. X *
  939. X * This module does not make any calls to the operating system
  940. X * directly.  Instead, all of its output functions are channeled
  941. X * through the TERMINAL module.
  942. X *
  943. X */
  944. X
  945. X/*
  946. X  The display can be in one of four modes:
  947. X    TALK:  In this mode, almost the entire screen is used for displaying
  948. X           talk messages between the players.  
  949. X    BID:   This is the display mode used during bidding.  
  950. X    PLAY:  This is the display mode used during play.  
  951. X    SCORE: This display mode is used for displaying the history of scores
  952. X           or the results of competitive play.
  953. X    HELP:  This mode is used for displaying help screens.
  954. X    MANUAL:In this mode, the display is given only minimal support by
  955. X           the display module.  Refresh requests are not honored.
  956. X           The status line is at the bottom of the screen.
  957. X
  958. X  In the latter three score modes, the lower 6 lines of the display are
  959. X  reserved for talk messages between the players.  In the BID and PLAY
  960. X  modes, an area in the upper right corner of the display is used for
  961. X  a scoring panel.  The scoring panel contains information such as the
  962. X  current vulnerabilities, the number of tricks which have been played
  963. X  form each side, and the total score of each side.
  964. X*/
  965. X
  966. X#define TALK_DISPLAY      0
  967. X#define BIDDING_DISPLAY   1
  968. X#define PLAYING_DISPLAY   2
  969. X#define SCORING_DISPLAY   3
  970. X#define HELP_DISPLAY      4
  971. X#define MANUAL_DISPLAY    5
  972. X
  973. X#ifdef _DISPLAY_
  974. X  int display_mode = TALK_DISPLAY; /* The current display mode. */
  975. X#else
  976. X  extern int display_mode;
  977. X#endif
  978. X
  979. Xextern void Initialize_Display ();
  980. X/* Should be called once when the program starts up. */
  981. Xextern void Reset_Display ();
  982. X/* Redraws the main features of the screen.  Used in the process
  983. X   of doing a 'refresh'. */
  984. Xextern void Refresh_Display ();
  985. X/* Updates the entire screen. */
  986. X
  987. Xextern void Refresh_Player_Names ();
  988. X/* Redraws the player names.  Useful in case one of the players has changed
  989. X   position. */
  990. X
  991. Xextern void Set_Display_Mode ();
  992. X/* void Set_Display_Mode (int mode); */
  993. X/* Sets the display mode.  If the mode is different than the current mode,
  994. X   then redraws the screen appropriately.
  995. X*/
  996. Xextern void Display_Player_Position ();
  997. X/* Displays okbridge header and the seat in which the local player
  998. X   is sitting. */
  999. X/* The scoring display gives information about the following attributes
  1000. X * for each side:
  1001. X *
  1002. X * -- The number of tricks taken in the current hand.
  1003. X * -- The current 'above the line' score.
  1004. X * -- The current 'below the line' score.
  1005. X * -- The vulnerabilities of each side.
  1006. X *
  1007. X */
  1008. Xextern void Display_Tricks_Taken      ();
  1009. Xextern void Display_Above_Line_Points ();
  1010. Xextern void Display_Below_Line_Points ();
  1011. Xextern void Display_Vulnerabilities   ();
  1012. Xextern void Display_Total_Time ();
  1013. X/* The bidding display is given as four columns, similar to that found
  1014. X * in many bridge books.  At the top of each column is printed the
  1015. X * name of the corresponding player.
  1016. X *
  1017. X * Before bidding can begin, the bidding display must be initialized.
  1018. X * Then, for each bid, that bid must be shown on the display.  And after
  1019. X * the bids have been made, the contract must be displayed.  Thus,
  1020. X * we have the following procedures:
  1021. X *
  1022. X * Display_Bidding_Board:  Called to initialize the bidding display.
  1023. X *   This procedure should be called once at the beginning of the bidding.
  1024. X *
  1025. X * Display_Hand_for_Bidding: Called to show what the local player is
  1026. X *   holding.  This procedure should be called once after the call to
  1027. X *   Display_Bidding_Board.
  1028. X *
  1029. X * Display_Bidder:  Called to show whose turn it is to bid now.
  1030. X *
  1031. X * Display_Bid:  Called to show a player's bid.  The current round of
  1032. X *   bidding and the player who has bid are passed as input parameters,
  1033. X *   but the actual bid is read from the global variable 'bids'.
  1034. X *
  1035. X * Clear_Bidding_Board:  Called to erase the bidding display.  This should
  1036. X *   be called once after the auction has concluded.
  1037. X *
  1038. X * Display_Contract:  To be called after the auction is over.  This
  1039. X *   procedure displays the contract which has been determined by the
  1040. X *   bidding.
  1041. X */
  1042. Xextern void Display_Bidding_Board ();
  1043. Xextern void Display_Hand_for_Bidding ();
  1044. Xextern void Display_Bidder ();
  1045. Xextern void Display_Bid ();
  1046. Xextern void Clear_Bidding_Board ();
  1047. Xextern void Display_Contract ();
  1048. X/* The playing board is a separate display which runs during the play
  1049. X * of the hands.  In the center of the screen is displayed a large square
  1050. X * which is supposed to represent the tabletop, and the cards which are
  1051. X * played are shown on this table top.
  1052. X *
  1053. X * The playing proceeds also in a series of stages.  First, there is an
  1054. X * initial call to draw the playing board.  Then, in each trick there are
  1055. X * calls to show the cards which have been played.  At the end of each
  1056. X * trick, there is a final call to clear the cards from the playing board.
  1057. X * And after all of the tricks have been played, the playing board is
  1058. X * cleared.  Thus, we have the following procedures:
  1059. X *
  1060. X * Display_Playing_Board:  called initially to draw the playing board.
  1061. X *
  1062. X * Display_Hand:  called at the beginning of each trick to display the
  1063. X *   contents of the (local) player's hand.  The player whose hand is to
  1064. X *   be displayed is passed as input.
  1065. X *
  1066. X * Display_Player: called before each card is played to display whose
  1067. X *   it is to play next.
  1068. X *
  1069. X * Display_Play:  called after each card has been played to display the
  1070. X *   card on the tabletop.  The player and the card are passed as input.
  1071. X *
  1072. X * Clear_Hand:  called intermittently to erase a player's hand from
  1073. X *   the display.
  1074. X *
  1075. X * Clear_Plays:  called at the end of each trick to clear the cards from
  1076. X *   the tabletop.
  1077. X *
  1078. X * Clear_Playing_Board:  called after all of the tricks have been played
  1079. X *   to clear the 'playing board' from the screen.
  1080. X *
  1081. X */
  1082. Xextern void Display_Playing_Board ();
  1083. Xextern void Display_Partial_Hand ();
  1084. Xextern void Display_Hand ();
  1085. Xextern void Display_Player ();
  1086. Xextern void Display_Play ();
  1087. Xextern void Clear_Plays  ();
  1088. Xextern void Clear_Hand ();
  1089. Xextern void Clear_Playing_Board ();
  1090. X
  1091. X
  1092. X/* If a hand is been played by multiple tables, then we can display 
  1093. X * the records of play for each table to the user.  
  1094. X *
  1095. X * First, we setup the scoring display with a call to Setup_Scoring_Display.
  1096. X * This displays the first page of scores.  
  1097. X *
  1098. X * The function More_Scores_to_Display () returns TRUE when not all of
  1099. X * the scores have yet been displayed.
  1100. X *
  1101. X * And the function Display_More_Scores () displays the next page of scores.
  1102. X */
  1103. X
  1104. Xextern void Display_First_Page_of_Scores ();
  1105. X/* void Display_First_Page_of_Scores (Board *b); */
  1106. X/* Initiales the scoring display and displays the first page of results from
  1107. X * board b. 
  1108. X */
  1109. X
  1110. Xextern int More_Scores_to_Display ();
  1111. X/* int More_Scores_to_Display (void); */
  1112. X/* Returns true if not all of the results have been displayed from the
  1113. X * board which is currently being displayed. 
  1114. X */
  1115. X
  1116. Xextern void Display_More_Scores ();
  1117. X/* void Display_More_Scores (void); */
  1118. X/* Displays the next page of scores for the board b. */
  1119. X
  1120. X
  1121. X/* One line of the display is reserved for displaying special messages about
  1122. X * the status of the game.  The following two procedures are given for
  1123. X * manipulating this display.
  1124. X */
  1125. Xextern void Status ();
  1126. X/* void Status (char *status_message); */
  1127. X/* Displays the given status message. */
  1128. X
  1129. Xextern void Clear_Status ();
  1130. X/* void Clear_Status (void); */
  1131. X/* Clears the status display. */
  1132. Xextern void Lock_Status ();
  1133. X/* void Lock_Status (char *message); */
  1134. X/* Locks the message into the status display.  If the status display is 
  1135. X   already locked, pushes the current message onto a stack, to be redisplayed
  1136. X   when Unlock_Status is called.
  1137. X*/
  1138. X
  1139. Xextern void Unlock_Status ();
  1140. X/* void Unlock_Status (void); */
  1141. X/* Unlocks the status display.  Redisplays the previous message on the
  1142. X   stack of status messages.  */
  1143. Xextern void Reset_Status ();
  1144. X/* void Reset_Status (void); */
  1145. X/* Clears all messages from the stack of status messages and resets the
  1146. X   status display. */
  1147. X
  1148. Xextern void Refresh_Status_Display ();
  1149. X/* void Refresh_Status_Display (void); */
  1150. X/* Redisplays the contents of the status buffer. */
  1151. X
  1152. X
  1153. X/* The bottom part of the screen is used for the exchange of comments
  1154. X * between the players.  The following procedures are used for managing
  1155. X * this part of the display.
  1156. X *
  1157. X * During startup, the entire screen is devoted to a comments display.
  1158. X */
  1159. Xextern void Initialize_Player_Comments ();
  1160. Xextern void Reinitialize_Player_Comments ();
  1161. Xextern void Display_Player_Comment ();
  1162. Xextern void Refresh_Player_Comments ();
  1163. Xextern void Clear_Comment_Display ();
  1164. X
  1165. Xextern void Moderator_Comment ();
  1166. X /* displays a comment from the MODERATOR. */
  1167. Xextern void Network_Comment ();
  1168. X /* displays a comment from the NETWORK. */
  1169. X
  1170. Xextern void Suspend_Comment_Display ();
  1171. Xextern void Continue_Comment_Display ();
  1172. X
  1173. END_OF_FILE
  1174. if test 9932 -ne `wc -c <'display.h'`; then
  1175.     echo shar: \"'display.h'\" unpacked with wrong size!
  1176. fi
  1177. # end of 'display.h'
  1178. fi
  1179. if test -f 'help.c' -a "${1}" != "-c" ; then 
  1180.   echo shar: Will not clobber existing file \"'help.c'\"
  1181. else
  1182. echo shar: Extracting \"'help.c'\" \(7995 characters\)
  1183. sed "s/^X//" >'help.c' <<'END_OF_FILE'
  1184. X/* help.c -- help functions for the bridge program.
  1185. X *
  1186. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  1187. X ! 
  1188. X ! OKbridge is made available as a free service to the Internet.
  1189. X ! Accordingly, the following restrictions are placed on its use:
  1190. X ! 
  1191. X ! 1.  OKbridge may not be modified in any way without the explicit 
  1192. X !     permission of Matthew Clegg.  
  1193. X ! 
  1194. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  1195. X !     It may not be placed on for-profit networks or on for-profit
  1196. X !     computer systems.  It may not be bundled as part of a package
  1197. X !     or service provided by a for-profit organization.
  1198. X ! 
  1199. X ! If you have questions about restrictions on the use of OKbridge,
  1200. X ! write to mclegg@cs.ucsd.edu.
  1201. X ! 
  1202. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  1203. X ! damage which may be caused by OKbridge.
  1204. X *
  1205. X */
  1206. X#include <stdio.h>
  1207. X#include <string.h>
  1208. X#include <ctype.h>
  1209. X
  1210. X#ifndef SEEK_SET
  1211. X#define SEEK_SET  0
  1212. X#endif
  1213. X#include "types.h"
  1214. X#include "input.h"
  1215. X#include "terminal.h"
  1216. X#include "display.h"
  1217. X/* char *help_file_name = "okbridge.help"; */
  1218. X#include "helpfile.h"
  1219. X
  1220. Xextern strcasecmp (), fseek ();
  1221. Xextern int errno;
  1222. Xextern char *sys_errlist[];
  1223. Xextern char *strdup();
  1224. Xextern char *getenv ();
  1225. Xextern char *malloc ();
  1226. Xextern int  input_help_topic ();
  1227. X
  1228. X
  1229. Xtypedef struct help_entry_struct {
  1230. X    char    *topic;
  1231. X    char    *description;
  1232. X    long int file_offset;
  1233. X    struct help_entry_struct *next;
  1234. X} *help_entry;
  1235. Xstatic help_entry main_topic = NULL;
  1236. XFILE *help_file = NULL;
  1237. X
  1238. Xlong int current_page = -1;
  1239. X  /* The offset into the help file of the current page being displayed,
  1240. X     or -1 if we are not displaying any page. */
  1241. X
  1242. Xvoid display_topics (message)
  1243. X    char *message;
  1244. X/* Displays the list of topics, with the given message as the top line.
  1245. X . Does not display the main topic.
  1246. X */
  1247. X{
  1248. X    int i;
  1249. X    help_entry e;
  1250. X    char msg_buf[80];
  1251. X    clear_screen ();
  1252. X    print (1,1,message);
  1253. X    if (main_topic == NULL) {
  1254. X        print (3,1,"The help system is empty.");
  1255. X    } else {
  1256. X        i = 3;
  1257. X        for (e = main_topic->next; e != NULL; e = e->next) {
  1258. X          if (strcasecmp(e->topic, "slam")) {
  1259. X            sprintf (msg_buf, "%-10s -- %s",e->topic,
  1260. X                e->description);
  1261. X            print (i++, 1, msg_buf);
  1262. X              }
  1263. X        }
  1264. X    }
  1265. X}
  1266. Xstatic int read_help_line (buf, buflen)
  1267. X    char *buf; int buflen;
  1268. X/* Reads a line from the help file.  Returns the number of characters
  1269. X   read of -1 if EOF is encountered.  Skips lines beginning with a '#'. 
  1270. X*/
  1271. X{
  1272. X    int i, ch;
  1273. X    do {
  1274. X        ch = getc(help_file);
  1275. X        i = 0;
  1276. X        while ((ch != '\n') && (ch != EOF)) {
  1277. X            if (i < buflen-1) buf[i++] = ch;
  1278. X            ch = getc(help_file);
  1279. X        }
  1280. X        buf[i] = '\0';
  1281. X        if (ch == EOF) return (-1);
  1282. X        while ((i > 0) && isspace(buf[i-1])) buf[--i] = '\0';
  1283. X    } while (buf[0] == '#');
  1284. X    return (i);
  1285. X}
  1286. Xstatic void display_help_entry (e)
  1287. X    help_entry e;
  1288. X/* Displays the help_entry e. */
  1289. X{
  1290. X    char line[81];
  1291. X    int lines_on_page, log;
  1292. X
  1293. X    lines_on_page = 0;
  1294. X    current_page = e->file_offset;
  1295. X    fseek (help_file, e->file_offset, SEEK_SET);
  1296. X    log = read_help_line (line, 81);
  1297. X    while ((log >= 0) && strcmp(line, "--")) {
  1298. X        if ((lines_on_page > terminal_lines-2) || (line[0] == '^')) {
  1299. X                Press_Return_to_Continue ("");
  1300. X            current_page = ftell (help_file);
  1301. X            clear_screen ();
  1302. X            lines_on_page = 0;
  1303. X             if (line[0] == '^') line[0] = ' ';
  1304. X        }
  1305. X        print (++lines_on_page, 1, line);
  1306. X        log = read_help_line (line, 81);
  1307. X    }
  1308. X    Press_Return_to_Continue ("");
  1309. X}
  1310. X
  1311. Xstatic FILE *open_helpfile ()
  1312. X/* Tries to open the helpfile with given name from the help_directory.
  1313. X * If an error, prints an error message and returns NULL.  Otherwise,
  1314. X * returns a pointer to the opened file.
  1315. X */
  1316. X{
  1317. X    char filename_buf [80], msg_buf[80], *envhelpdir;
  1318. X    FILE *fp;
  1319. X    if ((envhelpdir = getenv("OKBRIDGE_HELPFILE")) != NULL)
  1320. X        sprintf (filename_buf, "%s", envhelpdir);
  1321. X    else
  1322. X        sprintf (filename_buf, "%s", help_file_name);
  1323. X
  1324. X    fp = fopen (filename_buf, "r");
  1325. X    if (fp == NULL)
  1326. X        fp = fopen ("okbridge.help", "r");
  1327. X
  1328. X    if (fp == NULL) {
  1329. X        sprintf (msg_buf, "Error opening helpfile %s", filename_buf);
  1330. X        print (3, 1, msg_buf);
  1331. X        sprintf (msg_buf, "System reports error: %s",
  1332. X                sys_errlist[errno]);
  1333. X        print (4, 1, msg_buf);
  1334. X        Press_Return_to_Continue ("");
  1335. X    }
  1336. X    return (fp);
  1337. X}
  1338. Xstatic help_entry find_help_topic (topic)
  1339. X    char *topic;
  1340. X/* Looks for the help entry with the associated topic.  If it is found,
  1341. X * returns a pointer to the corresponding record.  Otherwise, returns NULL.
  1342. X */
  1343. X{
  1344. X    help_entry e;
  1345. X    e = main_topic;
  1346. X    while (e != NULL) {
  1347. X        if (!strcasecmp(e->topic, topic))
  1348. X            return (e);
  1349. X        e = e->next;
  1350. X    }
  1351. X    return (e);
  1352. X}
  1353. Xstatic help_entry read_new_help_entry ()
  1354. X/* Reads a help entry from the help_file.  Allocates a help_entry record
  1355. X . and records the pertinent information in that record.  Returns the
  1356. X . allocated record or NULL if the end of file is reached.
  1357. X */
  1358. X{
  1359. X    char line_buf[81];
  1360. X    help_entry e;
  1361. X    char *curpos, *keypos, *descpos;
  1362. X    int log;
  1363. X
  1364. X    log = read_help_line (line_buf, 81);
  1365. X    if (log < 0)
  1366. X        return (NULL);
  1367. X
  1368. X    for (keypos = line_buf; isspace(*keypos); keypos++);
  1369. X    for (curpos = keypos;(*curpos != '\0') && !isspace(*curpos);curpos++);
  1370. X    for (descpos = curpos; isspace(*descpos); descpos++);
  1371. X
  1372. X    e = (help_entry) malloc(sizeof(struct help_entry_struct));
  1373. X    *curpos = '\0';
  1374. X    e->topic = strdup (keypos);
  1375. X    e->description = strdup (descpos);
  1376. X    e->file_offset = ftell (help_file);
  1377. X    e->next = NULL;
  1378. X
  1379. X    do
  1380. X      log = read_help_line (line_buf, 81);
  1381. X    while 
  1382. X      ((log >= 0) && strcmp(line_buf, "--"));
  1383. X
  1384. X    return (e);
  1385. X
  1386. X}
  1387. X
  1388. Xvoid initialize_help_system ()
  1389. X/* Called once at the beginning of the program to read the file of help
  1390. X * topics.
  1391. X */
  1392. X{
  1393. X    help_entry e;
  1394. X    help_file = open_helpfile ();
  1395. X    if (help_file == NULL) return;
  1396. X    e = main_topic = read_new_help_entry ();
  1397. X    while (e != NULL) {
  1398. X        e->next = read_new_help_entry ();
  1399. X        e = e->next;
  1400. X    }
  1401. X
  1402. X}
  1403. Xvoid Browse_help_topics ();
  1404. Xvoid display_help (topic)
  1405. X    char *topic;
  1406. X/* Displays help on the given topic.  This consists of looking up the
  1407. X * help file associated to this topic and displaying the contents of this
  1408. X * file on the screen.  If the topic string is empty, then displays first
  1409. X * the contents of the main topic file, and then displays a list of the
  1410. X * topics.  If there is no help on the given topic, then displays a list
  1411. X * of topics.
  1412. X */
  1413. X{
  1414. X  help_entry he;
  1415. X  char line_buf[81];
  1416. X  
  1417. X  if (main_topic == NULL)
  1418. X    return;
  1419. X  
  1420. X  clear_screen ();
  1421. X  if (strlen(topic) == 0) {
  1422. X    display_help_entry (main_topic);
  1423. X  } else if ((he = find_help_topic(topic)) != NULL)
  1424. X    display_help_entry (he);
  1425. X  else {
  1426. X    sprintf (line_buf, "%s  %s",
  1427. X         "There is no help for this topic.",
  1428. X         "The available topics are");
  1429. X    display_topics (line_buf);
  1430. X    Press_Return_to_Continue ("");
  1431. X  }
  1432. X  
  1433. X}
  1434. X
  1435. Xvoid browse_help (topic)
  1436. X     char *topic;
  1437. X/* Displays help on the given topic.  Afterwards, displays a list of
  1438. X * topics along with a request to enter the name of a new topic.
  1439. X */
  1440. X{
  1441. X  help_entry he;
  1442. X  char line_buf[81];
  1443. X  int no_topic = 0;
  1444. X  
  1445. X  if (main_topic == NULL)
  1446. X    return;
  1447. X  
  1448. X  clear_screen ();
  1449. X  if (strlen(topic) == 0) {
  1450. X    display_help_entry (main_topic);
  1451. X  } else if ((he = find_help_topic(topic)) != NULL)
  1452. X    display_help_entry (he);
  1453. X  else 
  1454. X    no_topic = 1;
  1455. X  
  1456. X  display_topics ("LIST OF HELP TOPICS");
  1457. X  print (terminal_lines-1, 1, "HELP");
  1458. X  Refresh_Status_Display ();
  1459. X  
  1460. X  if (no_topic) {
  1461. X    sprintf (line_buf, "THERE IS NO HELP FOR THE TOPIC %s", topic);
  1462. X    print (terminal_lines-2, 1, line_buf);
  1463. X    ring_bell ();
  1464. X  }
  1465. X}
  1466. X
  1467. Xvoid Refresh_Help_Display ()
  1468. X/* Redisplays the current screen of help information. */
  1469. X{
  1470. X  char line[81];
  1471. X  int lines_on_page, log;
  1472. X
  1473. X  if (current_page < 0) {
  1474. X    display_topics ("LIST OF HELP TOPICS");
  1475. X    return;
  1476. X  }
  1477. X  
  1478. X  lines_on_page = 0;
  1479. X  fseek (help_file, current_page, SEEK_SET);
  1480. X  log = read_help_line (line, 81);
  1481. X  while ((log >= 0) && strcmp(line, "--")) {
  1482. X    if ((lines_on_page > terminal_lines-2) || (line[0] == '^'))
  1483. X      return;
  1484. X    print (++lines_on_page, 1, line);
  1485. X    log = read_help_line (line, 81);
  1486. X  }
  1487. X  
  1488. X}
  1489. X
  1490. Xvoid Clear_Help_Display ()
  1491. X/* Returns the help system to its initial state. */
  1492. X{
  1493. X  current_page = -1;
  1494. X}
  1495. END_OF_FILE
  1496. if test 7995 -ne `wc -c <'help.c'`; then
  1497.     echo shar: \"'help.c'\" unpacked with wrong size!
  1498. fi
  1499. # end of 'help.c'
  1500. fi
  1501. if test -f 'scoring.c' -a "${1}" != "-c" ; then 
  1502.   echo shar: Will not clobber existing file \"'scoring.c'\"
  1503. else
  1504. echo shar: Extracting \"'scoring.c'\" \(9823 characters\)
  1505. sed "s/^X//" >'scoring.c' <<'END_OF_FILE'
  1506. X/* scoring.c -- scoring functions for the bridge program.
  1507. X *
  1508. X ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  1509. X ! 
  1510. X ! OKbridge is made available as a free service to the Internet.
  1511. X ! Accordingly, the following restrictions are placed on its use:
  1512. X ! 
  1513. X ! 1.  OKbridge may not be modified in any way without the explicit 
  1514. X !     permission of Matthew Clegg.  
  1515. X ! 
  1516. X ! 2.  OKbridge may not be used in any way for commercial advantage.
  1517. X !     It may not be placed on for-profit networks or on for-profit
  1518. X !     computer systems.  It may not be bundled as part of a package
  1519. X !     or service provided by a for-profit organization.
  1520. X ! 
  1521. X ! If you have questions about restrictions on the use of OKbridge,
  1522. X ! write to mclegg@cs.ucsd.edu.
  1523. X ! 
  1524. X ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  1525. X ! damage which may be caused by OKbridge.
  1526. X *
  1527. X * This file defines the functions used for computing scores.
  1528. X * We provide functions for scoring according to the rules of
  1529. X * rubber bridge as well as according to the rules of Chicago style
  1530. X * bridge.  Instead of being passed parameters, these functions
  1531. X * obtain most of their information from the global variables
  1532. X * defined in globals.h.
  1533. X *
  1534. X * I would like to thank Tom Kronmiller for supplying the code
  1535. X * for scoring according to the Chicago rules.  Thanks Tom!
  1536. X */
  1537. X#include "types.h"
  1538. Xstatic int  first_trick   [] = {20, 20, 30, 30, 40};
  1539. Xstatic int  subseq_tricks [] = {20, 20, 30, 30, 30};
  1540. X
  1541. X
  1542. X/*  All of the routines in this module use the same set of parameters:
  1543. X *  
  1544. X *  vul     := a boolean flag which if true indicates that the declaring
  1545. X *             side was vulnerable.
  1546. X *  level   := the level of the contract.
  1547. X *  suit    := the trump suit (or SUIT_NOTRUMP).
  1548. X *  doubled := is 0 for an undoubled contract, 1 for a doubled contract,
  1549. X *             and 2 for a redoubled contract.
  1550. X *  made    := If the contract was made, then the number of tricks made
  1551. X *             minus 6.  Otherwise, the negative of the number of tricks set.
  1552. X *  hcp     := Number of highcard points held by the declaring side.
  1553. X */
  1554. X
  1555. Xint Rubber_score_above (vul, level, suit, doubled, made)
  1556. X     int vul, level, suit, doubled, made;
  1557. X/* Computes the above-the-line score for the current contract, assuming
  1558. X   the contract was made. */
  1559. X{
  1560. X  int above = 0;  /* computed above-the-line points. */
  1561. X
  1562. X  if (doubled) {
  1563. X    above = 100 * (made - level);
  1564. X    if (vul)         above *= 2;
  1565. X    if (doubled > 1) above *= 2;
  1566. X    above += 50;
  1567. X  } else
  1568. X    above = subseq_tricks[suit] * (made - level);
  1569. X
  1570. X  if (level == 6)
  1571. X    above += vul? 750: 500;
  1572. X  else if (level == 7)
  1573. X    above += vul? 1500: 1000;
  1574. X  return (above);
  1575. X    
  1576. X}
  1577. X
  1578. Xint Rubber_score_below (vul, level, suit, doubled, made)
  1579. X     int vul, level, suit, doubled, made;
  1580. X/* Computes the below-the-line score for the current contract,
  1581. X * assuming the contract was made. */
  1582. X{
  1583. X  int below = 0;  /* computed below-the-line points. */
  1584. X
  1585. X  below  = first_trick[suit] + 
  1586. X    (level - 1) * subseq_tricks[suit];
  1587. X  if (doubled > 1)
  1588. X    below *= 4;
  1589. X  else if (doubled)
  1590. X    below *= 2;
  1591. X  return (below);
  1592. X}
  1593. X
  1594. X
  1595. Xint Rubber_score_set (vul, level, suit, doubled, made)
  1596. X     int vul, level, suit, doubled, made;
  1597. X/* Computes the penalty score for the current contract assuming that
  1598. X * the contract was set.  
  1599. X */
  1600. X{
  1601. X  int penalty = 0;  /* computed penalty points. */
  1602. X  int down = -made - 1;
  1603. X
  1604. X  if (doubled) {
  1605. X    if (vul) penalty = 200 + 300 * down;
  1606. X    else     penalty = 100 + 200 * down;
  1607. X    if (doubled > 1) penalty *= 2;
  1608. X  } else {
  1609. X    if (vul) penalty = 100 + 100 * down;
  1610. X    else     penalty =  50 +  50 * down;
  1611. X  }
  1612. X  return (penalty);
  1613. X}
  1614. X
  1615. X
  1616. Xint Chicago_score_made (vul, level, suit, doubled, made)
  1617. X     int vul, level, suit, doubled, made;
  1618. X/* Computes the score for the current contract under the Chicago scoring
  1619. X * system, assuming that it was made.
  1620. X *
  1621. X * Original version by Tom Kronmiller.
  1622. X */
  1623. X{
  1624. X    int result = 0, perTrick;
  1625. X    int extra = made - level;
  1626. X
  1627. X    /* How much is making the bid worth? */
  1628. X    perTrick = (MINOR(suit))? 20:30;
  1629. X    result = perTrick * level;
  1630. X    if (suit == SUIT_NOTRUMP)    result += 10;
  1631. X    if (doubled > 1)                result *= 4;
  1632. X    else if (doubled == 1)          result *= 2;
  1633. X      
  1634. X    /* Was it a game we made? */
  1635. X    if (result >= 100)        result += (!vul)? 300:500;
  1636. X/*    else                    result += 50; */
  1637. X
  1638. X    /* Was it a slam we made? */
  1639. X    if (level == 6)        result += (!vul)? 500:750;
  1640. X    if (level == 7)        result += (!vul)? 1000:1500;
  1641. X
  1642. X    /* Were we insulted by a double? */
  1643. X    if (doubled > 1)                  result += 100;
  1644. X    else if (doubled == 1)            result += 50;
  1645. X
  1646. X    /* How much do we get for overtricks? */
  1647. X    if (doubled > 1)
  1648. X            result += (extra * 100) * (vul? 4: 2);
  1649. X    else if (doubled == 1)
  1650. X            result += (extra * 100) * (vul? 2: 1);
  1651. X    else
  1652. X        result += extra * perTrick;
  1653. X
  1654. X    return (result);
  1655. X}
  1656. X
  1657. X
  1658. Xint Chicago_score_set (vul, level, suit, doubled, made)
  1659. X     int vul, level, suit, doubled, made;
  1660. X/* Computes the score for the given contract under the Chicago scoring
  1661. X * system, assuming that it was set.
  1662. X *
  1663. X * Original version by Tom Kronmiller.
  1664. X */
  1665. X{
  1666. X    int result = 0;
  1667. X    int down =  -made;
  1668. X
  1669. X    if (!doubled)
  1670. X    {
  1671. X        result = 50 * down;
  1672. X        if (vul) result *= 2;
  1673. X    }
  1674. X    else
  1675. X    {
  1676. X        switch (down)
  1677. X        {
  1678. X            case 1:
  1679. X                result = (!vul)? 100:200;
  1680. X                break;
  1681. X            case 2:
  1682. X                result = (!vul)? 300:500;
  1683. X                break;
  1684. X            case 3:
  1685. X                result = (!vul)? 500:800;
  1686. X                break;
  1687. X            default:
  1688. X                result = 500 + (300*(down-3)) 
  1689. X                  + ((!vul)? 0:300);
  1690. X                break;
  1691. X        }
  1692. X        if (doubled > 1) result *= 2;
  1693. X    }
  1694. X    return (result);
  1695. X}
  1696. X
  1697. Xint Duplicate_score_made (vul, level, suit, doubled, made)
  1698. X     int vul, level, suit, doubled, made;
  1699. X/* Computes the score for the given contract under the rules of
  1700. X * duplicate scoring. 
  1701. X */
  1702. X{
  1703. X    int score;
  1704. X
  1705. X    if (made == 0)
  1706. X      return (0);
  1707. X
  1708. X    score = Chicago_score_made (vul, level, suit, doubled, made);
  1709. X    if (score < 300)
  1710. X        score += 50;
  1711. X    return (score);
  1712. X    
  1713. X}
  1714. X
  1715. Xint Duplicate_score_set (vul, level, suit, doubled, made)
  1716. X     int vul, level, suit, doubled, made;
  1717. X/* Computes the score for the given contract under the rules of
  1718. X * duplicate scoring, assuming that it was set.
  1719. X */
  1720. X{
  1721. X  return (Chicago_score_set(vul, level, suit, doubled, made));
  1722. X}
  1723. X
  1724. X
  1725. Xstatic int IMP_conversion_table [] = {
  1726. X    20,   50,   90,  130,  170,  220,  270,  320,  370,  430, 
  1727. X   500,  600,  750,  900, 1100, 1300, 1500, 1750, 2000, 2250,
  1728. X  2500, 3000, 3500, 4000, 99999};
  1729. X
  1730. Xint IMP_rating (score_diff)
  1731. X     int score_diff;
  1732. X/* Returns the number of IMPs awarded for the given score difference. */
  1733. X{
  1734. X  int imps = 0;
  1735. X
  1736. X  if (score_diff < 0)
  1737. X    return (-IMP_rating(-score_diff));
  1738. X
  1739. X  for (imps = 0; IMP_conversion_table[imps] <= score_diff; imps++);
  1740. X  return (imps + imps);
  1741. X}
  1742. X
  1743. Xstatic int IMP_score_conversion (pt, highcard_points)
  1744. X     int pt, highcard_points;
  1745. X/* Computes a 'simulated IMP' score.  This score is computed by looking
  1746. X   up the IMP_rating of the pt score of the declaring team, and subtracting
  1747. X   from this the number of highcard points over 20.
  1748. X*/
  1749. X{
  1750. X  return (IMP_rating(pt) - (highcard_points - 20));
  1751. X}
  1752. X
  1753. Xint Simulated_IMP_score_made (vul, level, suit, doubled, made, hcp)
  1754. X     int vul, level, suit, doubled, made, hcp;
  1755. X/* Computes the simulated IMP score for the given contract assuming that 
  1756. X * it was made.
  1757. X */
  1758. X{
  1759. X    int score;
  1760. X
  1761. X    score =
  1762. X      IMP_score_conversion
  1763. X        (Duplicate_score_made (vul, level, suit, doubled, made), hcp);
  1764. X
  1765. X    return (score);
  1766. X    
  1767. X}
  1768. X
  1769. Xint Simulated_IMP_score_set (vul, level, suit, doubled, made, hcp)
  1770. X     int vul, level, suit, doubled, made, hcp;
  1771. X/* Computes the simulated IMP score for the given contract assuming that 
  1772. X * it was set.
  1773. X */
  1774. X{
  1775. X    int score;
  1776. X
  1777. X    score =
  1778. X      IMP_score_conversion
  1779. X        (-Duplicate_score_set(vul, level, suit, doubled, made), hcp);
  1780. X
  1781. X    return (score);
  1782. X}
  1783. X
  1784. Xint MIMP_scoring_vuln [] = {
  1785. X    -2100, -2100, -2100, -2100, -1850, -1650, -1500, -1400, -1100, -950,
  1786. X    -800, -750, -700, -650, -600, -450, -300, -150, -100, -50,
  1787. X    0, 50, 100, 150, 300, 450, 600, 650, 700, 750,
  1788. X    800, 950, 1100, 1400, 1500, 1650, 1850, 2100, 2100, 2100,
  1789. X    2100
  1790. X};
  1791. X
  1792. Xint MIMP_scoring_nonvuln [] = {
  1793. X    -1500, -1500, -1500, -1500, -1300, -1150, -1050, -950, -800, -700,
  1794. X    -600, -550, -500, -450, -400, -300, -200, -150, -100, -50,
  1795. X    0, 50, 100, 150, 200, 300, 400, 450, 500, 550,
  1796. X    600, 700, 800, 950, 1050, 1150, 1300, 1500, 1500, 1500,
  1797. X    1500
  1798. X};
  1799. X
  1800. Xint MIMP_score_conversion (score, vulnerable, highcard_points)
  1801. X     int score, vulnerable, highcard_points;
  1802. X/* This code contributed by David Morrison. */
  1803. X{
  1804. X    /* If you think the code calculating the score here is magic, you
  1805. X     * are *right*.
  1806. X     */
  1807. X
  1808. X    if (vulnerable) { score -= MIMP_scoring_vuln[highcard_points]; }
  1809. X    else { score -= MIMP_scoring_nonvuln[highcard_points]; }
  1810. X
  1811. X    /* If I had a good description of the algorithm, and its
  1812. X     * justification, it would go here.  For now, you'll just have to
  1813. X     * accept the code.
  1814. X     */
  1815. X
  1816. X    if ( (score <= 600) && (score >= -600) ) {
  1817. X        score *= 2;
  1818. X    } else {
  1819. X    if (score > 600) {
  1820. X        score += 600;
  1821. X    } else {
  1822. X        score -= 600;
  1823. X    }
  1824. X    }
  1825. X
  1826. X    if (score >= 0)
  1827. X      score = (score + 25) / 50;
  1828. X    else
  1829. X      score = (score - 25) / 50;
  1830. X
  1831. X    return (score);
  1832. X
  1833. X}
  1834. X
  1835. Xint MIMP_score_made (vul, level, suit, doubled, made, hcp)
  1836. X     int vul, level, suit, doubled, made, hcp;
  1837. X/* Computes the MIMP score for the given contract assuming that 
  1838. X * it was made.
  1839. X *
  1840. X * This code contributed by David Morrison.
  1841. X */
  1842. X{
  1843. X  int score;
  1844. X
  1845. X  score =
  1846. X    MIMP_score_conversion
  1847. X      (Duplicate_score_made (vul, level, suit, doubled, made), vul, hcp);
  1848. X
  1849. X  return (score);
  1850. X    
  1851. X}
  1852. X
  1853. Xint MIMP_score_set (vul, level, suit, doubled, made, hcp)
  1854. X     int vul, level, suit, doubled, made, hcp;
  1855. X/* Computes the MIMP score for the given contract assuming that 
  1856. X * it was set.
  1857. X *
  1858. X * This code contributed by David Morrison.
  1859. X */
  1860. X{
  1861. X  int score;
  1862. X
  1863. X  score =
  1864. X    MIMP_score_conversion
  1865. X      (-Duplicate_score_set(vul, level, suit, doubled, made), vul, hcp);
  1866. X  
  1867. X  return (score);
  1868. X}
  1869. X
  1870. END_OF_FILE
  1871. if test 9823 -ne `wc -c <'scoring.c'`; then
  1872.     echo shar: \"'scoring.c'\" unpacked with wrong size!
  1873. fi
  1874. # end of 'scoring.c'
  1875. fi
  1876. echo shar: End of archive 12 \(of 14\).
  1877. cp /dev/null ark12isdone
  1878. MISSING=""
  1879. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  1880.     if test ! -f ark${I}isdone ; then
  1881.     MISSING="${MISSING} ${I}"
  1882.     fi
  1883. done
  1884. if test "${MISSING}" = "" ; then
  1885.     echo You have unpacked all 14 archives.
  1886.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1887. else
  1888.     echo You still need to unpack the following archives:
  1889.     echo "        " ${MISSING}
  1890. fi
  1891. ##  End of shell archive.
  1892. exit 0
  1893.