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
21 #include "settings.h"
22 #include "ccsolver.h"
23 #include "colorcode.h"
24 #include "colorpeg.h"
25 #include "pegrow.h"
26 #include "rowhint.h"
27 #include "msg.h"
28 #include "background.h"
29 #include "about.h"
30 #include "prefdialog.h"
31 #include "solutionrow.h"
32 #include "graphicsbtn.h"
33 #include "pegfactory.h"
34 #include "gamenodisplay.h"
35 #include "timedisplay.h"
36 #include "timedisplaybg.h"
37 #include "highscore.h"
38 #include "gametablesdialog.h"
39
40 using namespace std;
41
42 ColorCode* ColorCode::INSTANCE = NULL;
43
44 const QString ColorCode::VERSION = "0.8.5";
45
46 volatile bool ColorCode::mNoAct = false;
47 volatile bool ColorCode::mIgnoreGuess = false;
48
49 const int ColorCode::STATE_NONE = 0;
50 const int ColorCode::STATE_RUNNING = 1;
51 const int ColorCode::STATE_PAUSED = 2;
52 const int ColorCode::STATE_WON = 3;
53 const int ColorCode::STATE_LOST = 4;
54 const int ColorCode::STATE_GAVE_UP = 5;
55 const int ColorCode::STATE_ERROR = 6;
56
57 const int ColorCode::MODE_HVM = 0;
58 const int ColorCode::MODE_MVH = 1;
59
60 const int ColorCode::MAX_COLOR_CNT = 10;
61 const int ColorCode::MIN_COLOR_CNT = 2;
62 const int ColorCode::SOLUTION_ROW_IX = -1;
63
64 const int ColorCode::LAYER_BG = 1;
65 const int ColorCode::LAYER_ROWS = 2;
66 const int ColorCode::LAYER_HINTS = 3;
67 const int ColorCode::LAYER_SOL = 4;
68 const int ColorCode::LAYER_MSG = 5;
69 const int ColorCode::LAYER_PEGS = 6;
70 const int ColorCode::LAYER_BTNS = 7;
71 const int ColorCode::LAYER_DRAG = 8;
72
73 const int ColorCode::LEVEL_SETTINGS[5][3] = {
74 { 2, 2, 1},
75 { 4, 3, 0},
76 { 6, 4, 1},
77 { 8, 4, 1},
78 {10, 5, 1}
79 };
80
81
82 int ColorCode::mMaxRowCnt = 10;
83 int ColorCode::mRowY0 = 130;
84 int ColorCode::mColorCnt = 0;
85 int ColorCode::mPegCnt = 0;
86 int ColorCode::mDoubles = 1;
87 int ColorCode::mXOffs = 0;
88 int ColorCode::mMaxZ = 0;
89 int ColorCode::mLevel = -1;
90 int ColorCode::mGameMode = ColorCode::MODE_HVM;
91
92 QString ColorCode::GAME_TITLE = "";
93
ColorCode()94 ColorCode::ColorCode()
95 {
96 SetState(STATE_NONE);
97
98 GAME_TITLE = tr("ColorCode");
99
100 setWindowTitle(GAME_TITLE + " ");
101 setWindowIcon(QIcon(QPixmap(":/img/cc16.png")));
102 setIconSize(QSize(16, 16));
103
104 setMouseTracking(true);
105 setAttribute(Qt::WA_Hover, true);
106 setAttribute(Qt::WA_AlwaysShowToolTips, true);
107
108 INSTANCE = this;
109
110 QCoreApplication::setOrganizationName("dirks");
111 QCoreApplication::setOrganizationDomain("laebisch.com");
112 QCoreApplication::setApplicationName("colorcode");
113
114 QTime midnight(0, 0, 0);
115 qsrand(midnight.secsTo(QTime::currentTime()));
116
117 Init();
118 }
119
~ColorCode()120 ColorCode::~ColorCode()
121 {
122 mIgnoreGuess = true;
123 mSettings->WriteSettings();
124 WaitForSolver();
125 }
126
Init()127 void ColorCode::Init()
128 {
129 mGameTablesDialog = new GameTablesDialog(this);
130 mGameInput = NULL;
131 mFinishedGameInput = NULL;
132 mPrefDialog = NULL;
133 mSettings = GetSettings();
134 connect(mSettings, SIGNAL(ReadSettingsGamesDone()), mGameTablesDialog, SLOT(ReadSettingsGamesSlot()));
135 connect(this, SIGNAL(NewHighScoreSignal(CCGame*)), mGameTablesDialog, SLOT(InsertHighScoreSlot(CCGame*)));
136 connect(mGameTablesDialog, SIGNAL(NewGameInputSignal(CCGame*)), this, SLOT(NewGameInputSlot(CCGame*)));
137
138 mSettings->Init();
139
140 mHighScore = new HighScore();
141
142 mCurRow = NULL;
143 mColorCnt = 0;
144 mGameCnt = 0;
145 mGameId = 0;
146 mGuessCnt = 0;
147 mHintsCnt = 0;
148 mSolverStrength = CCSolver::STRENGTH_HIGH;
149
150 mOrigSize = NULL;
151
152 mMenuBar = menuBar();
153
154 // as long as menuBar's size is invalid populated initially ... done for 4.6
155 #ifdef Q_WS_X11
156 #if QT_VERSION < 0x040600
157 mScene = new QGraphicsScene(0, 0, 320, 580);
158 #else
159 mScene = new QGraphicsScene(0, 0, 320, 560);
160 #endif
161 #else
162 mScene = new QGraphicsScene(0, 0, 320, 560);
163 #endif
164
165 mScene->setBackgroundBrush(QBrush(QColor("#b0b1b3")));
166
167 mView = new QGraphicsView;
168 mView->setScene(mScene);
169 mView->setGeometry(0, 0, 320, 560);
170 mView->setDragMode(QGraphicsView::NoDrag);
171 mView->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
172 mView->setContextMenuPolicy(Qt::NoContextMenu);
173 mView->setAlignment(Qt::AlignCenter);
174 mView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
175 mView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
176 mView->setFrameStyle(QFrame::NoFrame);
177
178 setCentralWidget(mView);
179
180 mBg = new BackGround();
181 mScene->addItem(mBg);
182 mBg->setPos(0, 0);
183 mBg->setZValue(LAYER_BG);
184
185 mMsg = new Msg;
186 mScene->addItem(mMsg);
187 mMsg->setPos(20, 0);
188 mMsg->setZValue(LAYER_MSG);
189
190 mGameNoDisplay = new GameNoDisplay;
191 mScene->addItem(mGameNoDisplay);
192 mGameNoDisplay->setPos(10, 534);
193 mGameNoDisplay->setZValue(LAYER_MSG);
194
195 mDoneBtn = new GraphicsBtn;
196 mDoneBtn->SetLabel(tr("Done"));
197 mScene->addItem(mDoneBtn);
198 mDoneBtn->setPos(84, 118);
199 mDoneBtn->setZValue(LAYER_BTNS);
200 mDoneBtn->ShowBtn(false);
201 connect(mDoneBtn, SIGNAL(BtnPressSignal(GraphicsBtn *)), this, SLOT(DoneBtnPressSlot(GraphicsBtn *)));
202
203 mOkBtn = new GraphicsBtn;
204 mOkBtn->SetWidth(38);
205 mOkBtn->SetLabel("ok");
206 mScene->addItem(mOkBtn);
207 mOkBtn->setPos(5, 329);
208 mOkBtn->setZValue(LAYER_BTNS);
209 mOkBtn->ShowBtn(false);
210 connect(mOkBtn, SIGNAL(BtnPressSignal(GraphicsBtn *)), this, SLOT(DoneBtnPressSlot(GraphicsBtn *)));
211
212 mTimerBtn = new GraphicsBtn;
213 mTimerBtn->SetWidth(261);
214 mTimerBtn->SetLabel("");
215 mScene->addItem(mTimerBtn);
216 mTimerBtn->setScale(0.44);
217 mTimerBtn->setPos(102, 110);
218 mTimerBtn->setZValue(LAYER_HINTS);
219 mTimerBtn->InvertStates();
220 mTimerBtn->ShowBtn(true);
221 connect(mTimerBtn, SIGNAL(BtnPressSignal(GraphicsBtn *)), this, SLOT(PauseGameSlot(GraphicsBtn *)));
222
223 mSolutionRowBg = new GraphicsBtn;
224 mSolutionRowBg->SetEnabled(false);
225 mSolutionRowBg->SetWidth(219);
226 mSolutionRowBg->SetLabel("");
227 mScene->addItem(mSolutionRowBg);
228 mSolutionRowBg->setScale(1.14);
229 mSolutionRowBg->setPos(35, 66);
230 mSolutionRowBg->setZValue(LAYER_ROWS);
231 mSolutionRowBg->SetStatesOpacity(1.0, 0.1);
232 mSolutionRowBg->InvertStates();
233 mSolutionRowBg->ShowBtn(true);
234
235 mPegFactory = new PegFactory();
236 connect(mPegFactory, SIGNAL(SnapPegSignal(ColorPeg*)), this, SLOT(SnapPegSlot(ColorPeg*)));
237
238 mSolver = new CCSolver(this);
239 connect(mSolver, SIGNAL(finished()), this, SLOT(SetSolverGuessSlot()));
240 connect(mSolver, SIGNAL(GuessDoneSignal()), this, SLOT(SetSolverGuessSlot()));
241 mHintsDelayTimer = new QTimer();
242 mHintsDelayTimer->setSingleShot(true);
243 mHintsDelayTimer->setInterval(500);
244 connect(mHintsDelayTimer, SIGNAL(timeout()), this, SLOT(SetAutoHintsSlot()));
245
246 mGameTimerBg = new TimeDisplayBg();
247 mScene->addItem(mGameTimerBg);
248 mGameTimerBg->setPos(50, 108);
249 mGameTimerBg->setZValue(LAYER_SOL);
250
251 mGameTimer = new TimeDisplay();
252 mScene->addItem(mGameTimer);
253 mGameTimer->setPos(49, 109);
254 mGameTimer->setZValue(LAYER_MSG);
255
256 InitActions();
257 InitMenus();
258 InitToolBars();
259
260 statusBar()->setStyleSheet("QStatusBar::item { border: 0px solid black }; ");
261 mStatusLabel = new QLabel();
262 statusBar()->addPermanentWidget(mStatusLabel, 0);
263
264 InitSolution();
265 InitRows();
266
267 ApplySettingsSlot();
268 }
269
InitSolution()270 void ColorCode::InitSolution()
271 {
272 mSolutionRow = new SolutionRow();
273 mSolutionRow->SetIx(SOLUTION_ROW_IX);
274 mSolutionRow->setPos(50, 68);
275 mSolutionRow->setZValue(LAYER_SOL);
276 mScene->addItem(mSolutionRow);
277 connect(mSolutionRow, SIGNAL(RemovePegSignal(ColorPeg*)), mPegFactory, SLOT(RemovePegSlot(ColorPeg*)));
278 connect(mSolutionRow, SIGNAL(RowSolutionSignal(int)), this, SLOT(RowSolutionSlot(int)));
279 }
280
InitRows()281 void ColorCode::InitRows()
282 {
283 PegRow* row;
284 RowHint* hint;
285
286 int xpos = 60;
287 int ypos = mRowY0;
288 int i;
289
290 for (i = 0; i < mMaxRowCnt; ++i)
291 {
292 row = new PegRow();
293 row->SetIx(i);
294 row->setPos(QPoint(xpos, ypos + (mMaxRowCnt - (i + 1)) * 40));
295 row->setZValue(LAYER_ROWS);
296 row->SetActive(false);
297 mScene->addItem(row);
298 mPegRows[i] = row;
299 connect(row, SIGNAL(RemovePegSignal(ColorPeg*)), mPegFactory, SLOT(RemovePegSlot(ColorPeg*)));
300 connect(row, SIGNAL(RowSolutionSignal(int)), this, SLOT(RowSolutionSlot(int)));
301
302 hint = new RowHint;
303 hint->SetIx(i);
304 hint->setPos(QPoint(4, ypos + (mMaxRowCnt - (i + 1)) * 40));
305 hint->setZValue(LAYER_HINTS);
306 hint->SetActive(false);
307 mScene->addItem(hint);
308 mHintBtns[i] = hint;
309 connect(hint, SIGNAL(HintPressedSignal(int)), this, SLOT(HintPressedSlot(int)));
310 }
311 }
312
InitActions()313 void ColorCode::InitActions()
314 {
315 mActNewGame = new QAction(tr("&New Game"), this);
316 mActNewGame->setIcon(QIcon(":/img/document-new.png"));
317 mActNewGame->setShortcut(tr("Ctrl+N"));
318 connect(mActNewGame, SIGNAL(triggered()), this, SLOT(NewGameSlot()));
319
320 mActSelectGame = new QAction(tr("&Start particular Game"), this);
321 mActSelectGame->setIcon(QIcon(":/img/document-new.png"));
322 mActSelectGame->setShortcut(tr("Ctrl+Alt+N"));
323 connect(mActSelectGame, SIGNAL(triggered()), mGameTablesDialog, SLOT(ShowInputSlot()));
324
325 mActCopyGameNo = new QAction(tr("&Copy Game Number"), this);
326 mActCopyGameNo->setIcon(QIcon(":/img/edit-copy.png"));
327 mActCopyGameNo->setShortcut(tr("Ctrl+C"));
328 connect(mActCopyGameNo, SIGNAL(triggered()), this, SLOT(CopyGameNoSlot()));
329
330 mActRestartGame = new QAction(tr("&Restart Game"), this);
331 mActRestartGame->setIcon(QIcon(":/img/view-refresh.png"));
332 mActRestartGame->setShortcut(tr("Ctrl+Shift+R"));
333 connect(mActRestartGame, SIGNAL(triggered()), this, SLOT(RestartGameSlot()));
334
335 mActGiveIn = new QAction(tr("&Throw In The Towel"), this);
336 mActGiveIn->setIcon(QIcon(":/img/face-sad.png"));
337 mActGiveIn->setShortcut(tr("Ctrl+G"));
338 connect(mActGiveIn, SIGNAL(triggered()), this, SLOT(GiveInSlot()));
339
340 mActPauseGame = new QAction(tr("&Have a Break"), this);
341 mActPauseGame->setIcon(QIcon(":/img/pause.png"));
342 mActPauseGame->setShortcut(tr("Ctrl+P"));
343 connect(mActPauseGame, SIGNAL(triggered()), this, SLOT(PauseGameSlot()));
344
345 mActSaveGame = new QAction(tr("&Bookmark Current Game"), this);
346 mActSaveGame->setIcon(QIcon(":/img/bookmark_add.png"));
347 mActSaveGame->setShortcut(tr("Ctrl+B"));
348 connect(mActSaveGame, SIGNAL(triggered()), this, SLOT(SavePrevGameSlot()));
349
350 mActShowHighScores = new QAction(tr("&Highscores"), this);
351 mActShowHighScores->setIcon(QIcon(":/img/games-highscores.png"));
352 mActShowHighScores->setShortcut(tr("Ctrl+Alt+H"));
353 connect(mActShowHighScores, SIGNAL(triggered()), mGameTablesDialog, SLOT(ShowHighSlot()));
354
355 mActShowPrevGames = new QAction(tr("&Recent Games"), this);
356 mActShowPrevGames->setIcon(QIcon(":/img/history.png"));
357 mActShowPrevGames->setShortcut(tr("Ctrl+Alt+R"));
358 connect(mActShowPrevGames, SIGNAL(triggered()), mGameTablesDialog, SLOT(ShowPrevSlot()));
359
360 mActShowSavedGames = new QAction(tr("&Bookmarks"), this);
361 mActShowSavedGames->setIcon(QIcon(":/img/bookmark.png"));
362 mActShowSavedGames->setShortcut(tr("Ctrl+Alt+B"));
363 connect(mActShowSavedGames, SIGNAL(triggered()), mGameTablesDialog, SLOT(ShowSavedSlot()));
364
365 mActExit = new QAction(tr("E&xit"), this);
366 mActExit->setIcon(QIcon(":/img/application-exit.png"));
367 mActExit->setShortcut(tr("Ctrl+Q"));
368 connect(mActExit, SIGNAL(triggered()), this, SLOT(close()));
369
370 mActShowToolbar = new QAction(tr("Show Toolbar"), this);
371 mActShowToolbar->setCheckable(true);
372 mActShowToolbar->setChecked(true);
373 mActShowToolbar->setShortcut(tr("Ctrl+Shift+T"));
374 connect(mActShowToolbar, SIGNAL(triggered()), this, SLOT(ShowToolbarSlot()));
375
376 mActShowMenubar = new QAction(tr("Show Menubar"), this);
377 mActShowMenubar->setCheckable(true);
378 mActShowMenubar->setChecked(true);
379 mActShowMenubar->setShortcut(tr("Ctrl+M"));
380 connect(mActShowMenubar, SIGNAL(triggered()), this, SLOT(ShowMenubarSlot()));
381
382 mActShowStatusbar = new QAction(tr("Show Statusbar"), this);
383 mActShowStatusbar->setCheckable(true);
384 mActShowStatusbar->setChecked(true);
385 mActShowStatusbar->setShortcut(tr("Ctrl+Shift+B"));
386 connect(mActShowStatusbar, SIGNAL(triggered()), this, SLOT(ShowStatusbarSlot()));
387
388 mActShowTimer = new QAction(tr("Show Timer"), this);
389 mActShowTimer->setCheckable(true);
390 mActShowTimer->setChecked(true);
391 mActShowTimer->setShortcut(tr("Ctrl+T"));
392 connect(mActShowTimer, SIGNAL(triggered()), this, SLOT(ShowTimerSlot()));
393
394 mActShowGameNo = new QAction(tr("Display Game Number"), this);
395 mActShowGameNo->setCheckable(true);
396 mActShowGameNo->setChecked(true);
397 mActShowGameNo->setShortcut(tr("Ctrl+Shift+N"));
398 connect(mActShowGameNo, SIGNAL(triggered()), this, SLOT(ShowGameNoSlot()));
399
400 mActResetColorsOrder = new QAction(tr("Reset Color Order"), this);
401 mActResetColorsOrder->setShortcut(tr("Ctrl+Shift+C"));
402 connect(mActResetColorsOrder, SIGNAL(triggered()), mPegFactory, SLOT(ResetColorsOrderSlot()));
403
404 mActShowIndicators = new QAction(tr("Show Indicators"), this);
405 mActShowIndicators->setCheckable(true);
406 mActShowIndicators->setChecked(false);
407 mActShowIndicators->setShortcut(tr("Ctrl+Shift+L"));
408 connect(mActShowIndicators, SIGNAL(triggered()), this, SLOT(SetIndicatorsSlot()));
409
410 mActDoubles = new QAction(tr("Allow Pegs of the Same Color"), this);
411 mActDoubles->setCheckable(true);
412 mActDoubles->setChecked(true);
413 mActDoubles->setShortcut(tr("Ctrl+Shift+S"));
414 connect(mActDoubles, SIGNAL(triggered(bool)), this, SLOT(DoublesChangedSlot(bool)));
415
416 mActDoublesIcon = new QAction(tr("Allow Pegs of Same Color"), this);
417 mActDoublesIcon->setCheckable(true);
418 mActDoublesIcon->setChecked(true);
419 mActDoublesIcon->setToolTip(tr("Disallow Pegs of Same Color"));
420 mActDoublesIcon->setIcon(QIcon(":/img/same_color_1.png"));
421 connect(mActDoublesIcon, SIGNAL(triggered(bool)), this, SLOT(DoublesChangedSlot(bool)));
422
423 mActAutoClose = new QAction(tr("Close Rows when the last Peg is placed"), this);
424 mActAutoClose->setCheckable(true);
425 mActAutoClose->setChecked(false);
426 mActAutoClose->setShortcut(tr("Ctrl+L"));
427 connect(mActAutoClose, SIGNAL(triggered()), this, SLOT(AutoCloseSlot()));
428
429 mActAutoHints = new QAction(tr("Set Hints automatically"), this);
430 mActAutoHints->setCheckable(true);
431 mActAutoHints->setChecked(false);
432 mActAutoHints->setShortcut(tr("Ctrl+Shift+H"));
433 connect(mActAutoHints, SIGNAL(triggered()), this, SLOT(AutoHintsSlot()));
434
435 mLaunchHelpAction = new QAction(tr("Online &Help"), this);
436 mLaunchHelpAction->setIcon(QIcon(":/img/help.png"));
437 mLaunchHelpAction->setShortcut(tr("F1"));
438 connect(mLaunchHelpAction, SIGNAL(triggered()), this, SLOT(OnlineHelpSlot()));
439
440 mActAbout = new QAction(tr("About &ColorCode"), this);
441 mActAbout->setIcon(QIcon(":/img/help-about.png"));
442 mActAbout->setShortcut(tr("Ctrl+A"));
443 connect(mActAbout, SIGNAL(triggered()), this, SLOT(AboutSlot()));
444
445 mActAboutQt = new QAction(tr("About &Qt"), this);
446 mActAboutQt->setIcon(QIcon(":/img/qt.png"));
447 mActAboutQt->setShortcut(tr("Ctrl+I"));
448 connect(mActAboutQt, SIGNAL(triggered()), this, SLOT(AboutQtSlot()));
449
450 mActRandRow = new QAction(tr("Fill Row by Random"), this);
451 mActRandRow->setIcon(QIcon(":/img/system-switch-user.png"));
452 mActRandRow->setShortcut(tr("Ctrl+R"));
453 connect(mActRandRow, SIGNAL(triggered()), this, SLOT(RandRowSlot()));
454
455 mActPrevRow = new QAction(tr("Duplicate Previous Row"), this);
456 mActPrevRow->setIcon(QIcon(":/img/edit-copy.png"));
457 mActPrevRow->setShortcut(tr("Ctrl+D"));
458 connect(mActPrevRow, SIGNAL(triggered()), this, SLOT(PrevRowSlot()));
459
460 mActClearRow = new QAction(tr("Clear Row"), this);
461 mActClearRow->setIcon(QIcon(":/img/edit-clear.png"));
462 mActClearRow->setShortcut(tr("Ctrl+Alt+C"));
463 connect(mActClearRow, SIGNAL(triggered()), this, SLOT(ClearRowSlot()));
464
465 mActLevelEasy = new QAction(tr("Beginner (2 Colors, 2 Slots, Doubles)"), this);
466 mActLevelEasy->setData(0);
467 mActLevelEasy->setCheckable(true);
468 mActLevelEasy->setChecked(false);
469 connect(mActLevelEasy, SIGNAL(triggered()), this, SLOT(SetLevelSlot()));
470
471 mActLevelClassic = new QAction(tr("Easy (4 Colors, 3 Slots, No Doubles)"), this);
472 mActLevelClassic->setData(1);
473 mActLevelClassic->setCheckable(true);
474 mActLevelClassic->setChecked(false);
475 connect(mActLevelClassic, SIGNAL(triggered()), this, SLOT(SetLevelSlot()));
476
477 mActLevelMedium = new QAction(tr("Classic (6 Colors, 4 Slots, Doubles)"), this);
478 mActLevelMedium->setData(2);
479 mActLevelMedium->setCheckable(true);
480 mActLevelMedium->setChecked(true);
481 connect(mActLevelMedium, SIGNAL(triggered()), this, SLOT(SetLevelSlot()));
482
483 mActLevelChallenging = new QAction(tr("Challenging (8 Colors, 4 Slots, Doubles)"), this);
484 mActLevelChallenging->setData(3);
485 mActLevelChallenging->setCheckable(true);
486 mActLevelChallenging->setChecked(false);
487 connect(mActLevelChallenging, SIGNAL(triggered()), this, SLOT(SetLevelSlot()));
488
489 mActLevelHard = new QAction(tr("Hard (10 Colors, 5 Slots, Doubles)"), this);
490 mActLevelHard->setData(4);
491 mActLevelHard->setCheckable(true);
492 mActLevelHard->setChecked(false);
493 connect(mActLevelHard, SIGNAL(triggered()), this, SLOT(SetLevelSlot()));
494
495 mActSetGuess = new QAction(tr("Computer's Guess"), this);
496 mActSetGuess->setIcon(QIcon(":/img/business_user.png"));
497 mActSetGuess->setShortcut(tr("Ctrl+H"));
498 connect(mActSetGuess, SIGNAL(triggered()), this, SLOT(SetGuessSlot()));
499
500 mActSetHints = new QAction(tr("Rate it for me"), this);
501 mActSetHints->setIcon(QIcon(":/img/icon_female16.png"));
502 mActSetHints->setShortcut(tr("Ctrl+H"));
503 connect(mActSetHints, SIGNAL(triggered()), this, SLOT(SetHintsSlot()));
504
505 mActModeHvM = new QAction(tr("Human vs Computer"), this);
506 mActModeHvM->setData(MODE_HVM);
507 mActModeHvM->setCheckable(true);
508 mActModeHvM->setChecked(true);
509 connect(mActModeHvM, SIGNAL(triggered()), this, SLOT(SetGameModeSlot()));
510
511 mActModeMvH = new QAction(tr("Computer vs Human"), this);
512 mActModeMvH->setData(MODE_MVH);
513 mActModeMvH->setCheckable(true);
514 mActModeMvH->setChecked(false);
515 connect(mActModeMvH, SIGNAL(triggered()), this, SLOT(SetGameModeSlot()));
516
517 mActPreferences = new QAction(tr("Preferences"), this);
518 mActPreferences->setIcon(QIcon(":/img/configure.png"));
519 mActPreferences->setShortcut(tr("Ctrl+Shift+P"));
520 connect(mActPreferences, SIGNAL(triggered()), this, SLOT(OpenPreferencesSlot()));
521 }
522
InitMenus()523 void ColorCode::InitMenus()
524 {
525 mMenuGame = mMenuBar->addMenu(tr("&Game"));
526 mMenuGame->addAction(mActNewGame);
527 mMenuGame->addAction(mActSelectGame);
528 mMenuGame->addAction(mActRestartGame);
529 mMenuGame->addSeparator();
530 mMenuGame->addAction(mActPauseGame);
531 mMenuGame->addAction(mActGiveIn);
532 mMenuGame->addSeparator();
533 mMenuGame->addAction(mActCopyGameNo);
534 mMenuGame->addAction(mActSaveGame);
535 mMenuGame->addSeparator();
536 mMenuGame->addAction(mActExit);
537
538 mMenuRow = mMenuBar->addMenu(tr("&Row"));
539 mMenuRow->addAction(mActRandRow);
540 mMenuRow->addAction(mActPrevRow);
541 mMenuRow->addAction(mActClearRow);
542 mMenuRow->addSeparator();
543 mMenuRow->addAction(mActSetGuess);
544 mMenuRow->addAction(mActSetHints);
545 connect(mMenuRow, SIGNAL(aboutToShow()), this, SLOT(UpdateRowMenuSlot()));
546
547
548 mMenuGames = mMenuBar->addMenu(tr("Game &Lists"));
549
550 mMenuGames->addAction(mActShowHighScores);
551 mMenuGames->addAction(mActShowSavedGames);
552 mMenuGames->addAction(mActShowPrevGames);
553
554
555 mMenuSettings = mMenuBar->addMenu(tr("&Settings"));
556
557 mMenuModes = mMenuSettings->addMenu(tr("Game Mode"));
558 mActGroupModes = new QActionGroup(mMenuModes);
559 mActGroupModes->setExclusive(true);
560 mActGroupModes->addAction(mActModeHvM);
561 mActGroupModes->addAction(mActModeMvH);
562 QList<QAction *> modeacts = mActGroupModes->actions();
563 mMenuModes->addActions(modeacts);
564 mMenuSettings->addSeparator();
565
566 mMenuSettings->addAction(mActShowMenubar);
567 mMenuSettings->addAction(mActShowToolbar);
568 mMenuSettings->addAction(mActShowStatusbar);
569 mMenuSettings->addSeparator();
570 mMenuSettings->addAction(mActShowTimer);
571 mMenuSettings->addAction(mActShowGameNo);
572 mMenuSettings->addSeparator();
573 mMenuSettings->addAction(mActResetColorsOrder);
574 mMenuSettings->addAction(mActShowIndicators);
575 mMenuSettings->addSeparator();
576
577 mMenuLevels = mMenuSettings->addMenu(tr("Level Presets"));
578 mActGroupLevels = new QActionGroup(mMenuLevels);
579 mActGroupLevels->addAction(mActLevelEasy);
580 mActGroupLevels->addAction(mActLevelClassic);
581 mActGroupLevels->addAction(mActLevelMedium);
582 mActGroupLevels->addAction(mActLevelChallenging);
583 mActGroupLevels->addAction(mActLevelHard);
584 QList<QAction *> levelacts = mActGroupLevels->actions();
585 mMenuLevels->addActions(levelacts);
586 mMenuSettings->addSeparator();
587
588 mMenuSettings->addAction(mActDoubles);
589 mMenuSettings->addSeparator();
590
591 mMenuSettings->addAction(mActAutoClose);
592 mMenuSettings->addAction(mActAutoHints);
593
594 mMenuSettings->addSeparator();
595 mMenuSettings->addAction(mActPreferences);
596
597
598 mMenuHelp = mMenuBar->addMenu(tr("&Help"));
599 mMenuHelp->addAction(mLaunchHelpAction);
600 mMenuHelp->addSeparator();
601 mMenuHelp->addAction(mActAbout);
602 mMenuHelp->addAction(mActAboutQt);
603
604 mMenuRowContext = new QMenu();
605 mMenuRowContext->addAction(mActRandRow);
606 mMenuRowContext->addAction(mActPrevRow);
607 mMenuRowContext->addAction(mActClearRow);
608 mMenuRowContext->addSeparator();
609 mMenuRowContext->addAction(mActSetGuess);
610 mMenuRowContext->addAction(mActSetHints);
611 mMenuRowContext->addSeparator();
612 mMenuRowContext->addAction(mActNewGame);
613 mMenuRowContext->addAction(mActRestartGame);
614 mMenuRowContext->addAction(mActGiveIn);
615 mMenuRowContext->addSeparator();
616 mMenuRowContext->addAction(mActExit);
617
618 addActions(mMenuBar->actions());
619 }
620
InitToolBars()621 void ColorCode::InitToolBars()
622 {
623 mGameToolbar = addToolBar(tr("Game"));
624 mGameToolbar->setAllowedAreas(Qt::NoToolBarArea);
625 mGameToolbar->setFloatable(false);
626 mGameToolbar->setIconSize(QSize(16, 16));
627 mGameToolbar->setMovable(false);
628 mGameToolbar->addAction(mActNewGame);
629 mGameToolbar->addAction(mActRestartGame);
630 mGameToolbar->addAction(mActGiveIn);
631 mGameToolbar->addSeparator();
632 mGameToolbar->addAction(mActSetGuess);
633 mGameToolbar->addAction(mActSetHints);
634
635 mColorCntCmb = new QComboBox();
636 mColorCntCmb->setLayoutDirection(Qt::LeftToRight);
637 mColorCntCmb->setFixedWidth(84);
638 mColorCntCmb->addItem("2 " + tr("Colors"), 2);
639 mColorCntCmb->addItem("3 " + tr("Colors"), 3);
640 mColorCntCmb->addItem("4 " + tr("Colors"), 4);
641 mColorCntCmb->addItem("5 " + tr("Colors"), 5);
642 mColorCntCmb->addItem("6 " + tr("Colors"), 6);
643 mColorCntCmb->addItem("7 " + tr("Colors"), 7);
644 mColorCntCmb->addItem("8 " + tr("Colors"), 8);
645 mColorCntCmb->addItem("9 " + tr("Colors"), 9);
646 mColorCntCmb->addItem("10 " + tr("Colors"), 10);
647 mColorCntCmb->setCurrentIndex(6);
648 connect(mColorCntCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(ColorCntChangedSlot()));
649
650 mPegCntCmb = new QComboBox();
651 mPegCntCmb->setLayoutDirection(Qt::LeftToRight);
652 mPegCntCmb->setFixedWidth(76);
653 mPegCntCmb->addItem("2 " + tr("Slots"), 2);
654 mPegCntCmb->addItem("3 " + tr("Slots"), 3);
655 mPegCntCmb->addItem("4 " + tr("Slots"), 4);
656 mPegCntCmb->addItem("5 " + tr("Slots"), 5);
657 mPegCntCmb->setCurrentIndex(2);
658 connect(mPegCntCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(PegCntChangedSlot()));
659
660 mLevelToolbar = addToolBar(tr("Level"));
661 mLevelToolbar->setAllowedAreas(Qt::NoToolBarArea);
662 mLevelToolbar->setFloatable(false);
663 mLevelToolbar->setIconSize(QSize(16, 16));
664 mLevelToolbar->setMovable(false);
665 mLevelToolbar->setLayoutDirection(Qt::RightToLeft);
666 mLevelToolbar->addWidget(mColorCntCmb);
667 QWidget* spacer = new QWidget();
668 spacer->setMinimumWidth(4);
669 mLevelToolbar->addWidget(spacer);
670 mLevelToolbar->addWidget(mPegCntCmb);
671 QWidget* spacer2 = new QWidget();
672 spacer2->setMinimumWidth(4);
673 mLevelToolbar->addWidget(spacer2);
674 mLevelToolbar->addAction(mActDoublesIcon);
675 }
676
ApplySettingsSlot()677 void ColorCode::ApplySettingsSlot()
678 {
679 bool restart = NeedsRestart();
680 mNoAct = true;
681
682 mActShowToolbar->setChecked(mSettings->mShowToolBar);
683 ShowToolbarSlot();
684 mActShowMenubar->setChecked(mSettings->mShowMenuBar);
685 ShowMenubarSlot();
686 mActShowStatusbar->setChecked(mSettings->mShowStatusBar);
687 ShowStatusbarSlot();
688 mActShowTimer->setChecked(mSettings->mShowTimer);
689 ShowTimer();
690 mActShowGameNo->setChecked(mSettings->mShowGameNo);
691 UpdateGameNoDisplay();
692 mActShowIndicators->setChecked(mSettings->mShowIndicators);
693 SetIndicatorsSlot();
694
695 mActAutoClose->setChecked(mSettings->mAutoClose);
696 mActAutoHints->setChecked(mSettings->mAutoHints);
697
698 SetDoublesSlot(mSettings->mDoubles);
699 int i;
700 i = mColorCntCmb->findData(mSettings->mColorCnt);
701 if (i != -1 && mColorCntCmb->currentIndex() != i)
702 {
703 mColorCntCmb->setCurrentIndex(i);
704 }
705 i = mPegCntCmb->findData(mSettings->mPegCnt);
706 if (i != -1 && mPegCntCmb->currentIndex() != i)
707 {
708 mPegCntCmb->setCurrentIndex(i);
709 }
710 CheckLevel();
711
712 if (mSettings->mGameMode == MODE_HVM)
713 {
714 mActModeHvM->setChecked(true);
715 UpdateGameNoDisplay();
716 }
717 else
718 {
719 mActModeMvH->setChecked(true);
720 }
721
722 mHintsDelayTimer->setInterval(mSettings->mHintsDelay);
723
724 mNoAct = false;
725
726 if (restart)
727 {
728 TryNewGame();
729 }
730 }
731
TryNewGame()732 void ColorCode::TryNewGame()
733 {
734 int r = QMessageBox::Yes;
735 if (GamesRunning())
736 {
737 r = QMessageBox::question( this,
738 tr("Message"),
739 tr("The changed settings will only apply to new games!\nDo you want to give in the current and start a new Game?"),
740 QMessageBox::Yes | QMessageBox::No,
741 QMessageBox::Yes);
742 }
743
744 if (r == QMessageBox::Yes)
745 {
746 mGameInput = NULL;
747 NewGame();
748 }
749 }
750
NeedsRestart() const751 bool ColorCode::NeedsRestart() const
752 {
753 bool need = false;
754
755 if ( mSettings->mDoubles != mActDoubles->isChecked()
756 || mSettings->mColorCnt != mColorCnt
757 || mSettings->mPegCnt != mPegCnt
758 || mSettings->mGameMode != mGameMode
759 || (mGameMode == MODE_MVH && mSolverStrength != mSettings->mSolverStrength) )
760 {
761 need = true;
762 }
763
764 return need;
765 }
766
contextMenuEvent(QContextMenuEvent * e)767 void ColorCode::contextMenuEvent(QContextMenuEvent* e)
768 {
769
770 QList<QGraphicsItem *> list = mView->items(mView->mapFromGlobal(e->globalPos()));
771 int i = 0;
772 bool isrow = false;
773 if (mGameState == STATE_RUNNING && mCurRow != NULL)
774 {
775 for (i = 0; i < list.size(); ++i)
776 {
777 if (list.at(i) == mCurRow || list.at(i) == mHintBtns[mCurRow->GetIx()])
778 {
779 isrow = true;
780 break;
781 }
782 }
783 }
784
785 if (isrow)
786 {
787 UpdateRowMenuSlot();
788 mMenuRowContext->exec(e->globalPos());
789 }
790 else
791 {
792 mMenuGame->exec(e->globalPos());
793 }
794 }
795
resizeEvent(QResizeEvent * e)796 void ColorCode::resizeEvent (QResizeEvent* e)
797 {
798 Q_UNUSED(e);
799 Scale();
800 }
801
keyPressEvent(QKeyEvent * e)802 void ColorCode::keyPressEvent(QKeyEvent *e)
803 {
804 if (mCurRow == NULL || mGameState != STATE_RUNNING)
805 {
806 return;
807 }
808
809 switch (e->key())
810 {
811 case Qt::Key_Return:
812 case Qt::Key_Enter:
813 if (mGameMode == MODE_HVM)
814 {
815 int ix = mCurRow->GetIx();
816 if (mHintBtns[ix]->mActive)
817 {
818 std::vector<int> s = mCurRow->GetSolution();
819 if (s.size() == (unsigned) mPegCnt)
820 {
821 mHintBtns[ix]->SetActive(false);
822 HintPressedSlot(ix);
823 }
824 }
825 }
826 else if (mGameMode == MODE_MVH)
827 {
828 if (mDoneBtn->isVisible() || mOkBtn->isVisible())
829 {
830 DoneBtnPressSlot(mOkBtn);
831 }
832 }
833 break;
834 }
835 }
836
UpdateActions()837 void ColorCode::UpdateActions()
838 {
839 if (mGameState == STATE_PAUSED)
840 {
841 mActSelectGame->setEnabled(true);
842 mActSaveGame->setEnabled(true);
843 mActSetGuess->setEnabled(false);
844 mActRestartGame->setEnabled(false);
845 mActGiveIn->setEnabled(false);
846 return;
847 }
848
849 bool running = (mGameState == STATE_RUNNING && mCurRow != NULL);
850 if (mGameMode == MODE_HVM)
851 {
852 mActSelectGame->setVisible(true);
853 mActSelectGame->setEnabled(true);
854 mActSaveGame->setVisible(true);
855 mActSaveGame->setEnabled(true);
856 mActPauseGame->setVisible(true);
857 mActShowTimer->setVisible(true);
858 mActShowTimer->setEnabled(true);
859 mActShowGameNo->setVisible(true);
860 mActShowGameNo->setEnabled(true);
861 mActCopyGameNo->setVisible(true);
862 mActCopyGameNo->setEnabled(true);
863 if (running)
864 {
865 mActSetGuess->setEnabled(true);
866 mActRestartGame->setEnabled(true);
867 mActGiveIn->setEnabled(true);
868 mActPauseGame->setEnabled(true);
869 }
870 else
871 {
872 mActSetGuess->setEnabled(false);
873 mActRestartGame->setEnabled(false);
874 mActGiveIn->setEnabled(false);
875 mActPauseGame->setEnabled(false);
876 }
877 }
878 else if (mGameMode == MODE_MVH)
879 {
880 mActSelectGame->setVisible(false);
881 mActSelectGame->setEnabled(false);
882 mActSaveGame->setVisible(false);
883 mActSaveGame->setEnabled(false);
884 mActPauseGame->setVisible(false);
885 mActPauseGame->setEnabled(false);
886 mActShowTimer->setVisible(false);
887 mActShowTimer->setEnabled(false);
888 mActShowGameNo->setVisible(false);
889 mActShowGameNo->setEnabled(false);
890 mActCopyGameNo->setVisible(false);
891 mActCopyGameNo->setEnabled(false);
892 if (running)
893 {
894 mActRestartGame->setEnabled(true);
895 mActGiveIn->setEnabled(true);
896 if (mCurRow == mSolutionRow)
897 {
898 mActSetHints->setEnabled(false);
899 }
900 else
901 {
902 mActSetHints->setEnabled(!mSettings->mAutoHints && !mSolver->isRunning());
903 }
904 UpdateRowMenuSlot();
905 }
906 else
907 {
908 mActSetHints->setEnabled(false);
909 mActRestartGame->setEnabled(false);
910 mActGiveIn->setEnabled(false);
911 }
912 }
913 }
914
UpdateRowMenuSlot()915 void ColorCode::UpdateRowMenuSlot()
916 {
917 if (mGameMode == MODE_HVM)
918 {
919 if (mGameState != STATE_RUNNING || mCurRow == NULL)
920 {
921 mActRandRow->setEnabled(false);
922 mActPrevRow->setEnabled(false);
923 mActClearRow->setEnabled(false);
924 mActSetGuess->setEnabled(false);
925 return;
926 }
927 else
928 {
929 mActRandRow->setEnabled(true);
930 }
931
932 if (mCurRow->GetIx() < 1)
933 {
934 mActPrevRow->setEnabled(false);
935 }
936 else
937 {
938 mActPrevRow->setEnabled(true);
939 }
940
941 if (mCurRow->GetPegCnt() == 0)
942 {
943 mActClearRow->setEnabled(false);
944 }
945 else
946 {
947 mActClearRow->setEnabled(true);
948 }
949 }
950 else if (mGameMode == MODE_MVH)
951 {
952 if (mGameState == STATE_RUNNING)
953 {
954 if (mCurRow == mSolutionRow)
955 {
956 mActSetHints->setEnabled(false);
957 mActRandRow->setEnabled(true);
958 if (mSolutionRow->GetPegCnt() == 0)
959 {
960 mActClearRow->setEnabled(false);
961 }
962 else
963 {
964 mActClearRow->setEnabled(true);
965 }
966 }
967 else
968 {
969 mActSetHints->setEnabled(!mSettings->mAutoHints && !mSolver->isRunning());
970 mActRandRow->setEnabled(false);
971 mActClearRow->setEnabled(false);
972 }
973 }
974 else
975 {
976 mActRandRow->setEnabled(false);
977 mActClearRow->setEnabled(false);
978 mActSetHints->setEnabled(false);
979 }
980 }
981 }
982
PauseGameSlot(GraphicsBtn *)983 void ColorCode::PauseGameSlot(GraphicsBtn*)
984 {
985 if (mCurRow == NULL)
986 {
987 return;
988 }
989
990 bool paused = (mGameState == STATE_PAUSED);
991 if (mGameState == STATE_RUNNING)
992 {
993 mGameTimer->PauseT();
994 mActPauseGame->setText(tr("&Resume Game"));
995 mActPauseGame->setIcon(QIcon(":/img/resume.png"));
996 SetState(STATE_PAUSED);
997 UpdateGameNoDisplay();
998 ResolveGame();
999 }
1000 else if (paused)
1001 {
1002 mGameTimer->ResumeT();
1003 mActPauseGame->setText(tr("&Have a Break"));
1004 mActPauseGame->setIcon(QIcon(":/img/pause.png"));
1005 SetState(STATE_RUNNING);
1006 UpdateGameNoDisplay();
1007 RowSolutionSlot(mCurRow->GetIx());
1008 }
1009 mPegFactory->SetPaused();
1010 for (int i = 0; i < mMaxRowCnt; ++i)
1011 {
1012 mHintBtns[i]->SetPaused(paused);
1013 }
1014 UpdateActions();
1015 }
1016
RestartGameSlot()1017 void ColorCode::RestartGameSlot()
1018 {
1019 if (mSolver->isRunning())
1020 {
1021 WaitForSolver();
1022 }
1023
1024 if (mGameMode == MODE_HVM)
1025 {
1026 ResetRows();
1027 SetState(STATE_RUNNING);
1028 SetCurRow(NULL);
1029 mSolver->RestartGame();
1030 NextRow();
1031 }
1032 else if (mGameMode == MODE_MVH)
1033 {
1034 mHintsDelayTimer->stop();
1035 mOkBtn->ShowBtn(false);
1036 ResetRows();
1037
1038 SetCurRow(NULL);
1039 mSolver->NewGame(mColorCnt, mPegCnt, mDoubles, mSolverStrength, mMaxRowCnt);
1040 mSolutionRow->OpenRow();
1041 GetSolution();
1042 SetState(STATE_RUNNING);
1043 RowSolutionSlot(mSolutionRow->GetIx());
1044 }
1045 }
1046
NewGameSlot()1047 void ColorCode::NewGameSlot()
1048 {
1049 if (mGameState == STATE_RUNNING && mCurRow != NULL)
1050 {
1051 int r = QMessageBox::warning( this,
1052 tr("New Game"),
1053 tr("Do you want to give in\nand start a new Game?"),
1054 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
1055 if (r == QMessageBox::Yes)
1056 {
1057 mGameInput = NULL;
1058 NewGame();
1059 }
1060 }
1061 else
1062 {
1063 mGameInput = NULL;
1064 NewGame();
1065 }
1066 }
1067
GiveInSlot()1068 void ColorCode::GiveInSlot()
1069 {
1070 int r = QMessageBox::Yes;
1071 if (mGameState == STATE_RUNNING && mCurRow != NULL)
1072 {
1073 r = QMessageBox::warning( this,
1074 tr("Give In"),
1075 tr("Do you really want to give in?"),
1076 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
1077 }
1078
1079 if (r == QMessageBox::Yes)
1080 {
1081 SetState(STATE_GAVE_UP);
1082
1083 if (mSolver->isRunning())
1084 {
1085 WaitForSolver();
1086 }
1087
1088 if (mCurRow != NULL)
1089 {
1090 mCurRow->CloseRow();
1091 mHintBtns[mCurRow->GetIx()]->SetActive(false);
1092 }
1093
1094 ResolveGame();
1095 }
1096 }
1097
CopyGameNoSlot()1098 void ColorCode::CopyGameNoSlot()
1099 {
1100 uint no = 0;
1101 if (mGameInput != NULL)
1102 {
1103 no = mGameInput->mGameNo;
1104 }
1105 else if (mFinishedGameInput != NULL)
1106 {
1107 no = mFinishedGameInput->mGameNo;
1108 }
1109
1110 if (no > 0)
1111 {
1112 QClipboard* cb = QApplication::clipboard();
1113 cb->setText(QString::number(no));
1114 }
1115 }
1116
OpenPreferencesSlot()1117 void ColorCode::OpenPreferencesSlot()
1118 {
1119 if (mPrefDialog == NULL)
1120 {
1121 CreatePrefDialog();
1122 }
1123 if (mPrefDialog == NULL)
1124 {
1125 return;
1126 }
1127
1128 mSettings->SaveLastSettings();
1129 mPrefDialog->SetSettings();
1130 int r = mPrefDialog->exec();
1131
1132 if (r == QDialog::Accepted)
1133 {
1134 ApplySettingsSlot();
1135 }
1136 else
1137 {
1138 mSettings->RestoreLastSettings();
1139 }
1140 }
1141
OnlineHelpSlot()1142 void ColorCode::OnlineHelpSlot()
1143 {
1144 QDesktopServices::openUrl(QUrl("http://colorcode.laebisch.com/documentation", QUrl::TolerantMode));
1145 }
1146
AboutSlot()1147 void ColorCode::AboutSlot()
1148 {
1149 About ab(this);
1150 ab.exec();
1151 }
1152
AboutQtSlot()1153 void ColorCode::AboutQtSlot()
1154 {
1155 QMessageBox::aboutQt( this,
1156 tr("About Qt"));
1157 }
1158
ShowToolbarSlot()1159 void ColorCode::ShowToolbarSlot()
1160 {
1161 mSettings->mShowToolBar = mActShowToolbar->isChecked();
1162 if (!mActShowToolbar->isChecked())
1163 {
1164 mGameToolbar->hide();
1165 mLevelToolbar->hide();
1166 }
1167 else
1168 {
1169 mGameToolbar->show();
1170 mLevelToolbar->show();
1171 }
1172 Scale();
1173 }
1174
ShowMenubarSlot()1175 void ColorCode::ShowMenubarSlot()
1176 {
1177 mSettings->mShowMenuBar = mActShowMenubar->isChecked();
1178 if (!mActShowMenubar->isChecked())
1179 {
1180 mMenuBar->hide();
1181 }
1182 else
1183 {
1184 mMenuBar->show();
1185 }
1186 Scale();
1187 }
1188
ShowStatusbarSlot()1189 void ColorCode::ShowStatusbarSlot()
1190 {
1191 mSettings->mShowStatusBar = mActShowStatusbar->isChecked();
1192 if (!mActShowStatusbar->isChecked())
1193 {
1194 statusBar()->hide();
1195 }
1196 else
1197 {
1198 statusBar()->show();
1199 }
1200 Scale();
1201 }
1202
ShowTimerSlot()1203 void ColorCode::ShowTimerSlot()
1204 {
1205 mSettings->mShowTimer = mActShowTimer->isChecked();
1206 ShowTimer();
1207 }
1208
ShowTimer()1209 void ColorCode::ShowTimer()
1210 {
1211 if (mGameMode == MODE_HVM)
1212 {
1213 mGameTimer->SetTenth(mSettings->mShowTenth);
1214 mGameTimer->setVisible(mSettings->mShowTimer);
1215 mGameTimer->update();
1216 mGameTimerBg->setVisible(mSettings->mShowTimer);
1217 mTimerBtn->ShowBtn(mSettings->mShowTimer);
1218 }
1219 else
1220 {
1221 mGameTimer->setVisible(false);
1222 mGameTimerBg->setVisible(false);
1223 mTimerBtn->ShowBtn(false);
1224 }
1225 }
1226
ShowGameNoSlot()1227 void ColorCode::ShowGameNoSlot()
1228 {
1229 mSettings->mShowGameNo = mActShowGameNo->isChecked();
1230 UpdateGameNoDisplay();
1231 }
1232
UpdateGameNoDisplay()1233 void ColorCode::UpdateGameNoDisplay()
1234 {
1235 if (mGameMode == MODE_HVM)
1236 {
1237 QString str = tr("Human vs. Computer");
1238 CCGame* g = GetCurrentGameInput();
1239 if (mSettings->mShowGameNo && g != NULL && mGameState != STATE_PAUSED)
1240 {
1241 str += QString(" :: ") + QString(tr("Game Number")) + QString(": ") + QString::number(g->mGameNo);
1242 }
1243 mGameNoDisplay->ShowStr(str);
1244 }
1245 else if (mGameMode == MODE_MVH)
1246 {
1247 mGameNoDisplay->ShowStr(tr("Computer vs. Human"));
1248 }
1249 }
1250
GetCurrentGameInput() const1251 CCGame* ColorCode::GetCurrentGameInput() const
1252 {
1253 if (mGameInput != NULL && mGameInput->IsValidGame())
1254 {
1255 return mGameInput;
1256 }
1257 else if (mFinishedGameInput != NULL && mFinishedGameInput->IsValidGame())
1258 {
1259 return mFinishedGameInput;
1260 }
1261 return NULL;
1262 }
1263
CloseHighScoreDialogSlot()1264 void ColorCode::CloseHighScoreDialogSlot()
1265 {
1266 ;
1267 }
1268
SetIndicatorsSlot()1269 void ColorCode::SetIndicatorsSlot()
1270 {
1271 mSettings->mShowIndicators = mActShowIndicators->isChecked();
1272 mPegFactory->SetIndicators();
1273 }
1274
AutoCloseSlot()1275 void ColorCode::AutoCloseSlot()
1276 {
1277 mSettings->mAutoClose = mActAutoClose->isChecked();
1278 }
1279
AutoHintsSlot()1280 void ColorCode::AutoHintsSlot()
1281 {
1282 mSettings->mAutoHints = mActAutoHints->isChecked();
1283
1284 if (mGameMode == MODE_MVH && mGameState == STATE_RUNNING && mCurRow != NULL && mCurRow != mSolutionRow)
1285 {
1286 mActSetHints->setEnabled(!mSettings->mAutoHints);
1287 if (mSettings->mAutoHints)
1288 {
1289 SetHintsSlot();
1290 SetAutoHintsSlot();
1291 }
1292 }
1293 }
1294
ColorCntChangedSlot()1295 void ColorCode::ColorCntChangedSlot()
1296 {
1297 SetColorCnt();
1298
1299 if (mNoAct)
1300 {
1301 return;
1302 }
1303
1304 int r = QMessageBox::Yes;
1305 if (GamesRunning())
1306 {
1307 r = QMessageBox::question( this,
1308 tr("Message"),
1309 tr("The changed settings will only apply to new games!\nDo you want to give in the current and start a new Game?"),
1310 QMessageBox::Yes | QMessageBox::No,
1311 QMessageBox::Yes);
1312 }
1313
1314 if (r == QMessageBox::Yes)
1315 {
1316 mGameInput = NULL;
1317 NewGame();
1318 }
1319 }
1320
PegCntChangedSlot()1321 void ColorCode::PegCntChangedSlot()
1322 {
1323 SetPegCnt();
1324
1325 if (mNoAct)
1326 {
1327 return;
1328 }
1329
1330 int pcnt = GetPegCntInput();
1331 if (pcnt == mPegCnt)
1332 {
1333 return;
1334 }
1335
1336 int r = QMessageBox::Yes;
1337 if (GamesRunning())
1338 {
1339 r = QMessageBox::question( this,
1340 tr("Message"),
1341 tr("The changed settings will only apply to new games!\nDo you want to give in the current and start a new Game?"),
1342 QMessageBox::Yes | QMessageBox::No,
1343 QMessageBox::Yes);
1344 }
1345
1346 if (r == QMessageBox::Yes)
1347 {
1348 mGameInput = NULL;
1349 NewGame();
1350 }
1351 }
1352
DoublesChangedSlot(bool checked)1353 void ColorCode::DoublesChangedSlot(bool checked)
1354 {
1355 if (mNoAct)
1356 {
1357 return;
1358 }
1359
1360 SetDoublesSlot(checked);
1361
1362 if (mDoubles == mSettings->mDoubles)
1363 {
1364 return;
1365 }
1366
1367 int r = QMessageBox::Yes;
1368 if (GamesRunning())
1369 {
1370 r = QMessageBox::question( this,
1371 tr("Message"),
1372 tr("The changed settings will only apply to new games!\nDo you want to give in the current and start a new Game?"),
1373 QMessageBox::Yes | QMessageBox::No,
1374 QMessageBox::Yes);
1375 }
1376
1377 if (r == QMessageBox::Yes)
1378 {
1379 mGameInput = NULL;
1380 NewGame();
1381 }
1382 }
1383
SetLevelSlot()1384 void ColorCode::SetLevelSlot()
1385 {
1386 mNoAct = true;
1387 int ix = mActGroupLevels->checkedAction()->data().toInt();
1388
1389 if (ix < 0 || ix > 4)
1390 {
1391 return;
1392 }
1393
1394 int i;
1395 i = mColorCntCmb->findData(LEVEL_SETTINGS[ix][0]);
1396 if (i != -1 && mColorCntCmb->currentIndex() != i)
1397 {
1398 mColorCntCmb->setCurrentIndex(i);
1399 SetColorCnt();
1400 }
1401 i = mPegCntCmb->findData(LEVEL_SETTINGS[ix][1]);
1402 if (i != -1 && mPegCntCmb->currentIndex() != i)
1403 {
1404 mPegCntCmb->setCurrentIndex(i);
1405 SetPegCnt();
1406 }
1407
1408 SetDoublesSlot((LEVEL_SETTINGS[ix][2] == 1));
1409
1410 int r = QMessageBox::Yes;
1411 if (GamesRunning())
1412 {
1413 r = QMessageBox::question( this,
1414 tr("Message"),
1415 tr("The changed settings will only apply to new games!\nDo you want to give in the current and start a new Game?"),
1416 QMessageBox::Yes | QMessageBox::No,
1417 QMessageBox::Yes);
1418 }
1419
1420 mNoAct = false;
1421
1422 if (r == QMessageBox::Yes)
1423 {
1424 mGameInput = NULL;
1425 NewGame();
1426 }
1427 }
1428
SetGameModeSlot()1429 void ColorCode::SetGameModeSlot()
1430 {
1431 SetGameMode();
1432
1433 int r = QMessageBox::Yes;
1434 if (GamesRunning())
1435 {
1436 r = QMessageBox::question( this,
1437 tr("Message"),
1438 tr("The changed settings will only apply to new games!\nDo you want to give in the current and start a new Game?"),
1439 QMessageBox::Yes | QMessageBox::No,
1440 QMessageBox::Yes);
1441 }
1442
1443 if (r == QMessageBox::Yes)
1444 {
1445 mGameInput = NULL;
1446 NewGame();
1447 }
1448 }
1449
1450
SetPegCnt()1451 void ColorCode::SetPegCnt()
1452 {
1453 mSettings->mPegCnt = GetPegCntInput();
1454 }
1455
SetColorCnt()1456 void ColorCode::SetColorCnt()
1457 {
1458 mSettings->mColorCnt = GetColorCntInput();
1459 }
1460
SetGameMode()1461 void ColorCode::SetGameMode()
1462 {
1463 mSettings->mGameMode = GetGameModeInput();
1464 }
1465
ShowMsgSlot(QString msg)1466 void ColorCode::ShowMsgSlot(QString msg)
1467 {
1468 mMsg->ShowMsg(msg);
1469 }
1470
SnapPegSlot(ColorPeg * cp)1471 void ColorCode::SnapPegSlot(ColorPeg* cp)
1472 {
1473 int i;
1474 bool snapped = false;
1475
1476 if (mGameMode == MODE_HVM)
1477 {
1478 QList<QGraphicsItem *> list = mScene->items(QPointF(cp->pos().x() + 18, cp->pos().y() + 18));
1479
1480 if (mSolver->isRunning())
1481 {
1482 WaitForSolver();
1483 }
1484
1485 for (i = 0; i < list.size(); ++i)
1486 {
1487 if (mCurRow != NULL && list.at(i) == mCurRow)
1488 {
1489 snapped = mCurRow->SnapCP(cp);
1490 break;
1491 }
1492 }
1493 }
1494 else if (mGameMode == MODE_MVH)
1495 {
1496 snapped = mSolutionRow->SnapCP(cp);
1497 }
1498
1499 if (!snapped)
1500 {
1501 mPegFactory->RemovePegSlot(cp);
1502 }
1503 }
1504
RowSolutionSlot(int ix)1505 void ColorCode::RowSolutionSlot(int ix)
1506 {
1507 if (mGameMode == MODE_HVM)
1508 {
1509 if (ix == SOLUTION_ROW_IX) { return; }
1510
1511 std::vector<int> s = mPegRows[ix]->GetSolution();
1512 if (s.size() == (unsigned) mPegCnt)
1513 {
1514 if (mActAutoClose->isChecked())
1515 {
1516 HintPressedSlot(ix);
1517 }
1518 else
1519 {
1520 mHintBtns[ix]->SetActive(true);
1521 ShowMsgSlot(tr("Press the Hint Field or Key Enter if You're done."));
1522 }
1523 }
1524 else
1525 {
1526 mHintBtns[ix]->SetActive(false);
1527 ShowMsgSlot(tr("Place Your pegs ..."));
1528 }
1529 }
1530 else if (mGameMode == MODE_MVH)
1531 {
1532 if (ix == SOLUTION_ROW_IX)
1533 {
1534 std::vector<int> s = mSolutionRow->GetSolution();
1535 if (s.size() == (unsigned) mPegCnt)
1536 {
1537 bool valid = true;
1538 if (!mActDoubles->isChecked())
1539 {
1540 int i;
1541 int check[mColorCnt];
1542 for (i = 0; i < mColorCnt; ++i)
1543 {
1544 check[i] = 0;
1545 }
1546
1547 for (i = 0; (unsigned)i < s.size(); ++i)
1548 {
1549 if (s[i] >= mColorCnt)
1550 {
1551 valid = false;
1552 break;
1553 }
1554
1555 if (check[s[i]] != 0)
1556 {
1557 valid = false;
1558 break;
1559 }
1560
1561 check[s[i]] = 1;
1562 }
1563 }
1564
1565 if (valid)
1566 {
1567 mDoneBtn->ShowBtn(true);
1568 ShowMsgSlot(tr("Press the button below or Key Enter if You're done."));
1569 }
1570 else
1571 {
1572 ShowMsgSlot(tr("The chosen settings do not allow pegs of the same color!"));
1573 }
1574 }
1575 else
1576 {
1577 mDoneBtn->ShowBtn(false);
1578 ShowMsgSlot(tr("Place Your secret ColorCode ..."));
1579 }
1580 }
1581 }
1582 }
1583
HintPressedSlot(int)1584 void ColorCode::HintPressedSlot(int)
1585 {
1586 mCurRow->CloseRow();
1587 ResolveRow();
1588 NextRow();
1589 ResolveGame();
1590 }
1591
RandRowSlot()1592 void ColorCode::RandRowSlot()
1593 {
1594 if (mCurRow == NULL || !mCurRow->IsActive() || mGameState != STATE_RUNNING)
1595 {
1596 return;
1597 }
1598
1599 if (mGameMode == MODE_HVM || (mGameMode == MODE_MVH && mCurRow == mSolutionRow))
1600 {
1601 mCurRow->ClearRow();
1602
1603 int i, rndm;
1604 int check[mColorCnt];
1605 ColorPeg* peg;
1606 for (i = 0; i < mColorCnt; ++i)
1607 {
1608 check[i] = 0;
1609 }
1610
1611 for (i = 0; i < mPegCnt; ++i)
1612 {
1613 rndm = qrand() % mColorCnt;
1614 if (mDoubles == 0 && check[rndm] != 0)
1615 {
1616 --i;
1617 continue;
1618 }
1619
1620 check[rndm] = 1;
1621
1622 peg = mPegFactory->CreatePeg(rndm);
1623 mCurRow->ForceSnap(peg, i);
1624 }
1625 }
1626 }
1627
SetSolverGuessSlot()1628 void ColorCode::SetSolverGuessSlot()
1629 {
1630 if (mIgnoreGuess)
1631 {
1632 mIgnoreGuess = false;
1633 return;
1634 }
1635
1636 if (mGameState != STATE_RUNNING || mCurRow == NULL)
1637 {
1638 return;
1639 }
1640
1641 int* row = mSolver->GuessOut();
1642 if (row == NULL)
1643 {
1644 SetState(STATE_ERROR);
1645 }
1646 else
1647 {
1648 ColorPeg* peg;
1649 int i;
1650 for (i = 0; i < mPegCnt; ++i)
1651 {
1652 peg = mPegFactory->CreatePeg(row[i]);
1653 mCurRow->ForceSnap(peg, i);
1654 }
1655
1656 if (mGameMode == MODE_HVM)
1657 {
1658 return;
1659 }
1660 }
1661
1662 if (mGameState == STATE_RUNNING)
1663 {
1664 mCurRow->CloseRow();
1665 mHintBtns[mCurRow->GetIx()]->SetActive(true);
1666
1667 if (mActAutoHints->isChecked())
1668 {
1669 if (mOkBtn->isVisible())
1670 {
1671 mOkBtn->ShowBtn(false);
1672 }
1673 ShowMsgSlot(tr("guessed and rated ..."));
1674 SetHintsSlot();
1675 mHintBtns[mCurRow->GetIx()]->SetActive(false);
1676
1677 std::vector<int> rowhints = mHintBtns[mCurRow->GetIx()]->GetHints();
1678 int b = 0;
1679 for (unsigned i = 0; i < rowhints.size(); ++i)
1680 {
1681 if (rowhints.at(i) == 2)
1682 {
1683 ++b;
1684 }
1685 }
1686
1687 if (b == mPegCnt)
1688 {
1689 SetState(STATE_WON);
1690 ResolveGame();
1691 }
1692 else
1693 {
1694 mHintsDelayTimer->start();
1695 }
1696 }
1697 else
1698 {
1699 ShowMsgSlot(tr("Please rate the guess. Press OK or Key Enter if You're done."));
1700 mOkBtn->setPos(5, mCurRow->pos().y() - 39);
1701 mOkBtn->ShowBtn(true);
1702 }
1703 }
1704 else
1705 {
1706 mCurRow->SetActive(false);
1707 ResolveGame();
1708 }
1709 UpdateActions();
1710 }
1711
SetGuessSlot()1712 void ColorCode::SetGuessSlot()
1713 {
1714 if (mCurRow == NULL || mCurRow == mSolutionRow || mGameState != STATE_RUNNING || mSolver->isRunning())
1715 {
1716 return;
1717 }
1718
1719 mCurRow->ClearRow();
1720 ShowMsgSlot(tr("Let me think ..."));
1721 mSolver->StartGuess();
1722 UpdateActions();
1723 }
1724
SetHintsSlot()1725 void ColorCode::SetHintsSlot()
1726 {
1727 if (mCurRow == NULL || mGameState != STATE_RUNNING)
1728 {
1729 return;
1730 }
1731
1732 if (mGameMode == MODE_MVH)
1733 {
1734 if (mCurRow == mSolutionRow || !mHintBtns[mCurRow->GetIx()]->IsActive())
1735 {
1736 return;
1737 }
1738
1739 std::vector<int> hints = RateSol2Guess(mSolution, mCurRow->GetSolution());
1740 mHintBtns[mCurRow->GetIx()]->DrawHints(hints);
1741 }
1742 }
1743
PrevRowSlot()1744 void ColorCode::PrevRowSlot()
1745 {
1746 if (mCurRow == NULL || mGameState != STATE_RUNNING)
1747 {
1748 return;
1749 }
1750
1751 if (mCurRow->GetIx() < 1)
1752 {
1753 return;
1754 }
1755
1756 mCurRow->ClearRow();
1757
1758 ColorPeg* peg;
1759 std::vector<int> prev = mPegRows[mCurRow->GetIx() - 1]->GetSolution();
1760 int i;
1761 for (i = 0; i < mPegCnt; ++i)
1762 {
1763 peg = mPegFactory->CreatePeg(prev.at(i));
1764 mCurRow->ForceSnap(peg, i);
1765 }
1766 }
1767
ClearRowSlot()1768 void ColorCode::ClearRowSlot()
1769 {
1770 if (mCurRow == NULL || mGameState != STATE_RUNNING)
1771 {
1772 return;
1773 }
1774
1775 mCurRow->ClearRow();
1776 }
1777
DoneBtnPressSlot(GraphicsBtn *)1778 void ColorCode::DoneBtnPressSlot(GraphicsBtn*)
1779 {
1780 mDoneBtn->ShowBtn(false);
1781 mOkBtn->ShowBtn(false);
1782
1783 if (mCurRow == mSolutionRow)
1784 {
1785 SetSolution();
1786 NextRow();
1787 }
1788 else
1789 {
1790 ResolveHints();
1791 }
1792 }
1793
SetAutoHintsSlot()1794 void ColorCode::SetAutoHintsSlot()
1795 {
1796 DoneBtnPressSlot(mOkBtn);
1797 }
1798
TestSlot()1799 void ColorCode::TestSlot()
1800 {
1801 ;
1802 }
1803
ApplyPreferencesSlot()1804 void ColorCode::ApplyPreferencesSlot()
1805 {
1806 ;
1807 }
1808
CreatePrefDialog()1809 void ColorCode::CreatePrefDialog()
1810 {
1811 mPrefDialog = new PrefDialog(this);
1812 mPrefDialog->setModal(true);
1813 mPrefDialog->InitSettings();
1814 connect(mPrefDialog, SIGNAL(accepted()), this, SLOT(ApplyPreferencesSlot()));
1815 connect(mPrefDialog, SIGNAL(accepted()), mGameTablesDialog, SLOT(SetSettingsSlot()));
1816 connect(mPrefDialog, SIGNAL(ResetColorOrderSignal()), mPegFactory, SLOT(ResetColorsOrderSlot()));
1817 }
1818
CheckDoublesSetting()1819 void ColorCode::CheckDoublesSetting()
1820 {
1821 if (mColorCnt < mPegCnt)
1822 {
1823 if (mActDoubles->isEnabled())
1824 {
1825 mActDoubles->setEnabled(false);
1826 }
1827 if (mActDoublesIcon->isEnabled())
1828 {
1829 mActDoublesIcon->setEnabled(false);
1830 }
1831 if (!mActDoubles->isChecked())
1832 {
1833 mActDoubles->setChecked(true);
1834 }
1835 if (!mActDoublesIcon->isChecked())
1836 {
1837 mActDoublesIcon->setChecked(true);
1838 }
1839 }
1840 else
1841 {
1842 if (!mActDoubles->isEnabled())
1843 {
1844 mActDoubles->setEnabled(true);
1845 }
1846 if (!mActDoublesIcon->isEnabled())
1847 {
1848 mActDoublesIcon->setEnabled(true);
1849 }
1850 }
1851
1852 if (mActDoublesIcon->isChecked())
1853 {
1854 mActDoublesIcon->setIcon(QIcon(":/img/same_color_1.png"));
1855 mActDoublesIcon->setToolTip(tr("Disallow Pegs of the Same Color"));
1856 }
1857 else
1858 {
1859 mActDoublesIcon->setIcon(QIcon(":/img/same_color_0.png"));
1860 mActDoublesIcon->setToolTip(tr("Allow Pegs of the Same Color"));
1861 }
1862 }
1863
SetDoublesSlot(bool checked)1864 void ColorCode::SetDoublesSlot(bool checked)
1865 {
1866 mSettings->mDoubles = checked;
1867
1868 mActDoubles->setChecked(checked);
1869 mActDoublesIcon->setChecked(checked);
1870
1871 if (checked)
1872 {
1873 mActDoublesIcon->setIcon(QIcon(":/img/same_color_1.png"));
1874 mActDoublesIcon->setToolTip(tr("Disallow Pegs of the Same Color"));
1875 }
1876 else
1877 {
1878 mActDoublesIcon->setIcon(QIcon(":/img/same_color_0.png"));
1879 mActDoublesIcon->setToolTip(tr("Allow Pegs of the Same Color"));
1880 }
1881 }
1882
CheckLevel()1883 void ColorCode::CheckLevel()
1884 {
1885 int ix = -1;
1886 for (int i = 0; i < 5; ++i)
1887 {
1888 if ( LEVEL_SETTINGS[i][0] == mColorCnt
1889 && LEVEL_SETTINGS[i][1] == mPegCnt
1890 && LEVEL_SETTINGS[i][2] == mDoubles )
1891 {
1892 ix = i;
1893 break;
1894 }
1895 }
1896
1897 if (ix > -1)
1898 {
1899 QList<QAction *> levelacts = mActGroupLevels->actions();
1900 levelacts.at(ix)->setChecked(true);
1901 }
1902 else
1903 {
1904 QAction* act = mActGroupLevels->checkedAction();
1905 if (act != NULL)
1906 {
1907 act->setChecked(false);
1908 }
1909 }
1910 }
1911
ResetGame()1912 void ColorCode::ResetGame()
1913 {
1914 mDoneBtn->ShowBtn(false);
1915 mOkBtn->ShowBtn(false);
1916
1917 ApplyPegCnt();
1918
1919 mSolutionRow->Reset(mPegCnt, mGameMode);
1920 ResetRows();
1921
1922 mGameId = qrand();
1923 mGuessCnt = 0;
1924 ++mGameCnt;
1925
1926 mPegFactory->ApplyColorCnt();
1927
1928 CheckDoublesSetting();
1929
1930 mDoubles = GetDoublesInput();
1931 CheckLevel();
1932
1933 ApplySolverStrength();
1934 }
1935
ResetRows()1936 void ColorCode::ResetRows()
1937 {
1938 for (int i = 0; i < mMaxRowCnt; ++i)
1939 {
1940 mPegRows[i]->Reset(mPegCnt, mGameMode);
1941 mHintBtns[i]->Reset(mPegCnt, mGameMode);
1942 }
1943 }
1944
NewGameInputSlot(CCGame * g)1945 void ColorCode::NewGameInputSlot(CCGame* g)
1946 {
1947 if (g != NULL && g->IsValidGame())
1948 {
1949 mGameInput = g;
1950 mGameInput->Anonymize();
1951
1952 mNoAct = true;
1953 if (mGameInput->mGameMode == MODE_HVM)
1954 {
1955 mActModeHvM->setChecked(true);
1956 }
1957 else
1958 {
1959 mActModeMvH->setChecked(true);
1960 }
1961
1962 SetDoublesSlot((bool) mGameInput->mDoubles);
1963
1964 int i;
1965 i = mColorCntCmb->findData(mGameInput->mColorCnt);
1966 if (i != -1 && mColorCntCmb->currentIndex() != i)
1967 {
1968 mColorCntCmb->setCurrentIndex(i);
1969 }
1970 i = mPegCntCmb->findData(mGameInput->mPegCnt);
1971 if (i != -1 && mPegCntCmb->currentIndex() != i)
1972 {
1973 mPegCntCmb->setCurrentIndex(i);
1974 }
1975 CheckLevel();
1976
1977 mNoAct = false;
1978 }
1979
1980 NewGame();
1981 }
1982
GetRandGameInput()1983 CCGame* ColorCode::GetRandGameInput()
1984 {
1985 int gameno = mSolver->GetRandGameNo(mColorCnt, mPegCnt, mDoubles);
1986 CCGame* g = mSettings->GetCurSettingsGame();
1987 g->mGameNo = gameno;
1988
1989 return g;
1990 }
1991
NewGame()1992 void ColorCode::NewGame()
1993 {
1994 if (mGameState == STATE_PAUSED)
1995 {
1996 PauseGameSlot();
1997 }
1998
1999 mHintsDelayTimer->stop();
2000
2001 if (mSolver->isRunning())
2002 {
2003 WaitForSolver();
2004 }
2005
2006 ApplyGameMode();
2007 ResetGame();
2008 QString doubles = (mDoubles == 1) ? tr("Yes") : tr("No");
2009 QString colors = QString::number(mColorCnt, 10);
2010 QString pegs = QString::number(mPegCnt, 10);
2011 mStatusLabel->setText(tr("Pegs of Same Color") + ": <b>" + doubles + "</b> :: " + tr("Slots") + ": <b>" + pegs + "</b> :: " + tr("Colors") + ": <b>" + colors + "</b> ");
2012 SetState(STATE_RUNNING);
2013
2014 SetCurRow(NULL);
2015
2016 if (mGameMode == MODE_HVM)
2017 {
2018 mFinishedGameInput = NULL;
2019 mSolver->NewGame(mColorCnt, mPegCnt, mDoubles, CCSolver::STRENGTH_HIGH, mMaxRowCnt);
2020 mHighScore->NewGame(mSolver->CalcPosCnt(mColorCnt, mPegCnt, mDoubles));
2021 if (mGameInput == NULL)
2022 {
2023 mGameInput = mSettings->GetCurSettingsGame();
2024 }
2025
2026 if (mGameInput->mColorCnt != mColorCnt)
2027 {
2028 mGameInput->mColorCnt = mColorCnt;
2029 }
2030 if (mGameInput->mPegCnt != mPegCnt)
2031 {
2032 mGameInput->mPegCnt = mPegCnt;
2033 }
2034 if (mGameInput->mDoubles != mDoubles)
2035 {
2036 mGameInput->mDoubles = mDoubles;
2037 }
2038 if (mGameInput->mGameMode != mGameMode)
2039 {
2040 mGameInput->mGameMode = mGameMode;
2041 }
2042
2043 mGameInput->mDuration = 0;
2044 mGameInput->mTime = QDateTime::currentDateTime().toTime_t();
2045
2046 if (mGameInput->mGameNo == 0)
2047 {
2048 mGameInput->mGameNo = mSolver->GetRandGameNo(mColorCnt, mPegCnt, mDoubles);
2049 }
2050
2051 mGameTablesDialog->InsertPrevGameSlot(mGameInput);
2052
2053 SetSolution();
2054
2055 mGameTimer->StartT();
2056
2057 NextRow();
2058 }
2059 else if (mGameMode == MODE_MVH)
2060 {
2061 mSolver->NewGame(mColorCnt, mPegCnt, mDoubles, mSolverStrength, mMaxRowCnt);
2062 GetSolution();
2063 }
2064
2065 UpdateGameNoDisplay();
2066 }
2067
NextRow()2068 void ColorCode::NextRow()
2069 {
2070 if (mGameState != STATE_RUNNING)
2071 {
2072 return;
2073 }
2074
2075 if (mCurRow == NULL)
2076 {
2077 SetCurRow(mPegRows[0]);
2078 }
2079 else if (mCurRow->GetIx() < mMaxRowCnt - 1)
2080 {
2081 SetCurRow(mPegRows[mCurRow->GetIx() + 1]);
2082 }
2083 else
2084 {
2085 SetCurRow(NULL);
2086 SetState(STATE_LOST);
2087 }
2088
2089 if (mCurRow != NULL)
2090 {
2091 ++mGuessCnt;
2092 mCurRow->SetActive(true);
2093 if (mGameMode == MODE_HVM)
2094 {
2095 ++mHighScore->mRowsCnt;
2096 ShowMsgSlot(tr("Place Your pegs ..."));
2097 }
2098 else if (mGameMode == MODE_MVH)
2099 {
2100 SetGuessSlot();
2101 }
2102 }
2103 }
2104
SetCurRow(PegRow * const & row)2105 void ColorCode::SetCurRow(PegRow* const &row)
2106 {
2107 mCurRow = row;
2108 UpdateActions();
2109 }
2110
ResolveRow()2111 void ColorCode::ResolveRow()
2112 {
2113 std::vector<int> rowsol = mCurRow->GetSolution();
2114 mSolver->GuessIn(&rowsol);
2115
2116 std::vector<int> hints = RateSol2Guess(mSolution, rowsol);
2117
2118 if (hints.size() == (unsigned) mPegCnt)
2119 {
2120 int bl = 0;
2121 for (int i = 0; i < mPegCnt; ++i)
2122 {
2123 if (hints.at(i) == 2)
2124 {
2125 ++bl;
2126 }
2127 }
2128
2129 if (bl == mPegCnt)
2130 {
2131 SetState(STATE_WON);
2132 }
2133 }
2134
2135 mSolver->ResIn(&hints);
2136 mHintBtns[mCurRow->GetIx()]->DrawHints(hints);
2137 }
2138
RateSol2Guess(const std::vector<int> sol,const std::vector<int> guess)2139 std::vector<int> ColorCode::RateSol2Guess(const std::vector<int> sol, const std::vector<int> guess)
2140 {
2141 std::vector<int> hints;
2142 std::vector<int> left1;
2143 std::vector<int> left0;
2144
2145 int i, p0, p1;
2146 for (i = 0; i < mPegCnt; ++i)
2147 {
2148 p0 = guess.at(i);
2149 p1 = sol.at(i);
2150 if (p0 == p1)
2151 {
2152 hints.push_back(2);
2153 }
2154 else
2155 {
2156 left0.push_back(p0);
2157 left1.push_back(p1);
2158 }
2159 }
2160
2161 if (hints.size() < (unsigned) mPegCnt)
2162 {
2163 int len0 = left0.size();
2164 for (i = 0; i < len0; ++i)
2165 {
2166 p0 = left0.at(i);
2167 for (unsigned j = 0; j < left1.size(); ++j)
2168 {
2169 p1 = left1.at(j);
2170 if (p0 == p1)
2171 {
2172 hints.push_back(1);
2173 left1.erase(left1.begin() + j);
2174 break;
2175 }
2176 }
2177 }
2178 }
2179
2180 return hints;
2181 }
2182
ResolveHints()2183 void ColorCode::ResolveHints()
2184 {
2185 if (mCurRow == NULL)
2186 {
2187 return;
2188 }
2189
2190 mHintBtns[mCurRow->GetIx()]->SetActive(false);
2191
2192 std::vector<int> rowsol = mCurRow->GetSolution();
2193 mSolver->GuessIn(&rowsol);
2194 std::vector<int> rowhints = mHintBtns[mCurRow->GetIx()]->GetHints();
2195 int b = 0;
2196 int w = 0;
2197 for (unsigned i = 0; i < rowhints.size(); ++i)
2198 {
2199 if (rowhints.at(i) == 2)
2200 {
2201 ++b;
2202 }
2203 else if (rowhints.at(i) == 1)
2204 {
2205 ++w;
2206 }
2207 }
2208
2209 if (b == mPegCnt)
2210 {
2211 SetState(STATE_WON);
2212 ResolveGame();
2213 }
2214 else if (b == mPegCnt - 1 && w == 1)
2215 {
2216 ;
2217 }
2218 else
2219 {
2220 mSolver->ResIn(&rowhints);
2221 NextRow();
2222 ResolveGame();
2223 }
2224 }
2225
ResolveGame()2226 void ColorCode::ResolveGame()
2227 {
2228 if (mGameMode == MODE_HVM)
2229 {
2230 switch (mGameState)
2231 {
2232 case STATE_WON:
2233 {
2234 ShowMsgSlot(tr("Congratulation! You have won!"));
2235 mHighScore->mTime = mGameTimer->GetGameTime();
2236 mGameInput->mScore = mHighScore->GetScore();
2237 mGameInput->mDuration = mGameTimer->GetGameTime();
2238 CCGame* g = new CCGame(mGameInput->ToString());
2239 emit NewHighScoreSignal(g);
2240 }
2241 break;
2242 case STATE_LOST:
2243 ShowMsgSlot(tr("Sorry! You lost!"));
2244 break;
2245 case STATE_GAVE_UP:
2246 ShowMsgSlot(tr("Sure, You're too weak for me!"));
2247 break;
2248 case STATE_ERROR:
2249 ShowMsgSlot(tr("The impossible happened, sorry."));
2250 break;
2251 case STATE_PAUSED:
2252 ShowMsgSlot(tr("Paused"));
2253 return;
2254 break;
2255 case STATE_RUNNING:
2256 default:
2257 return;
2258 break;
2259 }
2260
2261 mFinishedGameInput = new CCGame(mGameInput->ToString());
2262 mGameInput = NULL;
2263 mGameTimer->StopT();
2264 ShowSolution();
2265 }
2266 else if (mGameMode == MODE_MVH)
2267 {
2268 switch (mGameState)
2269 {
2270 case STATE_WON:
2271 ShowMsgSlot(tr("Yeah! I guessed it, man!"));
2272 break;
2273 case STATE_LOST:
2274 ShowMsgSlot(tr("Embarrassing! I lost a game!"));
2275 break;
2276 case STATE_GAVE_UP:
2277 ShowMsgSlot(tr("Don't you like to see me winning? ;-)"));
2278 break;
2279 case STATE_ERROR:
2280 ShowMsgSlot(tr("Nope! Thats impossible! Did you gave me false hints?"));
2281 break;
2282 case STATE_RUNNING:
2283 default:
2284 return;
2285 break;
2286 }
2287
2288 mDoneBtn->ShowBtn(false);
2289 mOkBtn->ShowBtn(false);
2290 }
2291
2292 SetCurRow(NULL);
2293 }
2294
ApplyGameMode()2295 void ColorCode::ApplyGameMode()
2296 {
2297 mGameMode = GetGameModeInput();
2298
2299 if (mGameMode == MODE_HVM)
2300 {
2301 mActSetHints->setVisible(false);
2302
2303 mActSetGuess->setVisible(true);
2304 mActPrevRow->setVisible(true);
2305 }
2306 else if (mGameMode == MODE_MVH)
2307 {
2308 mActSetHints->setVisible(true);
2309
2310 mActSetGuess->setVisible(false);
2311 mActPrevRow->setVisible(false);
2312 }
2313 ShowTimer();
2314 }
2315
GetGameState() const2316 int ColorCode::GetGameState() const
2317 {
2318 return mGameState;
2319 }
2320
GetGameModeInput() const2321 int ColorCode::GetGameModeInput() const
2322 {
2323 int ix = mActGroupModes->checkedAction()->data().toInt();
2324 if (ix != MODE_HVM && ix != MODE_MVH)
2325 {
2326 ix = MODE_HVM;
2327 }
2328 return ix;
2329 }
2330
GetDoublesInput() const2331 int ColorCode::GetDoublesInput() const
2332 {
2333 return (int) mActDoubles->isChecked();
2334 }
2335
GetColorCntInput() const2336 int ColorCode::GetColorCntInput() const
2337 {
2338 int ccnt = mColorCntCmb->itemData(mColorCntCmb->currentIndex(), Qt::UserRole).toInt();
2339 ccnt = max(2, min(10, ccnt));
2340 return ccnt;
2341 }
2342
GetPegCntInput() const2343 int ColorCode::GetPegCntInput() const
2344 {
2345 int pegcnt = mPegCntCmb->itemData(mPegCntCmb->currentIndex(), Qt::UserRole).toInt();
2346 pegcnt = max(2, min(5, pegcnt));
2347 return pegcnt;
2348 }
2349
ApplyPegCnt()2350 void ColorCode::ApplyPegCnt()
2351 {
2352 mPegCnt = GetPegCntInput();
2353 mXOffs = 160 - mPegCnt * 20;
2354 }
2355
ApplySolverStrength()2356 void ColorCode::ApplySolverStrength()
2357 {
2358 mSolverStrength = mSettings->mSolverStrength;
2359 }
2360
SetSolution()2361 void ColorCode::SetSolution()
2362 {
2363 mSolution.clear();
2364
2365 if (mGameMode == MODE_HVM)
2366 {
2367 mSolutionRow->ClearRow();
2368 mSolution = mSolver->GetSolutionByNo(mGameInput->mGameNo);
2369 }
2370 else if (mGameMode == MODE_MVH)
2371 {
2372 std::vector<int> s = mSolutionRow->GetSolution();
2373 if (s.size() == (unsigned) mPegCnt)
2374 {
2375 mSolutionRow->CloseRow();
2376 mDoneBtn->ShowBtn(false);
2377
2378 for (int i = 0; i < mPegCnt; ++i)
2379 {
2380 mSolution.push_back(s.at(i));
2381 }
2382 }
2383 }
2384 }
2385
GetSolution()2386 void ColorCode::GetSolution()
2387 {
2388 ShowMsgSlot(tr("Place Your secret ColorCode ..."));
2389 mSolutionRow->SetActive(true);
2390 SetCurRow(mSolutionRow);
2391 }
2392
ShowSolution()2393 void ColorCode::ShowSolution()
2394 {
2395 mSolutionRow->SetActive(true);
2396 ColorPeg* peg;
2397 for (int i = 0; i < mPegCnt; ++i)
2398 {
2399 peg = mPegFactory->CreatePeg(mSolution.at(i));
2400 peg->SetBtn(false);
2401 mSolutionRow->ForceSnap(peg, i);
2402 }
2403 mSolutionRow->CloseRow();
2404 }
2405
SetState(const int s)2406 void ColorCode::SetState(const int s)
2407 {
2408 if (mGameState != s)
2409 {
2410 mGameState = s;
2411 }
2412 }
2413
GamesRunning()2414 bool ColorCode::GamesRunning()
2415 {
2416 if (mGameMode == MODE_HVM)
2417 {
2418 return ((mGameState == STATE_RUNNING || mGameState == STATE_PAUSED) && mGuessCnt > 1);
2419 }
2420 else if (mGameMode == MODE_MVH)
2421 {
2422 return (mGameState == STATE_RUNNING && mCurRow != mSolutionRow);
2423 }
2424 return false;
2425 }
2426
Scale()2427 void ColorCode::Scale()
2428 {
2429 if (mGameCnt == 0)
2430 {
2431 return;
2432 }
2433
2434 qreal w = geometry().width();
2435 qreal h = geometry().height();
2436
2437 if (mActShowStatusbar->isChecked())
2438 {
2439 h -= statusBar()->height();
2440 }
2441 if (mActShowMenubar->isChecked())
2442 {
2443 h -= mMenuBar->height();
2444 }
2445 if (mActShowToolbar->isChecked())
2446 {
2447 h -= mGameToolbar->height();
2448 }
2449
2450 if (w < 50 || h < 50)
2451 {
2452 return;
2453 }
2454
2455 if (mOrigSize == NULL)
2456 {
2457 mOrigSize = new QSize(320, 560);
2458 mScene->setSceneRect(QRectF(0, 0, 320, 560));
2459 }
2460 else
2461 {
2462 qreal sc = min(w / mOrigSize->width(), h / mOrigSize->height());
2463 mView->resetTransform();
2464 mView->scale(sc, sc);
2465 }
2466 }
2467
GetCCSolver() const2468 CCSolver* ColorCode::GetCCSolver() const
2469 {
2470 return mSolver;
2471 }
2472
WaitForSolver()2473 void ColorCode::WaitForSolver()
2474 {
2475 mIgnoreGuess = true;
2476 mSolver->Interrupt();
2477 mSolver->wait();
2478 }
2479
ForceRepaint()2480 bool ColorCode::ForceRepaint()
2481 {
2482 mView->viewport()->repaint();
2483 QApplication::processEvents();
2484 return true;
2485 }
2486
SavePrevGameSlot()2487 void ColorCode::SavePrevGameSlot()
2488 {
2489 CCGame* g = GetCurrentGameInput();
2490 if (g != NULL)
2491 {
2492 mGameTablesDialog->InsertSavedGameSlot(g);
2493 }
2494 }
2495