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 "gamewidget.h" // Actual mouse/drawing window
20 //#include "resource.h"
21 //#include "optiondlg.h" // Options dialog class
22 //#include "statdlg.h" // Statistics dialog class
27 gameWidget = new GameWidget(this);
28 setCentralWidget(gameWidget);
29 gameWidget->setFocusPolicy(Qt::StrongFocus); // Without this, it gets no keys
30 setWindowTitle("Warehouse Man Deluxe");
31 setWindowIcon(QIcon(":/wmd-icon.png"));
33 newGame = CreateAction(tr("&New"), tr("New Game"), tr("Start a new game of Warehouse Man Deluxe"), QIcon(), QKeySequence(tr("ctrl+n")));
34 // connect(newGame, SIGNAL(triggered()), this, SLOT(OnNewGame()));
36 undoAction = CreateAction(tr("&Undo"), tr(""), tr(""), QIcon(), QKeySequence(tr("ctrl+z")));
37 connect(undoAction, SIGNAL(triggered()), this, SLOT(HandleUndo()));
39 resetLevel = CreateAction(tr("&Reset Level"), tr("Reset Level"), tr("Start the current level over"), QIcon(), QKeySequence(tr("ctrl+r")));
40 connect(resetLevel, SIGNAL(triggered()), this, SLOT(HandleReset()));
42 skipLevel = CreateAction(tr("&Skip Level"), tr("Skip Level"), tr("Skip the current level"), QIcon(), QKeySequence(tr("ctrl+k")));
43 connect(skipLevel, SIGNAL(triggered()), this, SLOT(HandleSkipLevel()));
45 gameOptions = CreateAction(tr("&Options..."), tr("Options"), tr("Configure Warehouse Man Deluxe's options"), QIcon(), QKeySequence(tr("ctrl+o")));
46 // connect(gameOptions, SIGNAL(triggered()), this, SLOT(OnGameOptions()));
48 gameStats = CreateAction(tr("&Stats..."), tr("Game Stats"), tr("Show game stats"), QIcon(), QKeySequence(tr("ctrl+s")));
49 // connect(gameStats, SIGNAL(triggered()), this, SLOT(OnGameStats()));
51 appExit = CreateAction(tr("E&xit"), tr("Exit"), tr("Quit playing Warehouse Man Deluxe..."), QIcon(), QKeySequence(tr("ctrl+q")));
52 connect(appExit, SIGNAL(triggered()), this, SLOT(close()));
54 appAbout = CreateAction(tr("&About"), tr("About"), tr("Display program information..."), QIcon(), QKeySequence(tr("")));
55 connect(appAbout, SIGNAL(triggered()), this, SLOT(AboutGame()));
57 // Get signals from the gameboard to update scores...
58 // connect(gameBoard, SIGNAL(UpdateScore(int)), this, SLOT(OnUpdateScore(int)));
59 connect(gameWidget, SIGNAL(GameWasWon()), this, SLOT(WeHaveAWinner()));
61 QMenu * menu = menuBar()->addMenu(tr("&Game"));
62 menu->addAction(newGame);
64 // menu->addAction(gamePlay);
65 menu->addAction(undoAction);
66 menu->addAction(resetLevel);
67 menu->addAction(skipLevel);
69 menu->addAction(gameOptions);
70 menu->addAction(gameStats);
72 menu->addAction(appExit);
74 menu = menuBar()->addMenu(tr("&Help"));
75 menu->addAction(appAbout);
77 // statusBar()->addPermanentWidget(gameBoard->score);
78 statusBar()->showMessage(tr("Ready"));
80 QSettings settings("Underground Software", "Warehouse Man Deluxe");
81 QPoint mainWinPosition = settings.value("pos", QPoint(200, 100)).toPoint();
82 move(mainWinPosition);
83 QSize mainWinSize = settings.value("size", QSize(500, 500)).toSize();
86 /* nCardBack = settings.value("CardBack", BACK4).toInt();
87 m_nBackground = settings.value("Background", 0).toInt();
88 bSoundOn = settings.value("EnableSound", true).toBool();
89 m_bAnimationsOn = settings.value("EnableAnimations", true).toBool();
90 bAutoRemove = settings.value("AutoRemove", true).toBool();
91 scoringOn = settings.value("EnableScoring", false).toBool();
92 m_bCumulativeOn = settings.value("CumulativeScore", false).toBool();
93 m_bVegasStyle = settings.value("VegasScoring", false).toBool();
94 m_bDrawThree = settings.value("DrawThree", false).toBool();
95 m_nWins = settings.value("NumWins", 0).toInt();
96 m_nLosses = settings.value("NumLosses", 0).toInt();
97 m_nHiScore = settings.value("HiScore", 0).toInt();
98 m_nVHiScore = settings.value("VegasHiScore", 0).toInt();
99 m_nStreakW = settings.value("WinStreak", 0).toInt();
100 m_nStreakL = settings.value("LoseStreak", 0).toInt();
101 m_nStreakC = settings.value("CurrentStreak", 0).toInt();
102 m_bWonLastGame = settings.value("WonLastGame", false).toBool();
103 m_nScore = settings.value("LastScore", -52).toInt();*/
105 // gameBoard->CreateBackground();
106 // InitializeAudio();
108 // mouseDown = false;
109 // myDeck.SetCardWidth(CARD_WIDTH);
110 // myDeck.SetCardHeight(CARD_HEIGHT);
112 // for(int i=0; i<52; i++)
113 // myDeck.SetCardPosition(i, QPoint(0, 0));
116 // allowUserInput = true;
117 // m_bFreeCard = false;
118 // m_pFirstCard = NULL;
129 // Consolidates action creation from a multi-step process to a single-step one.
131 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
132 QIcon icon, QKeySequence key, bool checkable/*= false*/)
134 QAction * action = new QAction(icon, name, this);
135 action->setToolTip(tooltip);
136 action->setStatusTip(statustip);
137 action->setShortcut(key);
138 action->setCheckable(checkable);
145 // This is essentially the same as the previous function, but this allows more
146 // than one key sequence to be added as key shortcuts.
148 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
149 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
151 QAction * action = new QAction(icon, name, this);
152 action->setToolTip(tooltip);
153 action->setStatusTip(statustip);
154 QList<QKeySequence> keyList;
155 keyList.append(key1);
156 keyList.append(key2);
157 action->setShortcuts(keyList);
158 action->setCheckable(checkable);
164 void MainWin::closeEvent(QCloseEvent * event)
166 /* if (allowUserInput && m_bTouchedGame)
168 gameBoard->HandleStatistics();
169 m_bWonLastGame = false;
172 QSettings settings("Underground Software", "Warehouse Man Deluxe");
173 settings.setValue("pos", pos());
174 settings.setValue("size", size());
177 settings.setValue("CardBack", nCardBack);
178 settings.setValue("Background", m_nBackground);
179 settings.setValue("EnableSound", bSoundOn);
180 settings.setValue("EnableAnimations", m_bAnimationsOn);
181 settings.setValue("AutoRemove", bAutoRemove);
182 settings.setValue("EnableScoring", scoringOn);
183 settings.setValue("CumulativeScore", m_bCumulativeOn);
184 settings.setValue("VegasScoring", m_bVegasStyle);
185 settings.setValue("DrawThree", m_bDrawThree);
186 settings.setValue("NumWins", m_nWins);
187 settings.setValue("NumLosses", m_nLosses);
188 settings.setValue("HiScore", m_nHiScore);
189 settings.setValue("VegasHiScore", m_nVHiScore);
190 settings.setValue("WinStreak", m_nStreakW);
191 settings.setValue("LoseStreak", m_nStreakL);
192 settings.setValue("CurrentStreak", m_nStreakC);
193 settings.setValue("WonLastGame", m_bWonLastGame);
194 settings.setValue("LastScore", m_nScore);*/
201 void MainWin::OnUpdateScore(int n)
209 s = QString(tr("Score: $%1")).arg(n);
211 s = QString(tr("Score: %1")).arg(n);
213 gameBoard->score->setText(s);
214 printf("OUS: n=%i, s=%s\n", n, s.toAscii().data());
218 void MainWin::ResetGame(void)
220 gameWidget->level = 1;
224 for(int i=0; i<7; i++)
225 for(int j=0; j<20; j++)
226 solBoard[i][j] = -1; // Empty the board...
229 myDeck.SetAllFaceDown();
231 for(int i=0; i<7; i++) // Fill the tableaux
233 for(int j=i; j<7; j++)
235 solBoard[6 - i][6 - j] = card;
238 myDeck.SetCardFaceUp(card);
244 for(int i=0; i<24; i++) // Fill the stack
249 nAce[0] = nAce[1] = nAce[2] = nAce[3] = -1;
251 hitStack = hitDiscard = false;
253 m_bTouchedGame = false;
259 if (!m_bCumulativeOn)
265 m_nExhaustedDeck = 0;
269 OnUpdateScore(m_nScore);*/
273 void MainWin::AboutGame(void)
275 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"));
279 void MainWin::WeHaveAWinner(void)
281 QMessageBox::information(this, "Warehouse Man Deluxe", "Congratulations!\nYou beat this level!\nNow try the next level!");
282 gameWidget->NextLevel();
286 void MainWin::HandleReset(void)
288 gameWidget->ResetLevel();
292 void MainWin::HandleSkipLevel(void)
294 gameWidget->NextLevel();
298 void MainWin::HandleUndo(void)
300 gameWidget->UndoLastMove();
305 void MainWin::OnNewGame(void)
307 if (allowUserInput && m_bTouchedGame) // Player didn't win...
309 gameBoard->HandleStatistics();
310 m_bWonLastGame = false;
315 allowUserInput = true;
320 PlaySound(IDW_CARDKNOCK);
321 gameBoard->Pause(300);
322 PlaySound(IDW_SHUFFLE);
328 void MainWin::OnGameOptions(void)
332 dlg.m_cardBack = nCardBack - BACK1;
333 dlg.m_nBackground = m_nBackground;
334 dlg.m_bCheck1 = bSoundOn;
335 dlg.m_bCheck2 = m_bAnimationsOn;
336 dlg.m_bCheck3 = bAutoRemove;
337 dlg.m_bCheck4 = scoringOn;
338 dlg.m_bCheck5 = m_bCumulativeOn;
339 dlg.m_nRadio1 = m_bVegasStyle;
340 dlg.m_nRadio3 = m_bDrawThree;
344 if (dlg.exec() == QDialog::Rejected)
349 nCardBack = dlg.m_cardBack + BACK1;
350 m_nBackground = dlg.m_nBackground;
351 bSoundOn = (bool)dlg.m_bCheck1;
352 m_bAnimationsOn = (bool)dlg.m_bCheck2;
353 bAutoRemove = (bool)dlg.m_bCheck3;
354 m_bCumulativeOn = (bool)dlg.m_bCheck5;
356 // Reset game if Vegas Style/Draw Three changes at all...
357 bool bChanged = (bool)((m_bVegasStyle != (bool)dlg.m_nRadio1)
358 || (m_bDrawThree != (bool)dlg.m_nRadio3) || (scoringOn != (bool)dlg.m_bCheck4));
360 scoringOn = (bool)dlg.m_bCheck4;
361 m_bVegasStyle = (bool)dlg.m_nRadio1;
362 m_bDrawThree = (bool)dlg.m_nRadio3;
364 if (bChanged && m_bTouchedGame)
365 OnNewGame(); // Probably should warn of this...
367 gameBoard->CreateBackground();
372 void MainWin::OnGameStats(void)
376 /* dlg.m_nWins = m_nWins;
377 dlg.m_nLosses = m_nLosses;
378 dlg.m_nHiScore = m_nHiScore;
379 dlg.m_nVHiScore = m_nVHiScore;
380 dlg.m_nStreakW = m_nStreakW;
381 dlg.m_nStreakL = m_nStreakL;
382 dlg.m_nStreakC = m_nStreakC;*/
386 // Since it's possible to reset the stats, we grab the fields back here...
387 /* m_nWins = dlg.m_nWins;
388 m_nLosses = dlg.m_nLosses;
389 m_nHiScore = dlg.m_nHiScore;
390 m_nVHiScore = dlg.m_nVHiScore;
391 m_nStreakW = dlg.m_nStreakW;
392 m_nStreakL = dlg.m_nStreakL;
393 m_nStreakC = dlg.m_nStreakC;*/
397 void MainWin::OnundoAction(void)
401 for(int i=0; i<7; i++)
402 for(int j=0; j<20; j++)
403 solBoard[i][j] = solBoardUndo[i][j];
405 for(int i=0; i<24; i++)
406 stack1[i] = stack1Undo[i], stack2[i] = stack2Undo[i];
408 for(int i=0; i<4; i++)
409 nAce[i] = nAceUndo[i];
411 stack1p = stack1pUndo, stack2p = stack2pUndo;
412 m_nScore = m_nScoreUndo;
413 m_nExhaustedDeck = m_nExhaustedDeckUndo;
414 m_nNumToSplay = m_nNumToSplayUndo;
415 m_bShowX = m_bShowXUndo;
417 OnUpdateScore(m_nScore);
421 gameBoard->update(); // wil wok?
425 void MainWin::OnGamePlay(void)
427 // Play a card from discard deck...
428 //NOTE: can reduce size by eliminating duplicate code in OnLButtonDown...
431 if (stack1p == -1) // I.e. it's empty...
434 if ((m_bDrawThree && (m_nExhaustedDeck == 3))
435 || (!m_bDrawThree && (m_nExhaustedDeck == 1)))
439 m_nExhaustedDeck = 0;
440 m_nScore -= (m_bDrawThree ? 20 : 100);
445 OnUpdateScore(m_nScore);
449 if (!m_bVegasStyle || (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck < 3))
450 || (!m_bDrawThree && (m_nExhaustedDeck < 1)))))
452 for(; stack2p!=-1; stack2p--)
453 stack1[++stack1p] = stack2[stack2p];
457 PlaySound(IDW_CARDKNOCK);
465 for(int i=0; i<(m_bDrawThree ? 3 : 1); i++)
467 if (stack1p != -1) // I.e., there are cards left...
469 stack2[++stack2p] = stack1[stack1p--];
474 PlaySound(IDW_CARDFLIP);
476 gameBoard->Pause(55);
484 if (stack1p == -1) // This is done here because it's right!
488 if (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck == 3))
489 || (!m_bDrawThree && (m_nExhaustedDeck == 1))))
495 gameBoard->HandleAutoRemove();