2 // mainwin.cpp: Implementation of the MainWin class
4 // JLH = James Hammons <jlhamm@acm.org>
7 // --- ---------- ------------------------------------------------------------
8 // JLH 03/01/2014 Created this file
16 #include <stdlib.h> // For rand()
17 #include <time.h> // For time()
18 #include "gameboard.h"
19 #include "editorwindow.h" // Actual mouse/drawing window
20 #include "gamewidget.h" // Actual mouse/drawing window
21 //#include "resource.h"
22 //#include "optiondlg.h" // Options dialog class
23 //#include "statdlg.h" // Statistics dialog class
28 gameWidget = new GameWidget(this);
29 setCentralWidget(gameWidget);
30 gameWidget->setFocusPolicy(Qt::StrongFocus); // Without this, it gets no keys
31 setWindowTitle("Warehouse Man Deluxe");
32 setWindowIcon(QIcon(":/wmd-icon.png"));
34 // editor = new QWindow(this);
35 editorWindow = new EditorWindow(this);
36 // editor->setCentralWidget(editorWidget);
37 // editorWidget->setFocusPolicy(Qt::StrongFocus); // Without this, it gets no keys
40 newGame = CreateAction(tr("&New"), tr("New Game"), tr("Start a new game of Warehouse Man Deluxe"), QIcon(), QKeySequence(tr("ctrl+n")));
41 // connect(newGame, SIGNAL(triggered()), this, SLOT(OnNewGame()));
43 undoAction = CreateAction(tr("&Undo"), tr(""), tr(""), QIcon(), QKeySequence(tr("ctrl+z")));
44 connect(undoAction, SIGNAL(triggered()), this, SLOT(HandleUndo()));
46 resetLevel = CreateAction(tr("&Reset Level"), tr("Reset Level"), tr("Start the current level over"), QIcon(), QKeySequence(tr("ctrl+r")));
47 connect(resetLevel, SIGNAL(triggered()), this, SLOT(HandleReset()));
49 skipLevel = CreateAction(tr("&Skip Level"), tr("Skip Level"), tr("Skip the current level"), QIcon(), QKeySequence(tr("ctrl+k")));
50 connect(skipLevel, SIGNAL(triggered()), this, SLOT(HandleSkipLevel()));
52 gameOptions = CreateAction(tr("&Options..."), tr("Options"), tr("Configure Warehouse Man Deluxe's options"), QIcon(), QKeySequence(tr("ctrl+o")));
53 // connect(gameOptions, SIGNAL(triggered()), this, SLOT(OnGameOptions()));
55 gameStats = CreateAction(tr("&Stats..."), tr("Game Stats"), tr("Show game stats"), QIcon(), QKeySequence(tr("ctrl+s")));
56 // connect(gameStats, SIGNAL(triggered()), this, SLOT(OnGameStats()));
58 appExit = CreateAction(tr("E&xit"), tr("Exit"), tr("Quit playing Warehouse Man Deluxe..."), QIcon(), QKeySequence(tr("ctrl+q")));
59 connect(appExit, SIGNAL(triggered()), this, SLOT(close()));
61 appAbout = CreateAction(tr("&About"), tr("About"), tr("Display program information..."), QIcon(), QKeySequence(tr("")));
62 connect(appAbout, SIGNAL(triggered()), this, SLOT(AboutGame()));
64 // Get signals from the gameboard to update scores...
65 // connect(gameBoard, SIGNAL(UpdateScore(int)), this, SLOT(OnUpdateScore(int)));
66 connect(gameWidget, SIGNAL(GameWasWon()), this, SLOT(WeHaveAWinner()));
68 // Connect editor to game widget...
69 connect(editorWindow, SIGNAL(SetupLevel(Level *)), gameWidget,
70 SLOT(HandlePlayGameFromEditor(Level *)));
73 QMenu * menu = menuBar()->addMenu(tr("&Game"));
74 menu->addAction(newGame);
76 // menu->addAction(gamePlay);
77 menu->addAction(undoAction);
78 menu->addAction(resetLevel);
79 menu->addAction(skipLevel);
81 menu->addAction(gameOptions);
82 menu->addAction(gameStats);
84 menu->addAction(appExit);
86 menu = menuBar()->addMenu(tr("&Help"));
87 menu->addAction(appAbout);
89 // statusBar()->addPermanentWidget(gameBoard->score);
90 statusBar()->showMessage(tr("Ready"));
92 QSettings settings("Underground Software", "Warehouse Man Deluxe");
93 QPoint mainWinPosition = settings.value("pos", QPoint(200, 100)).toPoint();
94 move(mainWinPosition);
95 QSize mainWinSize = settings.value("size", QSize(500, 500)).toSize();
98 /* nCardBack = settings.value("CardBack", BACK4).toInt();
99 m_nBackground = settings.value("Background", 0).toInt();
100 bSoundOn = settings.value("EnableSound", true).toBool();
101 m_bAnimationsOn = settings.value("EnableAnimations", true).toBool();
102 bAutoRemove = settings.value("AutoRemove", true).toBool();
103 scoringOn = settings.value("EnableScoring", false).toBool();
104 m_bCumulativeOn = settings.value("CumulativeScore", false).toBool();
105 m_bVegasStyle = settings.value("VegasScoring", false).toBool();
106 m_bDrawThree = settings.value("DrawThree", false).toBool();
107 m_nWins = settings.value("NumWins", 0).toInt();
108 m_nLosses = settings.value("NumLosses", 0).toInt();
109 m_nHiScore = settings.value("HiScore", 0).toInt();
110 m_nVHiScore = settings.value("VegasHiScore", 0).toInt();
111 m_nStreakW = settings.value("WinStreak", 0).toInt();
112 m_nStreakL = settings.value("LoseStreak", 0).toInt();
113 m_nStreakC = settings.value("CurrentStreak", 0).toInt();
114 m_bWonLastGame = settings.value("WonLastGame", false).toBool();
115 m_nScore = settings.value("LastScore", -52).toInt();*/
117 // gameBoard->CreateBackground();
118 // InitializeAudio();
120 // mouseDown = false;
121 // myDeck.SetCardWidth(CARD_WIDTH);
122 // myDeck.SetCardHeight(CARD_HEIGHT);
124 // for(int i=0; i<52; i++)
125 // myDeck.SetCardPosition(i, QPoint(0, 0));
128 // allowUserInput = true;
129 // m_bFreeCard = false;
130 // m_pFirstCard = NULL;
142 // Consolidates action creation from a multi-step process to a single-step one.
144 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
145 QIcon icon, QKeySequence key, bool checkable/*= false*/)
147 QAction * action = new QAction(icon, name, this);
148 action->setToolTip(tooltip);
149 action->setStatusTip(statustip);
150 action->setShortcut(key);
151 action->setCheckable(checkable);
158 // This is essentially the same as the previous function, but this allows more
159 // than one key sequence to be added as key shortcuts.
161 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
162 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
164 QAction * action = new QAction(icon, name, this);
165 action->setToolTip(tooltip);
166 action->setStatusTip(statustip);
167 QList<QKeySequence> keyList;
168 keyList.append(key1);
169 keyList.append(key2);
170 action->setShortcuts(keyList);
171 action->setCheckable(checkable);
177 void MainWin::closeEvent(QCloseEvent * event)
179 /* if (allowUserInput && m_bTouchedGame)
181 gameBoard->HandleStatistics();
182 m_bWonLastGame = false;
185 QSettings settings("Underground Software", "Warehouse Man Deluxe");
186 settings.setValue("pos", pos());
187 settings.setValue("size", size());
190 settings.setValue("CardBack", nCardBack);
191 settings.setValue("Background", m_nBackground);
192 settings.setValue("EnableSound", bSoundOn);
193 settings.setValue("EnableAnimations", m_bAnimationsOn);
194 settings.setValue("AutoRemove", bAutoRemove);
195 settings.setValue("EnableScoring", scoringOn);
196 settings.setValue("CumulativeScore", m_bCumulativeOn);
197 settings.setValue("VegasScoring", m_bVegasStyle);
198 settings.setValue("DrawThree", m_bDrawThree);
199 settings.setValue("NumWins", m_nWins);
200 settings.setValue("NumLosses", m_nLosses);
201 settings.setValue("HiScore", m_nHiScore);
202 settings.setValue("VegasHiScore", m_nVHiScore);
203 settings.setValue("WinStreak", m_nStreakW);
204 settings.setValue("LoseStreak", m_nStreakL);
205 settings.setValue("CurrentStreak", m_nStreakC);
206 settings.setValue("WonLastGame", m_bWonLastGame);
207 settings.setValue("LastScore", m_nScore);*/
214 void MainWin::OnUpdateScore(int n)
222 s = QString(tr("Score: $%1")).arg(n);
224 s = QString(tr("Score: %1")).arg(n);
226 gameBoard->score->setText(s);
227 printf("OUS: n=%i, s=%s\n", n, s.toAscii().data());
231 void MainWin::ResetGame(void)
233 gameWidget->level = 1;
237 for(int i=0; i<7; i++)
238 for(int j=0; j<20; j++)
239 solBoard[i][j] = -1; // Empty the board...
242 myDeck.SetAllFaceDown();
244 for(int i=0; i<7; i++) // Fill the tableaux
246 for(int j=i; j<7; j++)
248 solBoard[6 - i][6 - j] = card;
251 myDeck.SetCardFaceUp(card);
257 for(int i=0; i<24; i++) // Fill the stack
262 nAce[0] = nAce[1] = nAce[2] = nAce[3] = -1;
264 hitStack = hitDiscard = false;
266 m_bTouchedGame = false;
272 if (!m_bCumulativeOn)
278 m_nExhaustedDeck = 0;
282 OnUpdateScore(m_nScore);*/
286 void MainWin::AboutGame(void)
288 QMessageBox::about(this, tr("About Warehouse Man Deluxe"), tr("Warehouse Man Deluxe Version 1.0\n\nCopyright (C) 2014 Underground Software\n\nWritten by James L. Hammons"));
292 void MainWin::WeHaveAWinner(void)
294 QMessageBox::information(this, "Warehouse Man Deluxe", "Congratulations!\nYou beat this level!\nNow try the next level!");
295 gameWidget->NextLevel();
299 void MainWin::HandleReset(void)
301 gameWidget->ResetLevel();
305 void MainWin::HandleSkipLevel(void)
307 gameWidget->NextLevel();
311 void MainWin::HandleUndo(void)
313 gameWidget->UndoLastMove();
318 void MainWin::OnNewGame(void)
320 if (allowUserInput && m_bTouchedGame) // Player didn't win...
322 gameBoard->HandleStatistics();
323 m_bWonLastGame = false;
328 allowUserInput = true;
333 PlaySound(IDW_CARDKNOCK);
334 gameBoard->Pause(300);
335 PlaySound(IDW_SHUFFLE);
341 void MainWin::OnGameOptions(void)
345 dlg.m_cardBack = nCardBack - BACK1;
346 dlg.m_nBackground = m_nBackground;
347 dlg.m_bCheck1 = bSoundOn;
348 dlg.m_bCheck2 = m_bAnimationsOn;
349 dlg.m_bCheck3 = bAutoRemove;
350 dlg.m_bCheck4 = scoringOn;
351 dlg.m_bCheck5 = m_bCumulativeOn;
352 dlg.m_nRadio1 = m_bVegasStyle;
353 dlg.m_nRadio3 = m_bDrawThree;
357 if (dlg.exec() == QDialog::Rejected)
362 nCardBack = dlg.m_cardBack + BACK1;
363 m_nBackground = dlg.m_nBackground;
364 bSoundOn = (bool)dlg.m_bCheck1;
365 m_bAnimationsOn = (bool)dlg.m_bCheck2;
366 bAutoRemove = (bool)dlg.m_bCheck3;
367 m_bCumulativeOn = (bool)dlg.m_bCheck5;
369 // Reset game if Vegas Style/Draw Three changes at all...
370 bool bChanged = (bool)((m_bVegasStyle != (bool)dlg.m_nRadio1)
371 || (m_bDrawThree != (bool)dlg.m_nRadio3) || (scoringOn != (bool)dlg.m_bCheck4));
373 scoringOn = (bool)dlg.m_bCheck4;
374 m_bVegasStyle = (bool)dlg.m_nRadio1;
375 m_bDrawThree = (bool)dlg.m_nRadio3;
377 if (bChanged && m_bTouchedGame)
378 OnNewGame(); // Probably should warn of this...
380 gameBoard->CreateBackground();
385 void MainWin::OnGameStats(void)
389 /* dlg.m_nWins = m_nWins;
390 dlg.m_nLosses = m_nLosses;
391 dlg.m_nHiScore = m_nHiScore;
392 dlg.m_nVHiScore = m_nVHiScore;
393 dlg.m_nStreakW = m_nStreakW;
394 dlg.m_nStreakL = m_nStreakL;
395 dlg.m_nStreakC = m_nStreakC;*/
399 // Since it's possible to reset the stats, we grab the fields back here...
400 /* m_nWins = dlg.m_nWins;
401 m_nLosses = dlg.m_nLosses;
402 m_nHiScore = dlg.m_nHiScore;
403 m_nVHiScore = dlg.m_nVHiScore;
404 m_nStreakW = dlg.m_nStreakW;
405 m_nStreakL = dlg.m_nStreakL;
406 m_nStreakC = dlg.m_nStreakC;*/
410 void MainWin::OnundoAction(void)
414 for(int i=0; i<7; i++)
415 for(int j=0; j<20; j++)
416 solBoard[i][j] = solBoardUndo[i][j];
418 for(int i=0; i<24; i++)
419 stack1[i] = stack1Undo[i], stack2[i] = stack2Undo[i];
421 for(int i=0; i<4; i++)
422 nAce[i] = nAceUndo[i];
424 stack1p = stack1pUndo, stack2p = stack2pUndo;
425 m_nScore = m_nScoreUndo;
426 m_nExhaustedDeck = m_nExhaustedDeckUndo;
427 m_nNumToSplay = m_nNumToSplayUndo;
428 m_bShowX = m_bShowXUndo;
430 OnUpdateScore(m_nScore);
434 gameBoard->update(); // wil wok?
438 void MainWin::OnGamePlay(void)
440 // Play a card from discard deck...
441 //NOTE: can reduce size by eliminating duplicate code in OnLButtonDown...
444 if (stack1p == -1) // I.e. it's empty...
447 if ((m_bDrawThree && (m_nExhaustedDeck == 3))
448 || (!m_bDrawThree && (m_nExhaustedDeck == 1)))
452 m_nExhaustedDeck = 0;
453 m_nScore -= (m_bDrawThree ? 20 : 100);
458 OnUpdateScore(m_nScore);
462 if (!m_bVegasStyle || (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck < 3))
463 || (!m_bDrawThree && (m_nExhaustedDeck < 1)))))
465 for(; stack2p!=-1; stack2p--)
466 stack1[++stack1p] = stack2[stack2p];
470 PlaySound(IDW_CARDKNOCK);
478 for(int i=0; i<(m_bDrawThree ? 3 : 1); i++)
480 if (stack1p != -1) // I.e., there are cards left...
482 stack2[++stack2p] = stack1[stack1p--];
487 PlaySound(IDW_CARDFLIP);
489 gameBoard->Pause(55);
497 if (stack1p == -1) // This is done here because it's right!
501 if (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck == 3))
502 || (!m_bDrawThree && (m_nExhaustedDeck == 1))))
508 gameBoard->HandleAutoRemove();