ultimatepp/uppdev/VegaTeam5/Tournament.cpp
cxl 3cd394812c Merge continued
git-svn-id: svn://ultimatepp.org/upp/trunk@10263 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2016-10-04 08:34:39 +00:00

1601 lines
65 KiB
C++

#include "VegaMain.h"
#include "Tournament.h"
/* definition of classes
- Tournament
- Round : general methods (specific methods are in RoundRobin and RoundSwiss
- TeamArchive
*/
TournamentStatus::TournamentStatus()
{
NAMETORNEO = "myTournament";
FILETORNEO = "myFile";
PLACETORNEO = "myTown";;
HOSTFEDERATION = "fed";;
DATATORNEO_B = DATATORNEO_E = "00000000";
ARBITER = "myArbiter";
PATHDIR = Null;
WON = 1.;
DRAW = 0.;
tyebreakorder[0]= 0; // order of the tyebreak
tyebreakorder[1]= 1;
tyebreakorder[2]= 2;
tyebreakorder[3]= tyebreakorder[4]= tyebreakorder[5]=tyebreakorder[6]=tyebreakorder[7]=
tyebreakorder[8]=tyebreakorder[9]=tyebreakorder[10]=tyebreakorder[11]=tyebreakorder[12]=0;
tyebreakname[0] = "";
tyebreakname[1] = " Buc1 ";
tyebreakname[2] = " BucT ";
tyebreakname[3] = " BucM ";
tyebreakname[4] = " S-B ";
tyebreakname[5] = " Cmlt ";
tyebreakname[6] = " ARO ";
tyebreakname[7] = " Mblk ";
tyebreakname[8] = " Mwns ";
tyebreakname[9] = " APRO ";
tyebreakname[10] =" PMss ";
tyebreakname[11] = "";
tyebreakname[12] = "";
NPlayer = 0; // player partecipating to the tournament
NAval = 0;
NRounds = 1; // rounds of the tournament
SCORE_TYPE = 1;
NBoards = 4;
NAccRound = 0;
currentRound = 0;
//useful flag
STATUS_ROUND = READY_FOR_PAIRING;
IS_DONE_MANUAL = IS_TORNEO_STARTED = DROP_PLAYER =
IS_CLOSED_REGISTRATION = IS_SAVED_ROUND = AVOID_SAME_COUNTRY =
IS_FIDE_TOURNAMENT = PERMIT3COLOR = IS_SWISS = false;
IS_SET_VERBOSE = true;
PLAY_SYSTEM = 2;
}
/////////////////////// class round ////////////////////////////////////
void RoundData::SaveVegFile(bool flag)
// flag = true, save normal
// flag = false, save the backup file
{ int i, k;
String filename;
if (flag) filename = PATHDIR + FILETORNEO + ".veg";
else filename = PATHDIR + FILETORNEO + ".bak";
FileOut out(filename);
String s;
s = VERSION; s << " # Do not edit this file!" ;
out.PutLine( s );
out.PutLine( NAMETORNEO);
// out.PutLine( PLACETORNEO );
// out.PutLine( HOSTFEDERATION);
out.PutLine( NFormat("%-20.20s %s", PLACETORNEO, HOSTFEDERATION ) );
out.PutLine( DATATORNEO_B + ", " + DATATORNEO_E);
out.PutLine( ARBITER);
out.PutLine( NFormat("%3.1f %3.1f", DRAW, WON ) );
out.PutLine( NFormat(" %d %d %d %d %d %d %d %d %d %d",
tyebreakorder[1], tyebreakorder[2], tyebreakorder[3], tyebreakorder[4],
tyebreakorder[5], tyebreakorder[6], tyebreakorder[7], tyebreakorder[8],
tyebreakorder[9], tyebreakorder[10]) );
out.PutLine( FILETORNEO );
out.PutLine( NFormat("%d %d %d %d %d %d",
NRounds, PLAY_SYSTEM, IS_FIDE_TOURNAMENT, NAccRound, NBoards, SCORE_TYPE) );
out.PutLine( NFormat("%d", IS_SAVED_ROUND) );
out.PutLine( NFormat("%d", db.GetCount()) ); // out.PutLine( AsString(teamList.GetCount()));
for (i=0; i<db.GetCount(); i++) { // NPlayer; i++) {
//String strID = AsString( i ); //db is zero based
String strID = db.GetKey(i); //db is zero based
TeamArchive& team = db.Get(strID);
//TeamArchive& team = db.GetKey(i);
String ss = team.name;
ss << ";" << team.origin << ";" << team.country << ";" << AsString(team.ratingfide) << ";" << team.isAvailable;
out.PutLine(ss); //add automatically a newline at the end of the line
for (k=0; k<MAX_BOARDS; k++) {
String s;
s = NFormat( "%-25.25s;", team.plr[k].name);
s << NFormat( "%3.3s;", team.plr[k].country);
s << NFormat( "%8.8s;", team.plr[k].data);
s << NFormat( "%s;", team.plr[k].sex);
s << NFormat( "%3.3s;", team.plr[k].codetitle);
s << NFormat( "%8d;", team.plr[k].idfide);
s << NFormat( "%5d;", team.plr[k].ratingfide);
s << NFormat( "%8d;", team.plr[k].idnat);
s << NFormat( "%5d;", team.plr[k].ratingnat);
s << NFormat( "%2d;", team.plr[k].kcoeff);
s << NFormat( "%2s", team.plr[k].isAvailable);
out.PutLine(s);
}
}
if (out.IsError()) Exclamation("Error writing the .veg FILE");
out.Close();
}
RoundData::RoundData()
{ Reset();
}
void RoundData::StartSystem(int play_system)
{ IS_TORNEO_STARTED = 1;
// set IS_SWISS
if (play_system == ROUND_ROBIN || play_system == ROUND_ROBIN2) IS_SWISS = false;
else IS_SWISS = true;
// set MAX_PLAYERS
if ( IS_SWISS ) MAX_PLAYERS = N_PLAYER_MAX;
else MAX_PLAYERS = N_PLAYER_MAX_RR; //for swiss system
}
void RoundData::Reset()
{ int i, j;
NPlayer = 0; // player partecipating to the tournament
currentRound = 0;
STATUS_ROUND = READY_FOR_PAIRING;
IS_DONE_MANUAL = IS_TORNEO_STARTED =
IS_CLOSED_REGISTRATION = IS_SAVED_ROUND = AVOID_SAME_COUNTRY =
PERMIT3COLOR = IS_SWISS = false;
IS_SET_VERBOSE = true;
PLAY_SYSTEM = ROUND_ROBIN;
MAX_PLAYERS = N_PLAYER_MAX_RR; // round Robin single
//add tye break name
// swiss tournament
for (i=0; i<=N_ROUND_MAX*4; i++) ScoreGroup[i] = 0.;
for (i=0; i<=N_PLAYER_MAX; i++)
for (j=0; j<=N_ROUND_MAX; j++) roundResult[i][j] = 0;
// pairing and result. pairing[0][r] is the number of pairs at the round r
for (i=0; i<=N_PLAYER_MAX/2; i++)
for (j=0; j<=N_ROUND_MAX; j++) pairing[i][j] = 0;
// specific round data
for (i=0; i<=N_PLAYER_MAX; i++)
for (j=0; j<=N_ROUND_MAX; j++) {
playerFloater[i][j] = 0;
playerColor[i][j] = 0;
playerOpponent[i][j] = 0;
}
// round robin tournament
for (i=0; i<=N_PLAYER_MAX_RR; i++)
for (j=0; j<=N_ROUND_MAX_RR; j++) roundResultRR[i][j] = 0;
// pairing and result. pairing[0][r] there is the number of pairs at the round r
for (i=0; i<=N_PLAYER_MAX_RR/2; i++)
for (j=0; j<=N_ROUND_MAX_RR; j++) pairingRR[i][j] = 0;
for (i=0; i<=N_PLAYER_MAX_RR; i++)
for (j=0; j<=N_ROUND_MAX_RR; j++) {
playerColorRR[i][j] = 0;
playerOpponentRR[i][j] = 0;
}
}
void RoundData::DecodeResult(int const code, int *idwhite, int *idblack, int *res)
//
// PURPOSE: parse the 7 digit integer and estract the players' id and result
//
// INPUT VARIABLE
// code = the number to be parsed
// *idwhite = pointer to int for white
// *idblack = pointer to int for black
// *res = pointer to int for result
//
{ int c;
*res = code % 10;
c = (int) (code/10); // remove last digit
*idblack = (int) (c % 1000); // the remainder is black's id
*idwhite = (int) (c / 1000); // remove last 3 digits and obtain white's id
}
int RoundData::CodifyResult(int idwhite, int idblack, int res)
//
// PURPOSE: put in a single integer the result of match between
// the player idwhite and idblack
//
// INPUT VARIABLE
// idwhite = id white player
// idblack = id black player
// res = match result. It is used the following convention
// 1: 1 - 0
// 0: 0 - 1
// 5: 1/2 - 1/2
// 3: 1F - 0 white win to forfait and get the BYE
// 4: 0 - 1F black win to forfait and get the BYE
// 2: 0 - 0 they lost, no color for both
// 6: 1/2F - 1/2F no color for both
// 7: adj 1/2 - 1/2 not valid for elo
// 8: 1/2F - 1/2F NB draw, forfeit, no color, no bucholz
// 9: ..... waiting a result
//
// OUTPUT VARIABLE
// a 7 digit integer with format "idwhite""idblack""res"
//
// NOTE: each id is 3 digit long as the max number player is fixed to 999
//
{ if ((idwhite>N_PLAYER_MAX) || (idblack>N_PLAYER_MAX))
{ Exclamation( t_("error in the data format"));
return 9;
}
return StrIntValue( NFormat( "%d%03d%1d", idwhite, idblack, res) );
}
void RoundData::SetPlayersResult(int round)
//
// PURPOSE: assign the result for each pair
//
// INPUT VARIABLE:
// round = round at which is done the assign
// pair[] = contains the code of the two players
//
// NOTE: code player result
// 1: player win
// 0: player lost
// 2: draw
// 3: win for forfeit
// 4: lost for forfeit
// 6: 1/2F - 1/2F draw forfeit
// 8: 1/2F - 1/2F draw forfeit, no bucholz
{ int npairs;
int i, idwhite, idblack, result, code;
if (TD.IS_SWISS) {
npairs = pairing[0][round];
for (i=1; i<=TD.NPlayer; i++) { // set the not available players
if (player[i].isAvailable != "1" ) TD.playerColor[i][round] = NO_COLOR;
}
}
else npairs = TD.pairingRR[0][round];
for (i=1; i<=npairs; i++)
{ if (TD.IS_SWISS) code = TD.pairing[i][round];
else code = TD.pairingRR[i][round];
TD.DecodeResult(code, &idwhite, &idblack, &result);
//
// NOTE: code player result set in roundresult
// 1: player win
// 0: player lost
// 2: draw
// 3: win for forfeit // i forfeit sono per res>2
// 4: lost for forfeit
// 6: 1/2F - 1/2F draw forfeit
// 5: no game (useful for round robin in case of odd player number //NEW
//
if (TD.IS_SWISS) {
switch (result)
{ case 0: TD.playerColor[idwhite][round] = WHITE_COLOR;
TD.playerColor[idblack][round] = BLACK_COLOR ;
TD.playerOpponent[idwhite][round] = idblack;
TD.playerOpponent[idblack][round] = idwhite;
TD.roundResult[idwhite][round] = 0; // White lost
TD.roundResult[idblack][round] = 1; // Black win
break;
case 1: TD.playerColor[idwhite][round] = WHITE_COLOR;
TD.playerColor[idblack][round] = BLACK_COLOR ;
TD.playerOpponent[idwhite][round] = idblack;
TD.playerOpponent[idblack][round] = idwhite;
TD.roundResult[idwhite][round] = 1; // White win
TD.roundResult[idblack][round] = 0; // Black lost
break;
case 5: TD.playerColor[idwhite][round] = WHITE_COLOR;
TD.playerColor[idblack][round] = BLACK_COLOR ;
TD.playerOpponent[idwhite][round] = idblack;
TD.playerOpponent[idblack][round] = idwhite;
TD.roundResult[idwhite][round] = 2; // White draw
TD.roundResult[idblack][round] = 2; // Black draw
break;
case 3: TD.playerColor[idwhite][round] = NO_COLOR;
TD.playerColor[idblack][round] = NO_COLOR ;
TD.playerOpponent[idwhite][round] = 0;
TD.playerOpponent[idblack][round] = 0;
TD.roundResult[idwhite][round] = 3; // win per forfeit
TD.roundResult[idblack][round] = 4; // lost per forfeit
break;
case 4: TD.playerColor[idwhite][round] = NO_COLOR; // black win forfait
TD.playerColor[idblack][round] = NO_COLOR ;
TD.playerOpponent[idwhite][round] = 0;
TD.playerOpponent[idblack][round] = 0;
TD.roundResult[idwhite][round] = 4; // lost per forfeit
TD.roundResult[idblack][round] = 3; // win per forfeit
break;
case 2: TD.playerColor[idwhite][round] = NO_COLOR;
TD.playerColor[idblack][round] = NO_COLOR ;
TD.playerOpponent[idwhite][round] = 0;
TD.playerOpponent[idblack][round] = 0;
TD.roundResult[idwhite][round] = 4; // lost per forfeit
TD.roundResult[idblack][round] = 4; // lost per forfeit
break;
case 7: TD.playerColor[idwhite][round] = WHITE_COLOR;
TD.playerColor[idblack][round] = BLACK_COLOR ;
TD.playerOpponent[idwhite][round] = idblack;
TD.playerOpponent[idblack][round] = idwhite;
TD.roundResult[idwhite][round] = 6; // White draw
TD.roundResult[idblack][round] = 6; // Black draw
break;
}
}
else {// Round Robin
switch (result)
{ case 0: TD.playerColorRR[idwhite][round] = WHITE_COLOR;
TD.playerColorRR[idblack][round] = BLACK_COLOR ;
TD.playerOpponentRR[idwhite][round] = idblack;
TD.playerOpponentRR[idblack][round] = idwhite;
TD.roundResultRR[idwhite][round] = 0; // White lost
TD.roundResultRR[idblack][round] = 1; // Black win
break;
case 1: TD.playerColorRR[idwhite][round] = WHITE_COLOR;
TD.playerColorRR[idblack][round] = BLACK_COLOR ;
TD.playerOpponentRR[idwhite][round] = idblack;
TD.playerOpponentRR[idblack][round] = idwhite;
TD.roundResultRR[idwhite][round] = 1; // White win
TD.roundResultRR[idblack][round] = 0; // Black lost
break;
case 5: TD.playerColorRR[idwhite][round] = WHITE_COLOR;
TD.playerColorRR[idblack][round] = BLACK_COLOR ;
TD.playerOpponentRR[idwhite][round] = idblack;
TD.playerOpponentRR[idblack][round] = idwhite;
TD.roundResultRR[idwhite][round] = 2; // White draw
TD.roundResultRR[idblack][round] = 2; // Black draw
break;
case 3: TD.playerColorRR[idwhite][round] = WHITE_COLOR;
TD.playerColorRR[idblack][round] = BLACK_COLOR ;
TD.playerOpponentRR[idwhite][round] = idblack;
TD.playerOpponentRR[idblack][round] = idwhite;
TD.roundResultRR[idwhite][round] = 3; // win per forfeit
TD.roundResultRR[idblack][round] = 4; // lost per forfeit
break;
case 4: TD.playerColorRR[idwhite][round] = WHITE_COLOR;
TD.playerColorRR[idblack][round] = BLACK_COLOR ;
TD.playerOpponentRR[idwhite][round] = idblack;
TD.playerOpponentRR[idblack][round] = idwhite;
TD.roundResultRR[idwhite][round] = 4; // lost per forfeit
TD.roundResultRR[idblack][round] = 3; // win per forfeit
break;
case 2: TD.playerColorRR[idwhite][round] = WHITE_COLOR;
TD.playerColorRR[idblack][round] = BLACK_COLOR ;
TD.playerOpponentRR[idwhite][round] = idblack;
TD.playerOpponentRR[idblack][round] = idwhite;
TD.roundResultRR[idwhite][round] = 4; // lost per forfeit
TD.roundResultRR[idblack][round] = 4; // lost per forfeit
break;
case 7: TD.playerColorRR[idwhite][round] = WHITE_COLOR;
TD.playerColorRR[idblack][round] = BLACK_COLOR ;
TD.playerOpponentRR[idwhite][round] = idblack;
TD.playerOpponentRR[idblack][round] = idwhite;
TD.roundResultRR[idwhite][round] = 6; // White draw
TD.roundResultRR[idblack][round] = 6; // Black draw
break;
}
}
}
}
/*
void RoundData::PrepareHTMLindex(void)
{ int j;
return;
FileOut savehtml(PATHDIRWWW + "index.html");
// produce index.HTML file
savehtml << "<html>\n<head>\n<title>"<< NAMETORNEO << "</title>\n";
savehtml << "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"> \n";
savehtml << "<style type=\"text/css\">\n";
savehtml << "<!-- td { font-size: x-medium; font-family: Verdana, Arial, Helvetica, sans-serif}\n";
savehtml << " th { background-color: #e2e2e2; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: medium; font-weight: bold; font-style: normal; color: #000000; clip: rect( )}\n";
savehtml << "A { font-family: verdana,arial,sans-serif; font-size:10pt; color: #0000FF; text-decoration: none; } \n";
savehtml << "A:hover { font-family: verdana,arial,sans-serif; font-size: 10pt; color: #FFFFFF; background-color: #ff0000} \n";
savehtml << "--> </style>\n";
savehtml << "</head>\n";
savehtml << "<body>\n";
savehtml << "<h2 align=\"center\">" << NAMETORNEO << "</h2>\n";
savehtml << "<h2 align=\"center\">" << PLACETORNEO << ", &nbsp;" << DATATORNEO_B <<", "<<DATATORNEO_E << "</h2>\n";
savehtml << "<hr width=\"100\%\" size=\"2\"> \n";
savehtml << "<h3 align=\"center\"> <a href=\"crosstbl.html\">" << t_("Cross Table") << "</a> </h3>\n";
savehtml << "<h3 align=\"center\"> <a href=\"tblscore.html\">" << t_("Ranking List") << "</a> </h3>\n";
savehtml << "<h3 align=\"center\"> <a href=\"playercard.html\">" << t_("Player Card") << "</a> </h3>\n";
if(IS_FIDE_TOURNAMENT) savehtml << "<h3 align=\"center\"> <a href=\"felovar.html\">" << t_("Rating Report") << "</a> </h3>\n";
if(PLAY_SYSTEM==DUBOV) savehtml << "<h3 align=\"center\"> <a href=\"scrgrp.html\">" << t_("Score Groups") << "</a> </h3>\n";
savehtml << "<table cellpadding=\"2\" cellspacing=\"4\" border=\"0\" align=\"center\"> \n";
savehtml << "<tbody>\n";
savehtml << "<tr>";
savehtml << "<th align=\"center\" >" << t_("Pairing/Results") << "</th> \n";
savehtml << "</tr>\n";
savehtml << "<tr>\n";
savehtml << "<td> \n";
for(j=1; j<=currentRound; j++)
{ savehtml << " <a href=\"pairs" <<j<< ".html\"> [ " << j <<" ] </a> \n";
}
savehtml << " </td>\n";
savehtml << "</tbody>\n";
savehtml << "</table>\n";
savehtml << "<br> <p align=\"center\"><a href=\"http://www.vegachess.com\"> Generated by Vega </a></p> \n";
savehtml << "</body>\n</html>\n";
savehtml.Close();
if(IS_FIDE_TOURNAMENT) FideEloVariationHTML();
}
*/
void RoundData::ShowTableCategoryScore(int nplayers)
//
// PURPOSE: sort the database according to the category, score and bucholz
//
// INPUT VARIABLE
// n = number of players to be sorted
//
{ int i, k, j, pos;
int arr[N_PLAYER_MAX+1];
String stringa, strname, str;
String filename;
extern int CompareCategoryScoreName(const void *pid1, const void *pid2);
filename = PATHDIR + "rankcat.txt";
// FileOut save( NFormat("%srankcat.txt", PATHDIR) );
FileOut save( filename );
save<< NAMETORNEO << "\n";
save<< PLACETORNEO << " - " << DATATORNEO_B <<", "<<DATATORNEO_E << "\n\n";
save<< t_("Standing at round ")<< currentRound<< t_(" sorted by category") << "\n\n";
for (i=0; i<nplayers; i++)
{ arr[i] = i+1; // set the id of each player in the array to be sort
}
qsort(arr, nplayers, sizeof(int), CompareCategoryScoreName);
save<<"Pos score ID NAME | Rtg Tit Fed | ";
j=1;
while (tyebreakorder[j]) {
switch ( tyebreakorder[j] ) // color the editSearch
{ case 1: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 2: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 3: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 4: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 5: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 6: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 7: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 8: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 9: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
}
j++;
}
save<< "\n";
j=1;
save<<"------------------------------------------------------------";
j=1;
while (tyebreakorder[j]) {
save<<"-------";
j++;
}
pos = 0;
save << "\n\n" << t_("Ranking for category: ") << player[ arr[0] ].codetitle << "\n";
for (k=0; k<nplayers; k++)
{ i=arr[k];
if ( (k != nplayers-1) && (k>=1) && (player[i].title != player[ arr[k-1] ].title) ) {
save << "\n" << t_("Ranking for category: ") << player[ arr[k] ].codetitle << "\n";
pos = 1;
} else pos++;
if (player[i].isAvailable != "0") strname = NFormat("%-20.20s", player[i].name);
else strname = NFormat("%-17.17s(W)", player[i].name);
save << NFormat("%3d %4.1f %3d %s | %4d %3s %3s | ",
pos, //position
player[i].tiebreak[SCORE],
i,
strname,
player[i].RATING,
player[i].codetitle,
player[i].country);
j=1;
while (tyebreakorder[j]) {
switch ( tyebreakorder[j] ) // color the editSearch
{ case 1: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_CUT1]);
break;
case 2: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_TOT]);
break;
case 3: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_MED]);
break;
case 4: save << NFormat(" %6.2f ", player[i].tiebreak[SONN_BERG]);
break;
case 5: save << NFormat(" %6.2f ", player[i].tiebreak[CUMUL]);
break;
case 6: save << NFormat(" %6.2f ", player[i].tiebreak[ARO]);
break;
case 7: save << NFormat(" %4.0f ", player[i].tiebreak[MOST_BLACKS]);
break;
case 8: save << NFormat(" %4.0f ", player[i].tiebreak[MOST_WINS]);
break;
case 9: save << NFormat(" %4.0f ", player[i].tiebreak[APRO]);
break;
}
j++;
}
save << "\n";
}
save<<"\n Generated by Vega - www.vegachess.com\n";
save.Close();
}
void RoundData::ShowTableScore(int nplayers)
//
// PURPOSE: rank the database according the score and bucholz
//
// INPUT VARIABLE
// n = number of players to be sorted
//
{ int i, inext, iprev, n, p, k, j;
int arr[N_PLAYER_MAX+1], next[11];
int tb, tbp=0;
String stringa, strname, str;
extern int CompareScoreName(const void *pid1, const void *pid2);
extern int (*cmpfunc[FUNC_CMP+1])(int, int);
FileOut save(PATHDIR + "tblscore.txt" );
FileOut savehtml(PATHDIRWWW + "index.html" );
save << NAMETORNEO << "\n";
save << PLACETORNEO << " - " << DATATORNEO_B <<", "<<DATATORNEO_E << "\n\n";
save << t_("Standing at round ")<< currentRound<< "\n\n";
for (i=0; i<nplayers; i++)
{ arr[i] = i+1; // set the id of each player in the array to be sort
}
qsort(arr, nplayers, sizeof(int), CompareScoreName);
save<<"Pos score ID NAME | Rtg Prat Fed | ";
j=1;
while (tyebreakorder[j]) {
switch ( tyebreakorder[j] )
{ case 1: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 2: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 3: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 4: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 5: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 6: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 7: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 8: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
case 9: save << NFormat(" %s ", tyebreakname[ tyebreakorder[j] ]);
break;
}
j++;
//save << str;
}
save<< "\n";
save<<"-----------------------------------------------------------";
j=1;
while (tyebreakorder[j]) {
save<<"-------";
j++;
}
save<< "\n";
for (j=0; j<10; j++) next[j]=0;
for (k=0; k<nplayers; k++)
{ i=arr[k];
inext=arr[k+1]; if (k==nplayers-1) inext=-1;
iprev=arr[k-1]; if (k==0) iprev= -1;
if (player[i].isAvailable != "0") strname = NFormat("%-20.20s", player[i].name);
else strname = NFormat("%-17.17s(W)", player[i].name);
stringa = NFormat( "%3d %4.1f %3d %3.3s %s | %4d %4d %3s | ",
k+1, //position
player[i].tiebreak[SCORE],
i,
player[i].codetitle, strname,
player[i].RATING,
(int) player[i].tiebreak[PER_RAT],
player[i].country);
save << stringa;
//tbp = (*cmpfunc[ tyebreakorder[1] ])(i, inext); //stampa il ritorno
switch ( tyebreakorder[1] ) // color the editSearch
{ case 1: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_CUT1]);
break;
case 2: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_TOT]);
break;
case 3: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_MED]);
break;
case 4: save << NFormat(" %6.2f ", player[i].tiebreak[SONN_BERG]);
break;
case 5: save << NFormat(" %6.2f ", player[i].tiebreak[CUMUL]);
break;
case 6: save << NFormat(" %6.2f ", player[i].tiebreak[ARO]);
break;
case 7: save << NFormat(" %4.0f ", player[i].tiebreak[MOST_BLACKS]);
break;
case 8: save << NFormat(" %4.0f ", player[i].tiebreak[MOST_WINS]);
break;
case 9: save << NFormat(" %4.0f ", player[i].tiebreak[APRO]);
break;
}
//save << str;
j=2; n=1; p=1;
while (tyebreakorder[j]) {
if (inext>=0 && n && player[i].tiebreak[SCORE] == player[inext].tiebreak[SCORE]) tb = (*cmpfunc[ tyebreakorder[j-1] ])(i, inext);
else tb=1;
if (iprev>=0 && p && player[i].tiebreak[SCORE] == player[iprev].tiebreak[SCORE]) tbp = (*cmpfunc[ tyebreakorder[j-1] ])(i, iprev); //stampa il ritorno
else tbp=1;
if (tb==0 || tbp==0) {
switch ( tyebreakorder[j] ) // color the editSearch
{ case 1: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_CUT1]);
break;
case 2: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_TOT]);
break;
case 3: save << NFormat(" %6.2f ", player[i].tiebreak[BUC_MED]);
break;
case 4: save << NFormat(" %6.2f ", player[i].tiebreak[SONN_BERG]);
break;
case 5: save << NFormat(" %6.2f ", player[i].tiebreak[CUMUL]);
break;
case 6: save << NFormat(" %6.2f ", player[i].tiebreak[ARO]);
break;
case 7: save << NFormat(" %4.0f ", player[i].tiebreak[MOST_BLACKS]);
break;
case 8: save << NFormat(" %4.0f ", player[i].tiebreak[MOST_WINS]);
break;
case 9: save << NFormat(" %4.0f ", player[i].tiebreak[APRO]);
break;
}
//save << str;
if ( tb != 0) n = 0;
if ( tbp != 0) p = 0;
j++;
}
else break;
}
save << "\n";
}
save<<"\n Generated by Vega - www.vegachess.com\n";
save.Close();
// produce HTML files
savehtml << TD.HTMLCommonHeader();
savehtml << HTMLNavBar();
savehtml << "<h2>" << NAMETORNEO << "</h2>\n";
savehtml << "<h2>" << PLACETORNEO << " - " << DATATORNEO_B <<", "<<DATATORNEO_E << "</h2>\n";
savehtml << "<h3> " << t_("Standing at round ")<< currentRound<< " </h3>\n";
savehtml << "<table bgcolor=#efefef cellpadding=4 cellspacing=0 border=\"0\"> \n";
savehtml << "<tbody>\n";
savehtml << "<tr> ";
savehtml << "<th>Pos</th> <th>Scr</th> <th>ID</th> <th width=\"200\">NAME</th> <th>Rat</th> <th>PRat</th> <th>Nat</th> ";
j=1;
while (tyebreakorder[j]) {
switch ( tyebreakorder[j] ) // color the editSearch
{ case 1: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 2: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 3: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 4: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 5: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 6: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 7: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 8: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
case 9: savehtml << NFormat("<th> %s </th>", tyebreakname[ tyebreakorder[j] ]);
break;
}
j++;
//savehtml << str;
}
savehtml << "\n</tr> \n";
for (k=0; k<nplayers; k++)
{ i=arr[k];
if (player[i].isAvailable != "0") strname = NFormat("%-20.20s", player[i].name);
else strname = NFormat("%-17.17s(W)", player[i].name);
stringa = NFormat("<td align=right>%3d</td> <td align=right>%4.1f</td> <td align=right>%2d</td> <td> <a href=\"playercard.html#%d\"> %3s %s </a> <td>%4d</td> <td align=right>%4d</td> <td>%3s</td>",
k+1,
player[i].tiebreak[SCORE],
i, i,
player[i].codetitle, strname,
player[i].RATING,
(int) player[i].tiebreak[PER_RAT],
player[i].country);
if ((k+1)&1) savehtml << "<tr bgcolor=#e2e2f8> ";
else savehtml << "<tr bgcolor=#ffffff> ";
savehtml << stringa;
j=1;
while (tyebreakorder[j]) {
switch ( tyebreakorder[j] ) // color the editSearch
{ case 1: savehtml << NFormat("<td> %6.2f </td> ", player[i].tiebreak[BUC_CUT1]);
break;
case 2: savehtml << NFormat("<td> %6.2f </td> ", player[i].tiebreak[BUC_TOT]);
break;
case 3: savehtml << NFormat("<td> %6.2f </td> ", player[i].tiebreak[BUC_MED]);
break;
case 4: savehtml << NFormat("<td> %6.2f </td> ", player[i].tiebreak[SONN_BERG]);
break;
case 5: savehtml << NFormat("<td> %6.2f </td> ", player[i].tiebreak[CUMUL]);
break;
case 6: savehtml << NFormat("<td> %6.2f </td> ", player[i].tiebreak[ARO]);
break;
case 7: savehtml << NFormat("<td align=\"center\"> %4.0f </td> ", player[i].tiebreak[MOST_BLACKS]);
break;
case 8: savehtml << NFormat("<td align=\"center\"> %4.0f </td> ", player[i].tiebreak[MOST_WINS]);
break;
case 9: savehtml << NFormat("<td align=\"center\"> %4.0f </td> ", player[i].tiebreak[APRO]);
break;
}
j++;
//savehtml << str;
}
savehtml << "\n</tr> \n";
}
savehtml << "</tbody>\n";
savehtml << "</table>\n";
savehtml << "<br> <a href=\"http://www.vegachess.com\"> Generated by Vega </a> \n";
savehtml << "</DIV></body>\n</html>\n";
savehtml.Close();
if(IS_FIDE_TOURNAMENT) FideEloVariationHTML();
}
void RoundData::NationalPlayerCard(int nplayers)
{ int i, j, idopp, per, var, aro, nopp, index;
String stringa, color;
double arrp[N_ROUND_MAX_RR+2][2];
double tot, totscore, result, sumtotscore, score_perform;
int *roundRes;
int *playerCol;
int *playerOpp;
extern int p_dp[];
extern int roundfloat( double per);
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];
}
FileOut save(PATHDIR + "playercd.txt");
FileOut saveelo(PATHDIR + "elovar.txt");
saveelo << NAMETORNEO << "\n";
saveelo<< PLACETORNEO << " - " << DATATORNEO_B <<", "<<DATATORNEO_E << "\n\n";
saveelo<< t_("Rating variation at round ")<< currentRound << "\n\n";
saveelo << " ID NAME K Rtg var Per.Rat\n";
saveelo <<"---------------------------------------------------------\n";
for (i=1; i<=nplayers; i++)
{ tot=0.;
aro = 0;
nopp = 0;
totscore = score_perform = 0.; //score without to consider the forfait, score for performance calculation
sumtotscore = 0.;
save<<"\n\n" << NAMETORNEO << "\n" << PLACETORNEO << ", " << DATATORNEO_B <<", "<<DATATORNEO_E << "\n";
stringa = NFormat(" %3d %s %-20.20s, K=%2d, Elo=%4d, ID=%d\n",
i, player[i].codetitle,
player[i].name,
player[i].kcoeff,
player[i].RATING,
player[i].idnat);
save << stringa;
save <<"----------------------------------------------------------------\n";
save<<" r Col ID Opponent Rtg diff exp. res Cum Score\n";
save <<"----------------------------------------------------------------\n";
calcelo(i, arrp, currentRound);
for(j=1; j<=currentRound; j++)
{ if (PLAY_SYSTEM != ROUND_ROBIN && PLAY_SYSTEM != ROUND_ROBIN2) 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];
aro += player[idopp].RATING; nopp++;
if (roundRes[index]==1)
{ totscore += WON; result = WON; sumtotscore += totscore; score_perform += 1.;}
else if (roundRes[index]==2)
{ totscore += DRAW; result = DRAW; sumtotscore += totscore; score_perform += 0.5;}
else if (roundRes[index]==0)
{ result = 0.; sumtotscore += totscore;}
else if (roundRes[index]==8)
{ result = DRAW; sumtotscore += totscore;}
if (playerCol[index] == WHITE_COLOR) color = "W ";
else if (playerCol[index] == BLACK_COLOR) color = " B";
save << NFormat("%2d %2s %3d %-20.20s %4d %4d %5.2f %4.1f %4.1f %5.1f\n",
j, color, idopp, player[idopp].name,
player[idopp].RATING, (int) arrp[j][0], // diff
arrp[j][1], // expected score
result, totscore, player[idopp].tiebreak[SCORE]);
}
else { //forfeit
if (roundRes[index]==1)
{ totscore += WON; result = WON; sumtotscore += totscore;}
else if (roundRes[index]==3) // forfeit
{ totscore += DRAW; result = WON; sumtotscore += totscore;}
else if (roundRes[index]==2 || roundRes[index]==6) // forfeit
{ totscore += DRAW; result = DRAW; sumtotscore += totscore;}
else if (roundRes[index]==0 || roundRes[index]==4)
{ result = 0.; sumtotscore += totscore + DRAW;} //il forfeit e' considerato patta
else if (roundRes[index]==8)
{ result = DRAW; sumtotscore += totscore;}
save << NFormat("%2d -- %3d %-20.20s %4d %4s %5s %4.1f %4.1f %5.1f\n",
j, idopp, "not played", //player[idopp].name,
player[idopp].RATING,
" - ", // diff
" - ", // expected score
result, totscore, 0.0);
}
}
if (nopp!=0) aro = aro/nopp; // else is 0
var = (int) player[i].tiebreak[ELO_VAR];
per = aro + p_dp[ roundfloat(100.* score_perform /nopp) ];
if (per==0 || per==1000) per=0;
if (per>9999) per=9999;
player[i].tiebreak[PER_RAT] = (float) per;
save <<"----------------------------------------------------------------\n";
save << NFormat(" var=%3d, PRat=%5d, ARO=%4d, %5.2f %4.1f %4.1f\n",
var, per, aro, tot, player[i].tiebreak[SCORE], sumtotscore);
saveelo << NFormat(" %3d %-20.20s %2d %4d %4d %5d\n",
i, player[i].name, player[i].kcoeff, player[i].RATING, var, per);
}
save.Close();
saveelo << "\nGenerated by Vega - www.vegachess.com\n";
saveelo.Close();
NationalPlayerCardHTML(nplayers);
}
void RoundData::NationalPlayerCardHTML(int nplayers)
{ int i, j, idopp, nopp, index;
String stringa, color;
double arrp[N_ROUND_MAX_RR+2][2], tot, totscore, result, aro;
int *roundRes;
int *playerCol;
int *playerOpp;
if (PLAY_SYSTEM != ROUND_ROBIN && PLAY_SYSTEM != ROUND_ROBIN2) {
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];
}
// produce HTML files
FileOut savehtml(PATHDIRWWW + "playercard.html");
savehtml << HTMLCommonHeader();
// savehtml << HTMLCommonHeader();
savehtml << HTMLNavBar();
savehtml << "<h2>" << t_("National Player Cards") << "</h2>\n";
savehtml << "<table cellpadding=4 cellspacing=0 border=1> \n";
savehtml << "<tbody>\n";
for(i=1; i<=nplayers; i++)
{ savehtml << "\n<tr> <td>\n";
tot=0.;
aro = 0;
nopp = 0;
totscore=0.; //score without to consider the forfait
stringa = NFormat(" %3d %s %-20.20s, K=%2d, Elo=%4d, ID=%d\n",
i, player[i].codetitle, player[i].name, player[i].kcoeff, player[i].RATING, player[i].idnat);
calcelo(i, arrp, currentRound);
savehtml << "\n\n <a name=\""<< i <<"\"></a> <H4>" << NAMETORNEO << " <br> " << PLACETORNEO << ", " << DATATORNEO_B <<", "<<DATATORNEO_E << "<br>\n";
savehtml << stringa << "</H4>\n";
savehtml << "<table bgcolor=#e2e2f8 cellpadding=3 cellspacing=0 border=0> \n";
savehtml << "<tbody>\n";
savehtml << "<tr> ";
savehtml << "<th>R</th> <th>C</th> <th>ID</th> <th width=165>OPPONENT</th> <th>Rtg</th> <th>diff</th> <th>exp.</th> <th>res</th> <th>Cum</th> <th>Score</th>\n";
savehtml << "</tr> \n";
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];
aro += player[idopp].RATING; nopp++;
if (roundRes[index]==1 || roundRes[index]==3)
{ totscore += 1.0; result = WON;}
else if (roundRes[index]==2 || roundRes[index]==6)
{ totscore += 0.5; result = DRAW;}
else if (roundRes[index]==0 || roundRes[index]==4) result = 0.;
if (playerCol[index] == WHITE_COLOR) color = "W ";
else if (playerCol[index] == BLACK_COLOR) color = " B";
stringa = NFormat("<td>%d</td> <td>%s</td> <td>%d</td> <td> <a href=\"playercard.html#%d\"> %s %-20.20s </a> <td>%d</td> <td>%d</td> \n",
j, color, idopp, idopp, player[idopp].codetitle, player[idopp].name,
player[idopp].RATING, (int) arrp[j][0] );
stringa << NFormat("<td>%5.2f</td> <td>%4.1f</td> <td>%4.1f</td> <td>%4.1f</td>\n",
arrp[j][1], result, totscore, player[idopp].tiebreak[SCORE]);
if (j&1) savehtml << "<tr> ";
else savehtml << "<tr bgcolor=#ffffff> ";
savehtml << stringa;
savehtml << "</tr> \n";
}
else {
if (roundRes[index]==1 || roundRes[index]==3) result = 1.0;
else if (roundRes[index]==2 || roundRes[index]==6) result = 0.5;
else if (roundRes[index]==0 || roundRes[index]==4) result = 0.;
stringa = NFormat("<td>%d</td> <td>--</td> <td>%d</td> <td>not played</td> <td>%d</td> <td>--</td> <td>--</td> <td>%4.1f</td> <td>%4.1f</td> <td>%4.1f</td>\n",
j,idopp,player[idopp].RATING, result, totscore, 0.0);
if (j&1) savehtml << "<tr> ";
else savehtml << "<tr bgcolor=#ffffff> ";
savehtml << stringa;
savehtml << "</tr> \n";
}
}
if (nopp!=0) aro = aro/nopp;
stringa = NFormat("<td></td> <td></td> <td></td> <td> <b>var = %3d, PRat=%4d </b></td> <td><b>%.1f</b></td> <td></td> <td><b>%5.2f</b></td> <td><b>%4.1f</b></td> <td></td> <td></td>\n",
(int) player[i].tiebreak[ELO_VAR], (int) player[i].tiebreak[PER_RAT], aro, tot,
player[i].tiebreak[SCORE]);
savehtml << "<tr bgcolor=#f2f2cc> ";
savehtml << stringa;
savehtml << "</tr> \n";
savehtml << "</tbody>\n";
savehtml << "</table>\n";
savehtml << "\n</tr> </td>\n";
}
savehtml << "</tbody>\n";
savehtml << "</table>\n";
savehtml << "<br> <a href=\"http://www.vegachess.com\"> Generated by Vega </a> \n";
savehtml << "</body>\n</DIV>\n</html>\n";
savehtml.Close();
}
void RoundData::ShowRoundCard2(int round)
{ int i, nhalf;
int code, idwhite, idblack, result;
String stringa;
FileOut save(PATHDIR + "boardcrd.txt");
if (IS_SWISS) nhalf = pairing[0][round];
else nhalf = pairingRR[0][round];
for (i=1; i<=nhalf; i++)
{ //if (i>0 && (i%4)==0) save << "\f\n"; // form feed each 4 cards
if (PLAY_SYSTEM != ROUND_ROBIN && PLAY_SYSTEM != ROUND_ROBIN2) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &idwhite, &idblack, &result);
save<<"\n" << "Table " << i<< t_(", Round: ") << round<< ", " <<NAMETORNEO<<" " << DATATORNEO_B <<", "<<DATATORNEO_E << "\n";
save << NFormat("\n %3d %-20.20s (%4d,%3s) %4.1f - %3d %-20.20s (%4d,%3s) %4.1f\n",
idwhite,
player[idwhite].name,
player[idwhite].RATING,
player[idwhite].codetitle,
player[idwhite].tiebreak[SCORE],
idblack,
player[idblack].name,
player[idblack].RATING,
player[idblack].codetitle,
player[idblack].tiebreak[SCORE]);
save<<"\n _______________________ _________ _______________________\n";
save<<" white signature result black signature\n";
save<<"\n - - - - - - - - -\n";
//if (i>0 && (i%5)==0) save<<"\n\n\n";
}
save<< "\n";
save.Close();
ShowRoundCard3(round);
}
void RoundData::ShowRoundCard3(int round)
{ const int np =7;
int i, r, c, nhalf, npages;
int code, idwhite, idblack, result;
String stringa;
FileOut save(PATHDIR + "boardcrd.rtf");
if (IS_SWISS) nhalf = pairing[0][round];
else nhalf = pairingRR[0][round];
save<<"{\\rtf1\\ansi\\uc0 \\deff1 " << "\n";
save<<"{\\fonttbl{\\f1\\froman\\fcharset0\\fprq2 Courier ;}} " << "\n";
save<<"{\\colortbl;\\red0\\green0\\blue0;\\red0\\green0\\blue255;\\red0\\green255\\blue255;\\red0\\green255\\blue0;\\red255\\green0\\blue255;\\red255\\green0\\blue0; " << "\n";
save<<"\\red255\\green255\\blue0;\\red255\\green255\\blue255;\\red0\\green0\\blue128;\\red0\\green128\\blue128;\\red0\\green128\\blue0;\\red128\\green0\\blue128;\\red128\\green0\\blue0;\\red128\\green128\\blue0;\\red128\\green128\\blue128;\\red192\\green192\\blue192;} " << "\n";
save<<"{\\info }\\paperw11900\\paperh16820\\margl560\\margr560\\margt700\\margb700\\widowctrl\\ftnbj\\aenddoc\\formshade \\fet0\\sectd " << "\n";
save<<"\\linex0\\endnhere\\plain " << "\n";
if (IS_SWISS) npages = (int) ceil(1.*pairing[0][round]/np);
else npages = (int) ceil(1.*pairingRR[0][round]/np);
for (c=1; c<=npages; c++)
{ for(r=1; r<=np; r++)
{ i = c + (r-1) * npages;
if (i<=nhalf) {
if (IS_SWISS) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &idwhite, &idblack, &result);
save<<"\n \\pard{\\cf1{\\fs20\\f1 Table " << i<<", Round = "<< round<<", Tournament: "<<NAMETORNEO<<", Date:" << DATATORNEO_B <<", "<<DATATORNEO_E << "}} \n \\par \\par \n";
save << NFormat("\\pard {\\cf1{\\fs20\\f1 %3d %-20.20s (%4d,%3s) %4.1f - %3d %-20.20s (%4d,%3s) %4.1f}} \n \\par \\par \n",
idwhite,
player[idwhite].name,
player[idwhite].RATING,
player[idwhite].codetitle,
player[idwhite].tiebreak[SCORE],
idblack,
player[idblack].name,
player[idblack].RATING,
player[idblack].codetitle,
player[idblack].tiebreak[SCORE] );
save<<"\\pard {\\cf1{\\fs20\\f1 _______________________ _________ _______________________ }} \n \\par \\par \n";
save<<"\\pard {\\cf1{\\fs20\\f1 white signature result black signature }} \n \\par \\par \n";
if ( (r%7)!=0 ) save<<"\\pard {\\cf1{\\fs20\\f1 - - - - - - - - - }} \n \\par \\par \n";
}
}
save<<"\\page ";
}
save<<"\\par }}";
save.Close();
}
/*
void RoundData::ShowRoundCard3(int round)
{ const int np = 6;
int i, r, c, nhalf, npages;
int code, idwhite, idblack, result;
String stringa;
FileOut save(PATHDIR + "boardcrd.qtf");
if (IS_SWISS) nhalf = pairing[0][round];
else nhalf = pairingRR[0][round];
save << "[ $$0,0#00000000000000000000000000000000:Default] \n";
if (IS_SWISS) npages = (int) ceil(1.*pairing[0][round]/np);
else npages = (int) ceil(1.*pairingRR[0][round]/np);
for (c=1; c<=npages; c++)
{ for(r=1; r<=np; r++)
{ i = c + (r-1) * npages;
if (i<=nhalf) {
if (IS_SWISS) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &idwhite, &idblack, &result);
//save<<"\n \\pard{\\cf1{\\fs20\\f1 Table " << i<<", Round = "<< round<<", Tournament: "<<NAMETORNEO<<", Date:" << DATATORNEO_B <<", "<<DATATORNEO_E << "}} \n \\par \\par \n";
save << "[{_} [s0;=QC2 [* Board " << i << " ], round " << round<< " , Tournament: " << NAMETORNEO << " &] \n";
save << NFormat("[s0;=QC2 %3d %-15.15s (%4d,%3s) %4.1f - %3d %-15.15s (%4d,%3s) %4.1f &] \n",
idwhite,
player[idwhite].name,
player[idwhite].RATING,
player[idwhite].codetitle,
player[idwhite].tiebreak[SCORE],
idblack,
player[idblack].name,
player[idblack].RATING,
player[idblack].codetitle,
player[idblack].tiebreak[SCORE] );
save << "[s0;Q2 &] [s0;=QC2 `_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_ `_`_`_`_`_`_`_`_`_ `_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_`_&]\n";
if (r<np) save << "[s0;Q2 ] [s0;=QC2 `_`_ `_`_ `_`_ `_`_ `_`_ `_`_&] \n";
}
}
save<<" ^^ \n";
}
save.Close();
}
*/
void RoundData::SavePairsResultFile(int round)
//
// PURPOSE: show the result
//
{ int i, code, iw, ib, res, npairs;
String name, stringa;
FileOut savepair(PATHDIR + "result" + AsString( round ) + ".txt");
// savepair << "==============================================================\n";
savepair << NAMETORNEO << t_(": Results of round ") << round <<"\n";
savepair << "=====================================================================================\n";
if (IS_SWISS) npairs = pairing[0][round];
else npairs = pairingRR[0][round];
for (i=1; i<=npairs; i++)
{
if (IS_SWISS) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &iw, &ib, &res);
savepair << NFormat("%3d = %-20.20s (%4.1f) - %-20.20s (%4.1f) = %3d - %3d = %s\n",
i,
player[iw].name, player[iw].tiebreak[SCORE],
player[ib].name, player[ib].tiebreak[SCORE],
iw, ib, LabelResult(res, code, round) );
savepair << "---------------------------------------------------------------------------------------\n";
}
savepair << "\n Generated by Vega - www.vegachess.com\n";
savepair.Close();
// produce HTML files
FileOut savehtml(PATHDIRWWW + "pairs" + AsString(round) + ".html");
savehtml << TD.HTMLCommonHeader();
savehtml << HTMLNavBar();
savehtml << "<h2>" << NAMETORNEO << "</h2>\n";
savehtml << "<h2>" << PLACETORNEO << " - " << DATATORNEO_B <<", "<<DATATORNEO_E << "</h2>\n";
savehtml << "<h3> Result at round "<< currentRound<< "</h3>\n";
savehtml << "<table bgcolor=#efefef cellpadding=4 cellspacing=0 border=0> \n";
savehtml << "<tbody>\n";
savehtml << "<tr> <th>Bo.</th> <th >White</th> <th>Black</th> <th>result</th></tr>\n";
if (IS_SWISS) npairs = pairing[0][round];
else npairs = pairingRR[0][round];
for (i=1; i<=npairs; i++)
{ if (IS_SWISS) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &iw, &ib, &res);
if (i&1) savehtml << "<tr bgcolor=#e2e2f8> ";
else savehtml << "<tr bgcolor=#ffffff> ";
savehtml << NFormat(" <td align=center >%3d</td> <td> <a href=\"playercard.html#%d\">%d %s %s </a> </td> <td><a href=\"playercard.html#%d\">%d %s %s </a></td> <td align=\"center\">%s</td></tr>\n",
i,
iw, iw, player[iw].codetitle, player[iw].name,
ib, ib, player[ib].codetitle, player[ib].name, LabelResult(res, code, round));
}
savehtml << "</tbody>\n";
savehtml << "</table>\n";
savehtml << "</DIV></body>\n</html>\n";
savehtml << "<br> <p align=\"center\"><a href=\"http://www.vegachess.com\"> Generated by Vega </a></p> \n";
savehtml.Close();
}
void RoundData::setAPRO(int round, int numberPlayer)
//
// NOTE: it is called just after the iserting the result of the round
// so at round N, the state refer to the previous N-1 rounds
//
{ int id, j, np, jopp, index;
float apro;
int *roundRes;
int *playerCol;
int *playerOpp;
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 (id=1; id<=numberPlayer; id++)
{
//set Average performance rating opponent
apro = 0.;
np = 0;
for (j=1; j<=round; j++)
{ if (PLAY_SYSTEM != ROUND_ROBIN && PLAY_SYSTEM != ROUND_ROBIN2) index = id*(N_ROUND_MAX+1) + j;
else index = id*(N_ROUND_MAX_RR+1) + j;
jopp = playerOpp[index];
if (jopp != 0 && roundRes[index] < 3) // no BYE o game won for forfait
{ apro += player[jopp].tiebreak[PER_RAT];
np++;
}
}
if (np != 0) player[id].tiebreak[APRO] = apro/np;
else player[id].tiebreak[APRO] = 0.;
}
}
void RoundData::SavePairsFile(int round)
//
// PURPOSE: show the current pairs, i.e. the last done
//
{ int i, code, iw, ib, res, npairs;
String name, stringa;
FileOut savepair(PATHDIR + "pairs" + AsString( round ) + ".txt");
savepair << NAMETORNEO << t_(": Pairing of round ") << round <<"\n\n";
savepair << "=================================================================================\n";
if (IS_SWISS) npairs = pairing[0][round];
else npairs = pairingRR[0][round];
for (i=1; i<=npairs; i++)
{ if (IS_SWISS) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &iw, &ib, &res);
savepair << NFormat("%3d = %-20.20s (%4.1f) - %-20.20s (%4.1f) = %3d - %3d = ...\n",
i,
player[iw].name, player[iw].tiebreak[SCORE],
player[ib].name, player[ib].tiebreak[SCORE],
iw, ib );
savepair << "---------------------------------------------------------------------------------\n";
}
savepair << t_("\n The following player(s) got a BYE:\n");
for (i=1; i<=TD.NPlayer; i++)
{ if ( IsNull(player[i].isAvailable) ) savepair << NFormat(" %3d - %-20.20s\n", i, player[i].name);
}
savepair << t_("\n The following player(s) withdrew:\n");
for (i=1; i<=TD.NPlayer; i++)
{ if (player[i].isAvailable== "0") savepair << NFormat(" %3d - %-20.20s\n", i, player[i].name);
}
savepair << "\n Generated by Vega - www.vegachess.com\n";
savepair.Close();
// produce HTML files
FileOut savehtml(PATHDIRWWW + "pairs" + AsString(round) + ".html");
savehtml << TD.HTMLCommonHeader();
savehtml << HTMLNavBar();
savehtml << "<h2>" << NAMETORNEO << "</h2>\n";
savehtml << "<h2>" << PLACETORNEO << " - " << DATATORNEO_B <<", "<<DATATORNEO_E << "</h2>\n";
savehtml << "<h3> Pairing at round "<< currentRound<< "</h3>\n";
savehtml << "<table bgcolor=#efefef cellpadding=4 cellspacing=0 border=0> \n";
savehtml << "<tbody>\n";
savehtml << "<tr><th>Bo.</th> <th >White</th> <th>Black</th> <th>result</th></tr>\n";
if (IS_SWISS) npairs = pairing[0][round];
else npairs = pairingRR[0][round];
for (i=1; i<=npairs; i++)
{ if (IS_SWISS) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &iw, &ib, &res);
if (i&1) savehtml << "<tr bgcolor=#e2e2f8> ";
else savehtml << "<tr bgcolor=#ffffff> ";
savehtml << NFormat(" <td align=center>%3d</td> <td> <a href=\"playercard.html#%d\"> %d %s %s </a> (%.1f)</td> ",
i,
iw, iw, player[iw].codetitle, player[iw].name, player[iw].tiebreak[SCORE]);
savehtml << NFormat(" <td> <a href=\"playercard.html#%d\"> %d %s %s </a> (%.1f)</td> <td>...</td></tr>\n",
ib, ib, player[ib].codetitle, player[ib].name, player[ib].tiebreak[SCORE]);
}
savehtml << "</tbody>\n";
savehtml << "</table>\n";
savehtml << "<br> <p align=\"center\"><a href=\"http://www.vegachess.com\"> Generated by Vega </a></p> \n";
savehtml << "</DIV></body>\n</html>\n";
savehtml.Close();
// save the pairing on a file
FileOut savepair2 (PATHDIR + "pairing" + AsString(round) + ".txt");
savepair2 << NAMETORNEO << " - Round " << round <<"\n";
savepair2 << "======================================================================\n";
savepair2 << " Board WHITE BLACK\n";
savepair2 << "======================================================================\n";
if (IS_SWISS) npairs = pairing[0][round];
else npairs = pairingRR[0][round];
for (i=1; i<=npairs; i++)
{ if (IS_SWISS) code = pairing[i][round];
else code = pairingRR[i][round];
DecodeResult(code, &iw, &ib, &res);
savepair2 << NFormat(" %3d = %-20.20s - %-20.20s = ... - ...\n",
i, player[iw].name, player[ib].name);
}
savepair2 << "\n";
savepair2 <<"\n Generated by Vega - www.vegachess.com\n";
savepair2.Close();
// repeat saving a file good for a manual pairing
if (IS_SWISS) {
FileOut savepair3(PATHDIR + "pairs" + AsString(round) + ".man");
savepair3 << pairing[0][round] << "\n";
for (i=1; i<=npairs; i++)
{ code = pairing[i][round];
DecodeResult(code, &iw, &ib, &res);
savepair3 << iw << " " << ib << "\n";
}
savepair3.Close();
}
}
String RoundData::LabelResult(int result, int code, int round)
// return the explicit result corresponding to its code
{ String strres, str;
int idw, idb, res;
switch (result)
{ case 1: return "1 - 0"; break;
case 0: return "0 - 1"; break;
case 5: return "½ - ½"; break;
case 3: return "1F- 0"; break; // white win to forfait and get the BYE
case 4: return "0 -1F"; break; // black win to forfait and get the BYE
case 2: return "0F-0F"; break; // they lost, no color for both
case 7: return " adj "; break; // waitint a result
case 8: // non standard result
DecodeResult(code, &idw, &idb, &res); // get the id players
return LabelResultNonStandard(idw, idb, round);
break;
case 9: return " ... "; break; // waiting a result
}
return " ... ";
}
String RoundData::LabelResultNonStandard(int idw, int idb, int round)
// return the explicit result corresponding to its code
{ String r1, r2;
if (TD.IS_SWISS) { //swiss
switch (TD.roundResult[idw][round])
{ case 1: r1 = "1 -"; break;
case 0: r1 = "0 -"; break;
case 2: r1 = "½ -"; break;
case 3: r1 = "1F-"; break;
case 4: r1 = "0F-"; break;
case 6: r1 = "½F-"; break;
case 8: r1 = "½T-"; break;
}
switch (TD.roundResult[idb][round])
{ case 1: r2 = " 1"; break;
case 0: r2 = " 0"; break;
case 2: r2 = " ½"; break;
case 3: r2 = "1F"; break;
case 4: r2 = "0F"; break;
case 6: r2 = "½F"; break;
case 8: r2 = "½T"; break;
}
}
else { //round robin
if (idb==0) {
TD.roundResultRR[idw][round] = 5; //new
TD.roundResultRR[0][round] = 5; //new
}
switch (TD.roundResultRR[idw][round])
{ case 1: r1 = "1 -"; break;
case 0: r1 = "0 -"; break;
case 2: r1 = "½ -"; break;
case 3: r1 = "1F-"; break;
case 4: r1 = "0F-"; break;
case 6: r1 = "½F-"; break;
case 8: r1 = "½T-"; break;
case 5: r1 = " null "; break; //new
}
switch (TD.roundResultRR[idb][round])
{ case 1: r2 = " 1"; break;
case 0: r2 = " 0"; break;
case 2: r2 = " ½"; break;
case 3: r2 = "1F"; break;
case 4: r2 = "0F"; break;
case 6: r2 = "½F"; break;
case 8: r2 = "½T"; break;
}
}
return (r1 + r2);
}
void RoundData::DeleteRound(int fromround, int toround)
{ int i, j, id;
if (IS_SWISS) {
for (j=fromround; j<=toround; j++)
{ for (id=1; id<=NPlayer; id++)
{ playerColor[id][j] = 0;
playerOpponent[id][j] = 0;
playerFloater[id][j] = 0;
roundResult[id][j] = 0;
}
}
currentRound = fromround-1;
for (j=fromround; j<=toround; j++) {
for (i=1; i<=pairing[0][j]; i++) pairing[i][j]=0;
}
AdjournCrossTableSwiss(currentRound);
}
else {
for (j=fromround; j<=toround; j++)
{ for (id=1; id<=NPlayer; id++)
{ playerColorRR[id][j] = 0;
roundResultRR[id][j] = 0;
}
}
currentRound = fromround-1;
for (j=fromround; j<=toround; j++) {
for (i=1; i<=pairingRR[0][j]; i++)
{ pairingRR[i][j] = pairingRR[i][j]/10;
pairingRR[i][j] = pairingRR[i][j]*10+9; // set to "wait result" attento al giocatore dispari!
}
}
AdjournCrossTableRR(currentRound);
}
}
String RoundData::HTMLCommonHeader()
{ String header; // for Linux and windows
header = "";
header << "<html>\n<head>\n<title>"<< NAMETORNEO << "</title>\n";
header << "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"> \n";
header << "<style type=\"text/css\">\n";
header << "<!-- td { font-size: x-small; font-family: Verdana, Arial, Helvetica, sans-serif}\n";
// header << " th { background-color: #efefef; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: medium; font-weight: bold; font-style: normal; color: #000000; clip: rect( )}\n";
header << " th { background-color: #efefef; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: medium; font-style: normal; color: #000000; clip: rect( )}\n";
header << "A { font-family: verdana,arial,sans-serif; font-size:10pt; color: #0000FF; text-decoration: none } \n";
header << "A:hover { font-family: verdana,arial,sans-serif; font-size: 10pt; color: #FFFFFF; background-color: #ff0000 } \n";
header << " P { font-family: verdana,arial,sans-serif; font-size:10pt; background-color: #efefef;}\n";
header << "--> </style>\n";
header << "</head>\n<body>\n<DIV align=center>";
return header;
}
String RoundData::HTMLNavBar() //int n, String name[], String url[])
{ int j;
String header;
header = "";
header << "<P align=center> ";
if (FileExists(TD.PATHDIRWWW + "tourstat.html")) header << " <a href=\"tourstat.html\">" << t_("Tournament Summary") << " :: </a> \n";
header << " <a href=\"crosstbl.html\"> " << t_("Cross Table") << " </a> :: <a href=\"index.html\"> " << t_("Standing") << " </a> :: <a href=\"playercard.html\"> " << t_("Player Card") << " </a> \n";
if(IS_FIDE_TOURNAMENT) header << " :: <a href=\"felovar.html\">" << t_("Rating Report") << "</a> \n";
if(PLAY_SYSTEM==DUBOV) header << " :: <a href=\"scrgrp.html\">" << t_("Score Groups") << "</a> \n";
if (FileExists(TD.PATHDIRWWW + "players.html")) header << " :: <a href=\"players.html\">" << t_("Participants") << "</a> \n";
header << "</P>\n";
header << "<P align=center> " << t_("Pairings/Results: ");
if (TD.STATUS_ROUND == READY_FOR_PAIRING ) {
for(j=1; j<=currentRound+1; j++)
{ header << " <a href=\"pairs" <<j<< ".html\"> [ " << j <<" ] </a> ";
}
}
else {
for(j=1; j<=currentRound; j++)
{ header << " <a href=\"pairs" <<j<< ".html\"> [ " << j <<" ] </a> ";
}
}
header << "</P>\n";
return header;
}
void RoundData::ConvertUSCFDB()
{ FileSel fs; // for Linux and windows
String fn, dname;
//if (!PromptYesNo( "All your data will be lost... continue?" ) ) return;;
fs.Type( "File text tab delimited", "*.txt")
.Type( "All file", "*.*")
.DefaultExt("txt");
if(fs.ExecuteOpen()) { // file selected
dname = fs.GetActiveDir(); //get directory
fn = ~fs;
}
else return;
#ifdef PLATFORM_WIN32
dname << "\\";
#endif
#ifdef PLATFORM_POSIX
dname << "/";
#endif
FileIn in(fn);
FileOut out(dname + "uscffxd.txt");
while( !in.IsEof() ) {
Vector<String> field = Split(in.GetLine(), '\t', false);
out << NFormat(" %-20.20s" , field[0]); //name
out << NFormat(" %8s" , field[1]); // USCF ID
out << NFormat(" %-10.10s" , field[2]); // expiration date
out << NFormat(" %3s" , field[3]); // state abbreviation
if ( !IsNull(field[4]) ) out << NFormat(" %4d", StrIntValue(field[4]) ); // regular rating
else out << NFormat(" %4d", 0 );
if (field.GetCount() == 6 && !IsNull(field[5]) ) out << NFormat(" %4d\n", StrIntValue(field[5]) ); // quick rating
else out << NFormat(" % 4d\n", 0 );
}
Exclamation( t_("UCSF archive converted") );
in.Close();
out.Close();
}
////////////////////// class Team /////////////////////////////////////////
TeamArchive::TeamArchive()
{ name = "BYE"; //25 chars max
country = "---"; //3 chars max
data = "00.00.00"; //10 chars max
sex = "m"; //1 chars max
idfide = 0; //8 chars max
ratingfide = 0; //4 chars max
idnat = 0; //8 chars max
ratingnat = 0; //4 chars max
kcoeff = 0; //3 chars max
title = 0; // int corrispondent to codetitleused during pairing
codetitle = "--"; // used during pairing, max 3 chars (GM, WGM, IM, ecc...
// status
isAvailable = "1"; //0=out, null=get the bye - only for swiss, 1=play
// pairing data
int rating = 0; // for DUBOV SYSTEM : rating = RATING,
// for VEGA system : rating = BUCHOLZ
float aro = 0.; // for DUBOV system : aro = ARO
// for VEGA system : aro = BUCHOLZ
int RATING = 0; // real rating used for pairing and printed in the output (it is useful when .rating is used for something else)
// it depends by the FIDE flag
// player state useful for swiss system
duecolor = -1; //no duecolor
canChangeDuecolor = true;
tiebreak[SCORE] = 0.;
}
int TeamArchive::TitleToCode()
{ if ( codetitle == "GM" || codetitle == "IGM") return 20;
else if ( codetitle == "WGM" ) return 18;
else if ( codetitle == " IM" || codetitle == "IM") return 16;
else if ( codetitle == "WIM" ) return 14;
else if ( codetitle == " FM" || codetitle == "FM") return 12;
else if ( codetitle == "WFM" ) return 11;
else if ( codetitle == " M" || codetitle == "M" || codetitle == "-M") return 10;
else if ( codetitle == " CM" || codetitle == "CM" ) return 9;
else if ( codetitle == " A" || codetitle == "A" || codetitle == "AX" || codetitle == " 1N" || codetitle == "1N" ) return 8;
else if ( codetitle == " B" || codetitle == "B" || codetitle == "BX" || codetitle == " 2N" || codetitle == "2N" ) return 7;
else if ( codetitle == " C" || codetitle == "C" || codetitle == "CX" || codetitle == " 3N" || codetitle == "3N" ) return 6;
else if ( codetitle == " D" || codetitle == "D" || codetitle == "DX" ) return 5;
else if ( codetitle == " E" || codetitle == "E" || codetitle == "EX" ) return 4;
else if ( codetitle == " F" || codetitle == "F" || codetitle == "FX" ) return 3;
else if ( codetitle == " G" || codetitle == "G" || codetitle == "GX" ) return 2;
else if ( codetitle == " H" || codetitle == "H" || codetitle == "HX" ) return 1;
else if ( codetitle == " " || codetitle == " --" || codetitle == "--" || codetitle == "not" || codetitle == "NC" || codetitle == " NC" ) return 0;
return 0; // silly return to remove a warning
}
////////////////////// class Team /////////////////////////////////////////
PlayerArchive::PlayerArchive()
{ name = "BYE"; //25 chars max
country = "---"; //3 chars max
data = "00.00.00"; //10 chars max
sex = "m"; //1 chars max
idfide = 0; //8 chars max
ratingfide = 0; //4 chars max
idnat = 0; //8 chars max
ratingnat = 0; //4 chars max
kcoeff = 0; //3 chars max
title = 0; // int corrispondent to codetitleused during pairing
codetitle = "--"; // used during pairing, max 3 chars (GM, WGM, IM, ecc...
// status
isAvailable = "1"; //0=out, null=get the bye - only for swiss, 1=play
// for VEGA system : aro = BUCHOLZ
int RATING = 0; // real rating used for pairing and printed in the output (it is useful when .rating is used for something else)
// it depends by the FIDE flag
tiebreak[SCORE] = 0.;
}