Allow mamer addtotourney to do late-joins
authorH.G. Muller <h.g.muller@hccnet.nl>
Mon, 25 Feb 2013 19:36:13 +0000 (20:36 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Mon, 25 Feb 2013 21:38:45 +0000 (22:38 +0100)
The score parameter of AddPlayer is now used to  indicate it was invoked
by addtotourney rather than join (info passed in pendingList through the
Player.floatValue field), as in the existing code it was only called with
score = 0. anyway. When invoked from addtotourney, the command is also
allowed in 'closed' tourneys. In this case it would not only add the player,
but also clear its color counts and give it a 0 result against the BYE.

lasker-2.2.3/bots/mamer/CommandEntry.cc
lasker-2.2.3/bots/mamer/Mamer.cc
lasker-2.2.3/bots/mamer/Tourney.cc

index 345fcb3..0b7708e 100644 (file)
@@ -785,7 +785,7 @@ printf("join\n");
   tourn = gMamer.FindTourney(params[0].val.integer);
   
   if(NULL != tourn) {    
-    newEntry = new Player(user->name, params[0].val.integer);
+    newEntry = new Player(user->name, 0., params[0].val.integer); // [HGM] signal this was from join
 printf("entry=%d\n",newEntry);
     gMamer.pendingList.Append(newEntry);
     gMamer.XServerCom("getpi %s%s", user->name, "\n");
@@ -804,7 +804,7 @@ int CommandEntry::AddToTourney(User *user, param_list params) {
   tourn = gMamer.FindTourney(params[1].val.integer);
   
   if(NULL != tourn) {
-    newEntry = new Player(params[0].val.word, params[1].val.integer);
+    newEntry = new Player(params[0].val.word, 1., params[1].val.integer); // [HGM] signal this was from att
     gMamer.pendingList.Append(newEntry);
     gMamer.XServerCom("getpi %s%s", params[0].val.word, "\n");
     return(1);
index e09cddf..9de4abc 100644 (file)
@@ -1302,7 +1302,7 @@ printf("player p=%d\n", p);
     return 0;
   } //Check for valid tourney is done in CommandEntry::JoinTourney
 
-  return_from_AddPlayer = t->AddPlayer(player, ratings[t->GetVariant()], 0.0);
+  return_from_AddPlayer = t->AddPlayer(player, ratings[t->GetVariant()], p->floatValue); // [HGM] use score to signal att/join
 printf("ret = %d\n", return_from_AddPlayer);
   TellUser(JoinedTourney, player, return_from_AddPlayer);
   if(return_from_AddPlayer == 1)
index 56a4b14..e37b85c 100644 (file)
@@ -120,7 +120,8 @@ int Tourney::AddPlayer(char *name, int rating, float score) {
   TourneyPlayers *newPlayer = NULL, *tp = NULL;
   Player *newSortPlayer = NULL;
 
-  if (status != OPEN) return 3;   // If we are not open then we can't enter the tourney
+  if (status != OPEN   // If we are not open then we can't enter the tourney
+      && !(score != 0. && status == CLOSED)) return 3; // [HGM] unless the manager adds us as late join!
   
   tp = GetPlayer(name);
 
@@ -128,7 +129,9 @@ int Tourney::AddPlayer(char *name, int rating, float score) {
 
   if(rating >= params.ratingLow && rating <= params.ratingHigh && status == OPEN) {
 
-    newPlayer = new TourneyPlayers(name, rating, score);
+    if(GetPlayerCount() >= params.maxPlayers) return(0); // [HGM] never exceed max players (or would it be safe to do so?)
+
+    newPlayer = new TourneyPlayers(name, rating, 0.); // [HGM] always set start score = 0.
     newSortPlayer = new Player(name, 0);
 
     playerList.Append(newPlayer);
@@ -136,6 +139,29 @@ int Tourney::AddPlayer(char *name, int rating, float score) {
     gMamer.XServerCom("%s %i %s %s%i%s %s%i %i %s%s", "tell", gMamer.channelNumber, name, "(", rating, ")", 
                      "has joined tourney #", number, GetPlayerCount(), "players now.", "\n");
     CalculateAverage();
+
+    if(status == CLOSED) { // [HGM] late join; do some stuff already done in CloseAndStart for the others
+       newPlayer->ClearWhites();
+       newPlayer->ClearBlacks();
+       newPlayer->ClearTotalWhites();
+       newPlayer->ClearTotalBlacks();
+
+       // give the player a BYE (which we might have to add)
+       LinkListIter<TourneyPlayers> playerIter(playerList);
+       playerIter.Reset();
+       while((tp = playerIter.Next())) {
+           if(strcmp(tp->name, "_BYE_") == 0)  break;
+       }
+       if(!tp) {
+           tp = new TourneyPlayers("_BYE_", 0, 0);  
+           playerList.Append(tp);                  // add the bye to the tourney players list
+           SortPlayers();
+       }
+       newPlayer->opponentList.Append(new Player("_BYE_", 0., 0, 0)); // add a BYE for missed round, to prevent it can get a second
+       
+       return 1; // in any case never start automatically
+    }
+
     if(GetPlayerCount() >= params.maxPlayers)
       CloseAndStart();
     return(1);   // we entered the tourney
@@ -465,7 +491,7 @@ int Tourney::MakeAssignments(void) {
   TourneyPlayers *tp = NULL, *opponent = NULL, *bye = NULL;
   Storage *newPairedPlayer=NULL;
   Player *p=NULL, *opp=NULL;
-  int everybodyPaired=0, byeFlag=1, playerCount=0, i=1;
+  int everybodyPaired=0, playerCount=0, i=1;
   LinkListIter<TourneyPlayers> playerIter(playerList);
   
   params.currentRound++;
@@ -478,14 +504,16 @@ int Tourney::MakeAssignments(void) {
   playerIter.Reset();
   while((tp = playerIter.Next())) {
     UnPairPlayer(tp);
-    if(strcmp(tp->name, "_BYE_") == 0)  { byeFlag = 0; }  // unset the byeFlag
+    if(strcmp(tp->name, "_BYE_") == 0)  { bye = tp; tp->activeFlag = 0; }  // unset the byeFlag [HGM] and remember bye and deactivate
   }
   playerCount = GetPlayerCount();
-  if((byeFlag) && (playerCount % 2)){   // we need to add a bye
+  if(playerCount % 2){   // we need to add a bye
+   if(bye) bye->activeFlag = 1; else { // [HGM] if bye existed, re-activate it
     bye = new TourneyPlayers("_BYE_", 0, 0);  
     playerList.Append(bye);                  // add the bye to the tourney players list
     SortPlayers();
     playerCount++;
+   }
   }
   
   // Set up the PairingScores