Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

rules.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 *       FILE:   rules.c
00003 *       AUTHOR: Evan H. B
00004 *       DATE:   29-30 April, 1993
00005 *       PURPOSE: Makes sure the game doesn't screw up.
00006 **********************************************************************/
00007 
00008 #include "map.h"
00009 #include "rules.h"
00010 #include "players.h"
00011 #include "random.h"
00012 #include <time.h>       // Shoot your seed into the random number generator
00013 
00014 bool Rules::DetectivesTrapped (void)
00015   {
00016    int counter;
00017    MoveList *steinBrenner;       // YOU got a better name?
00018 
00019    for (counter = 1; counter < NumPlayers; counter++)
00020      {
00021       steinBrenner = GetLegalMoves (*thePlayers [counter]);
00022       if (steinBrenner->Length ()) return False;
00023      }
00024    return True;
00025   }
00026 
00027 int Rules::SpyCaught (void)
00028   {
00029    PosType spyPos, sleuthPos;
00030    int counter;
00031 
00032    spyPos = thePlayers [theSpy] -> GetPosition ();
00033    for (counter = 1; counter < NumPlayers; counter++)
00034      {
00035       sleuthPos = thePlayers [counter] -> GetPosition ();
00036       if (spyPos == sleuthPos) return counter;
00037      }
00038    return False;
00039   }
00040 
00041 PosType Rules::RandomPos (void)
00042   {
00043    static playPosition [MAXPLAYERS];
00044    static int nextPlayer = 0;
00045    int min, max, counter, ok = False;
00046    PosType randPos;
00047 
00048    max = theMap.num_nodes ();
00049    while (!ok)
00050      {
00051       randPos = (Random * max) + 1;
00052       ok = True;
00053       while ((ok) && (counter < nextPlayer))
00054   if (randPos == playPosition [counter++]) ok = False;
00055       if (ok) playPosition [nextPlayer++] = randPos;
00056      }
00057    return randPos;
00058   }
00059 
00060 int Rules::StartingTokens (TokenType identity)
00061   {
00062    switch (identity)
00063      {
00064       case Subway: return NUM_SUBWAY_TOKENS;
00065       case Taxi: return NUM_TAXI_TOKENS;
00066       case Bus: return NUM_BUS_TOKENS;
00067       default : return 0;   // F---ing compiler!!!!!!!!!
00068      }
00069   }
00070 
00071 Move *Rules::CanGo (int taxi, int bus, int subway,
00072         PosType source, PosType dest)
00073   {
00074    Move *nextMove;
00075    int byTaxi, byBus, bySubway;        // We're bullish on the future (buy)
00076    PosType nextNode;
00077 
00078    byBus = theMap.bus (source, dest);   // Can we get there from here?
00079    byTaxi = theMap.taxi (source, dest);
00080    bySubway = theMap.subway (source, dest);
00081 
00082    byBus *= bus;                        // Can we pay for it?
00083    byTaxi *= taxi;                      // Confucius say -
00084    bySubway *= subway;                  // No tokie, no tickee!
00085 
00086    if (! (byBus | byTaxi | bySubway)) return NULL;      // Yer stuck!
00087 
00088    nextMove = new Move;                                 // Hungry hippoes
00089 
00090    if (byBus) nextMove -> Trans |= BusMask;             // Transporstation
00091    if (byTaxi) nextMove -> Trans |= TaxiMask;           // Transcendental
00092    if (bySubway) nextMove -> Trans |= SubwayMask;       // Transitive
00093 
00094    nextMove -> Source = source;
00095    nextMove -> Node = dest;
00096    nextMove -> Next = NULL;
00097    return nextMove;
00098   }
00099 
00100 bool Rules::Occupato (PosType birdsplat)
00101   {
00102    int counter;
00103    PosType windshield;
00104 
00105    for (counter = 1; counter < NumPlayers; counter++)
00106      {
00107       windshield = thePlayers [counter] -> GetPosition ();
00108       if (windshield == birdsplat) return True; // and kill the damned bird!
00109      }
00110    return False;
00111   }
00112 
00113 MoveList *Rules::GetLegalMoves (Player &dude)
00114   {
00115    Move *nextMove;              // These get added into the list
00116    MoveList *congaLine;         // Nuke () works on empty list?
00117    PosType position;            // Where is our frothing fiend?
00118    int busTokens;               // How many taxi tokens this guy has
00119    int taxiTokens;              // Duh, I wonder what she's
00120    int subwayTokens;            // talking about, Norm!
00121    int counter, city, limit;    // Austin City Limits :-)
00122    bool blocked;                // Cannot stack detectives in cities
00123 
00124    congaLine = new MoveList;
00125    position = dude.GetPosition ();
00126    taxiTokens = dude.NumTokens (Taxi);
00127    busTokens = dude.NumTokens (Bus);
00128    subwayTokens = dude.NumTokens (Subway);
00129    limit = theMap.num_connections (position);
00130    for (counter = 0; counter < limit; counter++)
00131      {
00132       city = theMap.connected_to (position, counter);
00133       nextMove = CanGo (taxiTokens, busTokens, subwayTokens, position, city);
00134       blocked = Occupato (city);
00135       if (blocked)                   // Oh, no. We gotta go, me-oh-my-oo.
00136   {
00137    delete nextMove;
00138    nextMove = NULL;
00139   }
00140       if (nextMove) congaLine -> Append (nextMove);
00141      }
00142    return congaLine;
00143   }
00144 
00145 void Rules::UpdateSpyPos (PosType locus)
00146   {
00147    tachymetabolic = theMap.x (locus);
00148    endothermy = theMap.y (locus);
00149   }
00150 
00151 PosType Rules::ShowSpy (void)
00152   {
00153    PosType serve;
00154 
00155    switch (turn)
00156      {
00157       case 2  :
00158       case 7  :
00159       case 12 :
00160       case 17 :
00161       case 22 : serve = thePlayers [theSpy] -> GetPosition ();
00162             UpdateSpyPos (serve);
00163             return serve;     // tennis, anyone?
00164       default: return 0;
00165      }
00166   }
00167 
00168 preyass Rules::GameOver (void)
00169   {
00170    preyass sleuth;
00171 
00172    /* All right. Here's the deal with the return value of this
00173       function. First, it's called "prey ass" because it describes
00174       the game's end. Get it? I tought you would.
00175 
00176       Now, if the spy wins, it returns -1. Why? Because I said so,
00177       that's why! If the game isn't done yet it returns "notYet"
00178       (duh). If a detective wins, it returns his number in the
00179       array (so, if detective 3 wins, it returns 3. It's amazing). */
00180 
00181     if (NoTurnsLeft ()) return spyWins;
00182     if (DetectivesTrapped ()) return spyWins;
00183     return (preyass) SpyCaught ();
00184    }

Generated on Sun Jul 6 23:07:16 2003 for Scotland Yard by doxygen1.2.15