#include "VegaMain.h" #include "Tournament.h" /* ** this file contains all the sort function used in the program */ int CanPlayWith(int player1, int player2, int round); int CanPlayWithThem(int player, int players[], int nplayers, int round); int comppair(int j1, int j2, int round); void SortPairs(int round); int CompareRatingTitleName( const void *pid1, const void *pid2); int CompareBLACK(const void *pid1, const void *pid2); int CompareWHITE(const void *pid1, const void *pid2); int CompareScoreName(const void *pid1, const void *pid2); int CompareCategoryScoreName(const void *pid1, const void *pid2); int CompareName(const void *pid1, const void *pid2); int CompareCountry(const void *pid1, const void *pid2); void SortUpfloater(int colorflag, int n, int array[]); int CompareUpfDuecRatAroNome0(int id1, int id2); int CompareUpfDuecRatAroNome1(int id1, int id2); int CompareUpfDuecRatAroNome2(int id1, int id2); void SortDownfloater(int colorflag, int n, int array[]); int CompareDuecRatAroNome0(int id1, int id2); int CompareDuecRatAroNome1(int id1, int id2); int CompareDuecRatAroNome2(int id1, int id2); int cmpdata(int d1, int d2); void DecodeData(int code, int *dd, int *mm, int *yy); int cmpSB(int id1, int id2); int cmpBUC1(int id1, int id2); int cmpBUCM(int id1, int id2); int cmpBUCT(int id1, int id2); int cmpCUMUL(int id1, int id2); int cmpARO(int id1, int id2); int cmpMB(int id1, int id2); int cmpMWINS(int id1, int id2); int cmpAPRO(int id1, int id2); int cmpMPSS(int id1, int id2); // missing point score system int (*cmpfunc[FUNC_CMP+1])(int, int)={NULL, cmpBUC1, cmpBUCT, cmpBUCM, cmpSB, cmpCUMUL, cmpARO, cmpMB, cmpMWINS, cmpAPRO, cmpMPSS}; // array of pointer to function /********************** test player compatibility ***********************/ int CanPlayWith(int player1, int player2, int round) // // PURPOSE: check if player1 and player2 are compatible, // i.e. if they: 1) have not yet played before, and 2) are color compatible // // INPUT VARIABLE // player1 = ID of the player 1 // player2 = ID of the player 2 // round = current round // // OUTPUT VARIABLE // 1 if yes, 0 otherwise // { int i; if (player1 == player2) return 0; // a player cannot play with himself! if ((player1 == -1) || (player2 == -1)) return 1; // -1 is a fictious player compatible with everybody // if (AVOID_SAME_COUNTRY) if ( strcmp(player[player1].name, player[player2].name )==0 ) return 0; if ( (player1 == 0) && (player[player2].canGetBYE == 1) ) return 1; // the bye can be assigned else if ( (player2 == 0) && (player[player1].canGetBYE == 1) ) return 1; // the bye can be assigned for (i=1; i=1; i--) for (j=2; j<=i; j++) if ( comppair(j-1, j, round)<0 ) { t = TD.pairing[j-1][round]; TD.pairing[j-1][round] = TD.pairing[j][round]; TD.pairing[j][round] = t; } } int comppair(int j1, int j2, int round) // // compare two pairs // { int code1, code2; int idw1, idw2, idb1, idb2, res; int m1, m2; float max1, max2, s1, s2; code1 = TD.pairing[j1][round]; TD.DecodeResult(code1, &idw1, &idb1, &res); if (idw1==0 || idb1==0) return 0; max1 = player[idw1].tiebreak[SCORE]; if (player[idb1].tiebreak[SCORE]>max1) max1 = player[idb1].tiebreak[SCORE]; code2 = TD.pairing[j2][round]; TD.DecodeResult(code2, &idw2, &idb2, &res); if (idw2==0 || idb2==0) return 0; max2 = player[idw2].tiebreak[SCORE]; if (player[idb2].tiebreak[SCORE]>max2) max2 = player[idb2].tiebreak[SCORE]; if (max2>max1) return -1; else if (max2s1) return -1; else if (max2==max1 && s2m1) m1 = player[idb1].rating; m2 = player[idw2].rating; if (player[idb2].rating>m2) m2 = player[idb2].rating; if (max2==max1 && s2==s1 && m2>m1) return -1; return 1; // silly return with no effect to avoid complain from compiler } /************* compare routine during pairing for colored subgroup **************/ int CompareRatingTitleName(const void *pid1, const void *pid2) { // id1>id2 return -1, else return 1 int *id1, *id2; id1 = (int *) pid1; id2 = (int *) pid2; if (player[*id1].RATING > player[*id2].RATING) return -1; else if ( (player[*id1].RATING == player[*id2].RATING) && (player[*id1].title > player[*id2].title)) return -1; else if ( (player[*id1].RATING == player[*id2].RATING) && (player[*id1].title == player[*id2].title) && (strcmp(player[*id1].name, player[*id2].name)<0)) return -1; else return 1; } /************* compare routine during the chooce of an upfloater **************/ void SortUpfloater(int colorflag, int n, int array[]) // // PURPOSE: sort the pairs of the pairing with respect some criteria defined in comppair // { int i, j, t; for(i=1; i<=n-1; i++) { for (j=i+1; j<=n; j++) { switch (colorflag) { case 0: if ( CompareUpfDuecRatAroNome0( array[i], array[j])<0) { t = array[i]; array[i] = array[j]; array[j] = t;} break; // no color preference case 1: if ( CompareUpfDuecRatAroNome1( array[i], array[j])<0) { t = array[i]; array[i] = array[j]; array[j] = t;} break; // white color case 2: if ( CompareUpfDuecRatAroNome2( array[i], array[j])<0) { t = array[i]; array[i] = array[j]; array[j] = t;} break; // black color } } } } int CompareUpfDuecRatAroNome0(int id1, int id2) { // black = white, group equal if (player[id1].canUpfloat < player[id2].canUpfloat) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].RATING > player[id2].RATING) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro < player[id2].aro) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro == player[id2].aro) && (strcmp(player[id1].name, player[id2].name)>0)) return -1; else return 1; } int CompareUpfDuecRatAroNome1(int id1, int id2) { // get a white player if (player[id1].canUpfloat < player[id2].canUpfloat) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor < player[id2].duecolor) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING < player[id2].RATING) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro < player[id2].aro) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro == player[id2].aro) && (strcmp(player[id1].name, player[id2].name)>0)) return -1; else return 1; } int CompareUpfDuecRatAroNome2(int id1, int id2) { if (player[id1].canUpfloat < player[id2].canUpfloat) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor > player[id2].duecolor) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING < player[id2].RATING) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro < player[id2].aro) ) return -1; else if ( (player[id1].canUpfloat == player[id2].canUpfloat) && (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro == player[id2].aro) && (strcmp(player[id1].name, player[id2].name)>0)) return -1; else return 1; } /************* compare routine to chooce the opponent of the upfloater **************/ void SortDownfloater(int colorflag, int n, int array[]) // // PURPOSE: sort the pairs of the pairing with respect some criteria defined in comppair // { int i, j, t; for(i=1; i<=n-1; i++) { for (j=i+1; j<=n; j++) { switch (colorflag) { case 0: if ( CompareDuecRatAroNome0( array[i], array[j])<0) { t = array[i]; array[i] = array[j]; array[j] = t;} break; // no color preference case 1: if ( CompareDuecRatAroNome1( array[i], array[j])<0) { t = array[i]; array[i] = array[j]; array[j] = t;} break; // white color case 2: if ( CompareDuecRatAroNome2( array[i], array[j])<0) { t = array[i]; array[i] = array[j]; array[j] = t;} break; // black color } } } } int CompareDuecRatAroNome0(int id1, int id2) { // black = white, group equal if ( (player[id1].RATING > player[id2].RATING) ) return -1; else if ( (player[id1].RATING == player[id2].RATING) && (player[id1].aro < player[id2].aro) ) return -1; else if ( (player[id1].RATING == player[id2].RATING) && (player[id1].aro == player[id2].aro) && (strcmp(player[id1].name, player[id2].name)>0)) return -1; else return 1; } int CompareDuecRatAroNome1(int id1, int id2) { // get a white player if ( (player[id1].duecolor < player[id2].duecolor) ) return -1; else if ( (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING < player[id2].RATING) ) return -1; else if ( (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro < player[id2].aro) ) return -1; else if ( (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro == player[id2].aro) && (strcmp(player[id1].name, player[id2].name)>0)) return -1; else return 1; } int CompareDuecRatAroNome2(int id1, int id2) { if ( (player[id1].duecolor > player[id2].duecolor) ) return -1; else if ( (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING < player[id2].RATING) ) return -1; else if ( (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro < player[id2].aro) ) return -1; else if ( (player[id1].duecolor==player[id2].duecolor) && (player[id1].RATING == player[id2].RATING) && (player[id1].aro == player[id2].aro) && (strcmp(player[id1].name, player[id2].name)>0)) return -1; else return 1; } /************* compare routine during pairing for colored subgroup **************/ int CompareScoreName(const void *pid1, const void *pid2) { // id1>id2 return -1, else return 1 int *id1, *id2, tb[FUNC_CMP+1], s[FUNC_CMP+1]; id1 = (int *) pid1; id2 = (int *) pid2; int s1, s2; s1 = (int) (10 * player[*id1].tiebreak[SCORE]); s2 = (int) (10 * player[*id2].tiebreak[SCORE]); if (s1 > s2) return -1; s[1] = TD.tyebreakorder[1]; if (s[1]) { tb[1] = (*cmpfunc[ s[1] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]<0) ) return -1; } else return 1; s[2] = TD.tyebreakorder[2]; if (s[2]) { tb[2] = (*cmpfunc[ s[2] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]<0) ) return -1; } else return 1; s[3] = TD.tyebreakorder[3]; if (s[3]) { tb[3] = (*cmpfunc[ s[3] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]<0)) return -1; } else return 1; s[4] = TD.tyebreakorder[4]; if (s[4]) { tb[4] = (*cmpfunc[ s[4] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]<0) ) return -1; } else return 1; s[5] = TD.tyebreakorder[5]; if (s[5]) { tb[5] = (*cmpfunc[ s[5] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5] < 0)) return -1; } else return 1; s[6] = TD.tyebreakorder[6]; if (s[6]) { tb[6] = (*cmpfunc[ s[6] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] < 0)) return -1; } else return 1; s[7] = TD.tyebreakorder[7]; if (s[7]) { tb[7] = (*cmpfunc[ s[7] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] == 0) && (tb[7] < 0)) return -1; } else return 1; s[8] = TD.tyebreakorder[8]; if (s[8]) { tb[8] = (*cmpfunc[ s[8] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] == 0) && (tb[7]==0) && (tb[8] < 0)) return -1; } else return 1; s[9] = TD.tyebreakorder[9]; if (s[9]) { tb[9] = (*cmpfunc[ s[9] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] == 0) && (tb[7]==0) && (tb[8]==0) && (tb[9] < 0)) return -1; } else return 1; return 1; } int CompareCategoryScoreName(const void *pid1, const void *pid2) { // id1>id2 return -1, else return 1 int *id1, *id2, tb[FUNC_CMP+1], s[FUNC_CMP+1]; id1 = (int *) pid1; id2 = (int *) pid2; int s1, s2; if (player[*id1].title > player[*id2].title) return -1; s1 = (int) (10 * player[*id1].tiebreak[SCORE]); s2 = (int) (10 * player[*id2].tiebreak[SCORE]); if ( (player[*id1].title == player[*id2].title) && (s1 > s2)) return -1; s[1] = TD.tyebreakorder[1]; if (s[1]) { tb[1] = (*cmpfunc[ s[1] ])(*id1, *id2); if ( (player[*id1].title == player[*id2].title) && ( s1 == s2 ) && (tb[1]<0) ) return -1; } else return 1; s[2] = TD.tyebreakorder[2]; if (s[2]) { tb[2] = (*cmpfunc[ s[2] ])(*id1, *id2); if ( (player[*id1].title == player[*id2].title) && ( s1 == s2 ) && (tb[1]==0) && (tb[2]<0) ) return -1; } else return 1; s[3] = TD.tyebreakorder[3]; if (s[3]) { tb[3] = (*cmpfunc[ s[3] ])(*id1, *id2); if ( (player[*id1].title == player[*id2].title) && ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]<0)) return -1; } else return 1; s[4] = TD.tyebreakorder[4]; if (s[4]) { tb[4] = (*cmpfunc[ s[4] ])(*id1, *id2); if ( (player[*id1].title == player[*id2].title) && ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]<0) ) return -1; } else return 1; s[5] = TD.tyebreakorder[5]; if (s[5]) { tb[5] = (*cmpfunc[ s[5] ])(*id1, *id2); if ( (player[*id1].title == player[*id2].title) && ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5] < 0)) return -1; } else return 1; s[6] = TD.tyebreakorder[6]; if (s[6]) { tb[6] = (*cmpfunc[ s[6] ])(*id1, *id2); if ( (player[*id1].title == player[*id2].title) && ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] < 0)) return -1; } else return 1; s[7] = TD.tyebreakorder[7]; if (s[7]) { tb[7] = (*cmpfunc[ s[7] ])(*id1, *id2); if ( (player[*id1].title == player[*id2].title) && ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] == 0) && (tb[7] < 0)) return -1; } else return 1; s[8] = TD.tyebreakorder[8]; if (s[8]) { tb[8] = (*cmpfunc[ s[8] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] == 0) && (tb[7]==0) && (tb[8] < 0)) return -1; } else return 1; s[9] = TD.tyebreakorder[9]; if (s[9]) { tb[9] = (*cmpfunc[ s[9] ])(*id1, *id2); if ( ( s1 == s2 ) && (tb[1]==0) && (tb[2]==0) && (tb[3]==0) && (tb[4]==0) && (tb[5]==0) && (tb[6] == 0) && (tb[7]==0) && (tb[8]==0) && (tb[9] < 0)) return -1; } else return 1; return 1; } int CompareName(const void *pid1, const void *pid2) { // id1>id2 return 1, else return -1 int *id1, *id2; id1 = (int *) pid1; id2 = (int *) pid2; if (strcmp(player[*id1].name, player[*id2].name)<0) return -1; else return 1; } int cmpSB(int id1, int id2) { if (player[id1].tiebreak[SONN_BERG] > player[id2].tiebreak[SONN_BERG] ) return -1; else if (player[id1].tiebreak[SONN_BERG] < player[id2].tiebreak[SONN_BERG] ) return 1; else return 0; } int cmpBUC1(int id1, int id2) { if (player[id1].tiebreak[BUC_CUT1] > player[id2].tiebreak[BUC_CUT1] ) return -1; else if (player[id1].tiebreak[BUC_CUT1] < player[id2].tiebreak[BUC_CUT1] ) return 1; else return 0; } int cmpBUCM(int id1, int id2) { if (player[id1].tiebreak[BUC_MED] > player[id2].tiebreak[BUC_MED] ) return -1; else if (player[id1].tiebreak[BUC_MED] < player[id2].tiebreak[BUC_MED] ) return 1; else return 0; } int cmpBUCT(int id1, int id2) { if (player[id1].tiebreak[BUC_TOT] > player[id2].tiebreak[BUC_TOT] ) return -1; else if (player[id1].tiebreak[BUC_TOT] < player[id2].tiebreak[BUC_TOT] ) return 1; else return 0; } int cmpCUMUL(int id1, int id2) { if (player[id1].tiebreak[CUMUL] > player[id2].tiebreak[CUMUL] ) return -1; else if (player[id1].tiebreak[CUMUL] < player[id2].tiebreak[CUMUL] ) return 1; else return 0; } int cmpARO(int id1, int id2) { if (player[id1].tiebreak[ARO] > player[id2].tiebreak[ARO] ) return -1; else if (player[id1].tiebreak[ARO] < player[id2].tiebreak[ARO] ) return 1; else return 0; } int cmpMB(int id1, int id2) { if (player[id1].tiebreak[MOST_BLACKS] > player[id2].tiebreak[MOST_BLACKS] ) return -1; else if (player[id1].tiebreak[MOST_BLACKS] < player[id2].tiebreak[MOST_BLACKS] ) return 1; else return 0; } int cmpMWINS(int id1, int id2) { if (player[id1].tiebreak[MOST_WINS] > player[id2].tiebreak[MOST_WINS] ) return -1; else if (player[id1].tiebreak[MOST_WINS] < player[id2].tiebreak[MOST_WINS] ) return 1; else return 0; } int cmpAPRO(int id1, int id2) { if (player[id1].tiebreak[APRO] > player[id2].tiebreak[APRO] ) return -1; else if (player[id1].tiebreak[APRO] < player[id2].tiebreak[APRO] ) return 1; else return 0; } int cmpMPSS(int id1, int id2) // missing point score system { if (player[id1].tiebreak[MPSS] > player[id2].tiebreak[MPSS] ) return -1; else if (player[id1].tiebreak[MPSS] < player[id2].tiebreak[MPSS] ) return 1; if ( player[id1].tiebreak[SCORE] > player[id2].tiebreak[SCORE]) return -1; else if ( player[id1].tiebreak[SCORE] < player[id2].tiebreak[SCORE]) return 1; else return 0; } int CompareCountry(const void *pid1, const void *pid2) { // id1>id2 return -1, else return +1 int *id1, *id2; int s1, s2; id1 = (int *) pid1; id2 = (int *) pid2; s1 = (int) (10 * player[*id1].tiebreak[SCORE]); s2 = (int) (10 * player[*id2].tiebreak[SCORE]); if (strcmp(player[*id1].country, player[*id2].country)<0) return -1; else if ( player[*id1].country == player[*id2].country && (s1 > s2)) return -1; else return 1; } int cmpdata(int d1, int d2) { // d1