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 "simon.h"
38
39#include "dealerinfo.h"
40#include "pileutils.h"
41#include "patsolve/simonsolver.h"
42
43#include <KLocale>
44
45
46Simon::Simon( const DealerInfo * di )
47 : DealerScene( di )
48{
49}
50
51
52void Simon::initialize()
53{
54 setDeckContents();
55
56 const qreal dist_x = 1.11;
57
58 for ( int i = 0; i < 4; ++i )
59 {
60 target[i] = new PatPile( this, i + 1, QString( "target%1" ).arg( i ) );
61 target[i]->setPileRole(PatPile::Foundation);
62 target[i]->setLayoutPos((i+3)*dist_x, 0);
63 target[i]->setSpread(0, 0);
64 target[i]->setKeyboardSelectHint( KCardPile::NeverFocus );
65 target[i]->setKeyboardDropHint( KCardPile::AutoFocusTop );
66 }
67
68 for ( int i = 0; i < 10; ++i )
69 {
70 store[i] = new PatPile( this, 5 + i, QString( "store%1" ).arg( i ) );
71 store[i]->setPileRole(PatPile::Tableau);
72 store[i]->setLayoutPos(dist_x*i, 1.2);
73 store[i]->setBottomPadding( 2.5 );
74 store[i]->setHeightPolicy( KCardPile::GrowDown );
75 store[i]->setZValue( 0.01 * i );
76 store[i]->setKeyboardSelectHint( KCardPile::AutoFocusDeepestRemovable );
77 store[i]->setKeyboardDropHint( KCardPile::AutoFocusTop );
78 }
79
80 setActions(DealerScene::Hint | DealerScene::Demo);
81 setSolver( new SimonSolver( this ) );
82 //setNeededFutureMoves( 1 ); // could be some nonsense moves
83}
84
85void Simon::restart( const QList<KCard*> & cards )
86{
87 QList<KCard*> cardList = cards;
88
89 QPointF initPos( 0, -deck()->cardHeight() );
90
91 for ( int piles = 9; piles >= 3; --piles )
92 for ( int j = 0; j < piles; ++j )
93 addCardForDeal( store[j], cardList.takeLast(), true, initPos );
94
95 for ( int j = 0; j < 10; ++j )
96 addCardForDeal( store[j], cardList.takeLast(), true, initPos );
97
98 Q_ASSERT( cardList.isEmpty() );
99
100 startDealAnimation();
101}
102
103bool Simon::checkPrefering(const PatPile * pile, const QList<KCard*> & oldCards, const QList<KCard*> & newCards) const
104{
105 return pile->pileRole() == PatPile::Tableau
106 && !oldCards.isEmpty()
107 && oldCards.last()->suit() == newCards.first()->suit();
108}
109
110bool Simon::checkAdd(const PatPile * pile, const QList<KCard*> & oldCards, const QList<KCard*> & newCards) const
111{
112 if (pile->pileRole() == PatPile::Tableau)
113 {
114 return oldCards.isEmpty()
115 || oldCards.last()->rank() == newCards.first()->rank() + 1;
116 }
117 else
118 {
119 return oldCards.isEmpty()
120 && newCards.first()->rank() == KCardDeck::King
121 && newCards.last()->rank() == KCardDeck::Ace;
122 }
123}
124
125bool Simon::checkRemove(const PatPile * pile, const QList<KCard*> & cards) const
126{
127 return pile->pileRole() == PatPile::Tableau
128 && isSameSuitDescending(cards);
129}
130
131
132
133static class SimonDealerInfo : public DealerInfo
134{
135public:
136 SimonDealerInfo()
137 : DealerInfo(I18N_NOOP("Simple Simon"), SimpleSimonId)
138 {}
139
140 virtual DealerScene *createGame() const
141 {
142 return new Simon( this );
143 }
144} simonDealerInfo;
145
146#include "simon.moc"
147