Fix misses count twice. Do not assume that rows are judged in order. Do not judge a row more than once. The JudgedRows class acts like an array of bools (more or less), one per note row but is implemented as a circular buffer (more or less). Note that m_JudgedRows[i] will only return false one time. After that, it is assumed to have been judged.

This commit is contained in:
Steve Checkoway
2006-07-18 00:26:37 +00:00
parent 9798712912
commit 4efb7c4078
2 changed files with 68 additions and 15 deletions
+17 -15
View File
@@ -327,6 +327,7 @@ void Player::Load()
m_iRowLastCrossed = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ) - 1; // why this? m_iRowLastCrossed = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ) - 1; // why this?
m_iMineRowLastCrossed = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ) - 1; // why this? m_iMineRowLastCrossed = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ) - 1; // why this?
m_iRowLastJudged = m_iRowLastCrossed; m_iRowLastJudged = m_iRowLastCrossed;
m_JudgedRows.Reset();
// TODO: Remove use of PlayerNumber. // TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
@@ -1365,7 +1366,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
//LOG->Trace( "iStartCheckingAt: %d iMissIfOlderThanThisIndex: %d", iStartCheckingAt, iMissIfOlderThanThisIndex ); //LOG->Trace( "iStartCheckingAt: %d iMissIfOlderThanThisIndex: %d", iStartCheckingAt, iMissIfOlderThanThisIndex );
int iNumMissesFound = 0; bool bMisses = false;
FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( m_NoteData, r, iStartCheckingAt, iMissIfOlderThanThisIndex-1 ) FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( m_NoteData, r, iStartCheckingAt, iMissIfOlderThanThisIndex-1 )
{ {
@@ -1407,31 +1408,32 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
} }
if( MissedNoteOnThisRow ) if( MissedNoteOnThisRow )
{ bMisses = true;
iNumMissesFound++;
HandleTapRowScore( r );
}
} }
if( iNumMissesFound > 0 ) if( bMisses )
{
SetJudgment( TNS_Miss, false ); SetJudgment( TNS_Miss, false );
}
} }
void Player::UpdateJudgedRows() void Player::UpdateJudgedRows()
{ {
const int iRow = BeatToNoteRow( GAMESTATE->m_fSongBeat ); const int iEndRow = BeatToNoteRow( GAMESTATE->m_fSongBeat );
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
bool bAllJudged = true;
while( m_iRowLastJudged <= iRow ) for( int iRow = m_iRowLastJudged+1; iRow <= iEndRow; ++iRow )
{ {
if( !NoteDataWithScoring::IsRowCompletelyJudged(m_NoteData, m_iRowLastJudged+1, pn) ) if( !NoteDataWithScoring::IsRowCompletelyJudged(m_NoteData, iRow, pn) )
break; {
++m_iRowLastJudged; bAllJudged = false;
if( NoteDataWithScoring::LastTapNoteWithResult(m_NoteData, m_iRowLastJudged, pn).result.tns == TNS_None )
continue; continue;
OnRowCompletelyJudged( m_iRowLastJudged ); }
if( bAllJudged )
++m_iRowLastJudged;
TapNoteScore tns = NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, iRow, pn ).result.tns;
if( m_JudgedRows[iRow] || tns == TNS_None )
continue;
OnRowCompletelyJudged( iRow );
} }
} }
+51
View File
@@ -36,6 +36,56 @@ AutoScreenMessage( SM_ComboStopped );
AutoScreenMessage( SM_ComboContinuing ); AutoScreenMessage( SM_ComboContinuing );
AutoScreenMessage( SM_MissComboAborted ); AutoScreenMessage( SM_MissComboAborted );
// Helper class to ensure that each row is only judged once without taking too much memory.
class JudgedRows
{
char *m_pRows;
int m_iStart;
int m_iOffset;
int m_iLen;
void Resize( int iMin )
{
char *p = m_pRows;
int newSize = max( m_iLen*2, iMin );
m_pRows = new char[newSize];
int i = 0;
if( p )
{
for( ; i < m_iLen; ++i )
m_pRows[i] = p[(i+m_iOffset)%m_iLen];
delete[] p;
}
m_iOffset = 0;
m_iLen = newSize;
memset( m_pRows + i, 0, newSize - i );
//LOG->Trace( "New size %d.", newSize );
}
public:
JudgedRows() : m_pRows(NULL), m_iStart(0), m_iOffset(0), m_iLen(0) { Resize( 32 ); }
~JudgedRows() { delete[] m_pRows; }
bool operator[]( int iRow )
{
if( iRow < m_iStart ) return true;
if( iRow >= m_iStart+m_iLen ) Resize( iRow+1-m_iStart );
const bool ret = m_pRows[(iRow-m_iStart+m_iOffset)%m_iLen];
m_pRows[(iRow-m_iStart+m_iOffset)%m_iLen] = 1;
while( m_pRows[m_iOffset] )
{
m_pRows[m_iOffset] = 0;
++m_iStart;
if( ++m_iOffset >= m_iLen ) m_iOffset -= m_iLen;
}
return ret;
}
void Reset()
{
m_iStart = m_iOffset = 0;
memset( m_pRows, 0, m_iLen );
}
};
class Player: public ActorFrame class Player: public ActorFrame
{ {
public: public:
@@ -123,6 +173,7 @@ protected:
int m_iRowLastCrossed; int m_iRowLastCrossed;
int m_iMineRowLastCrossed; int m_iMineRowLastCrossed;
int m_iRowLastJudged; // Everything up to and including this row has been judged. int m_iRowLastJudged; // Everything up to and including this row has been judged.
JudgedRows m_JudgedRows;
RageSound m_soundMine; RageSound m_soundMine;
RageSound m_soundAttackLaunch; RageSound m_soundAttackLaunch;