home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / game / think / chaos / src / pairingsami.c < prev    next >
C/C++ Source or Header  |  1994-11-19  |  16KB  |  555 lines

  1. /*  Chaos:            The Chess HAppening Organisation System    V5.3
  2.     Copyright (C)   1993    Jochen Wiedmann
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.  
  19.     $RCSfile: PairingsAmi.c,v $
  20.     $Revision: 3.2 $
  21.     $Date: 1994/11/19 19:32:01 $
  22.  
  23.     This file contains functions that allow to set games by the
  24.     administrator. This is highly system dependent.
  25.  
  26.     Computer:    Amiga 1200            Compiler:    Dice 2.07.54 (3.0)
  27.  
  28.     Author:    Jochen Wiedmann
  29.         Am Eisteich 9
  30.       72555 Metzingen
  31.         Tel. 07123 / 14881
  32.         Internet: wiedmann@mailserv.zdv.uni-tuebingen.de
  33. */
  34.  
  35.  
  36.  
  37. /*
  38.     The function GetSettings() should offer the user a list of players
  39.     and a list of games. Withdrawn players (which are indicated by the flag
  40.     TNFLAGSF_WITHDRAWN in their Flags field) should not appear. Players may
  41.     be included into the list of games by selecting them, so a game is set
  42.     by selecting the two opponents. If the number of selected players is odd,
  43.     the last player should get a point for free. (Of course this should be
  44.     rejected, if the number of players is odd!) Note, that selecting the
  45.     players doesn't mean deciding the colors. Chaos will select the colors
  46.     even for the set games, which allows to make the best choice.
  47.  
  48.     Inputs: user - TRUE, if the user should be allowed to set games
  49.  
  50.     Result: The number of games, that have been set. (Giving a point for
  51.         free to a player doesn't mean to set up a game, so if the user
  52.         has selected 5 players, the result will be 2.) -1 indicates, that
  53.         the user has cancelled.
  54.         The function has to indicate the selection by setting up the
  55.         Opponents field of the selected players or setting
  56.         GMFLAGSF_NOFIGHT in the GFlags field for the player who has got
  57.         a point for free.
  58.         The function is guaranteed, that all players Opponent fields are
  59.         initialized to NULL and the GFlags fiels is initialized with 0,
  60.         when the function is called. If you need flags, to mark special
  61.         players within the function, use TNFLAGSF_NOTDOWN.
  62.  
  63.     Note: I don't see a possibility to arrange this in a portable way. So
  64.       this is only ONE function. (But this allows me to use ALL the
  65.       advantages of MUI for the first time... :-)
  66. */
  67.  
  68.  
  69. #ifndef CHAOS_H
  70. #include "chaos.h"
  71. #endif
  72.  
  73.  
  74.  
  75.  
  76. #ifdef AMIGA
  77. /*
  78.     The set games are stored dynamically.
  79. */
  80. struct SetGame
  81. { struct MinNode node;
  82.   struct Player *plr1, *plr2;
  83.   char *gamestr;
  84.   int colors;
  85. };
  86. struct MinList *SetGames = NULL;
  87. static void *GmMem = NULL;
  88.  
  89.  
  90.  
  91.  
  92. /*
  93.     InitSetGames() initializes an empty list of games
  94.  
  95.     Result: TRUE, if successfull, FALSE otherwise
  96. */
  97. int InitSetGames(void)
  98.  
  99. { PutMemList (&GmMem);
  100.   if (!(SetGames = GetMem(&GmMem, sizeof(*SetGames))))
  101.   { return(FALSE);
  102.   }
  103.   NewList((struct List *) SetGames);
  104.   return(TRUE);
  105. }
  106.  
  107.  
  108.  
  109.  
  110. /*
  111.     SetPlayer adds one player to the list of set players
  112.  
  113.     Inputs: plr    - the player to be added
  114.         colors - TRUE, if the user wants to determine the colors, FALSE
  115.              otherwise
  116.         force  - FALSE, if the user should be asked for confirmation
  117.              in case both players had the same color in the last
  118.              two rounds, TRUE otherwise
  119.  
  120.     Result: TRUE, if successfull, FALSE otherwise
  121. */
  122. int SetPlayer(struct Player *plr, int force, int colors)
  123.  
  124. { struct SetGame *sg;
  125.   struct Game *gm;
  126.   int i;
  127.  
  128.   if (!SetGames  &&  !InitSetGames())
  129.   { return(FALSE);
  130.   }
  131.  
  132.   if (plr->Flags & TNFLAGSF_WITHDRAWN)
  133.   { ShowError((char *) GetChaosString(MSG_PLAYER_WITHDRAWN), plr->Name);
  134.     return(FALSE);
  135.   }
  136.   for (sg = (struct SetGame *) SetGames->mlh_Head;
  137.        sg->node.mln_Succ != NULL;
  138.        sg = (struct SetGame *) sg->node.mln_Succ)
  139.   { if (sg->plr1 == plr  ||  sg->plr2 == plr)
  140.     { ShowError((char *) GetChaosString(MSG_INVALID_PLAYER), plr->Name,
  141.         plr->Opponent->Name);
  142.       return(FALSE);
  143.     }
  144.   }
  145.  
  146.   /*
  147.       Check for valid game
  148.   */
  149.   sg = (struct SetGame *) SetGames->mlh_TailPred;
  150.   if (sg->node.mln_Pred != NULL  &&  sg->plr2 == NULL)
  151.   { for (i = 1, gm = plr->First_Game;  gm != NULL;
  152.      i++, gm = gm->Next)
  153.     { if (gm->Opponent == sg->plr1)
  154.       { ShowError((char *) GetChaosString(MSG_INVALID_GAME),
  155.           sg->plr1->Name, plr->Name, i);
  156.     return(FALSE);
  157.       }
  158.     }
  159.  
  160.     if ((i = sg->plr1->HowMuchWhiteLast) == plr->HowMuchWhiteLast  &&
  161.     (i >= 2  ||  i <= -2))
  162.     { if (!force  &&
  163.       !AskContinue((char *) GetChaosString(MSG_INVALID_COLORS),
  164.                sg->plr1->Name, plr->Name,
  165.                (i == 2) ? GetChaosString(MSG_WHITE_OUTPUT) :
  166.                   GetChaosString(MSG_BLACK_OUTPUT)))
  167.       { return(FALSE);
  168.       }
  169.     }
  170.     else if (i >= 2  &&  colors)
  171.     { if (!force  &&
  172.       !AskContinue((char *) GetChaosString(MSG_INVALID_COLOR),
  173.                sg->plr1->Name, GetChaosString(MSG_WHITE_OUTPUT)))
  174.       { return(FALSE);
  175.       }
  176.     }
  177.     else if (plr->HowMuchWhiteLast <= -2  &&  colors)
  178.     { if (!force  &&
  179.       !AskContinue((char *) GetChaosString(MSG_INVALID_COLOR),
  180.                plr->Name, GetChaosString(MSG_BLACK_OUTPUT)))
  181.       { return(FALSE);
  182.       }
  183.     }
  184.     sg->plr2 = plr;
  185.     sg->colors = colors;
  186.   }
  187.   else
  188.   { if (!(sg = GetMem(&GmMem, sizeof(*sg))))
  189.     { return(FALSE);
  190.     }
  191.     sg->plr1 = plr;
  192.     AddTail((struct List *) SetGames, (struct Node *) sg);
  193.   }
  194.   return(TRUE);
  195. }
  196.  
  197.  
  198.  
  199.  
  200. /*
  201.     The DoSetGames() function processes the list of set games and initializes
  202.     the players Opponent and GFlags fields.
  203.  
  204.     Result: Number of set games or -1, if an error occurred
  205. */
  206. static int DoSetGames(void)
  207.  
  208. { struct SetGame *sg;
  209.   int numplayers;
  210.   int result;
  211.  
  212.   struct Player *plr;
  213.  
  214.   if (SetGames == NULL)
  215.   { return(0);
  216.   }
  217.  
  218.   /*
  219.       Count the number of active players to see, if a one point bye is
  220.       needed.
  221.   */
  222.   for (numplayers = 0,  plr = (struct Player *) PlayerList.lh_Head;
  223.        plr->Tn_Node.ln_Succ != NULL;
  224.        plr = (struct Player *) plr->Tn_Node.ln_Succ)
  225.   { if (!(plr->Flags & TNFLAGSF_WITHDRAWN))
  226.     { numplayers++;
  227.     }
  228.   }
  229.  
  230.   /*
  231.       Check for invalid one point bye
  232.   */
  233.   sg = (struct SetGame *) SetGames->mlh_TailPred;
  234.   if (sg->node.mln_Pred != NULL  &&  sg->plr2 == NULL)
  235.   { if ((numplayers % 2)  ==  0)
  236.     { ShowError((char *) GetChaosString(MSG_INVALID_ONEPOINTBYE));
  237.       return(-1);
  238.     }
  239.     if (sg->plr1->Flags & TNFLAGSF_HADFREE)
  240.     { ShowError((char *) GetChaosString(MSG_HAD_ONEPOINTBYE),
  241.         sg->plr1->Name);
  242.       return(-1);
  243.     }
  244.   }
  245.  
  246.   for (result = 0, sg = (struct SetGame *) SetGames->mlh_Head;
  247.        sg->node.mln_Succ != NULL;
  248.        sg = (struct SetGame *) sg->node.mln_Succ)
  249.   { if (sg->plr2 == NULL)
  250.     { sg->plr1->GFlags = GMFLAGSF_NOFIGHT;
  251.     }
  252.     else
  253.     { sg->plr1->Opponent = sg->plr2;
  254.       sg->plr2->Opponent = sg->plr1;
  255.       sg->plr1->BoardNr = sg->plr2->BoardNr = result++;
  256.       if (sg->colors)
  257.       { sg->plr1->GFlags = GMFLAGSF_WHITE;
  258.       }
  259.     }
  260.   }
  261.   return(result);
  262. }
  263.  
  264.  
  265.  
  266.  
  267. /*
  268.     The following function is automagically called from MUI, if a game will
  269.     be displayed. (It's the game list's displayhook.)
  270. */
  271. SAVEDS ASM static LONG DispGameFunc(REG(a1) struct SetGame *setgame,
  272.                     REG(a2) char **array)
  273.  
  274. { *(array++) = setgame->plr1->Name;
  275.   *(array++) = setgame->plr2  ?  ":"  :  "";
  276.   *(array++) = setgame->plr2  ?   setgame->plr2->Name :
  277.                   (char *) GetChaosString(MSG_FREE_POINT_OUTPUT);
  278.   *array = (setgame->plr2 && setgame->colors)  ?
  279.             (char *) GetChaosString(MSG_COLORS_SET)  :  "";
  280.   return(0);
  281. }
  282. #ifdef AZTEC_C
  283. extern LONG MyDispGameFunc(struct SetGame *, char **);
  284. #asm
  285.             xref    _geta4
  286. _MyDispGameFunc:    move.l  a4,-(sp)
  287.             jsr     _geta4
  288.             move.l  a2,-(sp)
  289.             move.l  a1,-(sp)
  290.             jsr     _DispGameFunc
  291.