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