home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xcu16.zip / clients / xhearts / exchange.c < prev    next >
C/C++ Source or Header  |  1991-10-03  |  18KB  |  675 lines

  1. /*
  2.  * Copyright 1991 Cornell University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and its
  5.  * documentation for any purpose and without fee is hereby granted, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Cornell U. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Cornell U. makes no representations about the
  11.  * suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * CORNELL UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16.  * EVENT SHALL CORNELL UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  18.  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  20.  * PERFORMANCE OF THIS SOFTWARE.
  21.  *
  22.  * Author:  Gene W. Dykes, Program of Computer Graphics
  23.  *          580 Theory Center, Cornell University, Ithaca, NY 14853
  24.  *          (607) 255-6713   gwd@graphics.cornell.edu
  25.  */
  26.  
  27.  
  28. #include <stdio.h>
  29. #include <X11/Intrinsic.h>
  30. #include <X11/StringDefs.h>
  31. #include "hearts.h"
  32.  
  33. static Boolean all_players_have_exchanged () ;
  34. static void initialize_not_exchanged () ;
  35. static void get_next_pass_direction () ;
  36. static void exchange_cleanup () ;
  37. static void announce_pass_direction () ;
  38. static void discard_selected () ;
  39. static void undiscard_selected () ;
  40. static void show_received_discard () ;
  41. static void receive_discards () ;
  42. static void get_computer_discards () ;
  43. void confirm_receipt () ;
  44.  
  45. void
  46. exchange ()
  47. {
  48. get_next_pass_direction () ;
  49. if (snap->current_pass == KeepPass)
  50.     return ;
  51.  
  52. announce_pass_direction () ;
  53. initialize_not_exchanged () ;
  54. get_computer_discards () ;
  55.  
  56. for (  ;
  57.     !all_players_have_exchanged () ;
  58.     wait_for_player_events ()
  59.     )
  60.     ;
  61.  
  62. exchange_cleanup () ;
  63. }
  64.  
  65. static void
  66. initialize_not_exchanged ()
  67. {
  68. int i ;
  69.  
  70. for (i=0;  i < N_PLAYERS;  i++)
  71.     {
  72.     game->player[i].exchanged = False ;
  73.     game->player[i].exchange_confirmed = False ;
  74.     game->player[i].discard_confirmed = False ;
  75.     game->player[i].n_chosen = 0 ;
  76.     game->player[i].mode = DiscardMode ;
  77.     }
  78. }
  79.  
  80. static Boolean
  81. all_players_have_exchanged ()
  82. {
  83. int i ;
  84.  
  85. /*
  86.  * First see if there are any new exchanges to be performed
  87.  * For this to happen, a player must have confirmed his discards,
  88.  * the player passing to him must have confirmed his, and
  89.  * the player must not have already exchanged.
  90.  */
  91.  
  92. for (i=0;  i < N_PLAYERS;  i++)
  93.     {
  94.     if (
  95.        !game->player[i].exchanged &&
  96.        game->player[i].discard_confirmed &&
  97.        game->player[game->player[i].pass_from].discard_confirmed
  98.        )
  99.     {
  100.     receive_discards (i) ;
  101.     }
  102.     }
  103.  
  104. for (i=0;  i < N_PLAYERS;  i++)
  105.     {
  106.     if (!game->player[i].exchange_confirmed)
  107.     {
  108.     return False ;
  109.     }
  110.     }
  111.  
  112. return True ;
  113. }
  114.  
  115. static void
  116. receive_discards (player_index)
  117.     int player_index ;
  118. {
  119. int i ;
  120. int passer_index = game->player[player_index].pass_from ;
  121. char text_string[100] ;
  122. /*
  123.  * Need to change the deck pointers,
  124.  * Show the cards in the discard area
  125.  * Ask for confirmation
  126.  */
  127. game->player[player_index].exchanged = True ;
  128. game->player[player_index].n_chosen = 0 ;
  129. game->player[player_index].mode = ConfirmRMode ;
  130.  
  131. for (i=0;  i < N_DISCARDS;  i++)
  132.     {
  133.     int card_number ;
  134.     card_number = pvt_history[player_index].cards_passed[i] ;
  135.  
  136.     /* nobody's if not claimed by others yet */
  137.     if (game->deck[card_number].dealt_to == player_index)
  138.     game->deck[card_number].dealt_to = N_PLAYERS ;
  139.     card_number = pvt_history[passer_index].cards_passed[i] ;
  140.     game->deck[card_number].dealt_to = player_index ;
  141.     show_received_discard(player_index, card_number);
  142.     pvt_history[player_index].cards_received[i] = card_number ;
  143.     }
  144.  
  145. if (game->player[player_index].physiology == HumanPhysiology)
  146.     {
  147.     sprintf (text_string, "Received from\n%s\n(Click to get)",
  148.          game->player[passer_index].name_string) ;
  149.     XcuWlmSetValue (game->x.wlm_id[player_index],
  150.             "XcuCommand", "confirm_receipt", XtNlabel, text_string) ;
  151.     XcuDeckRaiseWidget (game->x.exchange_deck[player_index],
  152.             game->x.exchange_confirm_r[player_index]) ;
  153.     }
  154. else
  155.     {
  156.     long data[1] ;
  157.     data[0] = (long) player_index ;
  158.     confirm_receipt (NULL, data, NULL) ;
  159.     }
  160.  
  161. return ;
  162. }
  163.  
  164. static void
  165. get_next_pass_direction ()
  166. {
  167. int i ;
  168. switch (history->passing_style)
  169.   {
  170.   case LeftRight :
  171.     {
  172.     switch (snap->current_pass)
  173.       {
  174.       case LeftPass    : { snap->current_pass = RightPass ; break ; }
  175.       case InitialPass    :
  176.       case RightPass    : { snap->current_pass = LeftPass ; break ; }
  177.       }
  178.     break ;
  179.     }
  180.   case LeftRightAcross :
  181.     {
  182.     switch (snap->current_pass)
  183.       {
  184.       case LeftPass    : { snap->current_pass = RightPass ; break ; }
  185.       case RightPass    : { snap->current_pass = AcrossPass ; break ; }
  186.       case InitialPass    :
  187.       case AcrossPass    : { snap->current_pass = LeftPass ; break ; }
  188.       }
  189.     break ;
  190.     }
  191.   case LeftRightAcrossKeep :
  192.     {
  193.     switch (snap->current_pass)
  194.       {
  195.       case LeftPass    : { snap->current_pass = RightPass ; break ; }
  196.       case RightPass    : { snap->current_pass = AcrossPass ; break ; }
  197.       case AcrossPass    : { snap->current_pass = KeepPass ; break ; }
  198.       case InitialPass    :
  199.       case KeepPass    : { snap->current_pass = LeftPass ; break ; }
  200.       }
  201.     break ;
  202.     }
  203.   case LeftRightKeep :
  204.     {
  205.     switch (snap->current_pass)
  206.       {
  207.       case LeftPass    : { snap->current_pass = RightPass ; break ; }
  208.       case RightPass    : { snap->current_pass = KeepPass ; break ; }
  209.       case InitialPass    :
  210.       case KeepPass    : { snap->current_pass = LeftPass ; break ; }
  211.       }
  212.     break ;
  213.     }
  214.   }
  215.  
  216. for (i=0;  i < N_PLAYERS;  i++)
  217.     {
  218.     int target ;
  219.     switch (snap->current_pass)
  220.       {
  221.       case LeftPass    : { target = i+1 ; break ; }
  222.       case RightPass    : { target = i-1 ; break ; }
  223.       case AcrossPass    : { target = i+2 ; break ; }
  224.       }
  225.     if (target < 0)
  226.     target = N_PLAYERS - 1 ;
  227.     if (target >= N_PLAYERS)
  228.     target -= N_PLAYERS ;
  229.     game->player[target].pass_from = i ;
  230.     }
  231. return ;
  232. }
  233.  
  234. static void
  235. announce_pass_direction ()
  236. {
  237. int i, j ;
  238. char pass_text[30] ;
  239.  
  240. sprintf (pass_text, "Pass %d cards ", N_DISCARDS) ;
  241. switch (snap->current_pass)
  242.   {
  243.   case LeftPass : { strcat (pass_text, "left") ; break ; }
  244.   case RightPass : { strcat (pass_text, "right") ; break ; }
  245.   case AcrossPass : { strcat (pass_text, "across") ; break ; }
  246.   }
  247.  
  248. for (i=0;  i < N_PLAYERS;  i++)
  249.     {
  250.     if (game->player[i].physiology == ComputerPhysiology)
  251.     continue ;
  252.     proc_message (pass_text, i) ;
  253.     for (j=0;  j < N_DISCARDS;  j++)
  254.     {
  255.     XcuDeckRaiseWidget(game->x.discard_bitmap[i][j],
  256.                game->x.discard_suit[i][j][N_SUITS]);
  257.     }
  258.     XcuDeckRaiseWidget (game->x.table_deck[i], game->x.exchange_tbl[i]) ;
  259.     XcuDeckRaiseWidget (game->x.exchange_deck[i], game->x.exchange_discard[i]) ;
  260.     }
  261. return ;
  262. }
  263.  
  264. static void
  265. exchange_cleanup ()
  266. {
  267. }
  268.  
  269. /*
  270.  * client_data[0] : player number
  271.  * client_data[1] : suit number
  272.  * client_data[2] : rank number
  273.  */
  274.  
  275. void
  276. card_picked (card, client_data, call_data)
  277.     Widget card ;
  278.     XPointer client_data ;
  279.     XPointer call_data ;
  280. {
  281. long *data = (long *) client_data ;
  282. int i_player = (int) data[0] ;
  283. Player *player = &game->player[i_player] ;
  284.  
  285. /* For debugging */
  286. if (logerr) fprintf (logerr, "card_picked (%d)\n", i_player) ;
  287. if (logerr) fflush (logerr) ;
  288. show_card (i_player, data[1], data[2]) ;
  289.  
  290. switch (game->player[i_player].mode)
  291.   {
  292.   case DiscardMode :
  293.     {
  294.     discard_selected (data) ;
  295.     break ;
  296.     }
  297.   case PlayMode :
  298.     {
  299.     play_selected (data) ;
  300.     break ;
  301.     }
  302.   case ConfirmDMode :
  303.     {
  304.     err_message ("You must unselect one!", i_player) ;
  305.     player->error_mode = ClearOnLegalDiscard ;
  306.     break ;
  307.     }
  308.   case ConfirmRMode :
  309.     {
  310.     err_message ("You must acknowledge receipt!", i_player) ;
  311.     player->error_mode = ClearOnReceipt ;
  312.     break ;
  313.     }
  314.   case NullMode :
  315.     {
  316.     err_message ("Patience, Patience!", i_player) ;
  317.     player->error_mode = ClearOnLegalPlay ;
  318.     break ;
  319.     }
  320.   }
  321.  
  322. refresh_screens () ;
  323.  
  324. return ;
  325. }
  326.  
  327. static void
  328. show_received_discard (player_index, card_number)
  329.     int player_index ;
  330.     int card_number ;
  331. {
  332. Player *player = &game->player[player_index] ;
  333. int deck_suit_index = info->deck[card_number].suit ;
  334. int deck_rank_index = info->deck[card_number].rank ;
  335. Arg args[2] ;
  336.  
  337. /*
  338.  * Display the card in the discard region
  339.  */
  340.  
  341. if (game->player[player_index].physiology == HumanPhysiology)
  342.     {
  343.     char discard_string[20] ;
  344.     sprintf (discard_string, "discard%d", player->n_chosen) ;
  345. /***
  346. fprintf(stderr, "show_received_discard (%d) (%d) [%d] [%d]\n",
  347. player_index, card_number, deck_suit_index, deck_rank_index);
  348. fprintf(stderr, "%d (%s)\n", player->n_chosen, discard_string) ;
  349. fprintf(stderr, "%d (%s) (%s)\n", game->x.wlm_id[player_index],
  350. game->suit[deck_suit_index].color_string,
  351. game->suit[deck_suit_index].rank[deck_rank_index].symbol) ;
  352. ***/
  353.     XcuWlmSetValue (game->x.wlm_id[player_index],
  354.         "XcuCommand", discard_string,
  355.         XtNforeground, game->suit[deck_suit_index].color_string) ;
  356.     XcuWlmSetValue (game->x.wlm_id[player_index],
  357.         "XcuCommand", discard_string, XtNlabel,
  358.         game->suit[deck_suit_index].rank[deck_rank_index].symbol) ;
  359.     XcuDeckRaiseWidget(game->x.discard_bitmap[player_index][player->n_chosen],
  360.        game->x.discard_suit[player_index][player->n_chosen][deck_suit_index]);
  361.     }
  362.  
  363. player->n_chosen++ ;
  364.  
  365. return ;
  366. }
  367.  
  368. static void
  369. discard_selected (data)
  370.     long *data ;
  371. {
  372. int player_index = (int) data[0] ;
  373. int suit_index = (int) data[1] ;
  374. int rank_index = (int) data[2] ;
  375. Player *player = &game->player[player_index] ;
  376. int card_number = pvt_history[player_index].suit[suit_index][rank_index] ;
  377. int deck_suit_index = info->deck[card_number].suit ;
  378. int deck_rank_index = info->deck[card_number].rank ;
  379. Arg args[2] ;
  380.  
  381. /*
  382.  * First, display the card in the discard region
  383.  */
  384.  
  385. if (rank_index >= pvt_history[player_index].n_in_suit[suit_index])
  386.     {
  387.     err_message ("Fumble fingers!", player_index) ;
  388.     player->error_mode = ClearOnLegalDiscard ;
  389.     return ;
  390.     }
  391.  
  392. if (player->error_mode == ClearOnLegalDiscard)
  393.     {
  394.     err_message (" ", player_index) ;
  395.     player->error_mode = NullClear ;
  396.     }
  397.  
  398. pvt_history[player_index].cards_passed[player->n_chosen] = card_number ;
  399. if (game->player[player_index].physiology == HumanPhysiology)
  400.     {
  401.     char name_string[20] ;
  402.     sprintf (name_string, "discard%d", player->n_chosen) ;
  403.     XcuWlmSetValue (game->x.wlm_id[player_index],
  404.         "XcuCommand", name_string, XtNforeground,
  405.         game->suit[deck_suit_index].color_string) ;
  406.     XcuWlmSetValue (game->x.wlm_id[player_index],
  407.         "XcuCommand", name_string, XtNlabel,
  408.         game->suit[deck_suit_index].rank[deck_rank_index].symbol) ;
  409.     XcuDeckRaiseWidget(game->x.discard_bitmap[player_index][player->n_chosen],
  410.        game->x.discard_suit[player_index][player->n_chosen][0]);
  411.     XSync (XtDisplay(game->x.wlm_id[player_index]), False) ;
  412.     XcuDeckRaiseWidget(game->x.discard_bitmap[player_index][player->n_chosen],
  413.        game->x.discard_suit[player_index][player->n_chosen][1]);
  414.     XSync (XtDisplay(game->x.wlm_id[player_index]), False) ;
  415.     XcuDeckRaiseWidget(game->x.discard_bitmap[player_index][player->n_chosen],
  416.        game->x.discard_suit[player_index][player->n_chosen][2]);
  417.     XSync (XtDisplay(game->x.wlm_id[player_index]), False) ;
  418.     XcuDeckRaiseWidget(game->x.discard_bitmap[player_index][player->n_chosen],
  419.        game->x.discard_suit[player_index][player->n_chosen][deck_suit_index]);
  420.     }
  421.  
  422. /*
  423.  * Now, remove the card from the hand
  424.  * Collapse the labels left in the row and blank out the last one
  425.  */
  426.  
  427. if (game->player[player_index].physiology == HumanPhysiology)
  428.     {
  429.     XtSetArg (args[0], XtNlabel, " ") ;
  430.     XtSetValues (game->x.hands[player_index][suit_index]
  431.           [pvt_history[player_index].n_in_suit[suit_index]-1], args, 1) ;
  432.     }
  433.  
  434. player->n_chosen++ ;
  435. pvt_history[player_index].n_in_suit[suit_index]-- ;
  436. order_hand (player_index) ;
  437. show_deal (player_index) ;
  438.  
  439. /*
  440.  * Finally, see if this is the last discard to be selected
  441.  */
  442.  
  443. if (player->n_chosen == N_DISCARDS)
  444.     {
  445.     player->mode = ConfirmDMode ;
  446.     if (game->player[player_index].physiology == HumanPhysiology)
  447.     {
  448.     XcuDeckRaiseWidget (game->x.exchange_deck[player_index],
  449.                 game->x.exchange_confirm_d[player_index]) ;
  450.     }
  451.     }
  452. return ;
  453. }
  454.  
  455. static void
  456. undiscard_selected (data)
  457.     long *data ;
  458. {
  459. int i ;
  460. int player_index = (int) data[0] ;
  461. int discard_number = (int) data[1] ;
  462. Player *player = &game->player[player_index] ;
  463. int card_number = pvt_history[player_index].cards_passed[discard_number] ;
  464. int deck_suit_index = info->deck[card_number].suit ;
  465. int deck_rank_index = info->deck[card_number].rank ;
  466. Arg args[2] ;
  467.  
  468. /*
  469.  * First, undisplay the last card in the discard region
  470.  */
  471.  
  472. if (discard_number >= player->n_chosen)
  473.     {
  474.     err_message ("Fumble fingers!", player_index) ;
  475.     player->error_mode = ClearOnLegalDiscard ;
  476.     return ;
  477.     }
  478.  
  479. if (player->error_mode == ClearOnLegalDiscard)
  480.     {
  481.     err_message (" ", player_index) ;
  482.     player->error_mode = NullClear ;
  483.     }
  484.  
  485. if (game->player[player_index].physiology == HumanPhysiology)
  486.     {
  487. #ifndef NO_LOGGING
  488. if (logerr) fprintf(logerr,"XtSetValues : undiscard_selected(%d,%d)\n",
  489. player_index, player->n_chosen-1) ;
  490. #endif
  491.     XtSetArg (args[0], XtNlabel, " ") ;
  492.     XtSetValues (game->x.discards[player_index][player->n_chosen - 1], args, 1);
  493.     XcuDeckRaiseWidget(game->x.discard_bitmap[player_index][player->n_chosen-1],
  494.        game->x.discard_suit[player_index][player->n_chosen-1][N_SUITS]);
  495.     }
  496.  
  497. /*
  498.  * Collapse left
  499.  */
  500.  
  501. player->n_chosen-- ;
  502. for (i=discard_number;  i < player->n_chosen;  i++)
  503.     {
  504.     int suit_index ;
  505.     int rank_index ;
  506.     pvt_history[player_index].cards_passed[i] =
  507.     pvt_history[player_index].cards_passed[i+1] ;
  508.     suit_index = info->deck[pvt_history[player_index].cards_passed[i]].suit ;
  509.     rank_index = info->deck[pvt_history[player_index].cards_passed[i]].rank ;
  510.  
  511.     if (game->player[player_index].physiology == HumanPhysiology)
  512.     {
  513.     XtSetArg (args[0],  XtNforeground,
  514.                 game->suit[suit_index].color[player_index]) ;
  515.     XtSetArg (args[1], XtNlabel,
  516.                game->suit[suit_index].rank[rank_index].symbol) ;
  517. #ifndef NO_LOGGING
  518. if (logerr)fprintf(logerr,"XtSetValues :   undiscard_selected(%d,%d) [%d:%d]\n",
  519. player_index, i, suit_index, game->suit[suit_index].color[player_index]) ;
  520. #endif
  521.     XtSetValues (game->x.discards[player_index][i], args, 2) ;
  522.     XcuDeckRaiseWidget(game->x.discard_bitmap[player_index][i],
  523.        game->x.discard_suit[player_index][i][suit_index]);
  524.     }
  525.     }
  526.  
  527. /*
  528.  * Now, add the card back into the hand
  529.  */
  530.  
  531. pvt_history[player_index].n_in_suit[deck_suit_index]++ ;
  532. order_hand (player_index) ;
  533. show_deal (player_index) ;
  534.  
  535. if (player->mode == ConfirmDMode)
  536.     {
  537.     player->mode = DiscardMode ;
  538.     if (game->player[player_index].physiology == HumanPhysiology)
  539.     {
  540.     XcuDeckRaiseWidget (game->x.exchange_deck[player_index],
  541.                 game->x.exchange_discard[player_index]) ;
  542.     }
  543.     }
  544. return ;
  545. }
  546.  
  547. /*
  548.     if (!game->player[i].exchanged)
  549.  * client_data[0] : game pointer
  550.  * client_data[1] : player number
  551.  * client_data[2] : discard number
  552.  */
  553.  
  554. void
  555. discard_picked (card, client_data, call_data)
  556.     Widget card ;
  557.     XPointer client_data ;
  558.     XPointer call_data ;
  559. {
  560. long *data = (long *) client_data ;
  561. int i_player = (int) data[0] ;
  562. int discard_number = (int) data[1] ;
  563. Player *player = &game->player[i_player] ;
  564.  
  565. #ifndef NO_LOGGING
  566. if (logerr)fprintf (logerr, "Discard Picked (%d)\n", discard_number) ;
  567. #endif
  568.  
  569. switch (game->player[i_player].mode)
  570.   {
  571.   case ConfirmDMode :
  572.   case DiscardMode :
  573.     {
  574.     undiscard_selected (data) ;
  575.     break ;
  576.     }
  577.   case ConfirmRMode :
  578.     {
  579.     err_message ("You must acknowledge receipt!", i_player) ;
  580.     player->error_mode = ClearOnReceipt ;
  581.     break ;
  582.     }
  583.   case NullMode :
  584.     {
  585.     err_message ("Patience, Patience!", i_player) ;
  586.     player->error_mode = ClearOnLegalPlay ;
  587.     break ;
  588.     }
  589.   }
  590. return ;
  591. }
  592.  
  593. /*
  594.  * client_data[0] : game pointer
  595.  * client_data[1] : player number
  596.  */
  597.  
  598. void
  599. confirm_discard (card, client_data, call_data)
  600.     Widget card ;
  601.     XPointer client_data ;
  602.     XPointer call_data ;
  603. {
  604. long *data = (long *) client_data ;
  605. int player_index = (int) data[0] ;
  606. int passer_index = game->player[player_index].pass_from ;
  607. char text_string[100] ;
  608.  
  609. game->player[player_index].mode = NullMode ;
  610. game->player[player_index].discard_confirmed = True ;
  611.  
  612. proc_message (" ", player_index) ;
  613.  
  614. if (!game->player[passer_index].discard_confirmed)
  615.     {
  616.     if (game->player[player_index].physiology == HumanPhysiology)
  617.     {
  618.     sprintf (text_string, "Waiting for\n%s's\ndiscards",
  619.          game->player[passer_index].name_string) ;
  620.     XcuWlmSetValue (game->x.wlm_id[player_index],
  621.             "XcuLabel", "waiting", XtNlabel, text_string) ;
  622.  
  623.     XcuDeckRaiseWidget (game->x.exchange_deck[player_index],
  624.                 game->x.exchange_waiting[player_index]) ;
  625.     }
  626.     }
  627. return ;
  628. }
  629.  
  630. void
  631. confirm_receipt (card, client_data, call_data)
  632.     Widget card ;
  633.     XPointer client_data ;
  634.     XPointer call_data ;
  635. {
  636. long *data = (long *) client_data ;
  637. int player_index = (int) data[0] ;
  638. Player *player = &game->player[player_index] ;
  639.  
  640. if (player->error_mode == ClearOnReceipt)
  641.     {
  642.     err_message (" ", player_index) ;
  643.     player->error_mode = NullClear ;
  644.     }
  645.  
  646. player->mode = NullMode ;
  647. player->n_chosen = 0 ;
  648. order_hand (player_index) ;
  649. show_deal (player_index) ;
  650. player->exchange_confirmed = True ;
  651. if (game->player[player_index].physiology == HumanPhysiology)
  652.     {
  653.     XcuDeckRaiseWidget (game->x.table_deck[player_index],
  654.             game->x.play_tbl[player_index]) ;
  655.     }
  656. return ;
  657. }
  658.  
  659. static void
  660. get_computer_discards ()
  661. {
  662. int i ;
  663.  
  664. for (i=0;  i < N_PLAYERS;  i++)
  665.     {
  666.     if (game->player[i].physiology == ComputerPhysiology)
  667.     {
  668.     (*game->player[i].discard_program)(&pvt_history[i], i) ;
  669.         game->player[i].discard_confirmed = True ;
  670.     }
  671.     }
  672. return ;
  673. }
  674.  
  675.