home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume13 / okbridge / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-01-12  |  55.0 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: v13i016:  okbridge - computer-mediated bridge game, Part01/07
  5. Message-ID: <2275@masterCNA.TEK.COM>
  6. Date: 10 Jan 92 16:44:09 GMT
  7. Sender: news@masterCNA.TEK.COM
  8. Lines: 1609
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: mclegg@cs.UCSD.EDU (Matthew Clegg)
  12. Posting-number: Volume 13, Issue 16
  13. Archive-name: okbridge/Part01
  14. Environment: BSD-derived Unix, curses, sockets
  15.  
  16.  
  17.  
  18.     [This is a multiplayer networked bridge game that uses the
  19.      computer to handle dealing, scoring, etc. It was inspired
  20.      by the 'bridge' game posted in c.s.g. (v4i019/20), but has
  21.      been completely rewritten.  -br]
  22.  
  23. #! /bin/sh
  24. # This is a shell archive.  Remove anything before this line, then unpack
  25. # it by saving it into a file and typing "sh file".  To overwrite existing
  26. # files, type "sh file -c".  You can also feed this as standard input via
  27. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  28. # will see the following message at the end:
  29. #        "End of archive 1 (of 7)."
  30. # Contents:  README MANIFEST README.Install README.Playing network.c
  31. #   terminal.c
  32. # Wrapped by billr@saab on Fri Jan 10 08:31:27 1992
  33. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  34. if test -f 'README' -a "${1}" != "-c" ; then 
  35.   echo shar: Will not clobber existing file \"'README'\"
  36. else
  37. echo shar: Extracting \"'README'\" \(3772 characters\)
  38. sed "s/^X//" >'README' <<'END_OF_FILE'
  39. X
  40. Xintro -- introduction to the okbridge program
  41. XMatthew Clegg.  August 1990.
  42. X
  43. X
  44. XGeneral Description
  45. X------- -----------
  46. X
  47. XThe okbridge program is an interactive computer-mediated bridge game.
  48. XIt allows four players at (not necessarily) different locations on the
  49. Xinternet to participate in a game of rubber or Chicago (duplicate)
  50. Xbridge.  The program handles the dealing, scoring and communication of
  51. Xbids and plays.  It is screen oriented, although the screen display is
  52. Xrather simplistic.
  53. X
  54. X
  55. XCopyright Notice
  56. X--------- ------
  57. X
  58. XCopyright (C) 1990,1991 by Matthew Clegg
  59. X
  60. XThis program may be copied and distributed freely.  Please do not
  61. Xcharge money for this program or for any program derived from it.
  62. XIf you modify this program, then include a notice stating plainly
  63. Xthat your program is derived from the okbridge program and is not
  64. Xthe same as the official okbridge program.
  65. X
  66. XI welcome any suggestions for improvement to okbridge, and 
  67. XI would be especially happy to receive improved source code.
  68. XIf you have comments or suggestions, or if you would like to
  69. Xjoin the okbridge mailing list, then write to
  70. X
  71. X  mclegg@cs.ucsd.edu
  72. X
  73. X
  74. X
  75. XSystem Requirements
  76. X------ ------------
  77. X
  78. XThe program has been compiled and tested on a few SUN and VAX systems
  79. Xrunning derivatives of BSD UNIX.  The okbridge program uses the
  80. X"curses" library, which is available at most sites.  It also requires
  81. Xthat the machine on which it is running be an internet site.  If you
  82. Xobtained this software through the use of the 'ftp' program, then your
  83. Xmachine is probably an internet site.  The source code is written in
  84. Xthe C programming language.
  85. X
  86. X
  87. XHistory
  88. X-------
  89. X
  90. XMy interest in bridge began as an undergraduate at the University of
  91. XCalifornia, Riverside, where I learned the game.  After some time, I
  92. Xended up in Berkeley :-), while one of my best bridge-playing friends
  93. Xsomehow wound up stuck in Oklahoma :-(.  But then a bridge program was
  94. Xdiscovered archived somewhere on the net, and we happily continued
  95. Xplaying.  When I later moved to Finland (my wife is Finnish :-), it
  96. Xbecame impossible to use this program anymore.  So, I set out to write
  97. Xa new bridge program which would correct the deficiencies of the old one.
  98. X
  99. XThe old bridge program was quite inspirational, but it was also rather
  100. Xidiosyncratic.  Perhaps the difficulties with it can best be described
  101. Xby the authors themselves:
  102. X
  103. X        This program provides communication between different
  104. X        machines so that people can play bridge even they are
  105. X        on different machine.  It is written by Shyan-Ming
  106. X        Yuan and Jiang-Hsing Chu at University of Maryland,
  107. X        College Park.  It was tested on Vaxes and Sun 3/50
  108. X        running BSD 4.2 and BSD 4.3.  Since we don't have the
  109. X        previlege to create a 'bridge daemon' as a normal
  110. X        user, we decided to use 'talk daemon' instead.  The
  111. X        underlying communication program is modified from the
  112. X        'talk' program.  You will have confusion in trying to
  113. X        connect to the others...
  114. X
  115. XIn particular, we found that the talk daemons on various systems were
  116. Xoften incompatible.  So it was only possible for us to play when all
  117. Xfour of us logged onto a single machine via telnet.  In writing the
  118. Xnew program, I have abandoned the use of the 'talk daemon' in favor of
  119. Xestablishing the network connections directly through operating system
  120. Xcalls.  This has the advantage that it is universally standardized and
  121. Xperhaps faster and more reliable.  Also, the user interface for the
  122. Xold program was very unforgiving.  I have tried to correct this
  123. Xdeficiency too.
  124. X
  125. X
  126. X
  127. XFurther Documentation
  128. X------- -------------
  129. X
  130. XREADME.Install 
  131. X  Instructions about how to compile and install the program on your system.
  132. X
  133. XREADME.Playing
  134. X  Instructions about how to operate the program.
  135. END_OF_FILE
  136. if test 3772 -ne `wc -c <'README'`; then
  137.     echo shar: \"'README'\" unpacked with wrong size!
  138. fi
  139. # end of 'README'
  140. fi
  141. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  142.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  143. else
  144. echo shar: Extracting \"'MANIFEST'\" \(1199 characters\)
  145. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  146. X   File Name        Archive #    Description
  147. X-----------------------------------------------------------
  148. X MANIFEST                   1    This shipping list
  149. X MakeDistrib                2    
  150. X Makefile                   7    
  151. X README                     1    
  152. X README.Install             1    
  153. X README.Playing             1    
  154. X Revisions                  7    
  155. X bridge.c                   2    
  156. X code.c                     6    
  157. X code.h                     7    
  158. X display.c                  5    
  159. X display.h                  7    
  160. X email.c                    5    
  161. X email.h                    6    
  162. X globals.h                  6    
  163. X help.c                     6    
  164. X help.h                     7    
  165. X helpfile.h                 2    
  166. X input.c.aa                 3    
  167. X input.c.ab                 4    
  168. X input.h                    6    
  169. X network.c                  1    
  170. X network.h                  7    
  171. X okbridge.help              5    
  172. X okbridgerc                 7    
  173. X okshuffle.c                7    
  174. X oktally.c                  6    
  175. X ps.c                       5    
  176. X ps.h                       7    
  177. X scoring.c                  6    
  178. X scoring.h                  7    
  179. X socket.c                   7    
  180. X startup.c                  3    
  181. X terminal.c                 1    
  182. X terminal.h                 7    
  183. END_OF_FILE
  184. if test 1199 -ne `wc -c <'MANIFEST'`; then
  185.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  186. fi
  187. # end of 'MANIFEST'
  188. fi
  189. if test -f 'README.Install' -a "${1}" != "-c" ; then 
  190.   echo shar: Will not clobber existing file \"'README.Install'\"
  191. else
  192. echo shar: Extracting \"'README.Install'\" \(1004 characters\)
  193. sed "s/^X//" >'README.Install' <<'END_OF_FILE'
  194. X
  195. Xsetup -- how to compile the okbridge program
  196. XMatthew Clegg.  August 1990.
  197. X
  198. X
  199. XMaking the okbridge program
  200. X------ --- -------- -------
  201. X
  202. XThe okbridge program is distributed in a compressed tar file called
  203. Xokbridge.tar.Z.  The following two commands can be used to uncompress
  204. Xand untar the okbridge program:
  205. X
  206. X     uncompress okbridge.tar.Z
  207. X     tar -xf okbridge.tar
  208. X
  209. XBefore compiling the program, you may want to edit the makefile.
  210. XYou will have to decide where you would like the okbridge executable
  211. Xto reside and you will also have to decide where you would like the
  212. Xokbridge help file to reside.  The location of the executable is
  213. Xspecified with the variable OKBRIDGE_DIR.  The directory where the
  214. Xhelp file will be stored is specified with the variable OKBRIDGE_HELPFILE.
  215. X
  216. XTo compile okbridge, you would then simply type 'make'.  To then
  217. Xinstall the program, you should type 'make install'.  If you do not
  218. Xplan to install the program in a public directory, then there is no
  219. Xneed to type 'make install'.
  220. X
  221. END_OF_FILE
  222. if test 1004 -ne `wc -c <'README.Install'`; then
  223.     echo shar: \"'README.Install'\" unpacked with wrong size!
  224. fi
  225. # end of 'README.Install'
  226. fi
  227. if test -f 'README.Playing' -a "${1}" != "-c" ; then 
  228.   echo shar: Will not clobber existing file \"'README.Playing'\"
  229. else
  230. echo shar: Extracting \"'README.Playing'\" \(29891 characters\)
  231. sed "s/^X//" >'README.Playing' <<'END_OF_FILE'
  232. X
  233. Xplaying -- how to operate the okbridge program
  234. XMatthew Clegg.  September 1990.  Updated May 1991.
  235. X
  236. X
  237. XArranging the Game
  238. X--------- --- ----
  239. X
  240. XThe prerequisites for using the okbridge program are (1) there must
  241. Xbe four people wishing to play bridge together, and (2) each of these
  242. Xpersons must have access to a computer on the internet where the okbridge
  243. Xprogram has been compiled.  In addition, these players must reach prior
  244. Xagreement on the points outlined below.
  245. X
  246. XFirst, the players must agree on a common time to play.  The okbridge
  247. Xprogram is interactive, in the sense that it requires simultaneous
  248. Xparticipation by all of the players. 
  249. X
  250. XSecond, the players must agree about who will be `sitting' in which
  251. X`chair' around the bridge table.  Conceptually, the players will be
  252. Xsitting at a table where the chairs are labeled north, south, east
  253. Xand west.  North and south will form one team, while east and west
  254. Xwill form the other.  North will be the dealer in the first hand. 
  255. X
  256. XAnd third, the players must agree about who will be the `server'.
  257. XThis is a networking issue which does not affect the play of the game.
  258. XThe program is built so that all of the messages between the players
  259. Xare mediated (invisibly) by a single player.  This arrangement has
  260. Xsimplified the design of the communication protocols.  However, it
  261. Xrequires that the players decide beforehand who will act as the
  262. Xserver.  I suspect that the performance of the okbridge program
  263. Xmight be slightly improved if the server is `centrally located' with
  264. Xrespect to the other players.
  265. X
  266. X
  267. XInvoking the okbridge Program
  268. X-------- --- -------- -------
  269. X
  270. XThe situation we are about to describe is one where each of the four
  271. Xplayers is sitting at his or her terminal, ready to begin a game of
  272. Xbridge.  We describe how to begin the game from the point of view of
  273. Xa particular (but arbitrary) player.  This particular player will be known
  274. Xas the "local" player, while the other three players will be referred to
  275. Xas "remote" players.  Given this point of view, the command which the
  276. Xlocal player should type is as follows:
  277. X
  278. X    okbridge [-c] [-d] [-i] [-e] [-R] position name server
  279. X    [-p portno] [-r replay-file] [-l autoload-file] [-L logfile]
  280. X    [-z# zhang-logfile]
  281. X
  282. Xwhere
  283. X
  284. X    -c, -d, -i, -e, -R
  285. X      are optional parameters to indicate that the playing and
  286. X      scoring conventions respectively for Chicago, Duplicate,
  287. X      simulated IMP, Email duplicate, or Rubber bridge should be used.
  288. X      These parameters are only relevant for the player whose
  289. X      position is 'n' (north). In other words, north makes the 
  290. X      decision for everyone about the scoring convention that will be 
  291. X      used.  If this parameter is omitted, then the playing and scoring
  292. X      conventions will default to those of rubber bridge.  The -R
  293. X      parameter is suppplied for the sake of overriding any default
  294. X      which may appear in the .okbridgerc file.
  295. X
  296. X    position    
  297. X      is one of the characters: 'n', 's', 'e', or 'w'.  This specifies
  298. X      which seat the local player wishes to have in the game. 
  299. X
  300. X    name 
  301. X      is the name (a single word) which will be used to identify the 
  302. X      local player.  If this is omitted, then the local player's position  
  303. X      will be used.
  304. X
  305. X    server
  306. X      is the name (internet host name or address) of the remote machine 
  307. X      where the `server' will be playing.  If server is omitted, then the 
  308. X      local player will assume the role of the server.
  309. X
  310. X    -p portno
  311. X      specifies the port number which will be used for establishing
  312. X      the network connections.  It is only in unusual circumstances
  313. X      that this parameter need be specified.
  314. X
  315. X    -r replay-file
  316. X      specifies that the file "replay-file" contains a sequence of 
  317. X      duplicate deals which should be played and then recorded back
  318. X      to the file after play.  This is equivalent to the REPLAY command
  319. X      in the .okbridgerc file.  See the description of email duplicate 
  320. X      bridge below.
  321. X
  322. X    -l autoload-file
  323. X      specifies that the file "autoload-file" contains a sequence of
  324. X      duplicate deals which should be played (but will not be recorded
  325. X      back to the same file after play).  This is equivalent to the
  326. X      LOAD command in the .okbridgerc file.  See the description of
  327. X      email duplicate bridge below.
  328. X
  329. X    -L logfile
  330. X      specifies the name of the file to which the results of play will
  331. X      be written.  This is equivalent to the LOG command in the
  332. X      .okbridgerc file.
  333. X
  334. X    -z# [zhang-logfile]
  335. X      specifes an alternate log file which will be recorded in the
  336. X      format developed by Shangyou Zhang.  The character '#' should
  337. X      be replaced by a table number.  If the name of the file is
  338. X      omitted, then the name "okb_#_rec" will be used.
  339. X
  340. X
  341. XHere is an example.  Suppose that the names of the players are Alex,
  342. XBob, Cathy and Dot.  Alex and Cathy will be one team, while Bob and Dot
  343. Xwill be the other.  They decide that Alex will be north, and Bob will be
  344. Xeast.  Further, they decide that Bob will be the server.  Here is a
  345. Xlist of the commands that each might use to invoke the okbridge program
  346. Xon their respective (hypothetical) machines:
  347. X
  348. X   Name    Position  Machine         Command to invoke okbridge
  349. X   ----    --------  -------         --------------------------
  350. X   Alex    north     a.alaska.edu    okbridge n Alex b.berkeley.edu
  351. X   Bob     east      b.berkeley.edu  okbridge e Bob
  352. X   Cathy   south     c.florida.edu   okbridge s Cathy b.berkeley.edu
  353. X   Dot     west      d.maine.edu     okbridge w Dot b.berkeley.edu
  354. X
  355. XWhen the okbridge program first begins, it will attempt to establish
  356. Xthe network connections with the other players.  There will be no
  357. Xactivity on the screen at this time -- the okbridge program is
  358. Xsilently waiting for the other players to join the game.  The length
  359. Xof this wait is of course determined by the time at which the last
  360. Xperson joins the game.  When the last person has joined the game, the
  361. Xfirst hand will be dealt automatically and your cards will be
  362. Xdisplayed.  If the okbridge program waits for ten minutes without
  363. Xmanaging to establish the connections, then it gives up.
  364. X
  365. X
  366. XThe Modes of Operation
  367. X--- ----- -- ---------
  368. X
  369. XThere are two major phases in the playing of a hand of bridge.
  370. XIn the first phase, the players take turns bidding for the contract.
  371. XWhen this phase ends, the contract and trump suit have been decided.
  372. XIn the second phase, the cards are played and the tricks are taken.
  373. XWhen this phase ends, the hand can be scored.  The operation of the
  374. Xokbridge program is similarly divided into two phases, which reflect 
  375. Xthese two phases of play.
  376. X
  377. XWe will refer to the first of these two phases as the `bidding' phase.
  378. XFor lack of a better word, we will refer to the second of these two phases
  379. Xas the `playing' phase.  Unfortunately, the verb `to play' is already
  380. Xbeing used in other contexts, and I'm afraid this may lead to some
  381. Xambiguity.
  382. X
  383. X
  384. XThe Display and Entering Input
  385. X--- ------- --- -------- -----
  386. X
  387. XHere we give an example of the screen display during bidding.  The numbers
  388. Xin the left column do not actually appear on the screen -- they are given
  389. Xfor reference purposes only.
  390. X
  391. X   ========================================================================
  392. X 1 OKBRIDGE  1.3                                                 WE    THEY
  393. X 2                                                            -----   -----
  394. X 3 cathy's BID                                        TRICKS      0       0
  395. X 4                                                    ABOVE       0       0
  396. X 5    alex    bob     cathy   dot       |cathy        BELOW       0       0
  397. X 6    ----    ---     -----   ---       |-----        VUL        NO      NO
  398. X 7 1  1C      --                        |S KQ7642
  399. X 8                                      |H 652
  400. X 9                                      |D 76
  401. X10                                      |C K9
  402. X11 
  403. X12 
  404. X13 
  405. X14
  406. X15 
  407. X16 BID   1s
  408. X17 TALK
  409. X18 
  410. X19 ------------------------------------------------------------------------
  411. X20 |MODERATOR: WEST HAS JOINED THE GAME                                   |
  412. X21 |MODERATOR: WELCOME TO OKBRIDGE, BY MATTHEW CLEGG                      |
  413. X22 |MODERATOR: TYPE /HELP FOR INSTRUCTIONS ABOUT THIS PROGRAM             |
  414. X23 |MODERATOR: ACKNOWLEDGMENT RECEIVED FROM bob                           |
  415. X24 |MODERATOR: ACKNOWLEDGMENT RECEIVED FROM alex                          |
  416. X   ========================================================================
  417. X
  418. XIn the upper right corner of the screen (lines 1-6), the scores are
  419. Xdisplayed.  The number of tricks taken by each side is displayed on
  420. Xline 3.  The points above and below the line for each side are displayed
  421. Xon lines 3 and 4, respectively.  And an indication of which sides are
  422. Xvulnerable is displayed on line 6.  It has been pointed out to me that
  423. Xduring ordinary bridge play, the scores are only available to the players
  424. Xbetween hands and not during the bidding and playing.  I apologize that
  425. Xthe okbridge program is not faithful to the real game in this respect.
  426. X
  427. XAt the left hand margin of line 3, we can see that it is now Cathy's turn
  428. Xto bid.  On lines 5-9, we can see the bids that have been made up to
  429. Xthis point.  The display shows that Alex has bid 1 Club, while Bob has
  430. Xpassed.  Cathy's cards are displayed to the right of this table of bids.
  431. X
  432. XLine 16 is the place where the local player's input to the program is
  433. Xentered.  The word `BID' at the lefthand margin is printed by the program
  434. Xand indicates that the program is expecting Cathy to type her bid.
  435. XThe characters `1s' were entered by Cathy, and they indicate that she
  436. Xintends to bid 1 Spade.  At the time this screen was copied, the
  437. Xcursor was located just to the right of the letter `s' in `1s'.
  438. XIf Cathy now presses the return key, then the bid 1 Spade will be
  439. Xtransmitted to the other players.
  440. X
  441. XLine 17 is the line where the local player may type messages which will
  442. Xbe transmitted to the other players.  The position of the cursor is
  443. Xcontrolled by the okbridge program, and the cursor alternates between
  444. Xlines 16 and 17.  When it is the local player's turn to enter a bid or play,
  445. Xthe cursor is automatically placed on line 16.  At all other times, the
  446. Xcursor is placed on line 17.  The local player may type a message on
  447. Xline 17, and after pressing the return key, the message will be 
  448. Xtransmitted to each of the other players.
  449. X
  450. XWhen entering input, the backspace and delete keys will erase the last
  451. Xcharacter typed.  The escape key erases the entire input line.  And
  452. Xpressing control-R causes the entire screen to be redrawn from scratch.
  453. XAlways press return to have your input transmitted to the other players.
  454. X
  455. XThere is a `default' input option embedded in the input processor.
  456. XWhen the input line is empty, pressing return results in the display
  457. Xof a `default' input.  When in bidding mode, the default input is
  458. Xalways `pass'.  When in playing mode, the default input is the lowest
  459. Xranked card, where the trumps are ranked above all others.  Pressing
  460. Xreturn a second time (i.e., after the default input has been
  461. Xdisplayed) causes the default input to be transmitted to the other
  462. Xplayers.  Sometimes in playing mode there is only one legal input.
  463. XIn this case, this input is displayed automatically -- you need only
  464. Xpress return to transmit it to the other players.
  465. X
  466. XLines 20 through 24 display messages from the program and from other
  467. Xplayers.  Each message is of the form `source: text', where `source'
  468. Xis either MODERATOR or the name of one of the players.  Messages from
  469. Xthe MODERATOR give information about the internal state of the program.
  470. X
  471. X
  472. XBidding
  473. X-------
  474. X
  475. XThe rules for bidding in the okbridge program follow the standard
  476. Xrules in rubber bridge.  I think the only thing that needs to be
  477. Xspecified here is the syntax of a bid.
  478. X
  479. XA contract bid is specified by giving the level and then the trump suit.
  480. XThe level is given as an integer in the range 1-7, while the trump
  481. Xsuits are of course clubs, diamonds, hearts, spades and no trump. 
  482. XHowever, the name of the trump suit may be abbreviated to its initial
  483. Xletter.  Thus, here are some examples of legal contract bids:
  484. X  1c, 1 c, 1 C, 1 club, 1 CLUB
  485. X  1d, 1h, 1s, 1n, 2c, 2d, 2h, 2s, 2n, 3c, 3d, 3h, 3s, 3n, ...
  486. X  1 n, 1 no trump, 1 nt
  487. X
  488. XA passing bid is given by entering `pass' or just `p'.
  489. XA doubling bid is given by entering `double' or `d' or `X'.
  490. XA redoubling bid is given by entering `redouble' or `XX'.
  491. X
  492. X
  493. XPlaying
  494. X-------
  495. X
  496. XSimilarly to bidding, I think the only thing that needs be specified
  497. Xin playing is the syntax of a play.  A play of course consists of a
  498. Xselection of a card from the hand of the local player.  The name of
  499. Xa card is specified by giving its suit and then its rank.  The ranks
  500. Xof the honor cards are `ten', `jack', `queen', `king' and `ace', but 
  501. Xthis can be abbreviated to the first letter.  Thus, one way to
  502. Xspecify each of the cards in the deck is 
  503. X
  504. X    C2, C3, C4, C5, C6, C7, C8, C9, CT, CJ, CQ, CK, CA
  505. X    D2, D3, D4, D5, D6, D7, D8, D9, DT, DJ, DQ, DK, DA
  506. X    H2, H3, H4, H5, H6, H7, H8, H9, HT, HJ, HQ, HK, HA
  507. X    S2, S3, S4, S5, S6, S7, S8, S9, ST, SJ, SQ, SK, SA
  508. X
  509. XNote that CT for example could also be specified as `club t',
  510. X`c ten' or `club ten'.
  511. X
  512. X
  513. XCommands
  514. X--------
  515. X
  516. XThere a number of special commands that are available in the okbridge
  517. Xprogram.  These special commands are invoked by entering at the beginning
  518. Xof a line a slash `/', the name of the command, and perhaps some
  519. Xparameters.  Here is a brief list of the available commands:
  520. X
  521. X
  522. X     /BELL [ON|OFF]
  523. X       By default, the okbridge program rings the terminal's bell whenever
  524. X       it requests input from you.  However, this can be disabled by
  525. X       typing '/BELL OFF'.
  526. X
  527. X     /CLAIM [n]
  528. X       This command 'claims' n additional tricks for the declarer.
  529. X       If n is omitted, then all remaining tricks are claimed.
  530. X       The other players are shown the declarer's hand and are
  531. X       asked whether or not they agree to the declarer's request.
  532. X       If both agree, then the hand is ended early.  This command can
  533. X       be used only by the declarer and only when it is declarer's or
  534. X       dummy's turn to play.
  535. X
  536. X     /DEAL [nhands]
  537. X       This command can only be used by north when playing Email
  538. X       duplicate bridge.  It causes nhands hands to be dealt and
  539. X       played.  After they have been played, the results can be
  540. X       /SAVEd and emailed to another foursome for play.
  541. X
  542. X     /DEFAULT [ON | OFF]
  543. X       This command controls whether or not defaults will be provided
  544. X       for bids, plays and questions.
  545. X
  546. X     /LOAD filename
  547. X       This command can only be used by north when playing Email
  548. X       duplicate bridge.  It causes a series of boards to be read
  549. X       from the file "filename".  
  550. X
  551. X     /HELP [topic]
  552. X       Type '/HELP' alone to obtain general help, or type
  553. X       '/HELP topic' to obtain help about a particular topic.
  554. X
  555. X     /LOG [filename]
  556. X       Typing '/LOG filename' causes this hand and subsequent hands
  557. X       to be written to the file with name 'filename'.  If '+filename'
  558. X       is specified, then the log is appended to 'filename'.  Otherwise,
  559. X       'filename' is overwritten.  Omitting 'filename' causes the current 
  560. X       log file to be closed.
  561. X
  562. X     /PING
  563. X       Sends an invisible message to each of the other players, which is
  564. X       automatically echoed.  Reports the round-trip communication time.
  565. X
  566. X     /PROMPT [ON|OFF]
  567. X       By default, the dummy is asked to press RETURN after the end
  568. X       of each trick.  This allows the dummy to see each trick as
  569. X       it is played.  This prompting can be disabled by typing
  570. X       '/PROMPT OFF' (convenient if you need to run to the wc :-)
  571. X
  572. X     /REPLAY filename
  573. X       This command can only be used by north when playing email bridge.
  574. X       It first causes a sequence of boards to be read from filename, like
  575. X       the /LOAD command.  After the boards have been played, they are
  576. X       automatically saved along with the results of play back to the file
  577. X       from which they were read.
  578. X
  579. X     /REVIEW
  580. X       This command displays the bidding for review.  (It is intended
  581. X       to be used during the playing mode.)
  582. X
  583. X     /QUIT
  584. X       Terminates the program.
  585. X
  586. X     /SAVE filename
  587. X       This command causes the set of boards which have been played
  588. X       so far to be saved to a the file with name filename.  These
  589. X       boards can then be emailed to another foursome for competitive
  590. X       play.  Note that the /SAVE command can be used by any player
  591. X       at any time.  However, the previous results of play by other
  592. X       foursomes will only be recorded if /SAVE is used by north.
  593. X
  594. X     /TALK message
  595. X       Sends a short message to the other players.  This command can be used
  596. X       when the program is waiting for you to enter a bid or a play.  
  597. X       Not needed if the word 'TALK' is displayed to the left of the cursor.
  598. X
  599. X
  600. XControl-Character Equivalents
  601. X----------------- -----------
  602. X
  603. XThe following control characters have special meaning to okbridge:
  604. X  ^B -- If in the playing mode, a review of the bidding is displayed.
  605. X  ^C -- Same as the /QUIT command.
  606. X  ^D -- Toggles the default input mode (see the /DEFAULT command above).
  607. X  ^G -- Toggles the bell (see the /BELL command above).
  608. X  ^P -- Toggles the dummy prompting (see the /PROMPT command above).
  609. X  ^R -- Refreshes the screen.
  610. X
  611. X
  612. XScoring
  613. X-------
  614. X
  615. XThe following tables give a basic outline of how okbridge computes
  616. Xthe scores.  It was derived from the documentation supplied with
  617. Xthe bridge program written by Yuan and Chu.
  618. X
  619. X
  620. XTrick Score (below the line)
  621. X
  622. XIf the contracting team succeeds in making their contract,
  623. Xthen the base score for the hand is computed according to
  624. Xthe following chart.  For rubber bridge, the score computed
  625. Xaccording to the number of tricks bid.  For other scoring
  626. Xmethods, the score is computed according to how many tricks
  627. Xwere actually made.
  628. X
  629. XSpades of Hearts    30 per trick    |  If doubled:
  630. XDiamonds or Clubs    20 per trick    |    multiply by 2
  631. XNotrump        40 for first trick    |  If redoubled:
  632. X    30 for each additional trick    |    multiply by 4
  633. X
  634. XIn a doubled contract in rubber bridge, overtricks are
  635. Xscored at 100 points each if not vulnerable and 200 points
  636. Xeach if vulnerable.  In a redoubled contract in rubber bridge,
  637. Xovertricks are scored at 200 and 400 respectively.
  638. X
  639. XIn rubber bridge, a game is scored if 100 points or more are
  640. Xaccumulated below the line.  The scoring side then becomes
  641. Xvulnerable and wins the rubber if they win a second game.
  642. XIn other forms of bridge, the vulnerability proceeds according
  643. Xto a rotation.  In the first hand, neither side is vulnerable.
  644. XFor the next two hands, the dealer's side is vulnerable.  And
  645. Xfor the fourth hand, both sides are vulnerable.  For Duplicate,
  646. XIMP and Email scoring, the rotation then starts over.  For Chicago
  647. Xbridge, the rotation does not repeat itself until 16 hands have 
  648. Xbeen played.
  649. X
  650. X
  651. XBonuses
  652. X
  653. XFor rubber bridge, there is a bonus for winning the rubber,
  654. Xwhich is scored as follows: 
  655. X
  656. XRubber bonus:    500 if you win two games out of three
  657. X        700 if you win the only two games
  658. X
  659. X
  660. XFor all forms of bridge, there is a bonus for making a slam.
  661. X
  662. X            Not Vulnerable        Vulnerable
  663. XSlam Bonus:  Small Slam         500            750
  664. X         Grand Slam        1000           1500
  665. X
  666. XIn rubber and Chicago bridge, there is a bonus if the contracting
  667. Xside has enough honor cards in the trump suit:
  668. X
  669. XHonors:  4 trump honors in one hand        100
  670. X     5 trump honors in one hand        150
  671. X     4 aces in one hand at notrump        150
  672. X
  673. XIn non-rubber bridge, there is a 300 point bonus for bidding
  674. Xand making a game when not vulnerable.  The bonus is 500 points
  675. Xif vulnerable.
  676. X
  677. XMaking Doubled (or redoubled) Contract:     50 points
  678. X
  679. XPenalties (above the line)
  680. X
  681. X            Undoubled        Doubled
  682. X        Not Vul.    Vul.      Not Vul.    Vul.
  683. XDown 1           50        100        100        200
  684. XDown 2          100        200        300        500
  685. XDown 3          150        300        500        800
  686. XDown 4          200        400        700           1100
  687. XDown 5          250        500        900           1400
  688. XDown 6          300        600       1100           1700
  689. XDown 7          350        700       1300        2100
  690. XDown 8          400        800       1500           2500
  691. X  .                .             .           .           .
  692. X  .                .             .           .           .
  693. X  .                .             .           .           .
  694. X
  695. XIf redoubled: multiply the doubled penalty by two.
  696. X
  697. XFor IMP bridge, the base score is computed according to the
  698. Xabove rules for duplicate scoring.  It is then used to determine 
  699. Xan approximate number of international match points according
  700. Xto the following table:
  701. X
  702. X    Duplicate score        IMP points
  703. X    ---------------        ----------
  704. X         <=    20        0
  705. X        50        1
  706. X        80        2
  707. X        120        3
  708. X        160        4
  709. X        210        5
  710. X        260        6
  711. X        310        7
  712. X        360        8
  713. X        430        9
  714. X        500        10
  715. X        600        11
  716. X        750        12
  717. X        900        13
  718. X        1100        14
  719. X        1300        15
  720. X        1500        16
  721. X        1750        17
  722. X        2000        18
  723. X        2500        19
  724. X        3000        20
  725. X        3500        21
  726. X        4000        22
  727. X        4500        23
  728. X        above        24
  729. X
  730. XTo this number of IMP points is added 20 minus the number of high
  731. Xcard points held by the contracting team.
  732. X
  733. XPlaying Duplicate Bridge
  734. X------- --------- ------
  735. X
  736. XVersion 1.5 of okbridge introduces an 'email duplicate' scoring
  737. Xmode.  The idea is that a sequence of boards can be read from a
  738. Xfile for play.  After each board has been played, a match point
  739. Xscore is computed for all of the players who have played the board.
  740. XAfter the last board has been played, all of the boards along with
  741. Xthe match point scores can then be written to a file which can
  742. Xbe emailed to another foursome.  This allows for a type of competitive
  743. Xduplicate play.
  744. X
  745. XThe procedure for playing email duplicate is as follows.  To begin
  746. Xa fresh set of boards, north starts the okbridge program with the
  747. X-e scoring option.  He then types /DEAL n, where n is the number of
  748. Xboards he wishes to play.
  749. X
  750. XAfter the boards have been played, north then types /SAVE filename
  751. Xto save the boards along with the results of play to a file.
  752. XThe /SAVE command then creates to files.  One is named "filename"
  753. Xand the other is named "filename.plain".  The first file is intended
  754. Xfor being mailed to another foursome for play.  It contains the
  755. Xboards and the scores, but in an encoded format which is not
  756. Xeasily readable.  The second file contains the same information
  757. Xbut not encoded.  It can be emailed to those who have already
  758. Xplayed these boards, so they can see how well they have competed.
  759. X
  760. XTo play a sequence of boards which have already been played by
  761. Xothers, north should again start the okbridge program with the
  762. X-e option.  He then types /LOAD filename to read the boards from
  763. Xthe file with name filename.  At the end of each hand, the
  764. Xmatch point scores for the playing foursome will be displayed to
  765. Xthem.  After all of the boards have been played, north can save
  766. Xthe boards along with the results of play to a new file by typing
  767. X/SAVE newfilename.  This will create an encoded file named
  768. X"newfilename" which is suitable for mailing to a new foursome
  769. Xand an unencoded file named "newfilename.plain" which is suitable
  770. Xfor mailing to those who have already played these boards.
  771. X
  772. XAlternatively, a sequence of boards can be replayed by using the
  773. X/REPLAY command.  This first causes the boards to be read into the
  774. Xprogram for play.  After they have been played, they are then
  775. Xautomatically saved along with the results back to the file from
  776. Xwhich they were read.
  777. X
  778. XTo create a unplayed set of shuffled boards, use the okshuffle program.
  779. XThe format of the okshuffle command is:
  780. X
  781. X    okshuffle [nboards] [-m "message"] [-d] > <email-filename>
  782. X
  783. Xwhere  
  784. X
  785. X  nboards  
  786. X     is the number of boards to shuffle.  If this is omitted,
  787. X     then 4 is assumed.
  788. X
  789. X  -m "message"
  790. X     is an optional message that will displayed to each of the
  791. X     players as soon as the boards are /LOADed.
  792. X
  793. X  -d
  794. X     specifies that the date of the shuffle should be displayed to each of
  795. X     the players when the boards are /LOADed.
  796. X
  797. XAlso, to merge a number of boards that have already been played,
  798. Xyou can use the oktally program.  The format of the oktally command is:
  799. X
  800. X   oktally [-c] [-sn] file_1 file_2 ... file_n > output-email-file
  801. X
  802. XThe oktally program reads each of file_1, file_2, ..., file_n.  If one
  803. Xof the file names is "-", then standard input is read instead.  It
  804. Xthen merges the boards from these files and totals the match points
  805. Xfor each pair.  It writes the merged set of boards to standard output.
  806. XIf the -c flag is given, then the output is written in encoded format.
  807. XIf the -sn flag is given, then n is read as a positive integer which
  808. Xspecifies the number of boards to skip in the input files.
  809. X
  810. XHere is an example copy of a plain email duplicate file:
  811. X
  812. XThis is an email duplicate file for Okbridge version 1.5
  813. XbxnXwecs8mIQjz6DT7SYuEaFt0goHdqfR1vU2JByiMCrZWL5+9V4hApN-PG3OKlk
  814. X# nboards npairs
  815. X1 4
  816. X
  817. X# pair north/east south/west    match points
  818. X     1 matt       merja         0.0
  819. X     2 doug       ann           1.0
  820. X     3 norm       suzanne       1.0
  821. X     4 ernest     wilma         0.0
  822. X
  823. X# board 1
  824. X# NORTH  CLUBS: Q J T 3,  DIAMONDS: Q 4 3 2,  HEARTS: J T 9 4,  SPADES: 7
  825. X# EAST   CLUBS: A K 4,  DIAMONDS: A 9 6,  HEARTS: 6 2,  SPADES: K 9 5 4 3
  826. X# SOUTH  CLUBS: 9 8,  DIAMONDS: 8 5,  HEARTS: A K Q 7 3,  SPADES: T 8 6 2
  827. X# WEST   CLUBS: 7 6 5 2,  DIAMONDS: K J T 7,  HEARTS: 8 5,  SPADES: A Q J
  828. X# Dealer Vulnerabilities
  829. XNORTH  NONE
  830. XWNEWWWSSNNNEENNNSEWSEWWNWEESNWESWNNNSSSSEEESNSESWWEW
  831. X# ns  ew bid       by result    score  ns-mp  ew-mp
  832. X   1   2 4S        E      +5     -450    0.0    1.0
  833. X   3   4 3NT       E      -1       50    1.0    0.0
  834. X--
  835. X
  836. XThe pairs who have played these boards, along with their respective
  837. Xmatch point scores, are listed at the top of the file.  After the list
  838. Xof pairs follows the list of boards.  For each foursome, there is a
  839. Xscore line indicating how they performed in this board.  The score
  840. Xwhich is printed is relative to the north-south pair.  We see for
  841. Xexample that 4S was bid by east, making 5.  This results in a score of
  842. X+450 for east-west, but relative to north-south it is -450.  The
  843. Xcolumn 'ns-mp' gives the number of match points awarded to north-south
  844. Xfor this board, and the column 'ew-mp' gives the number of match
  845. Xpoints awarded to east-west in this board.
  846. X
  847. X
  848. XThe .okbridgerc initialization file
  849. X--- ----------- -------------- ----
  850. X
  851. XVersion 1.5 of okbridge introduces an initialization file which
  852. Xis automatically read when the program starts.  This initialization
  853. Xfile can specify a number of default settings for the program.
  854. XWhen the program starts, the current working directory is first
  855. Xsearched for a file named ".okbridgerc".  If no file is found, then
  856. Xthe home directory is searched for the same file.  For an example
  857. Xof an .okbridgerc file, see the file in this distribution named
  858. X"okbridgerc".  (Note that it is incorrectly named -- to be read by
  859. Xthe okbridge program, it should be named ".okbridgerc").
  860. X
  861. XEach line in this file is either a comment line or a (field, value) pair.  
  862. XComment lines begin with the pound sign '#' character.  
  863. XField, value pairs are of the format
  864. X<Field-name>    <value>
  865. X
  866. XThe fields which are currently recognized are as follows:
  867. X
  868. XBELL        ON | OFF
  869. X   When requesting input (a bid or a play), the terminal's
  870. X   bell is rung by default.  However, this can be disabled
  871. X   by specifying 'BELL OFF'.  This has the same effect as the
  872. X   '/BELL OFF' command.
  873. X
  874. XHELPFILE    <directory-name>
  875. X   This field specifies the location of the okbridge help file.
  876. X
  877. XLOAD            <email-duplicate-filename>
  878. X   This field is only valid if the position is north and the
  879. X   scoring mode is email duplicate.  In this case, okbridge will
  880. X   automatically read a set of email duplicate boards from the
  881. X   named file.
  882. X
  883. XLOG        <filename>
  884. X   If this statement is present in the startup file, then
  885. X   the hands will automatically be logged to the given filename.
  886. X   If the first character of <filename> is a plus sign '+', then
  887. X   the log is appended to <filename>.  Otherwise, <filename> is
  888. X   overwritten.
  889. X
  890. XNAME        <local-player-name>
  891. X   This field specifies the name that will be used to identify
  892. X   the local player to the other players.  If both the NAME field
  893. X   and the POSITION field are present in the .okbridgerc startup
  894. X   file, then the corresponding parameters can be omitted from
  895. X   the okbridge command line.  In this case, the SERVER field
  896. X   should also be specified in the .okbriderc file.
  897. X
  898. XPOSITION    NORTH | EAST | SOUTH | WEST
  899. X   This field specifies the local player's position.  If both the
  900. X   NAME field and the POSITION field are present in the .okbridgerc
  901. X   startup file, then the corresponding parameters can be omitted
  902. X   from the okbridge command line.  In this case, the SERVER field
  903. X   should also be specified in the .okbridgerc file.
  904. X
  905. XPORT        <positive-integer>
  906. X   This field specifies the internet port number that will be
  907. X   used for communications with the server.  It is usually not
  908. X   necessary to specify a port number.
  909. X
  910. XPROMPT             NO | YES
  911. X   The value of this field is only relevant in hands where the
  912. X   local player is the dummy.  In this case, the dummy is
  913. X   ordinarily prompted to press RETURN at the end of each trick.
  914. X   This allows the dummy to see the cards that are played as they
  915. X   are played.  However, if 'PROMPT NO' is specified, then the
  916. X   dummy will not be prompted.
  917. X
  918. XREPLAY          <email-duplicate-filename>
  919. X   This field is only valid if the position is north and the
  920. X   scoring mode is email duplicate.  In this case, a set of
  921. X   boards will automatically be read from the named file.
  922. X   After they have been played, the results will automatically
  923. X   be written back to the file from which the boards were read.
  924. X
  925. XSCORING            RUBBER | CHICAGO | DUPLICATE | EMAIL | IMP
  926. X   This field is only relevant if the local player is north.
  927. X   In this case, the SCORING field determines the type of scoring
  928. X   that will be used by default in the game.
  929. X
  930. XSERVER            ME | <internet-name-or-number>
  931. X   If the value of this field is 'ME', then the local player
  932. X   will assume the role of server.  If the value of this field
  933. X   is anything else, then it is interpreted as an internet name
  934. X   or number of the machine where the server is running.
  935. X
  936. END_OF_FILE
  937. if test 29891 -ne `wc -c <'README.Playing'`; then
  938.     echo shar: \"'README.Playing'\" unpacked with wrong size!
  939. fi
  940. # end of 'README.Playing'
  941. fi
  942. if test -f 'network.c' -a "${1}" != "-c" ; then 
  943.   echo shar: Will not clobber existing file \"'network.c'\"
  944. else
  945. echo shar: Extracting \"'network.c'\" \(12892 characters\)
  946. sed "s/^X//" >'network.c' <<'END_OF_FILE'
  947. X/* network.c
  948. X ! 
  949. X ! Copyright (C) 1990,1991 by Matthew Clegg
  950. X ! 
  951. X ! This program may be copied and distributed freely.  Please do not
  952. X ! charge money for this program or for any program derived from it.
  953. X ! If you modify this program, then include a notice stating plainly
  954. X ! that your program is derived from the okbridge program and is not
  955. X ! the same as the official okbridge program.
  956. X !
  957. X ! I welcome any suggestions for improvement to okbridge, and 
  958. X ! I would be especially happy to receive improved source code.
  959. X ! If you have comments or suggestions, or if you would like to
  960. X ! join the okbridge mailing list, then write to
  961. X !
  962. X !   mclegg@cs.ucsd.edu
  963. X !
  964. X*/
  965. X
  966. Xextern char *strdup();
  967. X
  968. X
  969. X#include <ctype.h>
  970. X#include <sys/types.h>
  971. X#include <sys/socket.h>
  972. X#include <sys/time.h>
  973. X#ifdef AIX
  974. X#include <sys/select.h>
  975. X#endif
  976. X#include <stdio.h>
  977. X#include <string.h>
  978. X#include <curses.h>
  979. X
  980. X#include "globals.h"
  981. X#include "display.h"
  982. X
  983. X#ifdef   LOOPBACK_MODE
  984. X#define  DEFAULT_PORT    1731
  985. X#else
  986. X#define  DEFAULT_PORT    1729
  987. X#endif
  988. X
  989. X#ifdef LOGFILE
  990. XFILE *netlog;
  991. X#endif
  992. X
  993. Xextern char socket_error [];
  994. X
  995. Xextern char *sys_errlist[];
  996. Xextern int  errno;
  997. Xextern int players_here [];
  998. X
  999. Xint network_port=1729; /* The port number that we will be doing our
  1000. X              communications through. */
  1001. Xint server_mode=1;   /* True if we are acting as a server. */
  1002. Xint listen_port;     /* The socket descriptor where we check for new
  1003. X            connections. */
  1004. Xchar *server_name;   /* If we are not acting as a server, then the
  1005. X            name of the remote machine. */
  1006. Xint clients [5];     /* The file descriptors for the clients that we
  1007. X            are serving. */
  1008. Xchar client_ids[5];  /* For each client, a character identifying his
  1009. X            position.  Only valid if we are the server. */
  1010. Xint connections;     /* The number of connections that have been made. */
  1011. Xint no_dropped = 0;  /* The number of connections that have been dropped. */
  1012. Xint expected;        /* The number of connections we expect to make. */
  1013. Xint network_down;    /* After an error, we refuse to send or receive any more
  1014. X            messages. */
  1015. X
  1016. X
  1017. Xint check_for_data (f, wait)
  1018. Xint f, wait;
  1019. X/* Does a poll of the opened file f to see if there is any input
  1020. X * data available.  If f is negative, then interprets -f as the
  1021. X * real socket number and polls stdin at the same time.
  1022. X * If wait is nonzero, then blocks for up to
  1023. X * wait milliseconds waiting for data.  If data is available,
  1024. X * returns 1.  Otherwise, returns 0.  If an error, returns -1
  1025. X * and places an error message in socket_error.
  1026. X */
  1027. X{
  1028. X    struct fd_set ready;
  1029. X    struct timeval wait_time;
  1030. X    int data_avail;
  1031. X
  1032. X    wait_time.tv_sec  = wait / 1000;
  1033. X    wait_time.tv_usec = (wait % 1000) * 1000;
  1034. X
  1035. X    FD_ZERO (&ready);
  1036. X    if (f < 0) {
  1037. X        f = -f;
  1038. X        FD_SET (0, &ready);
  1039. X    };
  1040. X
  1041. X    FD_SET  (f, &ready);
  1042. X     
  1043. X    data_avail = select (FD_SETSIZE, &ready, (fd_set *) 0, 
  1044. X                 (fd_set *) 0, &wait_time);
  1045. X    if (data_avail < 0) 
  1046. X        sprintf (socket_error, "select error: %s",
  1047. X             sys_errlist[errno]);
  1048. X    return (data_avail);
  1049. X};
  1050. X
  1051. Xint check_for_exception (f)
  1052. Xint f;
  1053. X/* Returns true if an exceptional condition has occurred at
  1054. X * file descriptor f.
  1055. X */
  1056. X{
  1057. X    struct fd_set exception_set;
  1058. X    struct timeval wait_time;
  1059. X    int exception;
  1060. X
  1061. X    wait_time.tv_sec = 0;
  1062. X    wait_time.tv_usec = 0;
  1063. X
  1064. X    FD_ZERO (&exception_set);
  1065. X    FD_SET  (f, &exception_set);
  1066. X
  1067. X    exception = select (FD_SETSIZE, (fd_set *) 0, (fd_set *) 0, 
  1068. X                 &exception_set, &wait_time);
  1069. X    if (exception < 0) 
  1070. X        sprintf (socket_error, "select error: %s",
  1071. X             sys_errlist[errno]);
  1072. X    return (exception);
  1073. X};
  1074. X
  1075. Xint socket_read_line (fd, buf, buflen)
  1076. Xint fd; char *buf; int buflen;
  1077. X/* Reads characters from the socket fd until a newline character \n
  1078. X * is detected.  Copies up to buflen-1 characters into buf, and
  1079. X * terminates the string with a null byte.  Returns the number of
  1080. X * bytes read.  -1 is returned if the socket is closed or if an
  1081. X * exceptional condition has occurred on the socket. 
  1082. X */
  1083. X{
  1084. X    int buflog, readlog, exception;
  1085. X    char chbuf[2];
  1086. X
  1087. X    buf[0] = '\0';
  1088. X    if (check_for_exception(fd))
  1089. X        return (-1);
  1090. X    readlog = read (fd, chbuf, 1);
  1091. X    if (readlog == 0)
  1092. X      sprintf (socket_error, "EOF on read from socket");
  1093. X    else if (readlog < 0)
  1094. X      sprintf (socket_error, "socket read error: %s",
  1095. X           sys_errlist[errno]);
  1096. X    if (readlog <= 0) return (readlog);
  1097. X    buflog = 0;
  1098. X    while (chbuf[0] != '\0') {
  1099. X        if (buflog < buflen-1)
  1100. X            buf[buflog++] = chbuf[0];
  1101. X        readlog = read (fd, chbuf, 1);
  1102. X        if (readlog <= 0) {
  1103. X          buf[0] = '\0';
  1104. X          if (readlog < 0)
  1105. X            sprintf (socket_error, "socket read error: %s",
  1106. X                 sys_errlist[errno]);
  1107. X          else
  1108. X            sprintf (socket_error, "EOF on read from socket");
  1109. X          return (readlog);
  1110. X        };
  1111. X    };
  1112. X    buf[buflog] = '\0';
  1113. X    return (buflog);
  1114. X};
  1115. X
  1116. Xint initialize_server_mode ()
  1117. X{
  1118. X  char comment_buf [80];
  1119. X  int i;
  1120. X
  1121. X  sprintf (comment_buf, "ENTERING SERVER MODE ON PORT %d", network_port);
  1122. X  Display_Player_Comment ("NETWORK", comment_buf);
  1123. X
  1124. X  listen_port = open_port (network_port);
  1125. X  if (listen_port < 0) {
  1126. X    Display_Player_Comment ("NETWORK: ", socket_error);
  1127. X    Terminate_Program ("IS THERE ALREADY A SERVER RUNNING?");
  1128. X  };
  1129. X
  1130. X  connections = 0;
  1131. X#ifdef LOOPBACK_MODE
  1132. X  expected = 0;
  1133. X#else
  1134. X#ifdef TWOPLAYER_MODE
  1135. X  expected = 1;
  1136. X#else
  1137. X  expected = 3;
  1138. X#endif
  1139. X#endif
  1140. X
  1141. X  for (i = 0; i < 4; i++) client_ids[i] = '\0';
  1142. X  return (0);
  1143. X};
  1144. X
  1145. Xint initialize_client_mode ()
  1146. X{
  1147. X  char comment_buf [80];
  1148. X
  1149. X  sprintf (comment_buf, "CONNECTING TO SERVER AT %s ON PORT %d", 
  1150. X       server_name, network_port);
  1151. X  Display_Player_Comment ("NETWORK", comment_buf);
  1152. X
  1153. X  restore_cursor ();
  1154. X
  1155. X  clients [0] = client_init (server_name, network_port);
  1156. X  if (clients[0] < 0) {
  1157. X    network_down = 1;
  1158. X    Terminate_Program (socket_error);
  1159. X  };
  1160. X/*
  1161. X  if (clients[0] < 0)
  1162. X    return (-1);
  1163. X*/
  1164. X
  1165. X  connections = 1;
  1166. X  expected = 1;
  1167. X
  1168. X  Display_Player_Comment ("NETWORK", "CONNECTION ESTABLISHED");
  1169. X  return (0);
  1170. X
  1171. X};
  1172. X  
  1173. Xinitialize_network ()
  1174. X{
  1175. X  int error;
  1176. X
  1177. X#ifdef LOGFILE
  1178. X  netlog = fopen (player_names[local_player], "w");
  1179. X#endif
  1180. X
  1181. X  network_down = 1;
  1182. X
  1183. X  if (server_mode) 
  1184. X    error = initialize_server_mode ();
  1185. X  else
  1186. X    error = initialize_client_mode ();
  1187. X  network_down = 0;
  1188. X
  1189. X  if (error) {
  1190. X    network_down = 1;
  1191. X    Terminate_Program (socket_error);
  1192. X  };
  1193. X};
  1194. X
  1195. Xclose_connection (connection_no)
  1196. X/* Closes the given connection in the list of connections.  If we
  1197. X   are a client, then we exit the program. */
  1198. X{
  1199. X  int i;
  1200. X
  1201. X
  1202. X  if (!server_mode)
  1203. X    Terminate_Program ("NETWORK CONNECTIONS CLOSED -- TERMINATING PROGRAM");
  1204. X
  1205. X  if (clients[connection_no] > 0) {
  1206. X    if (game_mode == STARTUP_MODE) {
  1207. X      switch (client_ids[connection_no]) {
  1208. X      case 'N':
  1209. X    players_here[PLAYER_NORTH] = 0;
  1210. X    break;
  1211. X      case 'E':
  1212. X    players_here[PLAYER_EAST] = 0;
  1213. X    break;
  1214. X      case 'W':
  1215. X    players_here[PLAYER_WEST] = 0;
  1216. X    break;
  1217. X      case 'S':
  1218. X    players_here[PLAYER_SOUTH] = 0;
  1219. X      default:
  1220. X    break;
  1221. X      };
  1222. X    };
  1223. X
  1224. X    close (clients[connection_no]);
  1225. X    for (i = connection_no; i < connections-1; i++) {
  1226. X      clients[i] = clients[i+1];
  1227. X      client_ids[i] = client_ids[i+1];
  1228. X    };
  1229. X    connections--;
  1230. X    if (game_mode != STARTUP_MODE)
  1231. X      no_dropped++;
  1232. X    client_ids[connections] = '\0';
  1233. X  };
  1234. X};
  1235. Xvoid Close_Network_Connection (player_name)
  1236. X     char *player_name;
  1237. X/* Closes the connection the named player.  Allows the connection to
  1238. X   be re-established. */
  1239. X{
  1240. X  int i, c;
  1241. X
  1242. X  if (!server_mode) return;
  1243. X  c = -1;
  1244. X  for (i = 0; i < connections; i++)
  1245. X    if (client_ids[i] == *player_name) c = i;
  1246. X  if (c < 0) return;
  1247. X
  1248. X  close (clients[c]);
  1249. X  for (i = c; i < connections-1; i++) {
  1250. X    clients[i] = clients[i+1];
  1251. X    client_ids[i] = client_ids[i+1];
  1252. X  };
  1253. X  if (game_mode != STARTUP_MODE) no_dropped++;
  1254. X  connections--;
  1255. X  client_ids[connections] = '\0';
  1256. X};
  1257. X
  1258. Xcheck_for_connections ()
  1259. X{
  1260. X  struct sockaddr net_addr;
  1261. X  int addrlen;
  1262. X  char error_buf[80];
  1263. X
  1264. X  if (network_down) return;
  1265. X  addrlen = sizeof(struct sockaddr);
  1266. X  if (server_mode) {
  1267. X    if (check_for_data (listen_port, 0)) {
  1268. X      clients[connections] = accept (listen_port, &net_addr, &addrlen);
  1269. X      if (clients[connections] < 0) {
  1270. X    sprintf (socket_error, "connection error: %s", sys_errlist[errno]);
  1271. X    Display_Player_Comment ("NETWORK ERROR!", socket_error);
  1272. X      } else if ((connections + no_dropped) >= expected) {
  1273. X    sprintf (error_buf, 
  1274. X         "NORTH SEATERR SORRY -- THERE ARE NO FREE SEATS.");
  1275. X    write (clients[connections], error_buf, strlen(error_buf)+1);
  1276. X    close (clients[connections]);
  1277. X      } else {
  1278. X    client_ids[connections++] = '\0';
  1279. X      };
  1280. X    };
  1281. X  };
  1282. X};
  1283. X
  1284. Xsend_message (message)
  1285. X    char *message;
  1286. X{
  1287. X  int i;
  1288. X  
  1289. X/*  Display_Player_Comment ("NET SENDING",message); */
  1290. X  if (network_down) return;
  1291. X  check_for_connections ();
  1292. X
  1293. X  if (server_mode && (client_ids[3] == '\0')) {
  1294. X#ifdef LOGFILE
  1295. Xfprintf (netlog, "SERVER ID IS %c\n", message[0]);
  1296. X#endif
  1297. X    client_ids[3] = message[0];
  1298. X  };
  1299. X
  1300. X  for (i = 0; i < connections; i++)
  1301. X    write (clients[i], message, strlen(message)+1);
  1302. X
  1303. X#ifdef LOGFILE
  1304. X  fprintf (netlog, "S%s\n", message);
  1305. X#endif
  1306. X};
  1307. X
  1308. Xstatic void wait_for_event ()
  1309. X/* Blocks until either a message arrives from the network or a
  1310. X   key is pressed.
  1311. X */
  1312. X{
  1313. X
  1314. X  int i, status;
  1315. X  struct fd_set wait_set;     /* A set representing the connections that
  1316. X                 have been established. */
  1317. X
  1318. X  if (network_down) return;
  1319. X
  1320. X  FD_ZERO (&wait_set);
  1321. X
  1322. X  while (1) {
  1323. X    /* We use a loop here because we think that the select call may
  1324. X       occasionally unblock with spurious (keyboard?) events. */
  1325. X
  1326. X    for (i = 0; i < connections; i++)
  1327. X      FD_SET (clients[i], &wait_set);
  1328. X
  1329. X    if (server_mode)
  1330. X      FD_SET (listen_port, &wait_set);
  1331. X
  1332. X    FD_SET (0, &wait_set);
  1333. X
  1334. X    status = select (FD_SETSIZE, &wait_set, (fd_set *) 0, (fd_set *) 0, 
  1335. X             (struct timeval *) 0);
  1336. X
  1337. X    if (FD_ISSET (0, &wait_set))  /* check for keyboard event */
  1338. X      return;
  1339. X
  1340. X    if (server_mode) /* check for new connection */
  1341. X      if (FD_ISSET (listen_port, &wait_set))
  1342. X    return;
  1343. X
  1344. X    for (i = 0; i < connections; i++)  /* check for incoming network message */
  1345. X      if (FD_ISSET (clients[i], &wait_set))
  1346. X    return;
  1347. X  };
  1348. X};
  1349. X
  1350. Xint message_available ()
  1351. X{
  1352. X  int i, status;
  1353. X  struct fd_set wait_set;     /* A set representing the connections that
  1354. X                 have been established. */
  1355. X  struct timeval wait_time;   /* The amount of time to wait in checking our
  1356. X                 connections. */
  1357. X
  1358. X  if (network_down) return;
  1359. X  check_for_connections ();
  1360. X
  1361. X  restore_cursor ();
  1362. X
  1363. X  wait_for_event (); 
  1364. X
  1365. X  wait_time.tv_sec = 0;
  1366. X  wait_time.tv_usec = 0;
  1367. X
  1368. X  FD_ZERO (&wait_set);
  1369. X
  1370. X  /* Check for network data without blocking.  */
  1371. X  for (i = 0; i < connections; i++)
  1372. X    FD_SET (clients[i], &wait_set);
  1373. X
  1374. X  status = select (FD_SETSIZE, &wait_set, (fd_set *) 0, (fd_set *) 0, 
  1375. X           &wait_time);
  1376. X
  1377. X  return (status != 0);
  1378. X
  1379. X};
  1380. X
  1381. Xstatic Duplicate_Seat_Error (message, error_port)
  1382. X     char *message;
  1383. X{
  1384. X  char error_buf[100];
  1385. X  int i;
  1386. X
  1387. X  for (i = 0; (message[i] != '\0') && !isspace(message[i]); i++);
  1388. X  message[i] = '\0';
  1389. X
  1390. X  sprintf (error_buf, "DUPLICATE SEAT REQUEST FOR %s", message);
  1391. X  Display_Player_Comment ("NETWORK", error_buf);
  1392. X
  1393. X  sprintf (error_buf, "NORTH SEATERR THE CURRENTLY TAKEN SEATS ARE: ");
  1394. X  client_ids[connections] = *("NESW" + local_player);
  1395. X  for (i = 0; i <= connections; i++) {
  1396. X    switch (client_ids[i]) {
  1397. X    case 'S':
  1398. X      sprintf (error_buf + strlen(error_buf)," SOUTH");
  1399. X      break;
  1400. X    case 'E':
  1401. X      sprintf (error_buf + strlen(error_buf)," EAST");
  1402. X      break;
  1403. X    case 'N':
  1404. X      sprintf (error_buf + strlen(error_buf), " NORTH");
  1405. X      break;
  1406. X    case 'W':
  1407. X      sprintf (error_buf + strlen(error_buf), " WEST");
  1408. X    default:
  1409. X      break;
  1410. X    };
  1411. X  };
  1412. X  write (clients[error_port], error_buf, strlen(error_buf)+1);
  1413. X  close (clients[error_port]);
  1414. X  connections--;
  1415. X
  1416. X};
  1417. X
  1418. Xreceive_message (message)
  1419. X    char *message;
  1420. X{
  1421. X  int i, j, log, no_message, in_port;
  1422. X
  1423. X  message[0] = '\0';
  1424. X  if (network_down) return;
  1425. X  check_for_connections ();
  1426. X  if (!message_available())
  1427. X    return;
  1428. X
  1429. X  no_message = 1;
  1430. X  for (i = 0; (i < connections) && no_message; i++)
  1431. X    no_message = !check_for_data (clients[in_port = i], 0);
  1432. X
  1433. X  log = socket_read_line (clients[in_port], message, 100);
  1434. X/*  Display_Player_Comment ("NET RECVD", message); */
  1435. X  if (server_mode && (log > 0) && (client_ids[in_port] == '\0')) {
  1436. X    for (j = 0; j < connections; j++)
  1437. X      if ((client_ids[j] == message[0]) || 
  1438. X      (*("NESW" + local_player) == message[0])) {
  1439. X    Duplicate_Seat_Error (message, in_port);
  1440. X    message [0] ='\0';
  1441. X    return;
  1442. X      };
  1443. X    client_ids[in_port] = message[0];
  1444. X#ifdef LOGFILE
  1445. Xfprintf (netlog, "ESTABLISHED CLIENT ID OF %c\n", client_ids[in_port]);
  1446. X#endif
  1447. X  };
  1448. X
  1449. X  if (log > 0) {
  1450. X    for (j = 0; j < connections; j++)
  1451. X      if (j != in_port) write (clients[j], message, log+1);
  1452. X  } else {
  1453. X    if (log < 0)
  1454. X      Display_Player_Comment ("NETWORK ERROR!", socket_error);
  1455. X    close_connection (in_port);
  1456. X    message [0] = '\0';
  1457. X  };
  1458. X#ifdef LOGFILE
  1459. X  fprintf (netlog, "R%s\n", message);
  1460. X#endif
  1461. X};
  1462. X
  1463. X
  1464. Xreset_network ()
  1465. X/* To be called once at the end of the program.  Resets the
  1466. X   communications network. */
  1467. X{
  1468. X  int i;
  1469. X
  1470. X  for (i = 0; i < connections; i++)
  1471. X    close (clients[i]);
  1472. X  connections = 0;
  1473. X
  1474. X  network_down = 1;
  1475. X};
  1476. END_OF_FILE
  1477. if test 12892 -ne `wc -c <'network.c'`; then
  1478.     echo shar: \"'network.c'\" unpacked with wrong size!
  1479. fi
  1480. # end of 'network.c'
  1481. fi
  1482. if test -f 'terminal.c' -a "${1}" != "-c" ; then 
  1483.   echo shar: Will not clobber existing file \"'terminal.c'\"
  1484. else
  1485. echo shar: Extracting \"'terminal.c'\" \(2072 characters\)
  1486. sed "s/^X//" >'terminal.c' <<'END_OF_FILE'
  1487. X/* terminal
  1488. X ! 
  1489. X ! Copyright (C) 1990,1991 by Matthew Clegg
  1490. X ! 
  1491. X ! This program may be copied and distributed freely.  Please do not
  1492. X ! charge money for this program or for any program derived from it.
  1493. X ! If you modify this program, then include a notice stating plainly
  1494. X ! that your program is derived from the okbridge program and is not
  1495. X ! the same as the official okbridge program.
  1496. X !
  1497. X ! I welcome any suggestions for improvement to okbridge, and 
  1498. X ! I would be especially happy to receive improved source code.
  1499. X ! If you have comments or suggestions, or if you would like to
  1500. X ! join the okbridge mailing list, then write to
  1501. X !
  1502. X !   mclegg@cs.ucsd.edu
  1503. X !
  1504. X*/
  1505. X#include <curses.h>
  1506. X
  1507. Xint cursor_x, cursor_y;   /* The current position of the input cursor. */
  1508. XInitialize_Terminal ()
  1509. X/* To be called once at the beginning of the program. */
  1510. X{
  1511. X    initscr ();
  1512. X#ifdef ultrix
  1513. X    crmode ();
  1514. X#else
  1515. X    cbreak ();
  1516. X#endif
  1517. X    noecho ();
  1518. X    nonl ();
  1519. X};
  1520. Xprint (row, col, message)
  1521. X    int row, col; char *message;
  1522. X/* (1,1) specifies the upper left corner of the screen. */
  1523. X{
  1524. X    mvaddstr (row-1, col-1, message);
  1525. X};
  1526. Xint char_avail ()
  1527. X/* Returns TRUE if a character is available from the keyboard. */
  1528. X{
  1529. X    int ch;
  1530. X
  1531. X    restore_cursor ();
  1532. X        return (check_for_data(0,0));
  1533. X
  1534. X};
  1535. Xint input_char ()
  1536. X/* Returns the next input character from the keyboard.
  1537. X   (The character is echo'ed if it is not a control character.) */
  1538. X{
  1539. X    int log;
  1540. X    char chbuf[2];
  1541. X    restore_cursor ();
  1542. X    log = 0;
  1543. X    while (log < 1) log = read (0, chbuf, 1);
  1544. X
  1545. X    return (chbuf[0]);
  1546. X};
  1547. Xset_cursor (row, col)
  1548. X    int row, col;
  1549. X/* Places the cursor at the specified (row, col). */
  1550. X{
  1551. X        cursor_x = col-1;
  1552. X    cursor_y = row-1;
  1553. X    restore_cursor ();
  1554. X};
  1555. Xrestore_cursor ()
  1556. X{
  1557. X  move (cursor_y, cursor_x);
  1558. X  refresh ();
  1559. X};
  1560. X
  1561. Xclear_screen ()
  1562. X{
  1563. X    clear ();
  1564. X    refresh ();
  1565. X};
  1566. Xring_bell ()
  1567. X/* void ring_bell (void); */
  1568. X/* Rings the terminal's bell */
  1569. X{
  1570. X    addstr ("\007");
  1571. X    restore_cursor ();
  1572. X};
  1573. X
  1574. XReset_Terminal ()
  1575. X/* To be called at the end of the program to reset the terminal to its
  1576. X   initial operating mode. */
  1577. X{
  1578. X    clear_screen ();
  1579. X    endwin ();
  1580. X};
  1581. END_OF_FILE
  1582. if test 2072 -ne `wc -c <'terminal.c'`; then
  1583.     echo shar: \"'terminal.c'\" unpacked with wrong size!
  1584. fi
  1585. # end of 'terminal.c'
  1586. fi
  1587. echo shar: End of archive 1 \(of 7\).
  1588. cp /dev/null ark1isdone
  1589. MISSING=""
  1590. for I in 1 2 3 4 5 6 7 ; do
  1591.     if test ! -f ark${I}isdone ; then
  1592.     MISSING="${MISSING} ${I}"
  1593.     fi
  1594. done
  1595. if test "${MISSING}" = "" ; then
  1596.     echo You have unpacked all 7 archives.
  1597.     rm -f ark[1-9]isdone
  1598.     echo creating input.c from input.c.aa and input.c.ab
  1599.     cat input.c.aa input.c.ab >input.c
  1600.     rm -f input.c.aa input.c.ab
  1601. else
  1602.     echo You still need to unpack the following archives:
  1603.     echo "        " ${MISSING}
  1604. fi
  1605. ##  End of shell archive.
  1606. exit 0
  1607.