#include "VegaMain.h" #include "Tournament.h" int roundfloat( double per) { String str, str2; int ldig; double p; str = NFormat("%6.1f", per); // trasforma in stringa per prenderne la prima cifra decimale str2 = str.Mid(5,1); // ("%c", str[5]); ldig = StrIntValue(str2); str = str.Mid(0,4); // str[5] = '\0'; //remove last digitltima cifra p = StrDblValue(str); // calcola tot senza la cifra dei decimi if (ldig>=5 ) p += 1.; // arrotonda tot return (int) p; } int rat_flor[] = {2250, 2100, 2050, 1900}; int rat_norm[] = {2601, 2451, 2401, 2251}; int p_dp[] = {-735, -677, -589, -538, -501, -470, -444, -422, -401, -383, -366, -351, -336, -322, -309, -296, -284, -273, -262, -251, -240, -230, -220, -211, -202, -193, -184, -175, -166, -158, -149, -141, -133, -125, -117, -110, -102, -95, -87, -80, -72, -65, -57, -50, -43, -36, -29, -21, -14, -7, 0, 7, 14, 21, 29, 36, 43, 50, 57, 65, 72, 80, 87, 95, 102, 110, 117, 125, 133, 141, 149, 158, 166, 175, 184, 193, 202, 211, 220, 230, 240, 251, 262, 273, 284, 296, 309, 322, 336, 351, 366, 383, 401, 422, 444, 470, 501, 538, 589, 677, 735}; double diff[] = {0.50, 0.50, 0.50, 0.50, 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, 0.52, 0.52, 0.52, 0.52, 0.52, 0.52, 0.52, 0.53, 0.53, 0.53, 0.53, 0.53, 0.53, 0.53, 0.53, 0.54, 0.54, 0.54, 0.54, 0.54, 0.54, 0.54, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.56, 0.56, 0.56, 0.56, 0.56, 0.56, 0.56, 0.57, 0.57, 0.57, 0.57, 0.57, 0.57, 0.57, 0.58, 0.58, 0.58, 0.58, 0.58, 0.58, 0.58, 0.58, 0.59, 0.59, 0.59, 0.59, 0.59, 0.59, 0.59, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.61, 0.61, 0.61, 0.61, 0.61, 0.61, 0.61, 0.62, 0.62, 0.62, 0.62, 0.62, 0.62, 0.62, 0.62, 0.63, 0.63, 0.63, 0.63, 0.63, 0.63, 0.63, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.66, 0.66, 0.66, 0.66, 0.66, 0.66, 0.66, 0.66, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.68, 0.68, 0.68, 0.68, 0.68, 0.68, 0.68, 0.68, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.72, 0.72, 0.72, 0.72, 0.72, 0.72, 0.72, 0.72, 0.73, 0.73, 0.73, 0.73, 0.73, 0.73, 0.73, 0.73, 0.73, 0.74, 0.74, 0.74, 0.74, 0.74, 0.74, 0.74, 0.74, 0.74, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.76, 0.76, 0.76, 0.76, 0.76, 0.76, 0.76, 0.76, 0.76, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.78, 0.78, 0.78, 0.78, 0.78, 0.78, 0.78, 0.78, 0.78, 0.78, 0.79, 0.79, 0.79, 0.79, 0.79, 0.79, 0.79, 0.79, 0.79, 0.79, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.82, 0.82, 0.82, 0.82, 0.82, 0.82, 0.82, 0.82, 0.82, 0.82, 0.82, 0.83, 0.83, 0.83, 0.83, 0.83, 0.83, 0.83, 0.83, 0.83, 0.83, 0.83, 0.84, 0.84, 0.84, 0.84, 0.84, 0.84, 0.84, 0.84, 0.84, 0.84, 0.84, 0.84, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.86, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.87, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.88, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.89, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.91, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.92, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.93, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.94, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.97, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 1.00}; void RoundData::calcelo (int idp, double arrp[][2], int round) { int d, k; int idopp; for(k=1; k<=round; k++) { //the rating is not calculated for game finished with forfait, code 3, 4, 2, and 6 if (IS_SWISS) { idopp = playerOpponent[idp][k]; if ( idopp>0 && roundResult[idp][k]<3 ) // no forfeit { d = abs(player[idp].RATING - player[idopp].RATING); if ( d > 350) d = 350; arrp[k][0]= (float) d; if (player[idp].RATING >= player[idopp].RATING) arrp[k][1] = diff[ d ]; else arrp[k][1] = 1.0 - diff[ d ]; } else { arrp[k][0] = 0.; // rating difference arrp[k][1] = 0.; // expected result } } else { idopp = playerOpponentRR[idp][k]; if ( idopp>0 && roundResultRR[idp][k]<3 ) { d = abs(player[idp].RATING - player[idopp].RATING); if ( d > 350) d = 350; arrp[k][0]= (float) d; if (player[idp].RATING >= player[idopp].RATING) arrp[k][1] = diff[ d ]; else arrp[k][1] = 1.0 - diff[ d ]; } else { arrp[k][0] = 0.; // rating difference arrp[k][1] = 0.; // expected result } } } } void RoundData::EloForesee(int nplayers, int round) { int i, j, index, idopp, idopp_old, var, npair; int code, idw, idb, res; int plopp[N_PLAYER_MAX+1]; String str, str2, stringa; double arrp[N_ROUND_MAX_RR+2][2]; double totscore, kpoint, expected, tot2, previousExp; int ldig, d; int *roundRes; int *playerOpp; if (IS_SWISS) { playerOpp = &playerOpponent[0][0]; roundRes = &roundResult[0][0]; } else { playerOpp = &playerOpponentRR[0][0]; roundRes = &roundResultRR[0][0]; } FileOut saveelo(PATHDIR + "eloprev.txt"); saveelo<0) { // not forfait previousExp = totscore = 0.; calcelo(i, arrp, round-1); for(j=1; j<=round-1; j++) { if (IS_SWISS) index = i*(N_ROUND_MAX+1) + j; else index = i*(N_ROUND_MAX_RR+1) + j; idopp_old = playerOpp[index]; if ( idopp_old!=0 && roundRes[index]<3 ) { // not forfait previousExp += arrp[j][1]; if (roundRes[index]==1 || roundRes[index]==3) totscore += 1.0; else if (roundRes[index]==2 || roundRes[index]==6) totscore += 0.5; } } d = abs(player[i].RATING - player[idopp].RATING); if ( d > 350) d = 350; if (player[i].RATING >= player[idopp].RATING) expected = diff[ d ]; else expected = 1.0 - diff[ d ]; saveelo<5 && ldig<=9) tot2 += 0.1; // arrotonda tot // var = (int) rintf (player[i].kcoeff * (kpoint + totscore - tot2)) ; var = fround (player[i].kcoeff * (kpoint + totscore - tot2)) ; saveelo << NFormat(" %5d ", var); kpoint += 0.5; } saveelo<<"\n"; } } saveelo <<"\n Generated by Vega - www.vegachess.com\n"; saveelo.Close(); } void RoundData::CalcVarElo(int nplayers) { int i, j, idopp, index; double arrp[N_ROUND_MAX_RR+2][2]; double tot, tot2, totscore; int *roundRes; int *playerOpp; int ldig; String str, str2; if (IS_SWISS) { playerOpp = &playerOpponent[0][0]; roundRes = &roundResult[0][0]; // playerCol = &playerColor[0][0]; } else { playerOpp = &playerOpponentRR[0][0]; roundRes = &roundResultRR[0][0]; // playerCol = &playerColorRR[0][0]; } for (i=1; i<=nplayers; i++) { tot=0.; totscore=0.; //score without to consider the forfait calcelo(i, arrp, currentRound); for(j=1; j<=currentRound; j++) { if (IS_SWISS) index = i*(N_ROUND_MAX+1) + j; else index = i*(N_ROUND_MAX_RR+1) + j; idopp = playerOpp[index]; if ( idopp!=0 && roundRes[index]<3 ) { // not forfait tot += arrp[j][1]; if (roundRes[index]==1 || roundRes[index]==3) totscore += 1.0; else if (roundRes[index]==2 || roundRes[index]==6) totscore += 0.5; } } str = NFormat("%5.2f", tot); // trasforma tot in stringa per prenderne l'ultima cifra // Exclamation(str); str2=str.Mid(4,1); // Exclamation(str2); ldig = StrIntValue(str2); str = str.Mid(0,4); //toglie l'ultima cifra // Exclamation(str); tot2 = StrDblValue(str); // calcola tot senza la cifra dei centisimi if (ldig>5 && ldig<=9) tot2 += 0.1; // arrotonda tot // player[i].tiebreak[ELO_VAR] = (float) rintf(player[i].kcoeff * (totscore - tot2)) ; player[i].tiebreak[ELO_VAR] = (float) fround(player[i].kcoeff * (totscore - tot2)) ; } } void RoundData::SaveFSIRatingReport() // // This file contains part of the *.veg and part of *.rnd file // { int i, j, k, index, id, code[2]; int var, aro, nopp, navv; int arr[N_PLAYER_MAX+1], id_to_pos[N_PLAYER_MAX+1]; String stringa, str, col; String master = "Norma Maestro FSI: & "; float score, totscore, puntiplayerfide; int *roundRes; int *playerOpp, *playerCol, idopp; extern int CompareScoreName(const void *pid1, const void *pid2); if(NPlayer<1) return; if (TD.IS_SWISS) { playerOpp = &playerOpponent[0][0]; roundRes = &roundResult[0][0]; playerCol = &playerColor[0][0]; } else { playerOpp = &playerOpponentRR[0][0]; roundRes = &roundResultRR[0][0]; playerCol = &playerColorRR[0][0]; } // avoid negative rating variation to the winners for (i=0; i0) { aro += player[idopp].RATING; nopp++; if (roundRes[index]==1) puntiplayerfide += 1.0; else if (roundRes[index]==2) puntiplayerfide += 0.5; } if (roundRes[index]==1) totscore += 1.0; else if (roundRes[index]==2) totscore += 0.5; } } if (nopp!=0) aro = aro/nopp; else aro = 0; var = (int) player[i].tiebreak[ELO_VAR]; out << NFormat("%4d,", var); out << NFormat("%2d,", nopp); if (player[i].kcoeff==0) out << NFormat("%4d,", aro); else if (player[i].kcoeff>0 && nopp>=3) out << NFormat("%4d,", aro); else out << " 0,"; out << NFormat("%4.1f,", puntiplayerfide); out << NFormat("%4d,", id_to_pos[ i ] + 1); // posizione out << NFormat("%s\n", stringa); //Norma maestro FSI if ( currentRound>=9 && navv>=8 && player[i].title<=9 && player[i].tiebreak[PER_RAT]>2250 ) master<=25) Exclamation(master); } void RoundData::TestResult(int res, int code[]) { // code[0] = valid, 1 yes, 0 not // code[1] = result, 1 win. 2 lost, 3 draw switch (res) { // lost case 0: code[0] = 1; code[1] = 2; break; // win case 1: code[0] = 1; code[1] = 1; break; // draw case 2: code[0] = 1; code[1] = 3; break; // lost forfeit case 4: code[0] = 0; code[1] = 2; break; // win forfeit case 3: code[0] = 0; code[1] = 1; break; // draw forfeit case 6: code[0] = 0; code[1] = 3; break; } }