/** Creates 2 groups: one from winners and one from loosers */ QList< Group* > SwissGroup::split( ) const { if ( _matches.count() < 2 ) { // nothing to split return QList< Group* >(); } QList< Group* > ret; PlayerList w = winners(), l = loosers(); // number of winnders and loosers can be non-even, when group consists, // for example, from 6 persons. We need to add 'bye' players if ( w.count() & 1 ) w << byePlayer; if ( l.count() & 1 ) l << byePlayer; qDebug() << "Winners:"; for ( int i = 0; i < w.count(); i ++ ) { qDebug() << w.at( i ).name(); } qDebug() << "Loosers:"; for ( int i = 0; i < l.count(); i ++ ) { qDebug() << l.at( i ).name(); } // winners group if ( !isPlayerListByed( w ) ) { ret << new SwissGroup( _fromPlace, _stage + 1, w ); } // loosers group if ( !isPlayerListByed( l ) ) { ret << new SwissGroup( _fromPlace + _players.count() / 2, _stage + 1, l ); } foreach( Group *g, ret ) { const TournAlgo *a = _tournData->algo(); Q_CHECK_PTR( a ); g->setTournData( _tournData ); g->setQualif( isQualif() ); dynamic_cast<SwissGroup*>(g)->permuteMatches( a->breakAlgo() ); // if there is at least one bye player, we should notify that // at least one game is fakely played. if ( g->const_players().contains( byePlayer ) ) { _tournData->groupChanged( g ); } } return ret; }
/** Writes match result and earned rating into specified cell. */ void RatingsTable::updateMatchCell( int row, int col ) { int aIndex = row - 1; int bIndex = col - 1; PlayerList players = _group->const_validPlayers(); if ( aIndex >= players.count() || bIndex >= players.count() ) { qCritical() << __FUNCTION__ << "invalid row&col indexes: " << row << col; return; } Player a = players.at( aIndex ); Player b = players.at( bIndex ); MatchList matches = _group->matchList( a, b ); QString text = item( row, col )->text(); QString toolTip = item( row, col )->toolTip(); foreach( Match m, matches ) { if ( m.played() ) { if ( !text.isEmpty() ) { text += " "; } text += m.toString(); text += " (+" + QString().setNum( m.earnedRating( a ), 'g', 2 ) + ")"; item( row, col )->setBackground( SPRING_GREEN1 ); if ( !toolTip.isEmpty() ) { toolTip += "\n\n"; } toolTip += m.gamesToString(); } else { item( row, col )->setBackground( palette().color( QPalette::Normal, QPalette::Base ) ); } } item( row, col )->setToolTip( toolTip ); item( row, col )->setText( text ); }
/** \brief rebuild player list accordingly with break algorithm. * assumed that pls.count() is even. */ PlayerList TournAlgo::permutePlayers( PlayerList pls ) const { PlayerList out; if ( _break == BreakAlgo::ADBC ) { // first - last // second - pre-last for ( int i = 0; i < pls.count() / 2; i ++ ) { out << pls.at( i ) << pls.at( pls.count() - i - 1 ); } } else if ( _break == BreakAlgo::ACBD ) { // first - middle // second - middle + 1 for ( int i = 0; i < pls.count() / 2; i ++ ) { out << pls.at( i ) << pls.at( pls.count() / 2 + i ); } } else { // ABCD does not require permutation } return out; }
/** calls updateMatchCell for each match cell ;) */ void RatingsTable::updateMatchCells( ) { PlayerList players = _group->const_validPlayers(); int plCnt = players.count(); for ( int i = 1; i < rowCount(); i ++ ) { for ( int j = 1; j < plCnt + 1; j ++ ) { if ( i != j ) { updateMatchCell( i, j ); } } } }
/** * Asks user to select a file with players in a plain text format: * Player, rating\nPlayer2, rating\n etc... */ void PlayerTable::mouseDoubleClickEvent( QMouseEvent * ) { QString fName = QFileDialog::getOpenFileName(this, tr("Open players list file"), QDir::homePath(), tr("Txt Files (*.txt)")); if ( !fName.isNull() ) { PlayerList players = loadPlayerList( fName ); if ( players.count() > 0 ) { setPlayerList( players ); } else { QMessageBox msg; msg.setText( tr( "I cannot find any player in '" ) + fName + "'" ); msg.exec(); } } }
/** should be called in constructor for basic setup of * table cells. */ void RatingsTable::setupCells() { PlayerList players = _group->const_validPlayers(); int plCnt = players.count(); setRowCount( plCnt + 1 ); setColumnCount( plCnt + 1 + 1 ); // 1 column for total rating results for ( int i = 0; i < rowCount(); i ++ ) { for ( int j = 0; j < plCnt + 1; j ++ ) { QTableWidgetItem *item = new QTableWidgetItem( ); QString text; if ( i == j ) { item->setBackground( palette().brush( QPalette::Disabled, QPalette::Background ) ); if ( i == 0 ) { text = _group->name(); } item->setFlags( Qt::NoItemFlags ); } else if ( i == 0 ) { // 0th row text = players.at( j - 1 ).name(); item->setFlags( Qt::NoItemFlags ); } else if ( j == 0 ) { // 0th column Player p = players.at( i - 1 ); text = p.name(); text += " (" + QString::number( p.rating(), 'f', 1 ) + ")"; item->setFlags( Qt::NoItemFlags ); } else { item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); } item->setText( text ); setItem( i, j, item ); } QTableWidgetItem *item = new QTableWidgetItem( ); if ( i == 0 ) { item->setText( tr( "New rating" ) ); } item->setFlags( Qt::NoItemFlags ); setItem( i, plCnt + 1, item ); } }
/** Update total rating for each player */ void RatingsTable::updateTotalRatings() { PlayerList players = _group->const_validPlayers(); int plCnt = players.count(); int col = plCnt + 1; for ( int i = 1; i < rowCount(); i ++ ) { Player p = players.at( i - 1 ); double earned = _group->earnedRating( p ); double total = p.rating() + earned; QString text; text += QString().setNum( total, 'f', 1 ); text += " (+" + QString().setNum( earned, 'f', 1 ) + ")"; item( i, col )->setText( text ); item( i, col )->setBackground( SPRING_GREEN1 ); } }