LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices


Reply
  Search this Thread
Old 06-27-2010, 10:13 AM   #1
hakan56
Member
 
Registered: Nov 2004
Location: Sweden
Distribution: Slackware64-14.0
Posts: 53

Rep: Reputation: 9
Modify Kpat (c++)


My wife refuses to give up kde3, because they changed the rules for her favorite solitaire-game "Mod3" in Kpat in kde4,
This means that I am responsible for kde 3 to be present on her computer (slackware 13.1)
It works now, but soon I am afraid that my reputation as "the data-guru" is going down a couple of points if
I can't came up with something else.

I don't knew anything about programming but found two files. mod3.cpp and mod3.h in the source-file of kpat (kde 4.4.3).
I belive this is C++ and in mod5.cpp I found this..
Code:
    // Special pile type used for the fourth row. Automatically grabs a new card
    // from the deck when emptied.
    class Mod3Pile : public Pile
    {
    public:
        Mod3Pile( int _index, Pile * pile, const QString & objectName = QString() )
            : Pile( _index, objectName ), drawPile( pile ) {}
        virtual void relayoutCards()
        {
            if ( isEmpty() && !drawPile->isEmpty() )
                animatedAdd( drawPile->top(), true );
            else
                Pile::relayoutCards();
        }
        Pile * drawPile;
    };
..in kde3 it doesn't "automatically grabs a new card from the deck" when there is a empty place in the fourth raw,
you can pick any card you want to go there...and that is how my wife likes it.

Is it possible to modify this so it does that?

/Håkan
 
Old 06-27-2010, 06:56 PM   #2
T3slider
Senior Member
 
Registered: Jul 2007
Distribution: Slackware64-14.1
Posts: 2,367

Rep: Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843
Quote:
Originally Posted by hakan56 View Post
I don't knew anything about programming but found two files. mod3.cpp and mod3.h in the source-file of kpat (kde 4.4.3).
I belive this is C++ and in mod5.cpp I found this..
Code:
    // Special pile type used for the fourth row. Automatically grabs a new card
    // from the deck when emptied.
    class Mod3Pile : public Pile
    {
    public:
        Mod3Pile( int _index, Pile * pile, const QString & objectName = QString() )
            : Pile( _index, objectName ), drawPile( pile ) {}
        virtual void relayoutCards()
        {
            if ( isEmpty() && !drawPile->isEmpty() )
                animatedAdd( drawPile->top(), true );
            else
                Pile::relayoutCards();
        }
        Pile * drawPile;
    };
..in kde3 it doesn't "automatically grabs a new card from the deck" when there is a empty place in the fourth raw,
you can pick any card you want to go there...and that is how my wife likes it.

Is it possible to modify this so it does that?

/Håkan
Assuming that is the class definition for the pile used in the mod3 game, you can probably remove the if check and just have it run Pile::relayoutCards() by default -- but I have *not* tested this and I have *not* looked over the code so I don't know what happens when Pile::relayoutCards() is called with an empty place. I also have not played this version of the game so definitely be cautious with my guess. If it does cause a problem when calling Pile::relayoutCards() with an empty place then you may need to check for the empty space but do not run animatedAdd() if found...but that may have other consequences.

I am not too strong in C++, and I certainly haven't looked over *anything* so keep that in mind. The following *might* work.

Code:
    // Special pile type used for the fourth row. Automatically grabs a new card
    // from the deck when emptied.
    class Mod3Pile : public Pile
    {
    public:
        Mod3Pile( int _index, Pile * pile, const QString & objectName = QString() )
            : Pile( _index, objectName ), drawPile( pile ) {}
        virtual void relayoutCards()
        {
            Pile::relayoutCards();
        }
        Pile * drawPile;
    };
I'm sure there's a more elegant solution as well, especially since Mod3Pile::relayoutCards() is just calling Pile::relayoutCards() from the base class, but aside from bad form the above might work.
 
1 members found this post helpful.
Old 06-28-2010, 01:25 AM   #3
hakan56
Member
 
Registered: Nov 2004
Location: Sweden
Distribution: Slackware64-14.0
Posts: 53

Original Poster
Rep: Reputation: 9
Yes!! It works!!
I am really grateful, thanks to you I can still pretend to be "the data-guru"..

Thank you very much.

/Håkan
 
Old 02-24-2011, 04:10 AM   #4
hakan56
Member
 
Registered: Nov 2004
Location: Sweden
Distribution: Slackware64-14.0
Posts: 53

