Completely removed getRaceResultOrder functions, added debug support
for duplicated ranks to world_with_rank. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5898 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -55,7 +55,7 @@ void FollowTheLeaderRace::countdownReachedZero()
|
||||
// kart, otherwise remove the last kart.
|
||||
int position_to_remove = m_karts[0]->getPosition()==1
|
||||
? getCurrentNumKarts() : 1;
|
||||
const Kart *kart = getKartAtPosition(position_to_remove);
|
||||
Kart *kart = getKartAtPosition(position_to_remove);
|
||||
if(!kart || kart->isEliminated())
|
||||
{
|
||||
fprintf(stderr,"Problem with removing leader: position %d not found\n",
|
||||
@@ -80,8 +80,13 @@ void FollowTheLeaderRace::countdownReachedZero()
|
||||
// position, since the eliminated kart was already removed
|
||||
// from the value returned by getCurrentNumKarts (and we have
|
||||
// to remove the kart before we can call updateRacePosition).
|
||||
setKartPosition(kart->getWorldKartId(),
|
||||
getCurrentNumKarts()+1);
|
||||
// Note that we can not call WorldWithRank::setKartPosition
|
||||
// here, since it would not properly support debugging kart
|
||||
// ranks (since this kart would get its position set again
|
||||
// in updateRacePosition). We only set the rank of the eliminated
|
||||
// kart, and updateRacePosition will then call setKartPosition
|
||||
// for the now eliminated kart.
|
||||
kart->setPosition(getCurrentNumKarts()+1);
|
||||
updateRacePosition();
|
||||
}
|
||||
}
|
||||
@@ -136,66 +141,15 @@ void FollowTheLeaderRace::restartRace()
|
||||
std::string FollowTheLeaderRace::getIdent() const
|
||||
{
|
||||
return FTL_IDENT;
|
||||
}
|
||||
} // getIdent
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the title for all karts that is displayed in the icon list. In
|
||||
* this mode the title for the first kart is set to 'leader'.
|
||||
*/
|
||||
RaceGUIBase::KartIconDisplayInfo* FollowTheLeaderRace::getKartsDisplayInfo()
|
||||
{
|
||||
LinearWorld::getKartsDisplayInfo();
|
||||
m_kart_display_info[0].special_title = _("Leader");
|
||||
return m_kart_display_info;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void FollowTheLeaderRace::getRaceResultOrder(std::vector<int> *order)
|
||||
{
|
||||
const unsigned int num_karts = getNumKarts();
|
||||
order->resize(num_karts);
|
||||
|
||||
int *scores = new int[num_karts];
|
||||
double *race_time = new double[num_karts];
|
||||
|
||||
// Ignore kart 0, since it was the leader
|
||||
(*order)[0] = -1;
|
||||
for( unsigned int kart_id = 1; kart_id < num_karts; ++kart_id )
|
||||
{
|
||||
(*order)[kart_id] = kart_id;
|
||||
scores[kart_id] = race_manager->getKartScore(kart_id);
|
||||
race_time[kart_id] = race_manager->getOverallTime(kart_id);
|
||||
|
||||
// check this kart is not in front of leader. If it is, give a score of 0
|
||||
if( getLapForKart(kart_id) * getTrack()->getTrackLength()
|
||||
+ getDistanceDownTrackForKart(kart_id)
|
||||
> getLapForKart(0) * getTrack()->getTrackLength()
|
||||
+ getDistanceDownTrackForKart(0))
|
||||
{
|
||||
scores[kart_id] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Bubblesort
|
||||
bool sorted;
|
||||
do
|
||||
{
|
||||
sorted = true;
|
||||
for( unsigned int i = 1; i < num_karts - 1; ++i )
|
||||
{
|
||||
if( scores[(*order)[i]] < scores[(*order)[i+1]] ||
|
||||
(scores[(*order)[i]] == scores[(*order)[i+1]]
|
||||
&& race_time[(*order)[i]] > race_time[(*order)[i+1]]) )
|
||||
{
|
||||
int tmp = (*order)[i];
|
||||
(*order)[i] = (*order)[i+1];
|
||||
(*order)[i+1] = tmp;
|
||||
sorted = false;
|
||||
}
|
||||
}
|
||||
} while(!sorted);
|
||||
|
||||
for(unsigned int i=1; i<num_karts; i++)
|
||||
{
|
||||
//FIXME JOERGH setKartPosition((*order)[i], i);
|
||||
}
|
||||
|
||||
delete []scores;
|
||||
delete []race_time;
|
||||
}
|
||||
|
||||
} // getKartsDisplayInfo
|
||||
|
||||
@@ -47,9 +47,6 @@ public:
|
||||
virtual bool isRaceOver();
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
|
||||
/** Called by the race result GUI at the end of the race to know the final order
|
||||
(fill in the 'order' array) */
|
||||
virtual void getRaceResultOrder(std::vector<int> *order);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -580,12 +580,11 @@ void LinearWorld::moveKartAfterRescue(Kart* kart)
|
||||
*/
|
||||
void LinearWorld::updateRacePosition()
|
||||
{
|
||||
// Mostly for debugging:
|
||||
beginSetKartPositions();
|
||||
const unsigned int kart_amount = m_karts.size();
|
||||
|
||||
#ifdef DEBUG
|
||||
std::vector<bool> rank_used;
|
||||
for (unsigned int n=0; n<=kart_amount; n++)
|
||||
rank_used.push_back(false);
|
||||
bool rank_changed = false;
|
||||
#endif
|
||||
|
||||
@@ -602,9 +601,9 @@ void LinearWorld::updateRacePosition()
|
||||
// crossing the finishing line and become second!
|
||||
if(kart->isEliminated() || kart->hasFinishedRace())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
rank_used[kart->getPosition()] = true;
|
||||
#endif
|
||||
// This is only necessary to support debugging inconsistencies
|
||||
// in kart position parameters.
|
||||
setKartPosition(i, kart->getPosition());
|
||||
continue;
|
||||
}
|
||||
KartInfo& kart_info = m_kart_info[i];
|
||||
@@ -655,9 +654,11 @@ void LinearWorld::updateRacePosition()
|
||||
#endif
|
||||
}
|
||||
} //next kart
|
||||
|
||||
#ifdef DEBUG
|
||||
if (rank_used[p])
|
||||
|
||||
#ifndef DEBUG
|
||||
setKartPosition(i, p);
|
||||
#else
|
||||
if (!setKartPosition(i,p))
|
||||
{
|
||||
std::cerr << "ERROR, same rank used twice!!\n";
|
||||
|
||||
@@ -668,13 +669,7 @@ void LinearWorld::updateRacePosition()
|
||||
<< "), is at lap (" << getLapForKart(d) << "), is at distance("
|
||||
<< getDistanceDownTrackForKart(d) << "), is eliminated(" << m_karts[d]->isEliminated() << ")" << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << "Used ranks:\n";
|
||||
for (unsigned int d=1; d<=kart_amount; d++)
|
||||
{
|
||||
std::cerr << " rank " << d << " used : " << rank_used[d] << std::endl;
|
||||
}
|
||||
|
||||
|
||||
std::cerr << "Who has each ranking so far :\n";
|
||||
for (unsigned int d=0; d<i; d++)
|
||||
{
|
||||
@@ -685,11 +680,9 @@ void LinearWorld::updateRacePosition()
|
||||
history->Save();
|
||||
assert(false);
|
||||
}
|
||||
rank_used[p] = true;
|
||||
rank_changed |= kart->getPosition()!=p;
|
||||
#endif
|
||||
|
||||
setKartPosition(i, p);
|
||||
// Switch on faster music if not already done so, if the
|
||||
// first kart is doing its last lap, and if the estimated
|
||||
// remaining time is less than 30 seconds.
|
||||
@@ -759,6 +752,7 @@ void LinearWorld::updateRacePosition()
|
||||
} // if rank_changed
|
||||
#endif
|
||||
|
||||
endSetKartPositions();
|
||||
} // updateRacePosition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -123,6 +123,7 @@ std::string ThreeStrikesBattle::getIdent() const
|
||||
//-----------------------------------------------------------------------------
|
||||
void ThreeStrikesBattle::updateKartRanks()
|
||||
{
|
||||
beginSetKartPositions();
|
||||
// sort karts by their times then give each one its position.
|
||||
// in battle-mode, long time = good (meaning he survived longer)
|
||||
|
||||
@@ -165,6 +166,7 @@ void ThreeStrikesBattle::updateKartRanks()
|
||||
setKartPosition(karts_list[n], n+1);
|
||||
}
|
||||
delete [] karts_list;
|
||||
endSetKartPositions();
|
||||
} // updateKartRank
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -24,13 +24,15 @@ void WorldWithRank::init()
|
||||
{
|
||||
World::init();
|
||||
m_position_index.resize(m_karts.size());
|
||||
m_position_used.resize(m_karts.size());
|
||||
m_position_setting_initialised = false;
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the kart with a given position.
|
||||
* \param p The position of the kart, 1<=p<=num_karts).
|
||||
*/
|
||||
const Kart* WorldWithRank::getKartAtPosition(unsigned int p) const
|
||||
Kart* WorldWithRank::getKartAtPosition(unsigned int p) const
|
||||
{
|
||||
if(p<1 || p>m_position_index.size())
|
||||
return NULL;
|
||||
@@ -39,66 +41,71 @@ const Kart* WorldWithRank::getKartAtPosition(unsigned int p) const
|
||||
} // getKartAtPosition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WorldWithRank::setKartPosition(unsigned int kart_id,
|
||||
/** This function must be called before starting to set all kart positions
|
||||
* again. It's mainly used to add some debug support, i.e. detect if the
|
||||
* same position is set in different karts.
|
||||
*/
|
||||
void WorldWithRank::beginSetKartPositions()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(!m_position_setting_initialised);
|
||||
m_position_setting_initialised = true;
|
||||
|
||||
for(unsigned int i=0; i<m_position_used.size(); i++)
|
||||
m_position_used[i] = false;
|
||||
#endif
|
||||
} // beginSetKartPositions
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the position of a kart. This will be saved in this object to allow
|
||||
* quick lookup of which kart is on a given position, but also in the
|
||||
* kart objects.
|
||||
* \param kart_id The index of the kart to set the position for.
|
||||
* \param position The position of the kart (1<=position<=num karts).
|
||||
* \return false if this position was already set, i.e. an inconsistency in
|
||||
* kart positions has occurred. This is used in debug mode only to
|
||||
* allow the calling function to print debug information.
|
||||
*/
|
||||
bool WorldWithRank::setKartPosition(unsigned int kart_id,
|
||||
unsigned int position)
|
||||
{
|
||||
m_position_index[position-1] = kart_id;
|
||||
m_karts[kart_id]->setPosition(position);
|
||||
#ifdef DEBUG
|
||||
assert(m_position_setting_initialised);
|
||||
if(m_position_used[position-1])
|
||||
{
|
||||
std::cerr << "== TWO KARTS ARE BEING GIVEN THE SAME POSITION!! ==\n";
|
||||
for (unsigned int j=0; j < m_position_index.size(); j++)
|
||||
{
|
||||
if (!m_position_used[j])
|
||||
{
|
||||
std::cout << " No kart is yet set at position " << j << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " Kart " << m_position_index[j]
|
||||
<< " is at position " << j << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "Kart " << kart_id << " is being given position "
|
||||
<< position << ", but this position is already taken\n";
|
||||
return false;
|
||||
}
|
||||
m_position_used[position-1] = true;
|
||||
#endif
|
||||
return true;
|
||||
} // setKartPosition
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called by the race result GUI at the end of the race to know the final
|
||||
* order.
|
||||
* \param[out] order returns the order of karts. order[0] will contain the ID
|
||||
* of the first kart, order[1] the ID of the second kart,
|
||||
* etc... Array dimension will be adjusted to the number of
|
||||
* karts.
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called once the last position was set. Note that we should not test
|
||||
* if all positions were set, since e.g. for eliminated and finished karts
|
||||
* the position won't be set anymore.
|
||||
*/
|
||||
void WorldWithRank::getRaceResultOrder(std::vector<int> *order)
|
||||
void WorldWithRank::endSetKartPositions()
|
||||
{
|
||||
const unsigned int num_karts = getNumKarts();
|
||||
order->resize(num_karts);
|
||||
|
||||
#ifndef NDEBUG
|
||||
for (unsigned int i=0; i < num_karts; i++) (*order)[i] = -1;
|
||||
|
||||
bool positions_ok = true;
|
||||
#endif
|
||||
|
||||
for (unsigned int i=0; i < num_karts; i++)
|
||||
{
|
||||
const int position = getKart(i)->getPosition()-1;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// sanity checks
|
||||
if ((*order)[position] != -1)
|
||||
{
|
||||
std::cerr << "== TWO KARTS ARE BEING GIVEN THE SAME POSITION!! ==\n";
|
||||
for (unsigned int j=0; j < num_karts; j++)
|
||||
{
|
||||
if ((*order)[j] == -1)
|
||||
{
|
||||
std::cout << " No kart is yet set at position " << j << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " Kart " << (*order)[j] << " is at position " << j << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "Kart " << i << " is being given posiiton " << (getKart(i)->getPosition()-1)
|
||||
<< ", but this position is already taken\n";
|
||||
positions_ok = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// actually assign the position
|
||||
(*order)[position] = i; // even for eliminated karts
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (!positions_ok) history->Save();
|
||||
assert(positions_ok);
|
||||
#endif
|
||||
|
||||
} // getRaceResultOrder
|
||||
assert(m_position_setting_initialised);
|
||||
m_position_setting_initialised = false;
|
||||
} // endSetKartPositions
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,18 @@ class WorldWithRank : public World
|
||||
private:
|
||||
/** This contains a mapping from race position to kart index. */
|
||||
std::vector<int> m_position_index;
|
||||
|
||||
#ifdef DEBUG
|
||||
/** Used for debugging to help detect if the same kart position
|
||||
* is used more than once. */
|
||||
std::vector<bool> m_position_used;
|
||||
|
||||
/** True if beginSetKartPositions was called, false after
|
||||
* endSetKartPositions. Used to make sure the sequence of calls
|
||||
* is correct. */
|
||||
bool m_position_setting_initialised;
|
||||
#endif
|
||||
|
||||
public:
|
||||
WorldWithRank() : World() {}
|
||||
/** call just after instanciating. can't be moved to the contructor as child
|
||||
@@ -41,13 +53,12 @@ public:
|
||||
results will be incorrect */
|
||||
virtual void init();
|
||||
|
||||
void setKartPosition(unsigned int kart_id,
|
||||
void beginSetKartPositions();
|
||||
bool setKartPosition(unsigned int kart_id,
|
||||
unsigned int position);
|
||||
const Kart* getKartAtPosition(unsigned int p) const;
|
||||
|
||||
/** Called by the race result GUI at the end of the race to know the
|
||||
* final order (fill in the 'order' array) */
|
||||
virtual void getRaceResultOrder(std::vector<int> *order);
|
||||
}; // WorldWithRank
|
||||
void endSetKartPositions();
|
||||
|
||||
Kart* getKartAtPosition(unsigned int p) const;
|
||||
}; // WorldWithRank
|
||||
|
||||
#endif
|
||||
|
||||
@@ -109,8 +109,6 @@ RaceOverDialog::RaceOverDialog(const float percentWidth,
|
||||
|
||||
WorldWithRank *world = (WorldWithRank*)World::getWorld();
|
||||
const unsigned int num_karts = world->getNumKarts();
|
||||
std::vector<int> order;
|
||||
world->getRaceResultOrder(&order);
|
||||
|
||||
const bool display_time = (world->getClockMode() == WorldStatus::CLOCK_CHRONO);
|
||||
|
||||
@@ -126,13 +124,11 @@ RaceOverDialog::RaceOverDialog(const float percentWidth,
|
||||
m_rankings_y_bottom = -1;
|
||||
|
||||
int kart_id = 0; // 'i' below is not reliable because some karts (e.g. leader) will be skipped
|
||||
for (unsigned int i = 0; i < num_karts; ++i)
|
||||
for (unsigned int position = 1; position <= num_karts; position++)
|
||||
{
|
||||
if (order[i] == -1) continue;
|
||||
|
||||
const Kart* current_kart = world->getKartAtPosition(position);
|
||||
stringw kart_results_line;
|
||||
|
||||
const Kart *current_kart = world->getKart(order[i]);
|
||||
const stringw& kart_name = current_kart->getName();
|
||||
|
||||
std::string time_string;
|
||||
@@ -147,8 +143,8 @@ RaceOverDialog::RaceOverDialog(const float percentWidth,
|
||||
//This shows position + driver name + time + points earned + total points
|
||||
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
|
||||
{
|
||||
const int prev_score = race_manager->getKartPrevScore(order[i]);
|
||||
const int new_score = race_manager->getKartScore(order[i]);
|
||||
const int prev_score = race_manager->getKartPrevScore(current_kart->getWorldKartId());
|
||||
const int new_score = race_manager->getKartScore(current_kart->getWorldKartId());
|
||||
|
||||
if (display_time)
|
||||
{
|
||||
@@ -191,6 +187,7 @@ RaceOverDialog::RaceOverDialog(const float percentWidth,
|
||||
const int entry_width = (show_highscores? m_area.getWidth()*2/3 : m_area.getWidth());
|
||||
|
||||
const int icon_size = text_height;
|
||||
unsigned int i = current_kart->getWorldKartId();
|
||||
core::rect< s32 > entry_area(10 + icon_size, lines_from_y + line_h*i,
|
||||
entry_width , lines_from_y + line_h*(i+1));
|
||||
core::rect< s32 > icon_area (5 , lines_from_y + line_h*i,
|
||||
|
||||
Reference in New Issue
Block a user