1 /* ColorCode, a free MasterMind clone with built in solver
2  * Copyright (C) 2009  Dirk Laebisch
3  * http://www.laebisch.com/
4  *
5  * ColorCode is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * ColorCode is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with ColorCode. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <QtWidgets>
20 #include "pegfactory.h"
21 
22 using namespace std;
23 
24 const int PegFactory::XPOS_BTNS_COL = 279;
25 
PegFactory()26 PegFactory::PegFactory()
27 {
28     mWin = ColorCode::INSTANCE;
29     mSettings = GetSettings();
30     mHideColors = false;
31 
32     InitTypesMap();
33     InitPegBtns();
34 }
35 
CreatePeg(int ix)36 ColorPeg* PegFactory::CreatePeg(int ix)
37 {
38     if (ix < 0 || ix >= ColorCode::mColorCnt)
39     {
40         ix = mAllPegs.size() % ColorCode::mColorCnt;
41     }
42 
43     QPoint btnpos = mBtnPos[ix];
44 
45     PegType *pt = mTypesMap[ix];
46     ColorPeg *peg;
47 
48     if (mPegBuff.empty())
49     {
50         peg = new ColorPeg;
51         peg->SetPegType(pt);
52         peg->SetBtn(true);
53         peg->SetIndicator(mSettings->mShowIndicators, mSettings->mIndicatorType, mHideColors);
54         peg->SetId(mAllPegs.size());
55         mWin->mScene->addItem(peg);
56         peg->setPos(btnpos);
57         peg->setZValue(ColorCode::LAYER_PEGS);
58         mAllPegs.push_back(peg);
59         mWin->mScene->clearSelection();
60         mWin->mScene->update(btnpos.x(), btnpos.y(), 38, 38);
61 
62         connect(peg, SIGNAL(PegPressSignal(ColorPeg *)), this, SLOT(PegPressSlot(ColorPeg *)));
63         connect(peg, SIGNAL(PegSortSignal(ColorPeg *)), this, SLOT(PegSortSlot(ColorPeg *)));
64         connect(peg, SIGNAL(PegReleasedSignal(ColorPeg *)), this, SLOT(PegReleasedSlot(ColorPeg *)));
65     }
66     else
67     {
68         unsigned int sz = mPegBuff.size();
69         peg = mPegBuff.at(sz - 1);
70         mPegBuff.resize(sz - 1);
71 
72         peg->setVisible(true);
73 
74         peg->SetPegType(pt);
75         peg->SetBtn(true);
76         peg->SetEnabled(true);
77         peg->setPos(btnpos);
78         mWin->mScene->clearSelection();
79         mWin->mScene->update(btnpos.x(), btnpos.y(), 38, 38);
80     }
81 
82     return peg;
83 }
84 
GetPegBtn(int ix)85 ColorPeg* PegFactory::GetPegBtn(int ix)
86 {
87     return mPegBtns[ix];
88 }
89 
RemovePegSlot(ColorPeg * cp)90 void PegFactory::RemovePegSlot(ColorPeg* cp)
91 {
92     if (cp != NULL)
93     {
94         cp->Reset();
95         cp->setVisible(false);
96         mPegBuff.push_back(cp);
97         mWin->mScene->update(cp->pos().x(), cp->pos().y(), 45, 45);
98     }
99 }
100 
PegPressSlot(ColorPeg * cp)101 void PegFactory::PegPressSlot(ColorPeg* cp)
102 {
103     if (cp == NULL) { return; }
104     cp->setZValue(ColorCode::LAYER_DRAG);
105     if (cp->IsBtn())
106     {
107         cp->SetBtn(false);
108         mPegBtns[cp->GetPegType()->ix] = CreatePeg(cp->GetPegType()->ix);
109         mPegBtns[cp->GetPegType()->ix]->SetEnabled(false);
110     }
111 }
112 
PegSortSlot(ColorPeg * cp)113 void PegFactory::PegSortSlot(ColorPeg* cp)
114 {
115     if (cp == NULL) { return; }
116     cp->setZValue(ColorCode::LAYER_DRAG);
117     if (cp->IsBtn())
118     {
119         cp->SetBtn(false);
120         mPegBtns[cp->GetPegType()->ix] = CreatePeg(cp->GetPegType()->ix);
121         mPegBtns[cp->GetPegType()->ix]->SetEnabled(false);
122     }
123 }
124 
PegReleasedSlot(ColorPeg * cp)125 void PegFactory::PegReleasedSlot(ColorPeg* cp)
126 {
127     if (cp == NULL || !cp) { return; }
128 
129     cp->setZValue(ColorCode::LAYER_PEGS);
130     mWin->mScene->clearSelection();
131     mWin->mScene->clearFocus();
132 
133     if (cp->GetSort() == 0)
134     {
135         emit(SnapPegSignal(cp));
136     }
137     else
138     {
139         int ystart = ColorCode::mRowY0 + (ColorCode::MAX_COLOR_CNT - ColorCode::mColorCnt) * 40;
140         int ix1 = qRound((cp->pos().y() - ystart + 18) / 40);
141         ix1 = min(ColorCode::mColorCnt - 1, max(0, ix1));
142 
143         int ix0 = cp->GetPegType()->ix;
144         if (ix0 != ix1)
145         {
146             ChangeColorOrder(cp->GetSort(), ix0, ix1);
147         }
148         RemovePegSlot(cp);
149     }
150 
151     if (!mPegBtns[cp->GetPegType()->ix]->isEnabled())
152     {
153         mPegBtns[cp->GetPegType()->ix]->SetEnabled(true);
154     }
155 }
156 
SetPaused()157 void PegFactory::SetPaused()
158 {
159     bool paused = (mWin->GetGameState() == ColorCode::STATE_PAUSED);
160     vector<ColorPeg *> dragged;
161     vector<ColorPeg *>::iterator it;
162     for (it = mAllPegs.begin(); it < mAllPegs.end(); it++)
163     {
164         if ((*it)->GetIsDragged())
165         {
166             dragged.push_back(*it);
167         }
168         (*it)->SetPaused(paused);
169     }
170     if (!paused)
171     {
172         for (it = dragged.begin(); it < dragged.end(); it++)
173         {
174             (*it)->ForceRelease();
175         }
176     }
177     SetIndicators();
178 }
179 
SetIndicators()180 void PegFactory::SetIndicators()
181 {
182     bool show_indicators;
183     if (mWin->GetGameState() == ColorCode::STATE_PAUSED)
184     {
185         mHideColors = true;
186         show_indicators = false;
187     }
188     else if (!mSettings->mShowIndicators)
189     {
190         mHideColors = false;
191         show_indicators = false;
192     }
193     else
194     {
195         mHideColors = mSettings->mHideColors;
196         show_indicators = mSettings->mShowIndicators;
197     }
198     vector<ColorPeg *>::iterator it;
199     for (it = mAllPegs.begin(); it < mAllPegs.end(); it++)
200     {
201         (*it)->SetIndicator(show_indicators, mSettings->mIndicatorType, mHideColors);
202     }
203 }
204 
ChangeColorOrder(const int sorttype,const int ix0,const int ix1)205 void PegFactory::ChangeColorOrder(const int sorttype, const int ix0, const int ix1)
206 {
207     QRadialGradient tmp = mGradMap[ix0];
208 
209     if (sorttype == 1)
210     {
211         mGradMap[ix0] = mGradMap[ix1];
212     }
213     else
214     {
215         int step = (ix1 > ix0) ? 1 : -1;
216         int i;
217         for (i = ix0;; i += step)
218         {
219             mGradMap[i] = mGradMap[i + step];
220             if (i == ix1 - step)
221             {
222                 break;
223             }
224         }
225     }
226 
227     mGradMap[ix1] = tmp;
228 }
229 
ResetColorsOrderSlot()230 void PegFactory::ResetColorsOrderSlot()
231 {
232     int ix;
233     for (ix = 0; ix < ColorCode::MAX_COLOR_CNT; ++ix)
234     {
235         mGradMap[ix] = mGradBuff[ix];
236     }
237     mWin->mScene->update(mWin->mScene->sceneRect());
238 }
239 
ApplyColorCnt()240 void PegFactory::ApplyColorCnt()
241 {
242     int ccnt = mSettings->mColorCnt;
243     ccnt = max(2, min(10, ccnt));
244 
245     if (ColorCode::mColorCnt == ccnt)
246     {
247         return;
248     }
249 
250     ColorCode::mColorCnt = ccnt;
251 
252     int ystart = ColorCode::mRowY0 + (ColorCode::MAX_COLOR_CNT - ccnt) * 40;
253     int ypos;
254     int i;
255 
256     for (i = 0; i < ColorCode::MAX_COLOR_CNT; ++i)
257     {
258         ypos = ystart + i * 40 + 2;
259         mBtnPos[i] = QPoint(XPOS_BTNS_COL, ypos);
260 
261         if (i < ColorCode::mColorCnt)
262         {
263             if (mPegBtns[i] == NULL)
264             {
265                 mPegBtns[i] = CreatePeg(i);
266             }
267             mPegBtns[i]->setPos(mBtnPos[i]);
268             mPegBtns[i]->setVisible(true);
269         }
270         else if (mPegBtns[i] != NULL)
271         {
272             mPegBtns[i]->setVisible(false);
273         }
274     }
275 }
276 
InitTypesMap()277 void PegFactory::InitTypesMap()
278 {
279     int ix;
280 
281     QRadialGradient grad = QRadialGradient(20, 20, 40, 5, 5);
282     QRadialGradient grad2 = QRadialGradient(18, 18, 18, 12, 12);
283 
284     ix = 0;
285     mTypesMap[ix] = new PegType;
286     grad.setColorAt(0.0, QColor("#FFFF80"));
287     grad.setColorAt(1.0, QColor("#C05800"));
288     mGradMap[ix] = grad;
289     mTypesMap[ix]->grad = &mGradMap[ix];
290     mTypesMap[ix]->ix = ix;
291     mTypesMap[ix]->pencolor = Qt::green;
292 
293     ix = 1;
294     mTypesMap[ix] = new PegType;
295     grad.setColorAt(0.0, QColor("#FF3300"));
296     grad.setColorAt(1.0, QColor("#400040"));
297     mGradMap[ix] = grad;
298     mTypesMap[ix]->grad = &mGradMap[ix];
299     mTypesMap[ix]->ix = ix;
300     mTypesMap[ix]->pencolor = Qt::green;
301 
302     ix = 2;
303     mTypesMap[ix] = new PegType;
304     grad.setColorAt(0.0, QColor("#33CCFF"));
305     grad.setColorAt(1.0, QColor("#000080"));
306     mGradMap[ix] = grad;
307     mTypesMap[ix]->grad = &mGradMap[ix];
308     mTypesMap[ix]->ix = ix;
309     mTypesMap[ix]->pencolor = Qt::red;
310 
311     ix = 3;
312     mTypesMap[ix] = new PegType;
313     grad2.setColorAt(0.0, Qt::white);
314     grad2.setColorAt(0.5, QColor("#f8f8f0"));
315     grad2.setColorAt(0.7, QColor("#f0f0f0"));
316     grad2.setColorAt(1.0, QColor("#d0d0d0"));
317     mGradMap[ix] = grad2;
318     mTypesMap[ix]->grad = &mGradMap[ix];
319     mTypesMap[ix]->ix = ix;
320     mTypesMap[ix]->pencolor = Qt::green;
321 
322     ix = 4;
323     mTypesMap[ix] = new PegType;
324     grad.setColorAt(0.0, QColor("#808080"));
325     grad.setColorAt(1.0, Qt::black);
326     mGradMap[ix] = grad;
327     mTypesMap[ix]->grad = &mGradMap[ix];
328     mTypesMap[ix]->ix = ix;
329     mTypesMap[ix]->pencolor = Qt::red;
330 
331     ix = 5;
332     mTypesMap[ix] = new PegType;
333     grad.setColorAt(0.0, QColor("#66FF33"));
334     grad.setColorAt(1.0, QColor("#385009"));
335     mGradMap[ix] = grad;
336     mTypesMap[ix]->grad = &mGradMap[ix];
337     mTypesMap[ix]->ix = ix;
338     mTypesMap[ix]->pencolor = Qt::red;
339 
340     ix = 6;
341     mTypesMap[ix] = new PegType;
342     grad.setColorAt(0.0, QColor("#FF9900"));
343     grad.setColorAt(1.0, QColor("#A82A00"));
344     mGradMap[ix] = grad;
345     mTypesMap[ix]->grad = &mGradMap[ix];
346     mTypesMap[ix]->ix = ix;
347     mTypesMap[ix]->pencolor = Qt::red;
348 
349     ix = 7;
350     mTypesMap[ix] = new PegType;
351     grad.setColorAt(0.0, QColor("#BA88FF"));
352     grad.setColorAt(1.0, QColor("#38005D"));
353     mGradMap[ix] = grad;
354     mTypesMap[ix]->grad = &mGradMap[ix];
355     mTypesMap[ix]->ix = ix;
356     mTypesMap[ix]->pencolor = Qt::green;
357 
358     ix = 8;
359     mTypesMap[ix] = new PegType;
360     grad.setColorAt(0.0, QColor("#00FFFF"));
361     grad.setColorAt(1.0, QColor("#004040"));
362     mGradMap[ix] = grad;
363     mTypesMap[ix]->grad = &mGradMap[ix];
364     mTypesMap[ix]->ix = ix;
365     mTypesMap[ix]->pencolor = Qt::green;
366 
367     ix = 9;
368     mTypesMap[ix] = new PegType;
369     grad.setColorAt(0.0, QColor("#FFC0FF"));
370     grad.setColorAt(1.0, QColor("#800080"));
371     mGradMap[ix] = grad;
372     mTypesMap[ix]->grad = &mGradMap[ix];
373     mTypesMap[ix]->ix = ix;
374     mTypesMap[ix]->pencolor = Qt::green;
375 
376     for (ix = 0; ix < ColorCode::MAX_COLOR_CNT; ++ix)
377     {
378         mTypesMap[ix]->let = 'A' + ix;
379         mGradBuff[ix] = mGradMap[ix];
380     }
381 }
382 
InitPegBtns()383 void PegFactory::InitPegBtns()
384 {
385     for (int i = 0; i < ColorCode::MAX_COLOR_CNT; ++i)
386     {
387         mPegBtns[i] = NULL;
388     }
389 }
390