Original Poster
Rep: Reputation: 9
Now in Kde 4.5.5 they have changed the "c++" for "mod3" so I am lost again , is there anyone who can help me solve this (to the same behavior as above).
Code:
/*
 * Copyright (C) 1997 Rodolfo Borges <barrett@labma.ufrj.br>
 * Copyright (C) 1998-2009 Stephan Kulow <coolo@kde.org>
 * Copyright (C) 2010 Parker Coates <parker.coates@kdemail.net>
 *
 * License of original code:
 * -------------------------------------------------------------------------
 *   Permission to use, copy, modify, and distribute this software and its
 *   documentation for any purpose and without fee is hereby granted,
 *   provided that the above copyright notice appear in all copies and that
 *   both that copyright notice and this permission notice appear in
 *   supporting documentation.
 *
 *   This file is provided AS IS with no warranties of any kind.  The author
 *   shall have no liability with respect to the infringement of copyrights,
 *   trade secrets or any patents by this file or any part thereof.  In no
 *   event will the author be liable for any lost revenue or profits or
 *   other special, indirect and consequential damages.
 * -------------------------------------------------------------------------
 *
 * License of modifications/additions made after 2009-01-01:
 * -------------------------------------------------------------------------
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License as
 *   published by the Free Software Foundation; either version 2 of 
 *   the License, or (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * -------------------------------------------------------------------------
 */

#include "mod3.h"

#include "dealerinfo.h"
#include "patsolve/mod3solver.h"

#include "Shuffle"

#include <KLocale>


void Mod3::initialize()
{
    // Piles are placed very close together. Set layoutSpacing to 0 to prevent
    // interference between them.
    setLayoutSpacing(0.0);

    const qreal dist_x = 1.114;
    const qreal dist_y = 1.31;
    const qreal bottomRowY = 3 * dist_y + 0.2;
    const qreal rightColumX = 8 * dist_x + 0.8;

    // This patience uses 2 deck of cards.
    static_cast<KStandardCardDeck*>( deck() )->setDeckContents( 2 );

    talon = new PatPile( this, 0, "talon" );
    talon->setPileRole(PatPile::Stock);
    talon->setLayoutPos(rightColumX, bottomRowY);
    talon->setSpread(0, 0);
    talon->setKeyboardSelectHint( KCardPile::NeverFocus );
    talon->setKeyboardDropHint( KCardPile::NeverFocus );
    connect( talon, SIGNAL(clicked(KCard*)), SLOT(drawDealRowOrRedeal()) );

    aces = new PatPile( this, 50, "aces");
    aces->setPileRole(PatPile::FoundationType1);
    aces->setLayoutPos(rightColumX, 0.5);
    aces->setReservedSpace( 0, 0, 1, 2 );
    aces->setKeyboardSelectHint( KCardPile::NeverFocus );
    aces->setKeyboardDropHint( KCardPile::ForceFocusTop );

    for ( int r = 0; r < 4; ++r )
    {
        for ( int c = 0; c < 8; ++c )
        {
            int pileIndex = r * 10 + c  + 1;
            QString objectName = QString( "stack%1_%2" ).arg( r ).arg( c );
            stack[r][c] = new PatPile( this, pileIndex, objectName );

            // The first 3 rows are the playing field, the fourth is the store.
            if ( r < 3 )
            {
                stack[r][c]->setLayoutPos( dist_x * c, dist_y * r );
                // Very tight spread makes it easy to quickly tell number of
                // cards in each pile and we don't care about the cards beneath.
                stack[r][c]->setSpread( 0, 0.08 );
                stack[r][c]->setReservedSpace( 0, 0, 1, 1.23 );
            }
            else
            {
                stack[r][c]->setLayoutPos( dist_x * c, bottomRowY );
                stack[r][c]->setReservedSpace( 0, 0, 1, 1.8 );
            }
            stack[r][c]->setPileRole( r == 0 ? PatPile::FoundationType2
                                      : r == 1 ? PatPile::FoundationType3
                                      : r == 2 ? PatPile::FoundationType4
                                      : PatPile::Tableau );
            stack[r][c]->setKeyboardSelectHint( KCardPile::AutoFocusTop );
            stack[r][c]->setKeyboardDropHint( KCardPile::AutoFocusTop );
        }
    }

    setActions(DealerScene::Hint | DealerScene::Demo  | DealerScene::Deal);
    setSolver( new Mod3Solver( this ) );
}

bool mod3CheckAdd(int baseRank, const QList<KCard*> & oldCards, const QList<KCard*> & newCards)
{
    if (oldCards.isEmpty())
        return getRank( newCards.first() ) == baseRank;
    else
        return getRank( oldCards.first() ) == baseRank
               && getSuit( newCards.first() ) == getSuit( oldCards.last() )
               && getRank( newCards.first() ) == getRank( oldCards.last() ) + 3;
}

bool Mod3::checkAdd(const PatPile * pile, const QList<KCard*> & oldCards, const QList<KCard*> & newCards) const
{
    switch (pile->pileRole())
    {
    case PatPile::FoundationType1:
        return newCards.size() == 1 && getRank( newCards.first() ) == KStandardCardDeck::Ace;
    case PatPile::FoundationType2:
        return mod3CheckAdd(KStandardCardDeck::Two, oldCards, newCards);
    case PatPile::FoundationType3:
        return mod3CheckAdd(KStandardCardDeck::Three, oldCards, newCards);
    case PatPile::FoundationType4:
        return mod3CheckAdd(KStandardCardDeck::Four, oldCards, newCards);
    case PatPile::Tableau:
        return oldCards.isEmpty();
    case PatPile::Stock:
    default:
        return false;
    }
}

bool Mod3::checkRemove(const PatPile * pile, const QList<KCard*> & cards) const
{
    switch (pile->pileRole())
    {
    case PatPile::FoundationType2:
    case PatPile::FoundationType3:
    case PatPile::FoundationType4:
    case PatPile::Tableau:
        return cards.first() == pile->top();
    case PatPile::FoundationType1:
    case PatPile::Stock:
    default:
        return false;
    }
}

void Mod3::moveCardsToPile( QList<KCard*> cards, KCardPile * pile, int duration )
{
    PatPile * p = dynamic_cast<PatPile*>( cards.first()->pile() );

    DealerScene::moveCardsToPile( cards, pile, duration );

    if ( p
         && p->pileRole() == PatPile::Tableau
         && p->isEmpty()
         && !talon->isEmpty() )
    {
        flipCardToPile( talon->top(), p, duration );
    }
}



void Mod3::restart()
{
    clearHighlightedItems();

    QList<KCard*> cards = shuffled( deck()->cards(), gameNumber() );

    while ( !cards.isEmpty() )
    {
        KCard * c = cards.takeFirst();
        c->setPos( talon->pos() );
        c->setFaceUp( false );
        talon->add( c );
    }

    for ( int r = 0; r < 4; r++ )
    {
        for ( int c = 0; c < 8; ++c )
        {
            KCard * card = talon->top();
            card->setFaceUp( true );
            moveCardToPileAtSpeed( card, stack[r][c], DEAL_SPEED );

            // Fudge the z values to keep cards from popping through one another.
            card->setZValue( card->zValue() + ((4 - r) * (4 - r)) + ((8 - c) * (8 - c)) );
        }
    }

    emit newCardsPossible(true);
}


bool Mod3::newCards()
{
    if ( talon->isEmpty() )
        return false;

    for ( int c = 0; c < 8; ++c )
    {
        if ( talon->isEmpty() )
            break;

        flipCardToPileAtSpeed( talon->top(), stack[3][c], DEAL_SPEED * 2 );
    }

    if (talon->isEmpty())
        emit newCardsPossible(false);

    return true;
}


void Mod3::setGameState(const QString &)
{
    emit newCardsPossible(!talon->isEmpty());
}



static class Mod3DealerInfo : public DealerInfo
{
public:
    Mod3DealerInfo()
      : DealerInfo(I18N_NOOP("Mod3"), Mod3Id)
    {}

    virtual DealerScene *createGame() const
    {
        return new Mod3();
    }
} mod3DealerInfo;


#include "mod3.moc"
/Håkan
 
Old 02-24-2011, 06:21 PM   #5
T3slider
Senior Member
 
Registered: Jul 2007
Distribution: Slackware64-14.1
Posts: 2,367

Rep: Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843
OK, they really changed a lot and this is not as obvious. I haven't tested this, so I may be wrong, but I believe the following patch should work for mod3.cpp:
Code:
--- mod3.cpp~	2010-06-06 16:36:37.000000000 -0400
+++ mod3.cpp	2011-02-24 19:20:17.879903275 -0500
@@ -161,13 +161,13 @@
 
     DealerScene::moveCardsToPile( cards, pile, duration );
 
-    if ( p
-         && p->pileRole() == PatPile::Tableau
-         && p->isEmpty()
-         && !talon->isEmpty() )
-    {
-        flipCardToPile( talon->top(), p, duration );
-    }
+//    if ( p
+//         && p->pileRole() == PatPile::Tableau
+//         && p->isEmpty()
+//         && !talon->isEmpty() )
+//    {
+//        flipCardToPile( talon->top(), p, duration );
+//    }
 }
I think I've followed the logic right but if it doesn't work I can try actually compiling it.
 
2 members found this post helpful.
Old 02-25-2011, 03:19 AM   #6
hakan56
Member
 
Registered: Nov 2004
Location: Sweden
Distribution: Slackware64-14.0
Posts: 53

Original Poster
Rep: Reputation: 9
It works!
I had to apply it "manually" because I got some errors using "patch", probably because I don't really know how to use it.

Thank you very much.

/Håkan
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Modify Mandriva citra.cool2 Mandriva 2 04-25-2008 11:00 AM
kpat bitblit no cards fix kevmccor Slackware 2 08-20-2007 11:27 PM
Trying to modify xcalc steve_f60 Linux - Software 2 07-15-2006 03:59 AM
How to modify the library path variable?modify the Electronkz Linux - Newbie 1 04-13-2004 06:18 AM
modify file access & modify timestamps i2itstud Linux - General 1 05-20-2003 03:34 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware

All times are GMT -5. The time now is 05:54 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration