00001
00002
00003
00004
00005
00006
00007
00008 #include "map.h"
00009 #include "rules.h"
00010 #include "players.h"
00011 #include "random.h"
00012 #include <time.h>
00013
00014 bool Rules::DetectivesTrapped (void)
00015 {
00016 int counter;
00017 MoveList *steinBrenner;
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;
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;
00076 PosType nextNode;
00077
00078 byBus = theMap.bus (source, dest);
00079 byTaxi = theMap.taxi (source, dest);
00080 bySubway = theMap.subway (source, dest);
00081
00082 byBus *= bus;
00083 byTaxi *= taxi;
00084 bySubway *= subway;
00085
00086 if (! (byBus | byTaxi | bySubway)) return NULL;
00087
00088 nextMove = new Move;
00089
00090 if (byBus) nextMove -> Trans |= BusMask;
00091 if (byTaxi) nextMove -> Trans |= TaxiMask;
00092 if (bySubway) nextMove -> Trans |= SubwayMask;
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;
00109 }
00110 return False;
00111 }
00112
00113 MoveList *Rules::GetLegalMoves (Player &dude)
00114 {
00115 Move *nextMove;
00116 MoveList *congaLine;
00117 PosType position;
00118 int busTokens;
00119 int taxiTokens;
00120 int subwayTokens;
00121 int counter, city, limit;
00122 bool blocked;
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)
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;
00164 default: return 0;
00165 }
00166 }
00167
00168 preyass Rules::GameOver (void)
00169 {
00170 preyass sleuth;
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 if (NoTurnsLeft ()) return spyWins;
00182 if (DetectivesTrapped ()) return spyWins;
00183 return (preyass) SpyCaught ();
00184 }