[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdegames/kpat
From:       Parker Coates <parker.coates () kdemail ! net>
Date:       2012-02-15 4:45:01
Message-ID: 20120215044501.C7516AC896 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1280166 by coates:

Store cards moved together as a single move.

Previously, if a run of ten cards was moved from one pile to another, we
would save a different state change for each card. Storing them together
means less data and hopefully, shorter more readable saved games.

 M  +65 -36    dealer.cpp  
 M  +25 -8     gamestate.h  


--- trunk/KDE/kdegames/kpat/dealer.cpp #1280165:1280166
@@ -1003,11 +1003,11 @@
 
     if ( !fromStack.isEmpty() && d->currentState )
     {
-        // If we're undoing, we use the oldStates of the diffs of the current
-        // state. If we're redoing, we use the newStates of the diffs of the
+        // If we're undoing, we use the oldStates of the changes of the current
+        // state. If we're redoing, we use the newStates of the changes of the
         // nextState.
-        const QHash<KCard*,CardDiff> & diffs = undo ? d->currentState->diffs
-                                                    : fromStack.top()->diffs;
+        const QList<CardStateChange> & changes = undo ? d->currentState->changes
+                                                      : fromStack.top()->changes;
 
         // Update the currentState pointer and undo/redo stacks.
         toStack.push( d->currentState );
@@ -1015,32 +1015,33 @@
         setGameState( d->currentState->stateData );
 
         QSet<KCardPile*> pilesAffected;
-        QHash<KCard*,CardDiff>::const_iterator it = diffs.constBegin();
-        QHash<KCard*,CardDiff>::const_iterator end = diffs.constEnd();
-        for ( ; it != end; ++it )
+        foreach ( const CardStateChange & change, changes )
         {
-            KCard * c = it.key();
-            const CardDiff & diff = it.value();
-            const CardState & sourceState = undo ? diff.newState : diff.oldState;
-            const CardState & destState = undo ? diff.oldState : diff.newState;
+            CardState sourceState = undo ? change.newState : change.oldState;
+            CardState destState = undo ? change.oldState : change.newState;
 
-            d->cardStates.insert( c, destState );
+            PatPile * sourcePile = dynamic_cast<PatPile*>( sourceState.pile );
+            PatPile * destPile = dynamic_cast<PatPile*>( destState.pile );
+            bool notDroppable = destState.takenDown
+                                || ((sourcePile && sourcePile->isFoundation())
+                                    && !(destPile && destPile->isFoundation()));
+
             pilesAffected << sourceState.pile << destState.pile;
 
+            foreach ( KCard * c, change.cards )
+            {
+                d->cardStates.insert( c, destState );
+
             c->setFaceUp( destState.faceUp );
-            destState.pile->add( c );
+                destState.pile->insert( c, destState.index );
 
-            PatPile * sourcePile = dynamic_cast<PatPile*>( sourceState.pile );
-            PatPile * destPile = dynamic_cast<PatPile*>( destState.pile );
-            if ( destState.takenDown
-                 || ((sourcePile && sourcePile->isFoundation())
-                     && !(destPile && destPile->isFoundation())) )
-            {
+                if ( notDroppable )
                 d->cardsNotToDrop.insert( c );
-            }
             else
-            {
                 d->cardsNotToDrop.remove( c );
+
+                ++sourceState.index;
+                ++destState.index;
             }
         }
 
@@ -1054,10 +1055,10 @@
             while ( i < p->count() )
             {
                 int index = d->cardStates.value( p->at( i ) ).index;
-                if ( i != index )
+                if ( i == index )
+                    ++i;
+                else
                     p->swapCards( i, index );
-                else
-                    ++i;
             }
 
             updatePileLayout( p, 0 );
@@ -1099,30 +1100,58 @@
     if ( !isDemoActive() )
         d->winMoves.clear();
 
-    QHash<KCard*,CardDiff> cardDiffs;
+    QList<CardStateChange> changes;
+
     foreach ( KCardPile * p, piles() )
     {
+        QList<KCard*> currentRun;
+        CardState oldRunState;
+        CardState newRunState;
+        
         for ( int i = 0; i < p->count(); ++i )
         {
             KCard * c = p->at( i );
 
-            CardState s;
-            s.pile = p;
-            s.index = i;
-            s.faceUp = c->isFaceUp();
-            s.takenDown = d->cardsNotToDrop.contains( c );
+            const CardState & oldState = d->cardStates.value( c );
+            CardState newState( p, i, c->isFaceUp(), d->cardsNotToDrop.contains( c ) \
);  
-            const CardState & oldState = d->cardStates.value( c );
-            if ( s != oldState )
+            // The card has changed.
+            if ( newState != oldState )
             {
-                cardDiffs.insert( c, CardDiff( oldState, s ) );
-                d->cardStates.insert( c, s );
+                // There's a run in progress, but this card isn't part of it.
+                if ( !currentRun.isEmpty()
+                     && (oldState.pile != oldRunState.pile
+                         || (oldState.index != -1 && oldState.index != \
oldRunState.index + currentRun.size()) +                         || oldState.faceUp \
!= oldRunState.faceUp +                         || newState.faceUp != \
newRunState.faceUp +                         || oldState.takenDown != \
oldRunState.takenDown +                         || newState.takenDown != \
newRunState.takenDown) ) +                {
+                    changes << CardStateChange( oldRunState, newRunState, currentRun \
); +                    currentRun.clear();
             }
+
+                // This card is the start of a new run.
+                if ( currentRun.isEmpty() )
+                {
+                    oldRunState = oldState;
+                    newRunState = newState;
         }
+                
+                currentRun << c;
+
+                d->cardStates.insert( c, newState );
     }
+        }
+        // Add the last run, if any.
+        if ( !currentRun.isEmpty() )
+        {
+            changes << CardStateChange( oldRunState, newRunState, currentRun );
+        }
+    }
 
     // If nothing has changed, we're done.
-    if ( cardDiffs.isEmpty()
+    if ( changes.isEmpty()
          && d->currentState
          && d->currentState->stateData == getGameState() )
     {
@@ -1135,7 +1164,7 @@
         qDeleteAll( d->redoStack );
         d->redoStack.clear();
     }
-    d->currentState = new GameState( cardDiffs, getGameState() );
+    d->currentState = new GameState( changes, getGameState() );
 
     emit redoPossible( false );
     emit undoPossible( !d->undoStack.isEmpty() );
--- trunk/KDE/kdegames/kpat/gamestate.h #1280165:1280166
@@ -54,6 +54,22 @@
     bool faceUp;
     bool takenDown;
 
+    CardState()
+      : pile( 0 ),
+        index( -1 ),
+        faceUp( false ),
+        takenDown( false )
+    {
+    }
+    
+    CardState( KCardPile * pile, int index, bool faceUp, bool takenDown )
+      : pile( pile ),
+        index( index ),
+        faceUp( faceUp ),
+        takenDown( takenDown )
+    {
+    }
+
     bool operator==( const CardState & rhs ) const
     {
         return pile == rhs.pile
@@ -69,30 +85,31 @@
 };
 
 
-class CardDiff
+class CardStateChange
 {
 public:
     CardState oldState;
     CardState newState;
+    QList<KCard*> cards;
 
-    CardDiff( CardState o, CardState n )
-      : oldState( o ),
-        newState( n )
+    CardStateChange( CardState oldState, CardState newState, QList<KCard*> cards )
+      : oldState( oldState ),
+        newState( newState ),
+        cards( cards )
     {
     };
 };
 
-
 class GameState
 {
 public:
-    QHash<KCard*,CardDiff> diffs;
+    QList<CardStateChange> changes;
     QString stateData;
     Solver::ExitStatus solvability;
     QList<MOVE> winningMoves;
 
-    GameState( QHash<KCard*,CardDiff> diffs, QString stateData )
-      : diffs( diffs ),
+    GameState( QList<CardStateChange> changes, QString stateData )
+      : changes ( changes ),
         stateData( stateData ),
         solvability( Solver::SearchAborted )
     {


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic