1/*
2 * Copyright (C) 2000-2009 Stephan Kulow <coolo@kde.org>
3 * Copyright (C) 2010 Parker Coates <coates@kde.org>
4 *
5 * License of original code:
6 * -------------------------------------------------------------------------
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation for any purpose and without fee is hereby granted,
9 * provided that the above copyright notice appear in all copies and that
10 * both that copyright notice and this permission notice appear in
11 * supporting documentation.
12 *
13 * This file is provided AS IS with no warranties of any kind. The author
14 * shall have no liability with respect to the infringement of copyrights,
15 * trade secrets or any patents by this file or any part thereof. In no
16 * event will the author be liable for any lost revenue or profits or
17 * other special, indirect and consequential damages.
18 * -------------------------------------------------------------------------
19 *
20 * License of modifications/additions made after 2009-01-01:
21 * -------------------------------------------------------------------------
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; either version 2 of
25 * the License, or (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program. If not, see <http://www.gnu.org/licenses/>.
34 * -------------------------------------------------------------------------
35 */
36
37#include "gypsy.h"
38
39#include "dealerinfo.h"
40#include "pileutils.h"
41#include "patsolve/gypsysolver.h"
42
43#include <KLocale>
44
45
46Gypsy::Gypsy( const DealerInfo * di )
47 : DealerScene( di )
48{
49}
50
51
52void Gypsy::initialize()
53{
54 const qreal dist_x = 1.11;
55 const qreal dist_y = 1.11;
56
57 setDeckContents( 2 );
58
59 talon = new PatPile( this, 0, "talon" );
60 talon->setPileRole(PatPile::Stock);
61 talon->setLayoutPos(8.5 * dist_x + 0.4, 4 * dist_y);
62 talon->setKeyboardSelectHint( KCardPile::NeverFocus );
63 talon->setKeyboardDropHint( KCardPile::NeverFocus );
64 connect( talon, SIGNAL(clicked(KCard*)), SLOT(drawDealRowOrRedeal()) );
65
66 for ( int i = 0; i < 8; ++i )
67 {
68 target[i] = new PatPile( this, i + 1, QString("target%1").arg(i) );
69 target[i]->setPileRole(PatPile::Foundation);
70 target[i]->setLayoutPos(dist_x*(8+(i/4)) + 0.4, (i%4)*dist_y);
71 target[i]->setKeyboardSelectHint( KCardPile::NeverFocus );
72 target[i]->setKeyboardDropHint( KCardPile::ForceFocusTop );
73 }
74
75 for ( int i = 0; i < 8; ++i )
76 {
77 store[i] = new PatPile( this, 9 + i, QString("store%1").arg(i) );
78 store[i]->setPileRole(PatPile::Tableau);
79 store[i]->setLayoutPos(dist_x*i,0);
80 store[i]->setAutoTurnTop(true);
81 store[i]->setBottomPadding( 4 * dist_y );
82 store[i]->setHeightPolicy( KCardPile::GrowDown );
83 store[i]->setKeyboardSelectHint( KCardPile::AutoFocusDeepestRemovable );
84 store[i]->setKeyboardDropHint( KCardPile::AutoFocusTop );
85 }
86
87 setActions(DealerScene::Hint | DealerScene::Demo | DealerScene::Deal);
88 setSolver( new GypsySolver( this ) );
89}
90
91void Gypsy::restart( const QList<KCard*> & cards )
92{
93 QList<KCard*> cardList = cards;
94
95 for ( int round = 0; round < 8; ++round )
96 addCardForDeal(store[round], cardList.takeLast(), false, store[round]->pos() + QPointF(-2*deck()->cardWidth(),-1.1*deck()->cardHeight()));
97
98 for ( int round = 0; round < 8; ++round )
99 addCardForDeal(store[round], cardList.takeLast(), true, store[round]->pos() + QPointF(-3*deck()->cardWidth(),-1.6*deck()->cardHeight()));
100
101 for ( int round = 0; round < 8; ++round )
102 addCardForDeal(store[round], cardList.takeLast(), true, store[round]->pos() + QPointF(-4*deck()->cardWidth(),-2.1*deck()->cardHeight()));
103
104 while ( !cardList.isEmpty() )
105 {
106 KCard * c = cardList.takeFirst();
107 c->setPos( talon->pos() );
108 c->setFaceUp( false );
109 talon->add( c );
110 }
111
112 startDealAnimation();
113
114 emit newCardsPossible(true);
115}
116
117bool Gypsy::checkAdd(const PatPile * pile, const QList<KCard*> & oldCards, const QList<KCard*> & newCards) const
118{
119 switch (pile->pileRole())
120 {
121 case PatPile::Tableau:
122 return checkAddAlternateColorDescending(oldCards, newCards);
123 case PatPile::Foundation:
124 return checkAddSameSuitAscendingFromAce(oldCards, newCards);
125 case PatPile::Stock:
126 default:
127 return false;
128 }
129}
130
131bool Gypsy::checkRemove(const PatPile * pile, const QList<KCard*> & cards) const
132{
133 switch (pile->pileRole())
134 {
135 case PatPile::Tableau:
136 return isAlternateColorDescending(cards);
137 case PatPile::Foundation:
138 return cards.first() == pile->topCard();
139 case PatPile::Stock:
140 default:
141 return false;
142 }
143}
144
145
146bool Gypsy::newCards()
147{
148 if ( talon->isEmpty() )
149 return false;
150
151 for ( int round = 0; round < 8; ++round )
152 {
153 KCard * c = talon->topCard();
154 flipCardToPileAtSpeed( c, store[round], DEAL_SPEED );
155 c->setZValue( c->zValue() + 8 - round );
156 }
157
158 if (talon->isEmpty())
159 emit newCardsPossible(false);
160
161 return true;
162}
163
164
165void Gypsy::setGameState( const QString & state )
166{
167 Q_UNUSED( state )
168 emit newCardsPossible(!talon->isEmpty());
169}
170
171
172
173static class GypsyDealerInfo : public DealerInfo
174{
175public:
176 GypsyDealerInfo()
177 : DealerInfo(I18N_NOOP("Gypsy"), GypsyId)
178 {}
179
180 virtual DealerScene *createGame() const
181 {
182 return new Gypsy( this );
183 }
184} gypsyDealerInfo;
185
186
187#include "gypsy.moc"
188