home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / x / xhearts.zip / HEARTSD.C < prev    next >
C/C++ Source or Header  |  1992-01-10  |  58KB  |  2,285 lines

  1. /* MIKEY: notes, todo */
  2.  
  3. /* shooting scoring messed up */
  4. /* improve passing */
  5. /*   keep high cards for jd trick at end? only if don't have jd */
  6. /*   => take all tricks for jd at end if qs gone */
  7. /* computer shoot attempt? */
  8. /* jdvoided */
  9.  
  10. /*
  11.  * dealer - more commonly known as heartsd
  12.  *
  13.  * Smarts of hearts program.  Runs in background when invoked by initial
  14.  * caller of hearts.  Contains all logic for communicating with other
  15.  * hearts players.  Handles all computer players, and communicates play
  16.  * of others to other players.
  17.  *
  18.  * JD variant addition and strategy mods by:
  19.  *      Mike Yang of Silicon Graphics (mikey@sgi.com)
  20.  *
  21.  * Computer strategy originally written in Pascal by:
  22.  *    Don Baccus of Oregon Software.
  23.  * Strategy mods by:
  24.  *    Jeff Hemmerling of Test Systems Strategies, Inc.
  25.  *
  26.  * Converted strategy to C, added curses and multi-player (sockets)
  27.  * interface by:
  28.  *    Bob Ankeney of Generic Computer Products
  29.  *
  30.  * Thanks to Keith Packard, for his invaluable (is that the same as
  31.  * unvaluable?) assistance as a unix guru, for design suggestions, and
  32.  * (I suppose) for convincing me to rewrite the bloody thing.
  33.  *
  34.  * Bug reports to Bob Ankeney at:
  35.  * ...!tektronix!reed!bob
  36.  *
  37.  */
  38.  
  39. #include "misc.h"
  40. #include "defs.h"
  41. #include "local.h"
  42. #include <sys/resource.h>
  43.  
  44. /* #define DEBUG     uncomment to enable play logging */
  45.   
  46. #define    BUF_SIZE    64
  47. #define FUNNY_FACTOR    2
  48. #define NPASS        3    /* # cards to pass */
  49. #define PLAYERS        4    /* # players total */
  50. #define NCARDS        (52 / PLAYERS)
  51.  
  52. #define ACE        13
  53. #define KING        12
  54. #define QUEEN        11
  55. #define JACK        10
  56.  
  57. #define HEARTS_PANIC    4
  58.  
  59. #define PANIC_RATIO    0.85
  60.  
  61. #define COMPUTER    1
  62. #define HUMAN        2
  63. #define VOYEUR        3
  64.  
  65. int debug = 0;
  66.  
  67. int num_humans,            /* # HUMAN players */
  68.   human_type,            /* HUMAN or VOYEUR */
  69.   player_mask;            /* Bit n+1 is set for each human player n */
  70.  
  71. char someone_is_shooting,
  72.   queen_played,
  73.   jack_played;
  74.  
  75. typedef struct node *ptr;
  76.  
  77. struct card {
  78.   int suit, rank;
  79. };
  80.  
  81. struct node {
  82.   ptr llink, rlink;
  83.   int rank;
  84. };
  85.  
  86. struct suit_list {
  87.   ptr head, tail;
  88.   int length;
  89. };
  90.  
  91. typedef struct suit_list card_hand[MAX_SUIT + 1];
  92.  
  93. struct player_status {
  94.   card_hand    cards;
  95.   int        pts, totalpts;
  96.   int        passer;
  97.   struct card    passed_cards[NPASS + 1];
  98.   int        num_passed;
  99.   int        player_kind;
  100.   int        socket;
  101.   char        name[9];
  102. };
  103.  
  104. struct player_status card_table[PLAYERS + 1];
  105.  
  106. card_hand cards_played;
  107.  
  108. struct card deck[53];
  109.  
  110. struct sockaddr_in sockaddr;
  111.  
  112.  
  113. int player_count, leader,
  114.   round, hand,
  115.   points_played;
  116.  
  117. int mikeyshooter,MIKEYJder,MIKEYJdintrick;
  118.  
  119. int privatemsgs = 1;
  120.  
  121. int voided[MAX_SUIT+1][PLAYERS+1], hasqs[PLAYERS+1][PLAYERS+1];
  122. /* FALSE: No info, assume not
  123.    TRUE:  Yes
  124.    MAYBE: Maybe, based on play */
  125. #define MAYBE 2
  126. #define NONE 666
  127.  
  128. FILE *fp;
  129.  
  130. char hearts_broken;
  131.  
  132. struct {
  133.   int card_count, highest_played, high_player, suit_led, pts;
  134.   char any_hearts;
  135.   struct card played[PLAYERS + 1];
  136. } trick;
  137.  
  138. char *snames[] = {
  139.   "",
  140.   "clubs",
  141.   "diamonds",
  142.   "hearts",
  143.   "spades"
  144.   },
  145.   rnames[] = " 23456789TJQKA",
  146.   *comp_names[] = {
  147.     "",
  148.     "zeppo",
  149.     "chico",
  150.     "harpo",
  151.     "groucho"
  152.     };
  153.  
  154. #define map_player(leader, player) (((leader + player - 1) % PLAYERS) + 1)
  155.  
  156. #define queen_safe(player) (queen_played || (find_true(hasqs[player]) == FALSE))
  157.  
  158. #define safe_suit(suit) ((suit != HEARTS) && (find_true(voided[suit]) == FALSE))
  159.  
  160. #define highest(player, suit) (card_table[player].cards[suit].head->rlink)
  161.  
  162. #define lowest(player, suit) (card_table[player].cards[suit].tail->llink)
  163.  
  164. #define cards_out(suit) (MAX_RANK - cards_played[suit].length)
  165.  
  166. #define spades_safe(player) (( (float) (cards_out(SPADES) - \
  167. card_table[player].cards[SPADES].length) / (PLAYERS - 1.0) >= 2.3) && \
  168.                  safe_suit(SPADES))
  169.  
  170. #define diamonds_safe(player) (( (float) (cards_out(DIAMONDS) -    \
  171. card_table[player].cards[DIAMONDS].length) / (PLAYERS - 1.0) >= 2.3) && \
  172. safe_suit(DIAMONDS))
  173.  
  174. #define clubs_safe(player) (( (float) (cards_out(CLUBS) - \
  175. card_table[player].cards[CLUBS].length) / (PLAYERS - 1.0) >= 2.3) && \
  176. safe_suit(CLUBS))
  177.  
  178. #define only_hearts(player) ((14 - round) == \
  179. card_table[player].cards[HEARTS].length)
  180.  
  181. #define max(a,b) ((a > b) ? a : b)
  182.  
  183. rnd(num)
  184. {
  185.   extern long random();
  186.   
  187.   return (random() % num);
  188. }
  189.  
  190.  
  191. init_deck()
  192. {
  193.   int suit_temp, rank_temp, j;
  194.   
  195.   j = 0;
  196.   for (rank_temp = MIN_RANK; rank_temp <= MAX_RANK ; rank_temp++)
  197.     for (suit_temp = CLUBS; suit_temp <= SPADES; suit_temp++) {
  198.       deck[++j].suit = suit_temp;
  199.       deck[j].rank = rank_temp;
  200.     }
  201. }
  202.  
  203. init_suit(list)
  204.      struct suit_list *list;
  205. {
  206.   char *malloc();
  207.   ptr p, p1;
  208.   
  209.   list->length = 0;
  210.   p = list->head = (ptr) malloc(sizeof(*p));
  211.   p1 = list->tail = (ptr) malloc(sizeof(*p1));
  212.   p->llink = NULL; 
  213.   p1->rlink = NULL;
  214.   p->rlink = p1;
  215.   p1->llink = p;
  216.   p->rank = MAX_RANK + 1;
  217.   p1->rank = 0;
  218. }
  219.  
  220. init()
  221. {
  222.   int player;
  223.   
  224.   srandom(getpid());    /* Init random number gen */
  225.   for (player = 1; player <= PLAYERS; player++) {
  226.     card_table[player].player_kind = COMPUTER;
  227.     (void) strcpy(card_table[player].name, comp_names[player]);
  228.     card_table[player].socket = -1;
  229.   }
  230.   num_humans = 0;
  231. }
  232.  
  233. new_game()
  234. {
  235.   int suit, player;
  236.   
  237.   init_deck();
  238.   for (player = 1; player <= PLAYERS; player++) {
  239.     card_table[player].totalpts = 0;
  240.     for (suit = CLUBS; suit <= SPADES; suit++)
  241.       init_suit(&card_table[player].cards[suit]);
  242.   }
  243.   for (suit = CLUBS; suit <= SPADES; suit++)
  244.     init_suit(&cards_played[suit]);
  245. }
  246.  
  247. get_rank(rch)
  248.      char rch;
  249. {
  250.   int i;
  251.   
  252.   for (i = 1; i <= MAX_RANK; i++)
  253.     if (rch == rnames[i])
  254.       return(i);
  255.   return(0);
  256. }
  257.  
  258. get_suit(sch)
  259.      char sch;
  260. {
  261.   int i;
  262.   
  263.   for (i = 1; i <= MAX_SUIT; i++)
  264.     if (sch == *snames[i])
  265.       return(i);
  266.   return(0);
  267. }
  268.  
  269. char *
  270.   get_name(player_num)
  271. int player_num;
  272. {
  273.   int i;
  274.   char unique_name = TRUE;
  275.   static char pname[16+64];
  276.   
  277.   for (i = 1; i <= PLAYERS; i++)
  278.     if ((i != player_num) &&
  279.     !strcmp(card_table[i].name, card_table[player_num].name))
  280.       unique_name = FALSE;
  281.   if (unique_name)
  282.     (void) strcpy(pname, card_table[player_num].name);
  283.   else
  284.     (void) sprintf(pname, "%s (%d)", card_table[player_num].name,
  285.            player_num);
  286.   if (strlen(pname) >= 16) {
  287.     pname[15] = '\0';
  288.   }
  289.   return(pname);
  290. }
  291.  
  292. /*
  293.  * Get a card from somebody.  get_mask is a bit mask specifying who is
  294.  * acceptable to get a card from (i.e., bit n states player n can send
  295.  * a card.)  Scans all sockets for input, handling messages and player
  296.  * leaving signals.  Returns when one of the specified players passes
  297.  * a card.  Returns 0 if one of the specified players exits the game.
  298.  */
  299. get_card(get_mask, from, buf)
  300.      int get_mask, *from;
  301.      char *buf;
  302. {
  303.   int i, player, ret;
  304.   char mesg_buf[64+16];
  305.   fd_type read_fd;
  306.   
  307.   for (;;) {
  308.     fd_init(4, &read_fd);        /* Watch for new arrivals */
  309.     for (player = 1; player <= PLAYERS; player++)
  310.       if (card_table[player].player_kind != COMPUTER)
  311.     fd_set(card_table[player].socket, &read_fd);
  312.     if (select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
  313.            (struct timeval *) 0)) {
  314.       if (fd_isset(4, read_fd))    /* New arrival? */
  315.     add_player();
  316.       for (player = 1; player <= PLAYERS; player++)    /* This player send? */
  317.     if (fd_isset(card_table[player].socket, read_fd)) {
  318.       ret = read_socket(card_table[player].socket, buf);
  319.       *from = player;
  320.       if (ret && (buf[0] == 'M')) {
  321.         (void) sprintf(mesg_buf, "M%d%s: %s", MESG_WINDOW,
  322.                get_name(player), buf + 1);
  323.         if (strlen(mesg_buf) >= 64) {
  324.           mesg_buf[63] = '\0';
  325.         }
  326.         send_to_all(mesg_buf);        /* Message to everyone */
  327.       } 
  328.       else if (ret && (buf[0] == '~')) {
  329.         if (privatemsgs)
  330.           privatemsgs = FALSE;
  331.         else
  332.           privatemsgs = TRUE;
  333.       }
  334.       else if (ret && (buf[0] == ';')) {
  335.         if ((1 <= buf[1]-'0') &&
  336.         privatemsgs &&
  337.         (buf[1]-'0' <= PLAYERS) &&
  338.         (card_table[buf[1]-'0'].player_kind != COMPUTER)) {
  339.           (void) sprintf(mesg_buf, "M%d%s; %s", MESG_WINDOW,
  340.                  get_name(player), buf + 2);
  341.           if (strlen(mesg_buf) >= 64) {
  342.         mesg_buf[63] = '\0';
  343.           }
  344.           send_buf(buf[1]-'0',mesg_buf);
  345.           send_buf(player,mesg_buf);
  346.         }
  347.       } 
  348.       else {
  349.         if (!ret) {
  350.           if (card_table[player].player_kind == HUMAN)
  351.         player_mask &= ~(1 << player);        /* player went away */
  352.           card_table[player].player_kind = COMPUTER;
  353.           (void) close(card_table[player].socket);
  354.           if (--num_humans == 0)
  355.         exit (0);    /* give up if nobody wants to play (sniff) */
  356.           for (i = 1; i <= PLAYERS; i++) {
  357.         if (card_table[i].player_kind != COMPUTER) {
  358.           (void) sprintf(buf,
  359.                  "M%d%s vanishes in a puff of greasy black smoke!",
  360.                  MESG_WINDOW, get_name(player));    /* Announce deletion */
  361.           send_buf(i, buf);        /* to others */
  362.           (void) sprintf(buf,
  363.                  /*
  364.                   * Inform dealer.
  365.                   */
  366.                  "p%d<empty>", player - 1);
  367.           write_socket(3, buf);
  368.         }
  369.           }
  370.           (void) strcpy(card_table[player].name, comp_names[player]);
  371.           send_all_totals();
  372.         }
  373.         if (get_mask & (1 << player))
  374.           return(ret);
  375.       }
  376.     }
  377.     }
  378.   }
  379. }
  380.  
  381. toss_card(player, card_to_toss, suit_to_toss)
  382.      int player, suit_to_toss;
  383.      ptr card_to_toss;
  384. {
  385.   char buf[BUF_SIZE];
  386.   
  387.   (void) sprintf(buf, "R%c%c",
  388.          rnames[card_to_toss->rank], *snames[suit_to_toss]);
  389.   send_buf(player, buf);        /* Tell player to remove card */
  390. }
  391.  
  392. read_card(read_mask, player, card_to_play, suit_to_play)
  393.      int read_mask, *player, *suit_to_play;
  394.      ptr *card_to_play;
  395. {
  396.   char buf[BUF_SIZE];
  397.   int rank, suit;
  398.   ptr p;
  399.   char rank_ch, suit_ch;
  400.   
  401.   if (get_card(read_mask, player, buf)) {
  402.     do {
  403.       rank_ch = buf[1];
  404.       if (rank_ch == '?') {
  405.     if (round == 0)
  406.       get_pass(*player, card_table[*player].num_passed+1,
  407.            &p, &suit);
  408.     else
  409.       if (leader == *player)
  410.         computer_lead(&p,&suit);
  411.       else
  412.         computer_pick(*player,&p,&suit);
  413.     erase_window(*player, TEXT_WINDOW);
  414.       } else {
  415.     suit_ch = buf[2];
  416.     rank = get_rank(rank_ch);
  417.     suit = get_suit(suit_ch);
  418.     erase_window(*player, TEXT_WINDOW);
  419.     p = card_table[*player].cards[suit].head->rlink;
  420.     while (p && (p->rank != rank))
  421.       p = p->rlink;
  422.     if (p == NULL) {
  423.       (void) sprintf(buf, "M%dPlay a card you have:",
  424.              TEXT_WINDOW);
  425.       send_buf(*player, buf);
  426.       send_buf(*player, "G");
  427.       if (!get_card(read_mask, player, buf))
  428.         return(0);
  429.     }
  430.       }
  431.     } 
  432.     while (p == NULL);
  433.     *card_to_play = p;
  434.     *suit_to_play = suit;
  435.     return(1);
  436.   }
  437.   return(0);
  438. }
  439.  
  440. send_card(player, rank, suit)
  441.      int player, rank, suit;
  442. {
  443.   char buf[BUF_SIZE];
  444.   
  445.   (void) sprintf(buf, "A%c%c", rnames[rank], *snames[suit]);
  446.   send_buf(player, buf);
  447. }
  448.  
  449. /*
  450.  *  send cards in hand to player
  451.  */
  452. send_hand(player)
  453.      int player;
  454. {
  455.   int suit;
  456.   ptr p;
  457.   
  458.   for (suit = CLUBS; suit <= SPADES; suit++) {    /* send cards in hand */
  459.     p = card_table[player].cards[suit].head->rlink;
  460.     while (p->rank) {
  461.       send_card(player, p->rank, suit);
  462.       p = p->rlink;
  463.     }
  464.   }
  465. }
  466.  
  467. get_first_player()
  468. {
  469.   fd_type read_fd;        /* main socket bit mask */
  470.   
  471.   /*
  472.    *  wait for new player to show up
  473.    */
  474.   fd_init(4, &read_fd);        /* Wait for someone to show up */
  475.   if (select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
  476.          (struct timeval *) 0) == -1) {
  477.     perror("select");
  478.     exit(1);
  479.   }
  480. }
  481.  
  482. add_player()
  483. {
  484.   int new_socket;            /* new file descriptor */
  485.   char pname[128], buf[128];
  486.   struct sockaddr_in sockad;
  487.   int ssize;            /* to make accept happy */
  488.   int new_player = 0;
  489.   int i;
  490.   
  491.   /*
  492.    *  add whoever's waiting
  493.    */
  494.   ssize = sizeof (sockad);
  495.   if ((new_socket = accept(4, &sockad, &ssize)) == -1) {
  496.     perror("accept");
  497.     exit(1);
  498.   }
  499.   /* get user name */
  500.   if (read_socket(new_socket, pname) > 0) {
  501.     pname[8] = '\0';    /* Name must be less than 9 chars */
  502.     for (i = PLAYERS; i >= 1; i--)
  503.       if (card_table[i].player_kind == COMPUTER)
  504.     new_player = i;
  505.   }
  506.   if (new_player) {
  507.     /*
  508.      * Inform distributor
  509.      */
  510.     (void) sprintf(buf, "p%d%s", new_player - 1, pname);
  511.     write_socket(3, buf);
  512.     card_table[new_player].player_kind = human_type;
  513.     card_table[new_player].socket = new_socket;
  514.     (void) strcpy(card_table[new_player].name, pname);
  515.     ++num_humans;
  516.     if (human_type == VOYEUR) {
  517.       (void) sprintf(buf,
  518.              "M%d    Game in progress...", PLAY_WINDOW);
  519.       send_buf(new_player, buf);
  520.       (void) sprintf(buf,
  521.              "M%dYou may watch till next hand.", MESG_WINDOW);
  522.       send_buf(new_player, buf);
  523.     } 
  524.     else
  525.       player_mask |= 1 << new_player;
  526.     for (i = 1; i <= PLAYERS; i++) {
  527.       if (card_table[i].player_kind != COMPUTER) {
  528.     (void) sprintf(buf,
  529.                "M%d%s added as player %d", MESG_WINDOW,
  530.                pname, new_player);
  531.     if (i != new_player)    /* Announce addition */
  532.       send_buf(i, buf);
  533.     send_totals(i);
  534.       }
  535.     }
  536.     send_hand(new_player);
  537.   }
  538.   else {
  539.     (void) sprintf(buf, "M%dAll seats are full!", MESG_WINDOW);
  540.     write_socket(new_socket, buf);
  541.     write_socket(new_socket, "Z");
  542.     (void) close(new_socket);
  543.   }
  544. }
  545.  
  546. erase_window(player, which_window)
  547.      int player, which_window;
  548. {
  549.   char buf[BUF_SIZE];
  550.   
  551.   (void) sprintf(buf, "E%d", which_window);
  552.   send_buf(player, buf);
  553. }
  554.  
  555. erase_all_window(which_window)
  556.      int which_window;
  557. {
  558.   int player;
  559.   
  560.   for (player = 1; player <= PLAYERS; player++)
  561.     if (card_table[player].player_kind != COMPUTER)
  562.       erase_window(player, which_window);
  563. }
  564.  
  565. send_totals(player)
  566.      int player;
  567. {
  568.   int i;
  569.   char buf[BUF_SIZE];
  570.   
  571.   if (card_table[player].player_kind != COMPUTER) {
  572.     for (i = 1; i <= PLAYERS; i++) {
  573.       (void) sprintf(buf, "S%d%03d%03d%s", i,
  574.              card_table[i].pts,
  575.              card_table[i].totalpts, card_table[i].name);
  576.       send_buf(player, buf);
  577.     }
  578.   }
  579. }
  580.  
  581. send_all_totals()
  582. {
  583.   int player;
  584.   
  585.   for (player = 1; player <= PLAYERS; player++)
  586.     send_totals(player);
  587. }
  588.  
  589. send_all_winner()
  590. {
  591.   int max_score,
  592.   player, shooter;
  593.   char buf[BUF_SIZE];
  594.   char    mikeysh;
  595.   
  596.   (void) sprintf(buf, "M%d--------------------------------------------------------", MESG_WINDOW);
  597.   send_to_all(buf);
  598.   max_score = 0;  
  599.   mikeysh = TRUE;
  600.   for (player = 1; player <= PLAYERS; player++) {
  601.     if ((max_score != 0) &&
  602.     (card_table[player].pts != 0) &&
  603.     (card_table[player].pts != -10))
  604.       mikeysh = FALSE;
  605.     if ((card_table[player].pts > max_score) &&
  606.     (card_table[player].pts != -10) &&
  607.     (card_table[player].pts != 0)) {
  608.       max_score = card_table[player].pts;
  609.       shooter = player;
  610.     }
  611.   }
  612.   mikeysh = mikeysh && (mikeyshooter == shooter);
  613.   
  614.   if (mikeysh) {
  615.     for (player = 1; player <= PLAYERS; player++) {
  616.       if (player != shooter)
  617.     card_table[player].totalpts += 26;
  618.       if ((player == MIKEYJder) && MIKEYJ)
  619.     card_table[player].totalpts -= 10;
  620.     }
  621.   } 
  622.   else {
  623.     for (player = 1; player <= PLAYERS; player++)
  624.       card_table[player].totalpts += card_table[player].pts;
  625.   }
  626.   if (mikeysh)
  627.     (void) sprintf(buf, "M %s wins by shooting the moon!",
  628.            get_name(shooter));
  629.   else {
  630.     get_winner(buf, FALSE);
  631.     (void) strcat(buf, ".");
  632.   }
  633.   buf[1] = MESG_WINDOW + '0';
  634.   send_to_all(buf);
  635. }
  636.  
  637. send_final_winner()
  638. {
  639.   char buf[64];
  640.   
  641.   get_winner(buf, TRUE);
  642.   buf[1] = PLAY_WINDOW + '0';
  643.   (void) strcat(buf, " total!");
  644.   erase_all_window(PLAY_WINDOW);
  645.   send_to_all(buf);
  646. }
  647.  
  648. /*
  649.  * Get buffer of form:    "M groucho wins with nn points"
  650.  *           or:    "M groucho and chico tie with nn points"
  651.  */
  652. get_winner(buf, use_totalpts)
  653.      char *buf;
  654.      char use_totalpts;
  655. {
  656.   int player, winning_score, temp,
  657.   scores[PLAYERS + 1], players[PLAYERS + 1];
  658.   char sorted;
  659.   
  660.   for (player = 1; player <= PLAYERS; player++) {
  661.     scores[player] = use_totalpts ? card_table[player].totalpts
  662.       : card_table[player].pts;
  663.     players[player] = player;
  664.   }
  665.   do {                /* Bubble sort the bloody thing */
  666.     sorted = TRUE;
  667.     for (player = 1; player < PLAYERS; player++)
  668.       if (scores[player + 1] < scores[player]) {
  669.     temp = scores[player];
  670.     scores[player] = scores[player + 1];
  671.     scores[player + 1] = temp;
  672.     temp = players[player];
  673.     players[player] = players[player + 1];
  674.     players[player + 1] = temp;
  675.     sorted = FALSE;
  676.       }
  677.   } 
  678.   while (!sorted);
  679.   winning_score = scores[1];
  680.   (void) sprintf(buf, "M %s", card_table[players[1]].name);
  681.   for (player = 2;
  682.        (player <= PLAYERS) && (scores[player] == winning_score); player++)
  683.     (void) sprintf(buf + strlen(buf), " and %s",
  684.            card_table[players[player]].name);
  685.   if (scores[2] == winning_score)
  686.     (void) sprintf(buf + strlen(buf),
  687.            " tie with %d point", winning_score);
  688.   else
  689.     (void) sprintf(buf + strlen(buf),
  690.            " wins with %d point", winning_score);
  691.   if (winning_score != 1)
  692.     (void) strcat(buf, "s");
  693. }
  694.  
  695. send_buf(player, buf)
  696.      int player;
  697.      char *buf;
  698. {
  699.   write_socket(card_table[player].socket, buf);
  700. }
  701.  
  702. send_to_all(buf)
  703.      char *buf;
  704. {
  705.   int player;
  706.   
  707.   for (player = 1; player <= PLAYERS; player++)
  708.     if (card_table[player].player_kind != COMPUTER)
  709.       send_buf(player, buf);
  710. }
  711.  
  712. new_round()
  713. {
  714.   char buf[BUF_SIZE];
  715.   int     mikey;
  716.   
  717.   for(mikey = 1;mikey <= PLAYERS;mikey++) {
  718.     trick.played[mikey].rank = 0;
  719.     trick.played[mikey].suit = 0;
  720.   }
  721.   for(mikey=CLUBS; mikey<=SPADES; mikey++) {
  722.     if (cards_out(mikey) <= 1.5*PLAYERS) {
  723.       int each;
  724.       
  725.       for (each=1; each<=PLAYERS; each++) {
  726.     if (voided[mikey][each] == FALSE) {
  727.       voided[mikey][each] = MAYBE;
  728.     }
  729.       }
  730.     }
  731.   }
  732.   trick.pts = 0;
  733.   trick.any_hearts = FALSE;
  734.   player_count = 0;
  735.   erase_all_window(PLAY_WINDOW);
  736.   /*
  737.    * Inform distributor
  738.    */
  739.   (void) sprintf(buf, "r%d", round);
  740.   write_socket(3, buf);
  741.   (void) sprintf(buf, "M%dHand: %d   Round: %d",
  742.          ROUND_WINDOW, hand, round);
  743.   send_to_all(buf);
  744. }
  745.  
  746. enter_card(which_card, which_hand)
  747.      struct card which_card;
  748.      card_hand which_hand;
  749.      
  750. {
  751.   ptr p, p1;
  752.   
  753.   p = which_hand[which_card.suit].head;
  754.   ++which_hand[which_card.suit].length;
  755.   while (p->rank > which_card.rank)
  756.     p = p->rlink;
  757.   p1 = (ptr) malloc(sizeof(*p1));
  758.   p1->llink = p->llink;
  759.   p1->llink->rlink = p1;
  760.   p->llink = p1;
  761.   p1->rlink = p;
  762.   p1->rank = which_card.rank;
  763. }
  764.  
  765. remove_node(p)
  766.      ptr p;
  767.      
  768. {
  769.   p->llink->rlink = p->rlink;
  770.   p->rlink->llink = p->llink;
  771.   free((char *) p);
  772. }
  773.  
  774. clear_hand(which_hand)
  775.      card_hand which_hand;
  776. {
  777.   int suit;
  778.   ptr p, p1;
  779.   
  780.   for (suit = CLUBS; suit <= SPADES; suit++) {
  781.     which_hand[suit].length = 0;
  782.     p = which_hand[suit].head->rlink;
  783.     while (p->rank > 0) {
  784.       p1 = p;
  785.       p = p->rlink;
  786.       remove_node(p1);
  787.     }
  788.   }
  789. }
  790.  
  791. shuffle()
  792. {
  793.   int j, k;
  794.   struct card t;
  795.   
  796.   for (j = 52; j >= 1; j--) {
  797.     k = rnd(j) + 1;
  798.     t = deck[k]; 
  799.     deck[k] = deck[j]; 
  800.     deck[j] = t;
  801.   }
  802. }
  803.  
  804. deal()
  805. {
  806.   int i, j, player;
  807.   
  808.   for (player = 1; player <= PLAYERS; player++) {
  809.     j = NCARDS * (player - 1);
  810.     for (i = 1; i <= NCARDS; i++)
  811.       enter_card(deck[i+j], card_table[player].cards);
  812.     if (card_table[player].player_kind != COMPUTER)
  813.       send_hand(player);
  814.   }
  815. }
  816.  
  817. new_hand()
  818. {
  819.   int player;
  820.   char buf[BUF_SIZE];
  821.   
  822.   mikeyshooter = 0;
  823.   MIKEYJder = 0;
  824.   MIKEYJdintrick = FALSE;
  825.   points_played = 0;
  826.   someone_is_shooting = FALSE;
  827.   jack_played = queen_played = hearts_broken = FALSE;
  828.   trick.suit_led = CLUBS;
  829.   for (player = 1; player <= PLAYERS; player++) {
  830.     int each;
  831.     
  832.     card_table[player].pts = 0;
  833.     clear_hand(card_table[player].cards);
  834.     voided[CLUBS][player] = voided[DIAMONDS][player] =
  835.       voided[HEARTS][player] = voided[SPADES][player] = FALSE;
  836.     for (each=1; each<=PLAYERS; each++) {
  837.       hasqs[player][each] = TRUE;
  838.     }
  839.   }
  840.   clear_hand(cards_played);
  841.   erase_all_window(PLAY_WINDOW);
  842.   send_all_totals();
  843.   /*
  844.    * Inform distributor
  845.    */
  846.   (void) sprintf(buf, "h%d", hand);
  847.   write_socket(3, buf);
  848.   write_socket(3, "r0");
  849.   (void) sprintf(buf, "M%dNew hand...", ROUND_WINDOW);
  850.   send_to_all(buf);
  851.   shuffle();            /* Shuffle three times! */
  852.   shuffle();            /* (just like vegas!)   */
  853.   shuffle();
  854.   deal();
  855. }
  856.  
  857. ptr
  858.   find_card(player,rank,suit)
  859. int player,rank,suit;
  860. {
  861.   ptr p;
  862.   
  863.   p = card_table[player].cards[suit].head->rlink;
  864.   while (p && p->rank)
  865.     if (p->rank == rank)
  866.       return(p);
  867.     else
  868.       p = p->rlink;
  869.   return(NULL);
  870. }
  871.  
  872. char
  873.   not_in_trick(rank,suit)
  874. int rank,suit;
  875. {
  876.   int mikey;
  877.   
  878.   for(mikey = 1;mikey <= PLAYERS;mikey++) {
  879.     if ((trick.played[mikey].rank == rank) &&
  880.     (trick.played[mikey].suit == suit))
  881.       return(FALSE);
  882.   }
  883.   return(TRUE);
  884. }
  885.  
  886. ptr
  887.   effective_high(player,rank,suit)
  888. int player,rank,suit;
  889. {
  890.   ptr card,p,q;
  891.   int r;
  892.   
  893.   r = rank-1;
  894.   card = find_card(player,rank,suit);
  895.   p = card->rlink;
  896.   q = cards_played[suit].head->rlink;
  897.   while (q->rank > r)
  898.     q = q->rlink;
  899.   while (r && (!MIKEYJ || (suit != DIAMONDS) || (r != JACK)) &&
  900.      ((suit != SPADES) || (r != QUEEN)) &&
  901.      ((p->rank == r) || ((q->rank == r) &&
  902.                  (not_in_trick(r,suit))))) {
  903.     if (p->rank == r) {
  904.       card = p;
  905.       p = p->rlink;
  906.     } else {
  907.       q = q->rlink;
  908.     }
  909.     r--;
  910.   }
  911.   return(card);
  912. }
  913.  
  914.  
  915. ptr
  916.   effective_low(player,rank,suit)
  917. int player,rank,suit;
  918. {
  919.   ptr card,p,q;
  920.   int r;
  921.   
  922.   r = rank+1;
  923.   card = find_card(player,rank,suit);
  924.   p = card->llink;
  925.   q = cards_played[suit].tail->llink;
  926.   while (q->rank < r)
  927.     q = q->llink;
  928.   while ((r <= MAX_RANK) &&
  929.      (!MIKEYJ || (suit != DIAMONDS) || (r != JACK)) &&
  930.      ((suit != SPADES) || (r != QUEEN)) &&
  931.      ((p->rank == r) || ((q->rank == r) &&
  932.                  (not_in_trick(r,suit))))) {
  933.     if (p->rank == r) {
  934.       card = p;
  935.       p = p->llink;
  936.     } else {
  937.       q = q->llink;
  938.     }
  939.     r++;
  940.   }
  941.   return(card);
  942. }
  943.  
  944.  
  945. ptr
  946.   next_highest(player, rank, suit_to_play)
  947. int player, rank, suit_to_play;
  948. {
  949.   ptr p;
  950.   
  951.   p = card_table[player].cards[suit_to_play].head->rlink;
  952.   while (p && p->rank)
  953.     if (p->rank < rank)
  954.       return(effective_high(player,p->rank,suit_to_play));
  955.     else
  956.       p = p->rlink;
  957.   return(NULL);
  958. }
  959.  
  960. int
  961.   highest_unplayed(suit, player)
  962. int suit, player;
  963. {
  964.   ptr p, q;
  965.   int last;
  966.   
  967.   p = cards_played[suit].head->rlink;
  968.   q = card_table[player].cards[suit].head->rlink;
  969.   last = MAX_RANK+1;
  970.   while (last) {
  971.     if ((p->rank != last-1) && (q->rank != last-1)) {
  972.       return(last-1);
  973.     } else {
  974.       if (q->rank == last-1) {
  975.     q = q->rlink;
  976.       } else {
  977.     p = p->rlink;
  978.       }
  979.       last--;
  980.     }
  981.   }
  982.   return(0);
  983. }
  984.  
  985. int
  986.   lowest_unplayed(suit, player)
  987. int suit, player;
  988. {
  989.   ptr p, q;
  990.   int last;
  991.   
  992.   p = cards_played[suit].tail->llink;
  993.   q = card_table[player].cards[suit].tail->llink;
  994.   last = 0;
  995.   while (last != MAX_RANK) {
  996.     if ((p->rank != last+1) && (q->rank != last+1)) {
  997.       return(last+1);
  998.     } else {
  999.       if (q->rank == last+1) {
  1000.     q = q->rlink;
  1001.       } else {
  1002.     p = p->rlink;
  1003.       }
  1004.       last++;
  1005.     }
  1006.   }
  1007.   return(MAX_RANK+1);
  1008. }
  1009.  
  1010. int
  1011.   count_losers(rank, suit)
  1012. int rank, suit;
  1013. {
  1014.   ptr p;
  1015.   int losers;
  1016.   
  1017.   p = cards_played[suit].head->rlink;
  1018.   losers = 0;
  1019.   while (p->rank) {
  1020.     if (p->rank < rank)
  1021.       losers++;
  1022.     p = p->rlink;
  1023.   }
  1024.   return(losers);
  1025. }
  1026.  
  1027. int
  1028.   find_true(array)
  1029. int array[PLAYERS+1];
  1030. {
  1031.   int each, result;
  1032.   
  1033.   result = FALSE;
  1034.   for (each=trick.card_count+1; each<=PLAYERS; each++) {
  1035.     if (array[map_player(leader,each)] == TRUE)
  1036.       result = TRUE;
  1037.     if ((array[map_player(leader,each)] == MAYBE) && (result != TRUE))
  1038.       result = MAYBE;
  1039.   }
  1040.   return(result);
  1041. }
  1042.  
  1043. int
  1044.   count_array(array, value)
  1045. int array[PLAYERS+1], value;
  1046. {
  1047.   int each, result;
  1048.   
  1049.   result = 0;
  1050.   for (each=1; each<=PLAYERS; each++) {
  1051.     if (array[each] == value)
  1052.       result++;
  1053.   }
  1054.   return(result);
  1055. }
  1056.  
  1057. int
  1058.   find_false(array)
  1059. int array[PLAYERS+1];
  1060. {
  1061.   int each, result;
  1062.   
  1063.   result = TRUE;
  1064.   for (each=trick.card_count+1; each<=PLAYERS; each++) {
  1065.     if (array[map_player(leader,each)] == FALSE)
  1066.       result = FALSE;
  1067.     if ((array[map_player(leader,each)] == MAYBE) && (result != FALSE))
  1068.       result = MAYBE;
  1069.   }
  1070.   return(result);
  1071. }
  1072.  
  1073. ptr
  1074.   effective_highest(player, suit)
  1075. int player, suit;
  1076. {
  1077.   ptr p;
  1078.   
  1079.   p = highest(player,suit);
  1080.   if (p->rank)
  1081.     return(effective_high(player,p->rank,suit));
  1082.   else
  1083.     return(p);
  1084. }
  1085.  
  1086. ptr
  1087.   effective_lowest(player, suit)
  1088. int player, suit;
  1089. {
  1090.   ptr p;
  1091.   
  1092.   p = lowest(player,suit);
  1093.   if (p->rank != MAX_RANK+1)
  1094.     return(effective_low(player,p->rank,suit));
  1095.   else
  1096.     return(p);
  1097. }
  1098.  
  1099. int
  1100.   lowestp(rank,suit)
  1101. int rank, suit;
  1102. {
  1103.   ptr p;
  1104.   int each;
  1105.   
  1106.   p = cards_played[suit].tail->llink;
  1107.   for (each=1; each<rank; each++) {
  1108.     if (p->rank == each) {
  1109.       p = p->llink;
  1110.     } else {
  1111.       return(FALSE);
  1112.     }
  1113.   }
  1114.   return(TRUE);
  1115. }
  1116.  
  1117.  
  1118. find_high_card(player, card_to_play, suit_to_play, play_points, play_spades, play_diamonds)
  1119.      int player, *suit_to_play;
  1120.      char play_points, play_spades, play_diamonds;
  1121.      ptr *card_to_play;
  1122. {
  1123.   int high_card, suit;
  1124.   ptr p;
  1125.   
  1126.   high_card = -1;
  1127.   *card_to_play = NULL;
  1128.   for (suit = CLUBS; suit <= SPADES; suit++)  {
  1129.     p = card_table[player].cards[suit].head->rlink;
  1130.     
  1131.     if ((suit == DIAMONDS) && (p->rank >= JACK) && MIKEYJ) {
  1132.       p=p->rlink;
  1133.     }
  1134.     
  1135.     if ((p->rank != 0) &&
  1136.     (p->rank-count_losers(p->rank,suit) > high_card) &&
  1137.     (play_spades ||
  1138.      (suit != SPADES)) &&
  1139.     (play_diamonds ||
  1140.      (suit != DIAMONDS)) &&
  1141.     (play_points ||
  1142.      (point_value(p->rank, suit) == 0))) {
  1143.       high_card = p->rank-count_losers(p->rank,suit);
  1144.       *card_to_play = p;
  1145.       *suit_to_play = suit;
  1146.     }
  1147.   }
  1148.   if (*card_to_play == NULL) {
  1149.     /*
  1150.      * No clubs or diamonds.  Q spades is highest spade, or no
  1151.      * spades at all.  Try to play next highest spade.
  1152.      */
  1153.     
  1154.     /*
  1155.      * May have Jack of Diamonds also, if MIKEYJ
  1156.      */
  1157.     if (play_spades)
  1158.       *card_to_play = next_highest(player, QUEEN, SPADES);
  1159.     if (*card_to_play)
  1160.       *suit_to_play = SPADES;
  1161.     else if (play_points &&
  1162.          (card_table[player].cards[HEARTS].length)) {
  1163.       /* Play highest heart */
  1164.       *card_to_play = effective_highest(player, HEARTS);
  1165.       *suit_to_play = HEARTS;
  1166.     }
  1167.     /* otherwise, try lowest diamond */
  1168.     if ((*card_to_play == NULL) &&
  1169.     card_table[player].cards[DIAMONDS].length) {
  1170.       *card_to_play = lowest(player, DIAMONDS);
  1171.       *suit_to_play = DIAMONDS;
  1172.     }
  1173.     if ((*card_to_play == NULL) &&
  1174.     card_table[player].cards[SPADES].length) {
  1175.       *card_to_play = effective_highest(player, SPADES);
  1176.       *suit_to_play = SPADES;
  1177.     }
  1178.     /* shouldn't ever need the following
  1179.        if (*card_to_play == NULL) {
  1180.        *card_to_play = effective_highest(player, CLUBS);
  1181.        *suit_to_play = CLUBS;
  1182.        if (((*card_to_play)->rank) == 0)
  1183.        *card_to_play = NULL;
  1184.        }
  1185.        */
  1186.   }
  1187. }
  1188.  
  1189. find_low_card(player, card_to_play, suit_to_play)
  1190.      int player, *suit_to_play;
  1191.      ptr *card_to_play;
  1192. {
  1193.   int low_card, suit;
  1194.   ptr p;
  1195.   
  1196.   low_card = MAX_RANK + 1;
  1197.   *card_to_play = NULL;
  1198.   for (suit = CLUBS; suit <= SPADES; suit++) {
  1199.     p = card_table[player].cards[suit].tail->llink;
  1200.     if (MIKEYJ && (p->rank == JACK) && (suit == DIAMONDS))
  1201.       p = p->llink;
  1202.     if ((p->rank < low_card) &&
  1203.     (point_value(p->rank, suit) == 0)) {
  1204.       low_card = p->rank;
  1205.       *card_to_play = p;
  1206.       *suit_to_play = suit;
  1207.     }
  1208.   }
  1209.   if (*card_to_play == NULL) {
  1210.     *suit_to_play = HEARTS;
  1211.     *card_to_play = card_table[player].cards[HEARTS].tail->llink;
  1212.     if ((*card_to_play)->rank == MAX_RANK+1) {
  1213.       *suit_to_play = DIAMONDS;
  1214.       *card_to_play = find_card(player,JACK,DIAMONDS);
  1215.     }
  1216.     if (!(*card_to_play) || (*card_to_play)->rank == MAX_RANK+1) {
  1217.       *suit_to_play = SPADES;
  1218.       *card_to_play = find_card(player,QUEEN,SPADES);
  1219.     }
  1220.   }
  1221. }
  1222.  
  1223. find_low_club(leader)
  1224.      int *leader;
  1225. {
  1226.   int player, low_club, rank;
  1227.   
  1228.   low_club = MAX_RANK;
  1229.   for (player = 1; player <= PLAYERS; player++)
  1230.     if ((rank = card_table[player].cards[CLUBS].tail->llink->rank) < low_club) {
  1231.       *leader = player;
  1232.       low_club = rank;
  1233.     }
  1234. }
  1235.  
  1236. find_queen(player, card_to_play)
  1237.      int player;
  1238.      ptr *card_to_play;
  1239. {
  1240.   ptr p;
  1241.   
  1242.   *card_to_play = NULL;
  1243.   p = card_table[player].cards[SPADES].head->rlink;
  1244.   while (p)
  1245.     if (p->rank == QUEEN) {
  1246.       *card_to_play = p;
  1247.       p = NULL;
  1248.     } 
  1249.     else
  1250.       p = p->rlink;
  1251. }
  1252.  
  1253. print_pass(player)
  1254.      int player;
  1255. {
  1256.   int i;
  1257.   char buf[BUF_SIZE];
  1258.   struct card cd;
  1259.   
  1260.   erase_window(player, PLAY_WINDOW);
  1261.   (void) sprintf(buf, "M%d%s passes you:", LEAD_WINDOW,
  1262.          get_name(card_table[player].passer));
  1263.   send_buf(player, buf);
  1264.   for (i = 1; i <= NPASS; i++) {
  1265.     cd = card_table[player].passed_cards[i];
  1266.     send_card(player, cd.rank, cd.suit);
  1267.     (void) sprintf(buf, "P%d%c%c", i, rnames[cd.rank], *snames[cd.suit]);
  1268.     send_buf(player, buf);
  1269.   }
  1270. }
  1271.  
  1272. /*
  1273.  * Get card to pass from computer player
  1274.  */
  1275. get_pass(from, which_pass, card_to_pass, suit_to_pass)
  1276.      int from, which_pass, *suit_to_pass;
  1277.      ptr *card_to_pass;
  1278. {
  1279.   ptr p1;
  1280.   int each;
  1281.   
  1282.   p1 = highest(from, SPADES);
  1283.   if ((((p1->rank > QUEEN) &&
  1284.     (!find_card(from,QUEEN,SPADES) ||
  1285.      (card_table[from].cards[SPADES].length <= 4))) ||
  1286.        ((p1->rank == QUEEN) &&
  1287.     (card_table[from].cards[SPADES].length <= 4))) &&
  1288.       card_table[from].cards[SPADES].length) {
  1289.     *card_to_pass = p1;
  1290.     *suit_to_pass = SPADES;
  1291.     if (p1->rank == QUEEN) {
  1292.       /* remember who has the QS */
  1293.       for (each=1; each<=PLAYERS; each++) {
  1294.     hasqs[from][each] = FALSE;
  1295.       }
  1296.       hasqs[from][map_player(from, hand)] = TRUE;
  1297.     }
  1298.   } else if (card_table[from].cards[DIAMONDS].length &&
  1299.          !find_card(from,JACK,DIAMONDS) &&
  1300.          (highest(from,DIAMONDS)->rank >= 4) &&
  1301.          (card_table[from].cards[DIAMONDS].length <= NPASS-which_pass+1)) {
  1302.     /* create void in DIAMONDS */
  1303.     *card_to_pass = highest(from, DIAMONDS);
  1304.     *suit_to_pass = DIAMONDS;
  1305.   } else if (card_table[from].cards[CLUBS].length &&
  1306.          (highest(from,CLUBS)->rank >= 4) &&
  1307.          (card_table[from].cards[CLUBS].length <= NPASS-which_pass+1)) {
  1308.     /* create void in CLUBS */
  1309.     *card_to_pass = highest(from, CLUBS);
  1310.     *suit_to_pass = CLUBS;
  1311.   } else if (card_table[from].cards[HEARTS].length &&
  1312.          (highest(from,HEARTS)->rank >= 7) &&
  1313.          (card_table[from].cards[HEARTS].length <= NPASS-which_pass+1)) {
  1314.     /* create void in HEARTS */
  1315.     *card_to_pass = highest(from, HEARTS);
  1316.     *suit_to_pass = HEARTS;
  1317.   } else if (card_table[from].cards[HEARTS].length &&
  1318.          ((card_table[from].cards[HEARTS].length <= 2) ||
  1319.           ((card_table[from].cards[HEARTS].length == 3) &&
  1320.            (highest(from,HEARTS)->rlink->rank > 8))) &&
  1321.          (highest(from,HEARTS)->rank > JACK)) {
  1322.     /* get rid of high HEART */
  1323.     *card_to_pass = highest(from, HEARTS);
  1324.     *suit_to_pass = HEARTS;
  1325.   } else if ((card_table[from].cards[CLUBS].length > 2) &&
  1326.          (lowest(from,CLUBS)->rank >= 8)) {
  1327.     /* get rid of high CLUBS */
  1328.     *card_to_pass = highest(from, CLUBS);
  1329.     *suit_to_pass = CLUBS;
  1330.   } else if ((card_table[from].cards[HEARTS].length > 2) &&
  1331.          (lowest(from,HEARTS)->rank >= 8)) {
  1332.     /* get rid of high HEARTS */
  1333.     *card_to_pass = highest(from, HEARTS);
  1334.     *suit_to_pass = HEARTS;
  1335.   } else if (card_table[from].cards[CLUBS].length &&
  1336.          (highest(from,CLUBS)->rank >= 7) &&
  1337.          (card_table[from].cards[CLUBS].length <= NPASS-which_pass+2)) {
  1338.     /* create almost void in CLUBS */
  1339.     *card_to_pass = find_card(from,1,CLUBS);
  1340.     if (!*card_to_pass)
  1341.       *card_to_pass = highest(from, CLUBS);
  1342.     *suit_to_pass = CLUBS;
  1343.   } else if (card_table[from].cards[HEARTS].length &&
  1344.          (card_table[from].cards[HEARTS].length >= 5) &&
  1345.          (highest(from,HEARTS)->rlink->rank >= 7)) {
  1346.     /* get rid of some HEARTS */
  1347.     if (highest(from, HEARTS)->rank >= JACK)
  1348.       *card_to_pass = highest(from, HEARTS)->rlink;
  1349.     else
  1350.       *card_to_pass = highest(from, HEARTS);
  1351.     *suit_to_pass = HEARTS;
  1352.   } else if (card_table[from].cards[CLUBS].length &&
  1353.          (card_table[from].cards[CLUBS].length >= 5)) {
  1354.     /* get rid of some CLUBS */
  1355.     *card_to_pass = find_card(from,1,CLUBS);
  1356.     if (!*card_to_pass)
  1357.       *card_to_pass = highest(from, CLUBS);
  1358.     *suit_to_pass = CLUBS;
  1359.   } else if (card_table[from].cards[DIAMONDS].length &&
  1360.          !find_card(from,JACK,DIAMONDS) &&
  1361.          (card_table[from].cards[DIAMONDS].length >= 5)) {
  1362.     /* get rid of some DIAMONDS */
  1363.     *card_to_pass = highest(from, DIAMONDS);
  1364.     *suit_to_pass = DIAMONDS;
  1365.   } else if (card_table[from].cards[SPADES].length &&
  1366.          !find_card(from,QUEEN,SPADES) &&
  1367.          (card_table[from].cards[SPADES].length >= 5)) {
  1368.     /* get rid of some SPADES */
  1369.     *card_to_pass = highest(from, SPADES);
  1370.     *suit_to_pass = SPADES;
  1371.   } else if (find_card(from,1,CLUBS)) {
  1372.     *card_to_pass = find_card(from,1,CLUBS);
  1373.     *suit_to_pass = CLUBS;
  1374.   } else {
  1375.     find_high_card(from, card_to_pass, suit_to_pass, FALSE, TRUE, TRUE);
  1376.   }
  1377. }
  1378.  
  1379.  
  1380. /*
  1381.  * Pass card to player
  1382.  */
  1383. pass_to(from, who_to, which_pass, card_to_pass, suit_to_pass)
  1384.      int from, who_to, which_pass;
  1385.      ptr card_to_pass;
  1386.      char suit_to_pass;
  1387. {
  1388.   char buf[BUF_SIZE];
  1389.   
  1390.   card_table[who_to].passed_cards[which_pass].rank = card_to_pass->rank;
  1391.   card_table[who_to].passed_cards[which_pass].suit = suit_to_pass;
  1392.   --card_table[from].cards[suit_to_pass].length;
  1393.   card_table[who_to].passer = from;
  1394.   if (card_table[from].player_kind != COMPUTER) {
  1395.     erase_window(from, INP_WINDOW);
  1396.     (void) sprintf(buf, "P%d%c%c", which_pass,
  1397.            rnames[card_to_pass->rank], *snames[suit_to_pass]);
  1398.     send_buf(from, buf);
  1399.     toss_card(from, card_to_pass, suit_to_pass);
  1400.   }
  1401.   remove_node(card_to_pass);
  1402. }
  1403.  
  1404. player_pass(player)
  1405.      int player;
  1406. {
  1407.   char buf[BUF_SIZE];
  1408.   
  1409.   (void) sprintf(buf, "M%dPass %d to %s:",
  1410.          TEXT_WINDOW, NPASS, get_name(map_player(player, hand)));
  1411.   send_buf(player, buf);
  1412.   (void) sprintf(buf, "M%dCard 1:", LEAD_WINDOW);
  1413.   send_buf(player, buf);
  1414.   send_buf(player, "G");
  1415. }
  1416.  
  1417. pass_cards()
  1418. {
  1419.   int player, pass, suit, old_mask;
  1420.   int passed_mask = 0;
  1421.   ptr p;
  1422.   char buf[BUF_SIZE];
  1423.   
  1424.   human_type = HUMAN;
  1425.   for (player = 1; player <= PLAYERS; player++) {
  1426.     card_table[player].num_passed = 0;
  1427.     if (card_table[player].player_kind == HUMAN)
  1428.       player_pass(player);
  1429.   }
  1430.   while (player_mask != passed_mask) {
  1431.     old_mask = player_mask;
  1432.     if (read_card(player_mask, &player, &p, &suit)) {
  1433.       pass_to(player, map_player(player, hand),
  1434.           ++card_table[player].num_passed, p, suit);
  1435.       if (card_table[player].num_passed == NPASS)
  1436.     /*
  1437.      * Done passing
  1438.      */
  1439.     passed_mask |= 1 << player;
  1440.       else {
  1441.     (void) sprintf(buf, "M%dCard %d:", LEAD_WINDOW,
  1442.                card_table[player].num_passed + 1);
  1443.     /*
  1444.      * Ask for next card
  1445.      */
  1446.     send_buf(player, buf);
  1447.     send_buf(player, "G");
  1448.       }
  1449.     } 
  1450.     else
  1451.       /*
  1452.        * Player left game
  1453.        */
  1454.       passed_mask &= ~(1 << player);
  1455.     /*
  1456.      * Player added?
  1457.      */
  1458.     for (player = 1; player <= PLAYERS; player++)
  1459.       if (~old_mask & player_mask & (1 << player)) {
  1460.     card_table[player].num_passed = 0;
  1461.     player_pass(player);
  1462.       }
  1463.   }
  1464.   erase_all_window(LEAD_WINDOW);
  1465.   human_type = VOYEUR;
  1466.   /*
  1467.    * Let computer pass.
  1468.    */
  1469.   for (player = 1; player <= PLAYERS; player++)
  1470.     if (card_table[player].player_kind != HUMAN)
  1471.       for (pass = ++card_table[player].num_passed;
  1472.        pass <= NPASS; pass++) {
  1473.     get_pass(player, pass, &p, &suit);
  1474.     pass_to(player, map_player(player, hand), pass, p, suit);
  1475.       }
  1476.   for (player = 1; player <= PLAYERS; player++) {
  1477.     for (pass = 1; pass <= NPASS; pass++)
  1478.       enter_card(card_table[player].passed_cards[pass],
  1479.          card_table[player].cards);
  1480.     if (card_table[player].player_kind != COMPUTER)
  1481.       print_pass(player);
  1482.   }
  1483. }
  1484.  
  1485. point_value(rank, suit)
  1486.      int rank, suit;
  1487. {
  1488.   if (suit == HEARTS)
  1489.     return(1);
  1490.   else
  1491.     if ((suit == SPADES) && (rank == QUEEN))
  1492.       return(13);
  1493.     else
  1494.       if ((suit == DIAMONDS) && (rank == JACK) && MIKEYJ)
  1495.     return(-10);
  1496.   return(0);
  1497. }
  1498.  
  1499. show(player, card_to_play, suit_to_play)
  1500.      int player, suit_to_play;
  1501.      ptr card_to_play;
  1502. {
  1503.   int rank_to_play;
  1504.   char buf[BUF_SIZE];
  1505.   
  1506.   rank_to_play = card_to_play->rank;
  1507.   if (card_table[player].player_kind != COMPUTER) {
  1508.     erase_window(player, INP_WINDOW);
  1509.     erase_window(player, LEAD_WINDOW);
  1510.     toss_card(player, card_to_play, suit_to_play);
  1511.   }
  1512.   remove_node(card_to_play);
  1513.   --card_table[player].cards[suit_to_play].length;
  1514.   if (suit_to_play == HEARTS)
  1515.     trick.any_hearts = TRUE;
  1516.   else {
  1517.     if ((suit_to_play == SPADES) && (rank_to_play == QUEEN))
  1518.       queen_played = TRUE;
  1519.     else
  1520.       if ((suit_to_play == DIAMONDS) &&
  1521.       (rank_to_play == JACK) &&
  1522.       MIKEYJ) {
  1523.     jack_played = TRUE;
  1524.     MIKEYJdintrick = TRUE;
  1525.       }
  1526.   }
  1527.   if ((suit_to_play == trick.suit_led) &&
  1528.       (rank_to_play > trick.highest_played)) {
  1529.     trick.highest_played = rank_to_play;
  1530.     trick.high_player = player;
  1531.   }
  1532.   trick.played[player].rank = rank_to_play;
  1533.   trick.played[player].suit = suit_to_play;
  1534.   trick.pts += point_value(rank_to_play, suit_to_play);
  1535.   
  1536.   enter_card(trick.played[player], cards_played);
  1537.   ++trick.card_count;
  1538.   (void) sprintf(buf, "P%d%c%c%s", player, rnames[rank_to_play],
  1539.          *snames[suit_to_play], card_table[player].name);
  1540.   send_to_all(buf);
  1541. }
  1542.  
  1543. really_safe(suit)
  1544.      int suit;
  1545. {
  1546.   char safe;
  1547.   int losers_out, low_rank;
  1548.   
  1549.   low_rank = card_table[leader].cards[suit].tail->llink->rank;
  1550.   /*
  1551.    * Count # cards of _suit_ played that would be losers
  1552.    * to leaders lowest of _suit_.
  1553.    */
  1554.   losers_out = count_losers(low_rank,suit);
  1555.   /*
  1556.    * Card is guaranteed to lose the trick if:
  1557.    * -- All cards of suit lower than low_rank have been played;
  1558.    * -- There is at least one other card of the suit unplayed.
  1559.    *
  1560.    */
  1561.   safe = (losers_out == (low_rank - 1)) &&
  1562.     (card_table[leader].cards[suit].length +
  1563.      cards_played[suit].length != 13);
  1564.   safe &= (find_true(voided[suit]) == FALSE);
  1565.   if (suit == SPADES)
  1566.     safe &= ((card_table[leader].cards[SPADES].tail->llink->rank <
  1567.           QUEEN) || queen_played);
  1568.   return(safe);
  1569. }
  1570.  
  1571. find_low_lead(card_to_play, suit_to_play, play_hearts)
  1572.      ptr *card_to_play;
  1573.      int *suit_to_play;
  1574.      char play_hearts;
  1575. {
  1576.   int pass, low_card, suit, f, last_gasp;
  1577.   ptr p, q;
  1578.   
  1579.   last_gasp = FALSE;
  1580.   *card_to_play = NULL;
  1581.   pass = 0;
  1582.   q = find_card(leader,QUEEN,SPADES);
  1583.   while (*card_to_play == NULL) {
  1584.     pass++;
  1585.     if (pass > 20)
  1586.       last_gasp = TRUE;
  1587.     low_card = MAX_RANK+1;
  1588.     for (suit = CLUBS; suit <= SPADES; suit++) {
  1589.       p = card_table[leader].cards[suit].tail->llink;
  1590.       if ((((p->rank == JACK) && (suit == DIAMONDS) && MIKEYJ) ||
  1591.        ((p->rank == QUEEN) && (suit == SPADES))) &&
  1592.       (card_table[leader].cards[suit].length > 1)) {
  1593.     p = p->llink;
  1594.       }
  1595.       if ((p->rank <= MAX_RANK) &&
  1596.       (p->rank-count_losers(p->rank,suit) < low_card) &&
  1597.       (play_hearts || (suit != HEARTS) || last_gasp)) {
  1598.     f = TRUE;
  1599.     switch(pass) {
  1600.     case 1:
  1601.       f = ((cards_out(suit) == card_table[leader].cards[suit].length+1) &&
  1602.            (!q || (suit != SPADES)) &&
  1603.            (highest_unplayed(suit,leader) > p->rank));
  1604.       break;
  1605.     case 2:
  1606.       f = (lowestp(p->rank, suit) &&
  1607.            (!q || (suit != SPADES)) &&
  1608.            (highest_unplayed(suit,leader) > p->rank));
  1609.       break;
  1610.     case 3:
  1611.       f = ((count_array(voided[suit],TRUE) == 2) &&
  1612.            (!q || (suit != SPADES)) &&
  1613.            (highest_unplayed(suit,leader) > p->rank) &&
  1614.            (lowest_unplayed(suit,leader) > p->rank));
  1615.       break;
  1616.     case 4:
  1617.       f = (safe_suit(suit) &&
  1618.            (!q || (suit != SPADES) ||
  1619.         (card_table[leader].cards[suit].length > 3)) &&
  1620.            (highest_unplayed(suit,leader) > p->rank) &&
  1621.            (count_array(voided[suit],TRUE) < 2) &&
  1622.            !((MIKEYJ && (suit == DIAMONDS) && (p->rank == JACK)) ||
  1623.          ((suit == SPADES) && (p->rank == QUEEN))));
  1624.       break;
  1625.     case 5:
  1626.       f = ((find_true(voided[suit]) == MAYBE) &&
  1627.            (!q || (suit != SPADES) ||
  1628.         (card_table[leader].cards[suit].length > 2)) &&
  1629.            (highest_unplayed(suit,leader) > p->rank) &&
  1630.            (count_array(voided[suit],TRUE) < 2) &&
  1631.            !((MIKEYJ && (suit == DIAMONDS) && (p->rank == JACK)) ||
  1632.          ((suit == SPADES) && (p->rank == QUEEN))));
  1633.       break;
  1634.     case 6:
  1635.       f = ((highest_unplayed(suit,leader) > p->rank) &&
  1636.            (count_array(voided[suit],TRUE) < 2) &&
  1637.            (!q || (suit != SPADES) ||
  1638.         (card_table[leader].cards[suit].length > 2)) &&
  1639.            !((MIKEYJ && (suit == DIAMONDS) && (p->rank == JACK)) ||
  1640.          ((suit == SPADES) && (p->rank == QUEEN))));
  1641.       break;
  1642.     case 7:
  1643.       f = ((highest_unplayed(suit,leader) > p->rank) &&
  1644.            (count_array(voided[suit],TRUE) < 2) &&
  1645.            !((MIKEYJ && (suit == DIAMONDS) && (p->rank == JACK)) ||
  1646.          ((suit == SPADES) && (p->rank == QUEEN))));
  1647.       break;
  1648.     case 8:
  1649.       f = ((highest_unplayed(suit,leader) > p->rank) &&
  1650.            (count_array(voided[suit],TRUE) < 2) &&
  1651.            ((suit != SPADES) || (p->rank != QUEEN)));
  1652.       break;
  1653.     case 9:
  1654.       f = ((highest_unplayed(suit,leader) > p->rank) &&
  1655.            (count_array(voided[suit],TRUE) < 2));
  1656.       break;
  1657.     }
  1658.     if (f) {
  1659.       low_card = p->rank-count_losers(p->rank,suit);
  1660.       *card_to_play = p;
  1661.       *suit_to_play = suit;
  1662.     }
  1663.       }
  1664.     }
  1665.   }
  1666. #ifdef DEBUG
  1667.   fprintf(fp, "%2d ",pass);
  1668. #endif
  1669. }
  1670.  
  1671.  
  1672. show_lead(card_to_play, suit_to_play)
  1673.      int suit_to_play;
  1674.      ptr card_to_play;
  1675. {
  1676.   trick.card_count = 1;
  1677.   trick.highest_played = card_to_play->rank;
  1678.   trick.suit_led = suit_to_play;
  1679.   trick.high_player = leader;
  1680.   show(leader, card_to_play, suit_to_play);
  1681. }
  1682.  
  1683. read_lead(leader, card_to_play, suit_to_play)
  1684.      int leader, *suit_to_play;
  1685.      ptr *card_to_play;
  1686. {
  1687.   char good, alive, buf[64];
  1688.   int t;    /* Ignored */
  1689.   
  1690.   do {
  1691.     send_buf(leader, "G");
  1692.     if (alive = read_card(1 << leader, &t, card_to_play, suit_to_play)) {
  1693.       good = (((round != 1) ||
  1694.            (*card_to_play == card_table[leader].cards[CLUBS].tail->llink)) &&
  1695.           ((*suit_to_play != HEARTS) || hearts_broken || only_hearts(leader)));
  1696.       if (!good) {
  1697.     if (*suit_to_play == HEARTS)
  1698.       (void) sprintf(buf,"M%dHearts not broken yet!", TEXT_WINDOW);
  1699.     else
  1700.       (void) sprintf(buf,"M%dLead your lowest club!", TEXT_WINDOW);
  1701.     send_buf(leader, buf);
  1702.     send_buf(leader, "G");
  1703.       }
  1704.     }
  1705.   } 
  1706.   while (alive && !good);
  1707. }
  1708.  
  1709. read_next_card(player, card_to_play, suit_to_play)
  1710.      int player, *suit_to_play;
  1711.      ptr *card_to_play;
  1712. {
  1713.   char good, good_pts, alive, buf[64];
  1714.   int t;    /* Ignored */
  1715.   
  1716.   do {
  1717.     send_buf(player, "G");
  1718.     if (alive = read_card(1 << player, &t, card_to_play, suit_to_play)) {
  1719.       good_pts = (((*suit_to_play != SPADES) ||
  1720.            ((*card_to_play)->rank != QUEEN))
  1721.           && ((*suit_to_play != HEARTS) || only_hearts(player)) ||
  1722.           (round != 1));
  1723.       good = (((*suit_to_play == trick.suit_led) ||
  1724.            (card_table[player].cards[trick.suit_led].length == 0)) && good_pts);
  1725.       if (!good) {
  1726.     if (!good_pts)
  1727.       (void) sprintf(buf, "M%dCan't dump points yet!", TEXT_WINDOW);
  1728.     else
  1729.       (void) sprintf(buf, "M%dTry following suit!", TEXT_WINDOW);
  1730.     send_buf(player, buf);
  1731.     send_buf(player, "G");
  1732.       }
  1733.     }
  1734.   } 
  1735.   while (alive && !good);
  1736. }
  1737.  
  1738. int
  1739.   num_lower(player, rank, suit_to_play)
  1740. int player, rank, suit_to_play;
  1741. {
  1742.   ptr p;
  1743.   int     mikey;
  1744.   
  1745.   mikey = 0;
  1746.   p = card_table[player].cards[suit_to_play].head->rlink;
  1747.   while (p && p->rank) {
  1748.     if (p->rank < rank)
  1749.       mikey++;
  1750.     p = p->rlink;
  1751.   }
  1752.   return(mikey);
  1753. }
  1754.  
  1755. char flushdiamonds(player)
  1756.      int player;
  1757. {
  1758.   ptr mikey;
  1759.   
  1760.   mikey = find_card(player,JACK,DIAMONDS);
  1761.   if (MIKEYJ && mikey && (mikey->rank == JACK) &&
  1762.       (safe_suit(DIAMONDS) || queen_played) &&
  1763.       (cards_out(DIAMONDS) > PLAYERS) &&
  1764.       ((safe_suit(DIAMONDS) &&
  1765.     (card_table[player].cards[DIAMONDS].length >
  1766.      ((cards_out(DIAMONDS)/PLAYERS)+2))) ||
  1767.        (num_lower(player,JACK,DIAMONDS) >=
  1768.     (cards_out(DIAMONDS) - card_table[player].cards[DIAMONDS].length))))
  1769.     return(TRUE);
  1770.   else
  1771.     return(FALSE);
  1772. }
  1773.  
  1774. char gotthejack(player)
  1775.      int player;
  1776. {
  1777.   ptr p,q;
  1778.   
  1779.   if (card_table[player].cards[DIAMONDS].length > 0)
  1780.     p = card_table[player].cards[DIAMONDS].head->rlink;
  1781.   else
  1782.     p = NULL;
  1783.   if (cards_played[DIAMONDS].length > 0)
  1784.     q = cards_played[DIAMONDS].head->rlink;
  1785.   else
  1786.     q = NULL;
  1787.   
  1788.   if (!((p&&(p->rank == ACE)) || ((q&&(q->rank == ACE)&&
  1789.                    (not_in_trick(ACE,DIAMONDS))))))
  1790.     return(FALSE);
  1791.   if ((p&&(p->rank == ACE)))
  1792.     p = p->rlink;
  1793.   else
  1794.     q = q->rlink;
  1795.   if (!((p&&(p->rank == KING)) || ((q&&(q->rank == KING)&&
  1796.                     (not_in_trick(KING,DIAMONDS))))))
  1797.     return(FALSE);
  1798.   if ((p&&(p->rank == KING)))
  1799.     p = p->rlink;
  1800.   else
  1801.     q = q->rlink;
  1802.   if (!((p&&(p->rank == QUEEN)) || ((q&&(q->rank == QUEEN)&&
  1803.                      (not_in_trick(QUEEN,DIAMONDS))))))
  1804.     return(FALSE);
  1805.   if ((p&&(p->rank == QUEEN)))
  1806.     p = p->rlink;
  1807.   else
  1808.     q = q->rlink;
  1809.   if (p&&(p->rank == JACK))
  1810.     return(TRUE);
  1811.   else
  1812.     return(FALSE);
  1813. }
  1814.  
  1815. computer_lead(card_to_play, suit_to_play)
  1816.      int *suit_to_play;
  1817.      ptr *card_to_play;
  1818. {
  1819.   ptr p;
  1820.   
  1821.   find_queen(leader, &p);
  1822.   if (round == 1) {
  1823.     /* Lead the 2 of clubs */
  1824.     *card_to_play = card_table[leader].cards[CLUBS].tail->llink;
  1825.     *suit_to_play = CLUBS;
  1826.   } else if (MIKEYJ && gotthejack(leader) &&
  1827.          (safe_suit(DIAMONDS) || queen_played)) {
  1828.     *card_to_play = find_card(leader,JACK,DIAMONDS);
  1829.     *suit_to_play = DIAMONDS;
  1830.   } else if (!queen_played && !p && spades_safe(leader) &&
  1831.          next_highest(leader,QUEEN,SPADES) &&
  1832.          (highest(leader,SPADES)->rank < QUEEN)) {
  1833.     /* try and flush the queen out */
  1834.     *suit_to_play = SPADES;
  1835.     *card_to_play = next_highest(leader, QUEEN, SPADES);
  1836.   } else if (flushdiamonds(leader)) {
  1837.     *suit_to_play = DIAMONDS;
  1838.     if (diamonds_safe(leader) || queen_safe(leader)) {
  1839.       *card_to_play = next_highest(leader,JACK,DIAMONDS);
  1840.       if (*card_to_play == NULL)
  1841.     *card_to_play = highest(leader,DIAMONDS);
  1842.     } else {
  1843.       *card_to_play = lowest(leader,DIAMONDS);
  1844.       if ((*card_to_play)->rank == JACK)
  1845.     *card_to_play = highest(leader,DIAMONDS);
  1846.     }
  1847.   } else {
  1848.     find_low_lead(card_to_play, suit_to_play,
  1849.           (hearts_broken || only_hearts(leader)));
  1850.   }
  1851. }
  1852.  
  1853.  
  1854. pick_a_loser(player, card_to_play, suit_to_play)
  1855.      int player, *suit_to_play;
  1856.      ptr *card_to_play;
  1857. {
  1858.   ptr p;
  1859.   
  1860.   if (card_table[player].cards[trick.suit_led].length > 0) {
  1861.     *card_to_play = NULL;
  1862.     *suit_to_play = trick.suit_led;
  1863.     if ((trick.suit_led != SPADES) &&
  1864.     (trick.pts == 0) &&
  1865.     (!MIKEYJ || jack_played || (trick.suit_led != DIAMONDS) ||
  1866.      (((highest(player,DIAMONDS))->rank) < JACK)) &&
  1867.     ((trick.card_count == PLAYERS) ||
  1868.      (round == 1)))
  1869.       /*
  1870.        * Play the highest card of suit led if player is last
  1871.        * and there are no points in current trick.
  1872.        */
  1873.       *card_to_play = effective_highest(player, trick.suit_led);
  1874.     else
  1875.       switch (trick.suit_led) {
  1876.       case SPADES:
  1877.     if ((trick.card_count == PLAYERS) && (trick.pts == 0)) {
  1878.       /*
  1879.        * Play the highest spade.  Don't play queen if
  1880.        * it will win the trick.
  1881.        */
  1882.       *card_to_play = effective_highest(player, SPADES);
  1883.       if (((*card_to_play)->rank == QUEEN) &&
  1884.           (QUEEN > trick.highest_played))
  1885.         *card_to_play = next_highest(player, QUEEN, SPADES);
  1886.     } else {
  1887.       find_queen(player,&p);
  1888.       if (p && (trick.highest_played > QUEEN))
  1889.         *card_to_play = p;
  1890.       else
  1891.         if (!queen_played &&
  1892.         (find_true(hasqs[player]) == FALSE) &&
  1893.         (spades_safe(player) ||
  1894.          ((highest(player, SPADES)->rank > QUEEN) &&
  1895.           (trick.pts < PLAYERS)))) {
  1896.           *card_to_play = effective_highest(player, SPADES);
  1897.           if ((p == NULL) || (p == *card_to_play))
  1898.         *card_to_play =
  1899.           next_highest(player,max(trick.highest_played,QUEEN),SPADES); 
  1900.         }
  1901.     }
  1902.     break;
  1903.     
  1904.       case CLUBS:
  1905.     if (clubs_safe(player) && (trick.pts <= 0))
  1906.       *card_to_play = effective_highest(player, CLUBS);
  1907.     break;
  1908.     
  1909.       case DIAMONDS:
  1910.     if (MIKEYJ && (trick.pts < PLAYERS) && (trick.highest_played < JACK) &&
  1911.         find_card(player,JACK,DIAMONDS) && queen_safe(player) &&
  1912.         ((trick.card_count == PLAYERS) ||
  1913.          (find_false(voided[DIAMONDS]) == TRUE) ||
  1914.          gotthejack(player))) {
  1915.       *card_to_play = find_card(player,JACK,DIAMONDS);
  1916.     } else if (MIKEYJ && (trick.pts < 0)) {
  1917.       /* dump highest diamond if jd in trick */
  1918.       *card_to_play = highest(player,DIAMONDS);
  1919.     } else if (MIKEYJ && !jack_played && diamonds_safe(player)) {
  1920.       *card_to_play = next_highest(player,JACK,DIAMONDS);
  1921.     } else if ((!MIKEYJ || jack_played) && diamonds_safe(player)) {
  1922.       *card_to_play = highest(player,DIAMONDS);
  1923.     } else if (MIKEYJ && !jack_played && (trick.pts == 0)) {
  1924.       *card_to_play = next_highest(player,JACK,DIAMONDS);
  1925.        if ((*card_to_play == NULL) && find_card(player,JACK,DIAMONDS))
  1926.         *card_to_play = highest(player,DIAMONDS);
  1927.     } else if ((next_highest(player, trick.highest_played,
  1928.                  DIAMONDS) == NULL) &&
  1929.            MIKEYJ &&
  1930.            ((trick.card_count == PLAYERS) ||
  1931.             (find_false(voided[DIAMONDS]) == TRUE)) &&
  1932.            find_card(player,JACK,DIAMONDS)) {
  1933.       *card_to_play = find_card(player,JACK,DIAMONDS);
  1934.     } else if ((next_highest(player, trick.highest_played,
  1935.                  DIAMONDS) == NULL) &&
  1936.            (card_table[player].cards[DIAMONDS].length > 1) &&
  1937.            (lowest(player,DIAMONDS)->rank == JACK) &&
  1938.            MIKEYJ) {
  1939.       *card_to_play = lowest(player,DIAMONDS)->llink;
  1940.     }
  1941.     break;
  1942.     
  1943.       case HEARTS:
  1944.     break;
  1945.       }
  1946.     
  1947.     if (*card_to_play == NULL)
  1948.       *card_to_play = next_highest(player, trick.highest_played,
  1949.                    *suit_to_play);
  1950.     
  1951.     if ((*card_to_play == NULL) &&
  1952.     (find_false(voided[*suit_to_play]) == TRUE))
  1953.       *card_to_play = highest(player, *suit_to_play);
  1954.     
  1955.     if (*card_to_play == NULL) {
  1956.       *card_to_play = card_table[player].cards[trick.suit_led].tail->llink;
  1957.       /*
  1958.        * Don't play the Q spades if:
  1959.        *   1. The Queen is your lowest spade and
  1960.        *   2. You have a higher spade.
  1961.        */
  1962.       if (((*card_to_play)->rank == QUEEN) && (trick.suit_led == SPADES) &&
  1963.       (card_table[player].cards[trick.suit_led].length > 1))
  1964.     *card_to_play = card_table[player].cards[trick.suit_led].head->rlink;
  1965.     }
  1966.     if (((*card_to_play)->rank > trick.highest_played) &&
  1967.     (*suit_to_play == trick.suit_led) &&
  1968.     ((*suit_to_play != SPADES) ||
  1969.      ((card_table[player].cards[trick.suit_led].head->rlink)->rank !=
  1970.       QUEEN)) &&
  1971.     ((trick.card_count == PLAYERS) ||
  1972.      (find_false(voided[trick.suit_led]) == TRUE)) &&
  1973.     ((*suit_to_play != DIAMONDS) || !MIKEYJ || jack_played))
  1974.       *card_to_play = card_table[player].cards[trick.suit_led].head->rlink;
  1975.   } else {
  1976.     /* void */
  1977.     if (round != 1) {
  1978.       /*
  1979.        * Play the queen of spades if player has it.
  1980.        */
  1981.       find_queen(player,card_to_play);
  1982.       if (*card_to_play)
  1983.     *suit_to_play = SPADES;
  1984.       if ((*card_to_play == NULL) &&
  1985.       !queen_played &&
  1986.       (card_table[player].cards[SPADES].length) &&
  1987.       ((effective_highest(player,SPADES))->rank > QUEEN)) {
  1988.     *card_to_play = effective_highest(player,SPADES);
  1989.     *suit_to_play = SPADES;
  1990.       }
  1991.       if ((*card_to_play == NULL) &&
  1992.       (card_table[player].cards[HEARTS].length)) {
  1993.     /* MIKEY: does this work? */
  1994.     if (someone_is_shooting &&
  1995.         (mikeyshooter != NONE) &&
  1996.         (mikeyshooter != player)) {
  1997.       if ((trick.high_player != mikeyshooter) &&
  1998.           trick.played[mikeyshooter].suit)
  1999.         *card_to_play = highest(player, HEARTS);
  2000.       else
  2001.         *card_to_play = next_highest(player, JACK, HEARTS);
  2002.       if (*card_to_play == NULL)
  2003.         *card_to_play = effective_lowest(player, HEARTS);
  2004.     } else if ((mikeyshooter != NONE) &&
  2005.            (mikeyshooter != player) &&
  2006.            someone_is_shooting &&
  2007.            (card_table[player].cards[HEARTS].length > 3)) {
  2008.       *card_to_play = highest(player, HEARTS)->rlink;
  2009.     } else {
  2010.       *card_to_play = effective_highest(player, HEARTS);
  2011.     }
  2012.     *suit_to_play = HEARTS;
  2013.       }
  2014.     }
  2015.     if (*card_to_play == NULL)
  2016.       find_high_card(player, card_to_play, suit_to_play,
  2017.              (round != 1),
  2018.              (find_card(player,QUEEN,SPADES) != NULL),
  2019.              (!MIKEYJ || jack_played));
  2020.   }
  2021. }
  2022.  
  2023. stop_the_bastard(player, card_to_play, suit_to_play)
  2024.      int player, *suit_to_play;
  2025.      ptr *card_to_play;
  2026. {
  2027.   if (card_table[player].cards[trick.suit_led].length) {
  2028.     *suit_to_play = trick.suit_led;
  2029.     if ((trick.suit_led == SPADES) && !queen_safe(player)) {
  2030.       *card_to_play = next_highest(player, QUEEN, SPADES);
  2031.       if (*card_to_play == NULL)
  2032.     *card_to_play = effective_lowest(player, SPADES);
  2033.     } 
  2034.     else
  2035.       *card_to_play = effective_highest(player, trick.suit_led);
  2036.     if ((trick.pts < PLAYERS) &&
  2037.     !(((cards_out(trick.suit_led) <
  2038.         (PLAYERS - player_count)) ||
  2039.        trick.any_hearts) &&
  2040.       ((*card_to_play)->rank > trick.highest_played) &&
  2041.       (mikeyshooter == trick.high_player)))
  2042.       *card_to_play = effective_lowest(player, trick.suit_led);
  2043.   } 
  2044.   else
  2045.     if ((mikeyshooter != trick.high_player) &&
  2046.     (mikeyshooter != NONE) &&
  2047.     someone_is_shooting &&
  2048.     (card_table[player].cards[HEARTS].length > 0)) {
  2049.       *card_to_play = effective_highest(player, HEARTS);
  2050.       *suit_to_play = HEARTS;
  2051.     } 
  2052.     else
  2053.       find_low_card(player, card_to_play, suit_to_play);
  2054. }
  2055.  
  2056. computer_pick(player, card_to_play, suit_to_play)
  2057.      int player, *suit_to_play;
  2058.      ptr *card_to_play;
  2059. {
  2060.   *card_to_play = NULL;
  2061.   
  2062.   /* MIKEY: computer too stupid to shoot */
  2063.   if (someone_is_shooting && (player == mikeyshooter))
  2064.     someone_is_shooting = FALSE;
  2065.   
  2066.   if (someone_is_shooting && (player != mikeyshooter))
  2067.     stop_the_bastard(player, card_to_play, suit_to_play);
  2068.   else
  2069.     pick_a_loser(player, card_to_play, suit_to_play);
  2070. }
  2071.  
  2072. lead(leader)
  2073.      int leader;
  2074. {
  2075.   int suit_to_play;
  2076.   ptr card_to_play;
  2077.   char buf[BUF_SIZE];
  2078.   
  2079.   if (card_table[leader].player_kind == HUMAN) {
  2080.     (void) sprintf(buf, "M%dYour lead:", LEAD_WINDOW);
  2081.     send_buf(leader, buf);
  2082.     read_lead(leader, &card_to_play, &suit_to_play);
  2083.   }
  2084.   if (card_table[leader].player_kind != HUMAN)    /* If player left */
  2085.     computer_lead(&card_to_play, &suit_to_play);
  2086.   show_lead(card_to_play, suit_to_play);
  2087. }
  2088.  
  2089. play_next_card(player)
  2090.      int player;
  2091. {
  2092.   int suit_to_play;
  2093.   ptr card_to_play;
  2094.   char buf[BUF_SIZE];
  2095.   
  2096.   if (card_table[player].player_kind == HUMAN) {
  2097.     (void) sprintf(buf, "M%dYour play:", LEAD_WINDOW);
  2098.     send_buf(player, buf);
  2099.     read_next_card(player, &card_to_play, &suit_to_play);
  2100.   }
  2101.   if (card_table[player].player_kind != HUMAN)    /* If player left */
  2102.     computer_pick(player, &card_to_play, &suit_to_play);
  2103.   
  2104.   if (suit_to_play != trick.suit_led) {
  2105.     int each;
  2106.     
  2107.     voided[trick.suit_led][player] = TRUE;
  2108.     if (trick.suit_led == SPADES) {
  2109.       for (each=1; each<=PLAYERS; each++) {
  2110.     hasqs[each][player] = FALSE;
  2111.       }
  2112.     }
  2113.   } else if ((card_to_play->rank >= JACK) && (trick.pts > 0) &&
  2114.          (trick.card_count != PLAYERS)) {
  2115.     voided[suit_to_play][player] = MAYBE;
  2116.   }
  2117.   if ((suit_to_play == trick.suit_led) &&
  2118.       (suit_to_play == DIAMONDS) &&
  2119.       (card_to_play->rank > JACK) &&
  2120.       !jack_played) {
  2121.     voided[DIAMONDS][player] = MAYBE;
  2122.   }
  2123.   
  2124.   if (trick.suit_led == SPADES &&
  2125.       ((suit_to_play != SPADES) ||
  2126.        ((trick.highest_played > QUEEN) &&
  2127.     (card_to_play->rank != QUEEN)))) {
  2128.     int each;
  2129.     
  2130.     for (each=1; each<=PLAYERS; each++) {
  2131.       hasqs[each][player] = FALSE;
  2132.     }
  2133.   }
  2134.   
  2135.   show(player, card_to_play, suit_to_play);
  2136. }
  2137.  
  2138. find_winner(winner)
  2139.      int *winner;
  2140. {
  2141.   char    mikeyshoot;
  2142.   int     maxscore, player, possibly_shooting;
  2143.   
  2144. #ifdef DEBUG
  2145.   for (mikey=1; mikey<=PLAYERS; mikey++) {
  2146.     fprintf(fp, "%c%c  ", rnames[trick.played[mikey].rank],
  2147.         *snames[trick.played[mikey].suit]);
  2148.   }
  2149.   fprintf(fp, "\n %d ", trick.high_player);
  2150. #endif
  2151.   
  2152.   *winner = trick.high_player;
  2153.   if (trick.any_hearts)
  2154.     hearts_broken = TRUE;
  2155.   points_played += trick.pts;
  2156.   card_table[*winner].pts += trick.pts;
  2157.   if (MIKEYJdintrick) {
  2158.     MIKEYJder = *winner;
  2159.     MIKEYJdintrick = FALSE;
  2160.   }
  2161.   if ((trick.pts != 0) && (trick.pts != -10))
  2162.     if ((mikeyshooter == 0) || (mikeyshooter == *winner))
  2163.       mikeyshooter = *winner;
  2164.     else
  2165.       mikeyshooter = NONE;
  2166.   
  2167.   possibly_shooting = ((mikeyshooter != NONE) && (mikeyshooter != 0));
  2168.   if (MIKEYJ && jack_played && !queen_played)
  2169.     someone_is_shooting = (possibly_shooting &&
  2170.                (card_table[*winner].pts >= HEARTS_PANIC-10));
  2171.   else if (!jack_played && queen_played)
  2172.     someone_is_shooting = (possibly_shooting &&
  2173.                (card_table[*winner].pts >= HEARTS_PANIC+13));
  2174.   else
  2175.     someone_is_shooting = (possibly_shooting &&
  2176.                (card_table[*winner].pts >= HEARTS_PANIC));
  2177.   
  2178.   /* or if lead void */
  2179.   trick.card_count = 1;
  2180.   if ((*winner == leader) &&
  2181.       (find_false(voided[trick.suit_led]) == TRUE))
  2182.     someone_is_shooting = possibly_shooting;
  2183.   
  2184.   mikeyshoot = TRUE;
  2185.   maxscore = 0;
  2186.   for (player = 1; player <= PLAYERS; player++) {
  2187.     if ((maxscore != 0) && (card_table[player].pts != 0))
  2188.       mikeyshoot = FALSE;
  2189.     if ((card_table[player].pts != 0) &&
  2190.     (card_table[player].pts != -10) &&
  2191.     (maxscore == 0)) {
  2192.       maxscore = card_table[player].pts;
  2193.     }
  2194.   }
  2195.   someone_is_shooting = someone_is_shooting && mikeyshoot;
  2196. }
  2197.  
  2198.  
  2199. main()
  2200. {
  2201.   int player;
  2202.   int     mikeytemp;
  2203.   
  2204.   init();
  2205.   new_game();
  2206.   
  2207.   if (debug)
  2208.     human_type = VOYEUR;
  2209.   else
  2210. #ifdef DEBUG
  2211.     human_type = VOYEUR;
  2212. #else
  2213.   human_type = HUMAN;
  2214. #endif
  2215.   
  2216.   if (debug)
  2217.     mikeytemp = 100;
  2218.   else
  2219.     mikeytemp = PLAYERS;
  2220.   
  2221.   get_first_player();
  2222.   add_player();
  2223.   
  2224. #ifdef DEBUG
  2225.   fp = fopen("hearts.log", "w");
  2226.   if (fp == NULL) {
  2227.     fprintf(stderr, "Can't open file hearts.log for writing\n");
  2228.     exit(1);
  2229.   }
  2230.   for (mikeytemp=3; mikeytemp<=3; mikeytemp++) {
  2231. #else
  2232.     for (;;) {
  2233. #endif
  2234.       for (hand = 1; hand <= mikeytemp; hand++) {
  2235.     int mikey;
  2236.     
  2237. #ifdef DEBUG
  2238.     fprintf(fp,"\n--- New Hand ---\n      ");
  2239. #endif
  2240.     for(mikey = 1;mikey <= PLAYERS;mikey++) {
  2241.       trick.played[mikey].rank = 0;
  2242.       trick.played[mikey].suit = 0;
  2243.     }
  2244.     round = 0;
  2245.     new_hand();
  2246.     if (hand != PLAYERS)
  2247.       pass_cards();
  2248.     find_low_club(&leader);
  2249.     for (mikey=1; mikey<=PLAYERS; mikey++) {
  2250.       if (find_card(mikey,QUEEN,SPADES)) {
  2251.         int each;
  2252.         
  2253.         for (each=1; each<=PLAYERS; each++) {
  2254.           hasqs[mikey][each] = (each == mikey);
  2255.         }
  2256.       }
  2257.     }
  2258.     for (round = 1; round <= NCARDS; round++) {
  2259.       new_round();
  2260.       lead(leader);
  2261.       for (player_count = 1; player_count <= PLAYERS - 1; player_count++)
  2262.         play_next_card(map_player(leader, player_count));
  2263.       find_winner(&leader);
  2264.       send_all_totals();
  2265.     }
  2266.     send_all_winner();
  2267. #ifndef DEBUG
  2268.     if (!debug)
  2269.       for (player = 1; player <= PLAYERS; player++)
  2270.         if (card_table[player].player_kind == VOYEUR) {
  2271.           card_table[player].player_kind = HUMAN;
  2272.           player_mask |= 1 << player;
  2273.         }
  2274. #endif
  2275.       }
  2276.       send_all_totals();
  2277.       send_final_winner();
  2278.       send_to_all("X");
  2279.       new_game();
  2280.     }
  2281. #ifdef DEBUG
  2282.     fclose(fp);
  2283. #endif
  2284.   }
  2285.