1 //--------------------------------------------------------------------------
2 // Tourney.cc - Source file for Tourney class
7 // $Date: 1998/09/10 19:57:17 $
12 // $Log: Tourney.cc,v $
13 // Revision 1.11 1998/09/10 19:57:17 mlong
14 // lots of little bug fixes and a few new features
16 // Revision 1.10 1998/04/29 15:23:19 mlong
17 // prepairing for the move to daimi
18 // new sorting routine.
20 // Revision 1.9 1998/04/18 20:05:14 mlong
23 // Revision 1.8 1998/04/18 18:46:04 mlong
25 // added delete tourney function
27 // Revision 1.4 1997/10/08 21:03:35 chess
28 // preparing for move to oracle machine at eworks.
30 // Revision 1.3 1997/05/15 18:27:53 chess
31 // added pending and TourneyPlayers support
32 // added HandleGetPlayerInfo & HandleGetGameInfo
34 // Revision 1.2 1996/10/01 20:14:43 moses
35 // Added a new method IsTourney
37 // Revision 1.1 1996/09/30 20:52:48 moses
40 //--------------------------------------------------------------------------
42 //static char RCSid[] = "$Id: Tourney.cc,v 1.11 1998/09/10 19:57:17 mlong Exp $";
49 //- Constructor ------------------------------------------------------------
53 Tourney::Tourney(int n,User *u, TourneyParameters *tp) {
54 InitTourney(n, u, tp->time, tp->inc, tp->mode, tp->style, tp->rounds, tp->variant, tp->ratingLow, tp->ratingHigh);
57 Tourney::Tourney(int n, User *u, TourneyParameters *tp, int t, int i, char m, char s, int r) {
58 InitTourney(n, u, t, i, m, s, r, tp->variant, tp->ratingLow, tp->ratingHigh);
61 Tourney::Tourney(int n, User *u, TourneyParameters *tp, int t, int i, char m, char s, int r, char v) {
62 InitTourney(n, u, t, i, m, s, r, v, tp->ratingLow, tp->ratingHigh);
65 void Tourney::InitTourney(int n, User *u, int t, int i, char m, char s, int r, char v, int rl, int rh) {
67 strncpy(manager, u->name, NAMELEN - 1);
68 managerLevel = u->GetManagerLevel();
77 params.ratingLow = rl;
78 params.ratingHigh = rh;
79 params.currentRound = 0;
80 params.maxPlayers = DEFAULT_MAX_PLAYERS;
91 //- Deconstructor ---------------------------------------------------------
96 //- IsTourney -------------------------------------------------------------
97 int Tourney::IsTourney(int tourn) {
102 } //- End of IsTourney
104 //- IsNotNew-------------------------------------------------------------
105 short Tourney::IsNotNew(void) {
111 //- IsNotClosed-------------------------------------------------------------
112 short Tourney::IsNotClosed(void) {
118 //- AddPlayer ----------------------------------------------------------
119 int Tourney::AddPlayer(char *name, int rating, float score) {
120 TourneyPlayers *newPlayer = NULL, *tp = NULL;
121 Player *newSortPlayer = NULL;
123 if (status != OPEN // If we are not open then we can't enter the tourney
124 && !(score != 0. && status == CLOSED)) return 3; // [HGM] unless the manager adds us as late join!
126 tp = GetPlayer(name);
128 if(tp != NULL) return(2); // if we are already in the tourney we can't enter it again/
130 if(rating >= params.ratingLow && rating <= params.ratingHigh && status == OPEN) {
132 if(GetPlayerCount() >= params.maxPlayers) return(0); // [HGM] never exceed max players (or would it be safe to do so?)
134 newPlayer = new TourneyPlayers(name, rating, 0.); // [HGM] always set start score = 0.
135 newSortPlayer = new Player(name, 0);
137 playerList.Append(newPlayer);
139 gMamer.XServerCom("%s %i %s %s%i%s %s%i %i %s%s", "tell", gMamer.channelNumber, name, "(", rating, ")",
140 "has joined tourney #", number, GetPlayerCount(), "players now.", "\n");
143 if(status == CLOSED) { // [HGM] late join; do some stuff already done in CloseAndStart for the others
144 newPlayer->ClearWhites();
145 newPlayer->ClearBlacks();
146 newPlayer->ClearTotalWhites();
147 newPlayer->ClearTotalBlacks();
149 // give the player a BYE (which we might have to add)
150 LinkListIter<TourneyPlayers> playerIter(playerList);
152 while((tp = playerIter.Next())) {
153 if(strcmp(tp->name, "_BYE_") == 0) break;
156 tp = new TourneyPlayers("_BYE_", 0, 0);
157 playerList.Append(tp); // add the bye to the tourney players list
160 newPlayer->opponentList.Append(new Player("_BYE_", 0., 0, 0)); // add a BYE for missed round, to prevent it can get a second
162 return 1; // in any case never start automatically
165 if(GetPlayerCount() >= params.maxPlayers)
167 return(1); // we entered the tourney
169 return(0); // sucks to be us cause our rating doesn't fit the params
172 //- RemovePlayer ----------------------------------------------------------
173 int Tourney::RemovePlayer(char *name) {
174 TourneyPlayers *tp = NULL, *p=NULL;
176 int roundsRemaining=0;
178 tp = GetPlayer(name);
179 printf("forfeiting %s\n", tp->name);
180 if(tp == NULL) return -1; // Player not in THIS tourney
184 roundsRemaining = GetRoundsRemaining();
186 // This code will go through a forfeited players list and give him a loss for current opponent
187 // with a quick modification it will give losses for all games played as well...
188 LinkListIter<Player> opponentIter(tp->opponentList); // List of opponents this player has had
189 opponentIter.Reset();
190 while((opp = opponentIter.Next())) {
191 if(strcmp("_BYE_", opp->name) != 0) { // If I am not _BYE_
192 p = GetPlayer(opp->name);
193 if(opp->floatValue == -1) { // floatValue stores the game result for this player
194 if(opp->value) { // if player leaving was white
195 SetGameResult(tp->name, opp->name, 0);
197 SetGameResult(opp->name, tp->name, 1);
204 LinkListIter<TourneyPlayers> playerIter(playerList);
206 while((p = playerIter.Next())) {
207 if(strcmp(p->name, "_BYE_") == 0) {
208 if(p->activeFlag != 0)
218 return roundsRemaining;
221 //- GetPlayer ----------------------------------------------------------
222 TourneyPlayers *Tourney::GetPlayer(char *name) {
223 LinkListIter<TourneyPlayers> playerIter(playerList);
224 TourneyPlayers *tp = NULL;
227 while((tp = playerIter.Next()))
228 if(!strcasecmp(tp->name, name))
234 //- GetRound ----------------------------------------------------------
235 int Tourney::GetRound() {
236 return params.currentRound;
237 }//- end of GetRound --------------------------------------------------
239 //- GetRoundsRemaining ------------------------------------------------
240 int Tourney::GetRoundsRemaining() {
241 return (params.rounds - params.currentRound);
242 }//- end of GetRoundsRemaining -----------------------------------------
244 //- SortPlayers ----------------------------------
245 void Tourney::SortPlayers() {
246 Player *temp=NULL, *s=NULL;
247 TourneyPlayers *tp = NULL;
250 LinkListIter<TourneyPlayers> playerIter(playerList);
251 LinkListIter<Player> sortIter(sortList);
254 while((s = sortIter.Next())) sortList.Delete(s);
257 while((tp = playerIter.Next())) {
258 (tp->activeFlag) ? tp->sortValue = (tp->score + tp->rating/10000.0) : tp->sortValue = -1.0;
259 // tp->ClearWhites();
260 // tp->ClearBlacks();
261 if((status == OPEN) && (i < (GetPlayerCount()/2)))
262 (i % 2) ? tp->AddWhite() : tp->AddBlack();
267 while((tp = playerIter.Next())) {
270 temp = new Player(tp->name, tp->sortValue);
271 while((s = sortIter.Next())) {
272 if(tp->sortValue > s->floatValue) {
273 sortList.Insert(s, temp);
279 sortList.Append(temp);
284 while((s = sortIter.Next())) {
286 if(gMamer.debugLevel >= 10) printf("%4d %-18s\n", s->value, s->name);
289 }//- end of Sort Players ----------------------
291 //- GetSortValueCount -------------------------------------------------------
292 int Tourney::GetSortValueCount(double value) {
293 LinkListIter<TourneyPlayers> playerIter(playerList);
295 TourneyPlayers *tp=NULL;
298 while((tp = playerIter.Next())) {
299 if(tp->sortValue == value) {
300 s = GetSortPlayer(tp->name);
309 //- GetSortPlayer ----------
310 Player *Tourney::GetSortPlayer(char *name) {
312 LinkListIter<Player> sortIter(sortList);
314 while((p = sortIter.Next())) {
315 if(strcasecmp(p->name, name) == 0) {
321 }//- end of GetSortPlayer -----
323 //- GetSortPlayer ------------------------------
324 Player *Tourney::GetSortPlayer(int place) {
326 LinkListIter<Player> sortIter(sortList);
328 while((p = sortIter.Next())) {
329 if(p->value == place) {
335 }//- end of GetSortPlayer -----
337 //- CalculateAverage --------------------------------------------------
338 void Tourney::CalculateAverage(void) {
339 int total=0, count=0;
341 LinkListIter<TourneyPlayers> playerIter(playerList);
343 while((p = playerIter.Next())) {
350 averageRating = ((float)total/(float)count);
353 }//- end CalculateAverage
355 //- GetAverageRating ----------------------------------------------------------
356 float Tourney::GetAverageRating(void) {
357 return averageRating;
358 }//end GetAverageRating
360 //- GetVariant ----------------------------------------------------------
361 int Tourney::GetVariant(void) {
364 switch(params.variant) {
368 eTime = (float)params.time + (0.6666667 * (float)params.inc);
384 //- Open ----------------------------------------------------------
385 int Tourney::Open(void) {
394 //- GetPlayerCount ----------------------------------------------------------
395 int Tourney::GetPlayerCount() {
398 LinkListIter<TourneyPlayers> playerIter(playerList);
400 while((p = playerIter.Next())) {
401 if(p->activeFlag != 0)
406 }//- end GetPlayerCount ----------------------------------
408 //- SetPersist -------------------------------------------------------------
409 void Tourney::SetPersist(int i) {
413 //- GetPersist -------------------------------------------------------------
414 int Tourney::GetPersist() {
418 //- SetEndDate -------------------------------------------------------------
419 void Tourney::SetEndDate() {
421 } //- end of SetEndDate ----------------------------------------------------
423 //- CloseAndStart ----------------------------------------------------------
424 void Tourney::CloseAndStart(void) {
425 TourneyPlayers *tp = NULL;
427 params.currentRound = 0;
429 LinkListIter<TourneyPlayers> playerIter(playerList);
433 cout << "tourney started at: " << ctime(&startDate) << endl;
435 if(params.rounds == 0) {
436 switch(params.style) {
438 params.rounds = GetPlayerCount() - 1;
441 params.rounds = (int)ceil(log2(GetPlayerCount()));
444 params.rounds = DEFAULT_ROUNDS;
449 // this is to stop a 4 player tourney from having 2 rounds
450 params.rounds = (params.rounds < MINIMUM_ROUNDS) ? MINIMUM_ROUNDS : params.rounds;
452 playerIter.Reset(); // [HGM] this code moved here from SortPlayers
453 while((tp = playerIter.Next())) {
456 tp->ClearTotalWhites();
457 tp->ClearTotalBlacks();
461 TellThemWhoTheyPlay(); // tell them who they play
464 int Tourney::PopLastPairedPlayer() {
465 Storage *p=NULL, *lastPlayer=NULL;
466 LinkListIter<Storage> pairedIter(pairedPlayers);
469 while((p = pairedIter.Next())) {
475 cout << "Popping: " << lastPlayer->name << " from the paired list " << endl;
476 pairedPlayers.Delete(lastPlayer);
478 cout << "Popping: _NOBODY_" << " from the paired list " << endl;
483 void Tourney::ClearPairedPlayers() {
485 LinkListIter<Storage> pairedIter(pairedPlayers);
487 while((p = pairedIter.Next())) pairedPlayers.Delete(p);
490 int Tourney::MakeAssignments(void) {
491 TourneyPlayers *tp = NULL, *opponent = NULL, *bye = NULL;
492 Storage *newPairedPlayer=NULL;
493 Player *p=NULL, *opp=NULL;
494 int everybodyPaired=0, playerCount=0, i=1;
495 LinkListIter<TourneyPlayers> playerIter(playerList);
497 params.currentRound++;
498 if(params.currentRound > params.rounds) {
499 cout << "Returning because current round is > rounds" << endl;
500 cerr << "Returning because current round is > rounds" << endl;
503 // Initialize a few things...make sure nobody is paired,
505 while((tp = playerIter.Next())) {
507 if(strcmp(tp->name, "_BYE_") == 0) { bye = tp; tp->activeFlag = 0; } // unset the byeFlag [HGM] and remember bye and deactivate
509 playerCount = GetPlayerCount();
510 if(playerCount % 2){ // we need to add a bye
511 if(bye) bye->activeFlag = 1; else { // [HGM] if bye existed, re-activate it
512 bye = new TourneyPlayers("_BYE_", 0, 0);
513 playerList.Append(bye); // add the bye to the tourney players list
519 // Set up the PairingScores
521 while((tp = playerIter.Next())) { if(!tp->IsPaired()) SetPairingScores(tp); }
524 while((tp = playerIter.Next())) { UnPairPlayer(tp); tp->oppChoice=0; } // unpair all the players
527 ClearPairedPlayers();
528 while(everybodyPaired == 0) {
530 p = GetSortPlayer(i);
531 tp = GetPlayer(p->name);
532 opponent = (TourneyPlayers *)NULL;
533 // PrintPotentialLists();
534 if((tp->IsPaired() == FALSE) && tp->activeFlag) { // If I am not paired and I am active pair me
535 if((opponent = FindBestOpponent(tp))) {
536 newPairedPlayer = new Storage(tp->name, i);
537 pairedPlayers.Append(newPairedPlayer);
538 cerr << "Adding: " << tp->name << " " << i << " " << "to the paired list " << opponent->name << endl;
539 everybodyPaired = PairPlayers(tp, opponent); // Actually Pair me
540 i++; // go to the next player
541 } else { // If there is no opponent for me go back and repair up the tree
542 if(tp->oppChoice > playerCount) { // If I have tried all my opponents
543 tp->oppChoice = 0; // reset me so I can try again later
544 i = PopLastPairedPlayer(); // returns the last player paired & removes him from the paired list
545 cerr << "i=" << i << endl;
546 if(i <= 0) { // this would be really bad means we can't even find
547 cout << "Returning because we can't find pairings" << endl;
548 cerr << "Returning because we can't find pairings" << endl;
549 return 0; // an opponent for the first player. Tourney has to be over now
551 p = GetSortPlayer(i);
552 tp = GetPlayer(p->name);
553 opponent = GetPlayer(tp->oppName);
554 cout << "UnPairing: " << tp->name << " " << opponent->name << " choice: " << tp->oppChoice << endl;
555 tp->RemoveLastOpponent(); // removes the person we were planning on playing
556 opponent->RemoveLastOpponent();
557 UnPairPlayer(tp); // unpair us so we can be re-paired
558 UnPairPlayer(opponent);
559 tp->oppChoice++; // try his next possible opponent
561 tp->oppChoice++; // Try my next opponent
564 } else { // if I am already paired go to the next player and pair him
569 if(everybodyPaired > 0) {
571 while((tp = playerIter.Next())) UnPairPlayer(tp); // unpair all players so we can use that to tell
572 playerIter.Reset(); // if they have been assiged a color
573 while((tp = playerIter.Next())) {
574 if((!tp->IsPaired()) && (tp->activeFlag != 0)) {
575 opponent = GetPlayer(tp->oppName);
576 AssignColors(tp, opponent);
577 tp->NowPaired(TRUE); // mark BOTH players as having a color
578 opponent->NowPaired(TRUE); // this is important for when we hit this player later in the Iter
584 while((tp = playerIter.Next())) {
585 if(0 == strcmp(tp->name, "_BYE_")) { // If I am the bye
586 LinkListIter<Player> opponentIter(tp->opponentList);
587 while((opp = opponentIter.Next())) { // Got through my opponents and find the one I am playing now
588 if(0 == strcasecmp(opp->name, tp->oppName)) { // & Give him a win
590 SetGameResult(tp->name, tp->oppName, 0);
592 SetGameResult(tp->oppName, tp->name, 1);
593 gMamer.XServerCom("tell %s you get a BYE this round.%s", opp->name, "\n");
601 //- PrintPotentialLists
602 void Tourney::PrintPotentialLists() {
603 TourneyPlayers *tp=NULL;
606 LinkListIter<TourneyPlayers> playerIter(playerList);
608 while((tp = playerIter.Next())) {
609 printf("%-10s %i\n", tp->name, tp->oppChoice);
610 LinkListIter<Player> oppIter(tp->potentialOpponentList);
611 while((o = oppIter.Next())) {
612 printf("%d %-10s ", o->value, o->name);
618 //- Start of FindBestOpponent
619 TourneyPlayers *Tourney::FindBestOpponent(TourneyPlayers *tp) {
622 LinkListIter<Player> opponentIter(tp->potentialOpponentList);
623 while((tmp = opponentIter.Next())) {
624 if((tmp->value == tp->oppChoice) && (0 == GetPlayer(tmp->name)->IsPaired())) {
625 return GetPlayer(tmp->name);
632 //- Start of SetPairingSores -------------------------------
633 void Tourney::SetPairingScores(TourneyPlayers *tp) {
635 TourneyPlayers *opponent = NULL;
636 Player *temp=NULL, *newOpp=NULL, *t=NULL, *me=NULL;
637 int offset=2, place=1, i=0, added=0;
639 tp->RemovePotentialOppList();
641 LinkListIter<TourneyPlayers> playerIter(playerList);
645 while((opponent = playerIter.Next())) {
646 if((strcmp(tp->name, opponent->name) != 0) &&
647 (tp->score == opponent->score)) {
649 if(opponent->rating > tp->rating) {
655 if(place > offset) { offset *= -1; }
657 me = GetSortPlayer(tp->name);
659 while((opponent = playerIter.Next())) {
660 if(strcmp(tp->name, opponent->name) && (tp->activeFlag !=0)) { // If this isn't MY name & I am active
661 if((!tp->AlreadyPlayed(opponent->name)) && (!opponent->IsPaired()) && (opponent->activeFlag != 0)
662 && (tp->ColorDue() != opponent->ColorDue() // they are due different color, never a problem
663 || tp->ColorDue() ? // both are due white. Check if one of them could accept black without breaking 'absolute' color rules
664 tp->GetConsecutiveBlacks() < 2 &&
665 tp->GetTotalBlacks() - tp->GetTotalWhites() < 2 ||
666 opponent->GetConsecutiveBlacks() < 2 &&
667 opponent->GetTotalBlacks() - opponent->GetTotalWhites() < 2
668 : // both are due black. Check if any of them can accept white
669 tp->GetConsecutiveWhites() < 2 &&
670 tp->GetTotalWhites() - tp->GetTotalBlacks() < 2 ||
671 opponent->GetConsecutiveWhites() < 2 &&
672 opponent->GetTotalWhites() - opponent->GetTotalBlacks() < 2
675 // and I haven't played this person and this person is active. (not forfeited)
676 t = GetSortPlayer(opponent->name);
677 score = ((abs(t->value - (me->value + offset))) * 1000);
678 if(opponent->score >= tp->score) {
679 score = score + ((opponent->score - tp->score) * 10.0);
681 score = score + ((tp->score - opponent->score) * 10.0);
683 score += abs(opponent->ColorDue() - tp->ColorDue());
684 score += (abs(opponent->rating - tp->rating)) * 0.0001;
686 if(!strcmp(opponent->name, "_BYE_")) { score = 999999; }
689 newOpp = new Player(opponent->name, score);
690 LinkListIter<Player> opponentIter(tp->potentialOpponentList);
691 opponentIter.Reset();
692 while((temp = opponentIter.Next())) {
693 if(score < temp->floatValue) {
694 tp->potentialOpponentList.Insert(temp, newOpp);
700 tp->potentialOpponentList.Append(newOpp);
701 opponentIter.Reset();
703 while((temp = opponentIter.Next())) {
712 //- Start of PairPlayers ----------------------------------
713 int Tourney::PairPlayers(TourneyPlayers *p1, TourneyPlayers *p2) {
717 LinkListIter<TourneyPlayers> playerIter(playerList);
719 temp = new Player(p2->name, -1.0, 0, p2->rating);
720 p1->opponentList.Append(temp);
722 strcpy(p1->oppName, p2->name);
724 temp = new Player(p1->name, -1.0, 0, p1->rating);
725 p2->opponentList.Append(temp);
727 strcpy(p2->oppName, p1->name);
730 while((tp = playerIter.Next())) {
731 if((!tp->IsPaired()) && (tp->activeFlag != 0))
738 //- Start of UnPairPlayer ----------------------------------
739 void Tourney::UnPairPlayer(TourneyPlayers *p1) {
741 p1->NowPaired(FALSE);
742 }//- end of UnPairPlayer
745 int Tourney::intcmp(int a, int b) {
758 //- AssignColors ----------------------------------------------------------
759 void Tourney::AssignColors(TourneyPlayers *p1, TourneyPlayers *p2) {
760 int p1Color=0, rated = 1;
762 Player *opp1 = NULL, *opp2 = NULL;
764 cerr << "P1: " << p1->name << " due=" << p1->ColorDue() << " total=" << p1->GetTotalWhites() << "/" << p1->GetTotalBlacks()
765 << " consecutive=" << p1->GetConsecutiveWhites() << "/" << p1->GetConsecutiveBlacks() << endl;
766 cerr << "P2: " << p2->name << " due=" << p2->ColorDue() << " total=" << p2->GetTotalWhites() << "/" << p2->GetTotalBlacks()
767 << " consecutive=" << p2->GetConsecutiveWhites() << "/" << p2->GetConsecutiveBlacks() << endl;
768 if(params.mode != 'r') { rated = 0; }
769 if(intcmp(p1->ColorDue(), p2->ColorDue()) != 0) {
770 if(p1->ColorDue()) { p1Color = 1; }
772 if(p1->ColorDue()) { // Both are due white; need to find out how due.
773 switch (intcmp(p1->GetConsecutiveBlacks(), p2->GetConsecutiveBlacks())) {
779 switch (intcmp(p1->GetTotalBlacks(), p2->GetTotalBlacks())) {
785 if((p1->score * 10000 + p1->rating) >= (p2->score * 10000 + p2->rating))
792 switch (intcmp(p1->GetConsecutiveWhites(), p2->GetConsecutiveWhites())) {
798 switch (intcmp(p1->GetTotalWhites(), p2->GetTotalWhites())) {
804 if((p1->score * 10000 + p1->rating) >= (p2->score * 10000 + p2->rating))
812 LinkListIter<Player> opponentIter1(p1->opponentList);
813 LinkListIter<Player> opponentIter2(p2->opponentList);
814 while((opp1 = opponentIter1.Next())) {
815 if(!strcasecmp(opp1->name, p2->name)) { break; }
817 while((opp2 = opponentIter2.Next())) {
818 if(!strcasecmp(opp2->name, p1->name)) { break; }
820 cerr << "assigned color = " << p1Color << endl;
822 p1->AddWhite(); p2->AddBlack();
824 g = new Game(p1->name, p2->name, params.time, params.inc, rated, 'r');
826 p1->AddBlack(); p2->AddWhite();
828 g = new Game(p2->name, p1->name, params.time, params.inc, rated, 'r');
833 //- GetStatus --------------------------------------------------------
834 int Tourney::GetStatus(void) {
838 //- EndTourney -----------------------
839 void Tourney::EndTourney(void) {
843 //- IsPaused --------------------------------------------------------
844 int Tourney::IsPaused(void) {
848 //- SetPause -----------------------
849 void Tourney::SetPause(int x) {
853 //- Announce ----------------------------------------------------------
854 void Tourney::Announce(void) {
859 announce = new char[MAX_LINE_SIZE];
860 memset(announce, '\0', MAX_LINE_SIZE);
861 sprintf(announce, "*****Tourney Announcement***** %80s Trny #%d %d %d %c ",
862 "", number, params.time, params.inc, params.mode);
863 if(params.style == 's') { strcat(announce, " SWISS"); } else { strcat(announce, " RR"); }
864 switch(params.variant) {
866 strcat(announce, " Wild ");
867 strcat(announce, GetWild(params.wild));
870 strcat(announce, " Bug"); break;
872 strcat(announce, " Suicide"); break;
876 memset(temp, '\0', 128);
877 sprintf(temp, " %i-%i %i plr(s). tell %s join %d. Avg: %5.1f",
878 params.ratingLow, params.ratingHigh, GetPlayerCount(), gMamer.username, number, averageRating);
879 strcat(announce, temp);
881 printf("%s + cha 49\n", announce);
884 gMamer.XServerCom("%s %i %s%s", "tell", gMamer.channelNumber, announce, "\n");
887 if((now - lastCshouted) > (SEC_BETWEEN_CSHOUTS)) {
888 gMamer.XServerCom("%s %s%s", "cshout", announce, "\n");
895 //- SetVariable ---------------------------------------------------------------
896 void Tourney::SetVariable(int why, int newValue) {
900 if((newValue >= 0) && (newValue <= MAX_TIME))
901 params.time = newValue;
904 if((newValue >= 0) && (newValue <= MAX_INCREMENT))
905 params.inc = newValue;
908 params.rounds = newValue;
909 params.rounds = MIN(params.rounds, MAX_ROUNDS);
910 params.rounds = MIN((params.maxPlayers - 1), params.rounds);
913 if(((newValue >= 0) && (newValue <= 5)) ||
914 ((newValue >= 8) || (newValue <= 10)))
915 params.wild = newValue;
918 params.ratingLow = newValue;
919 params.ratingLow = MAX(0, params.ratingLow);
920 if(params.ratingLow >= (params.ratingHigh - 200))
921 params.ratingLow = params.ratingHigh - 200;
924 params.ratingHigh = newValue;
925 if(params.ratingHigh <= (params.ratingLow + 200))
926 params.ratingHigh = params.ratingLow + 200;
929 params.maxPlayers = newValue;
930 params.maxPlayers = MAX(params.maxPlayers, MINIMUM_PLAYERS);
931 params.maxPlayers = MAX(params.maxPlayers, (params.rounds + 1));
938 //- SetVariable ---------------------------------------------------------------
939 void Tourney::SetVariable(int why, char *newValue) {
943 if((newValue[0] == 's') || (newValue[0] == 'r'))
944 params.style = newValue[0];
947 if((newValue[0] == 'r') || (newValue[0] == 'w') || (newValue[0] == 'b') || (newValue[0] == 's'))
948 params.variant = newValue[0];
951 if((newValue[0] == 'r') || (newValue[0] == 'u'))
952 params.mode = newValue[0];
959 //- Begin GetWild - take a int return a string
960 char *Tourney::GetWild(int w) {
985 //- TellThemWhoTheyPlay ------------------------------------------
986 void Tourney::TellThemWhoTheyPlay() {
988 LinkListIter<Game> gameIter(gameList); // List of games in this tourney
989 char *Variant=new char[MAX_LINE_SIZE];
991 memset(Variant, '\0', MAX_LINE_SIZE);
993 if(params.variant == 'w')
994 sprintf(Variant, "wild %2s", GetWild(params.wild));
995 else if(params.variant == 's')
996 sprintf(Variant, "suicide");
997 else if(params.variant == 'b')
998 sprintf(Variant, "bug");
1000 while((g = gameIter.Next())) {
1001 /* note that we rely on rmatch and on the ; separated commands from lasker */
1003 gMamer.XServerCom("rmatch %s %s %i %i %c %s white ; rmatch %s %s %i %i %c %s black\n",
1004 g->whiteName, g->blackName, g->time, g->inc, params.mode, Variant,
1005 g->blackName, g->whiteName, g->time, g->inc, params.mode, Variant);
1008 }//- end TellThemWhoTheyPlay --------------------------------------
1010 //- SetGameResult --------------------------------------------
1011 int Tourney::SetGameResult(char *white, char *black, int result) {
1012 Player *opp1 = NULL, *opp2 = NULL;
1013 TourneyPlayers *tp1 = NULL, *tp2 = NULL;
1017 tp1 = GetPlayer(white);
1018 tp2 = GetPlayer(black);
1020 if((NULL == tp1) || (NULL == tp2)) { return 0; }
1022 LinkListIter<Player> opponentIter1(tp1->opponentList); // List of opponents this player has had
1023 while((opp1 = opponentIter1.Next())) {
1024 if(!strcasecmp(opp1->name, black)) { break; }
1026 LinkListIter<Player> opponentIter2(tp2->opponentList);
1027 while((opp2 = opponentIter2.Next())) {
1028 if(!strcasecmp(opp2->name, white)) { break; }
1030 if((NULL == opp1) || (NULL == opp2)) { return -1; }
1032 switch (result) { // set the result
1034 opp1->floatValue = 1.0;
1035 opp2->floatValue = 0.0;
1038 opp1->floatValue = 0.0;
1039 opp2->floatValue = 1.0;
1042 opp1->floatValue = 0.5;
1043 opp2->floatValue = 0.5;
1048 tp1->CalculateScore();
1049 tp2->CalculateScore();
1051 LinkListIter<Game> gameIter(gameList); // List of games in this tourney
1052 while((g = gameIter.Next())) {
1053 if(!(strcasecmp(g->whiteName, white)) && !(strcasecmp(g->blackName, black))) {
1061 if((g = gameIter.Next())) {
1069 } //- End SetGameResult --------------------------------------
1071 //- GetStartDate ---------------------------------------------
1072 long Tourney::GetStartDate() {
1074 } //- end of GetStartDate ------------------------------------
1076 //- GetEndDate ---------------------------------------------
1077 long Tourney::GetEndDate() {
1079 } //- end of GetEndDate ------------------------------------