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 QMenu * menu = menuBar()->addMenu(tr("&Game"));
69 menu->addAction(newGame);
71 // menu->addAction(gamePlay);
72 menu->addAction(undoAction);
73 menu->addAction(resetLevel);
74 menu->addAction(skipLevel);
76 menu->addAction(gameOptions);
77 menu->addAction(gameStats);
79 menu->addAction(appExit);
81 menu = menuBar()->addMenu(tr("&Help"));
82 menu->addAction(appAbout);
84 // statusBar()->addPermanentWidget(gameBoard->score);
85 statusBar()->showMessage(tr("Ready"));
87 QSettings settings("Underground Software", "Warehouse Man Deluxe");
88 QPoint mainWinPosition = settings.value("pos", QPoint(200, 100)).toPoint();
89 move(mainWinPosition);
90 QSize mainWinSize = settings.value("size", QSize(500, 500)).toSize();
93 /* nCardBack = settings.value("CardBack", BACK4).toInt();
94 m_nBackground = settings.value("Background", 0).toInt();
95 bSoundOn = settings.value("EnableSound", true).toBool();
96 m_bAnimationsOn = settings.value("EnableAnimations", true).toBool();
97 bAutoRemove = settings.value("AutoRemove", true).toBool();
98 scoringOn = settings.value("EnableScoring", false).toBool();
99 m_bCumulativeOn = settings.value("CumulativeScore", false).toBool();
100 m_bVegasStyle = settings.value("VegasScoring", false).toBool();
101 m_bDrawThree = settings.value("DrawThree", false).toBool();
102 m_nWins = settings.value("NumWins", 0).toInt();
103 m_nLosses = settings.value("NumLosses", 0).toInt();
104 m_nHiScore = settings.value("HiScore", 0).toInt();
105 m_nVHiScore = settings.value("VegasHiScore", 0).toInt();
106 m_nStreakW = settings.value("WinStreak", 0).toInt();
107 m_nStreakL = settings.value("LoseStreak", 0).toInt();
108 m_nStreakC = settings.value("CurrentStreak", 0).toInt();
109 m_bWonLastGame = settings.value("WonLastGame", false).toBool();
110 m_nScore = settings.value("LastScore", -52).toInt();*/
112 // gameBoard->CreateBackground();
113 // InitializeAudio();
115 // mouseDown = false;
116 // myDeck.SetCardWidth(CARD_WIDTH);
117 // myDeck.SetCardHeight(CARD_HEIGHT);
119 // for(int i=0; i<52; i++)
120 // myDeck.SetCardPosition(i, QPoint(0, 0));
123 // allowUserInput = true;
124 // m_bFreeCard = false;
125 // m_pFirstCard = NULL;
137 // Consolidates action creation from a multi-step process to a single-step one.
139 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
140 QIcon icon, QKeySequence key, bool checkable/*= false*/)
142 QAction * action = new QAction(icon, name, this);
143 action->setToolTip(tooltip);
144 action->setStatusTip(statustip);
145 action->setShortcut(key);
146 action->setCheckable(checkable);
153 // This is essentially the same as the previous function, but this allows more
154 // than one key sequence to be added as key shortcuts.
156 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
157 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
159 QAction * action = new QAction(icon, name, this);
160 action->setToolTip(tooltip);
161 action->setStatusTip(statustip);
162 QList<QKeySequence> keyList;
163 keyList.append(key1);
164 keyList.append(key2);
165 action->setShortcuts(keyList);
166 action->setCheckable(checkable);
172 void MainWin::closeEvent(QCloseEvent * event)
174 /* if (allowUserInput && m_bTouchedGame)
176 gameBoard->HandleStatistics();
177 m_bWonLastGame = false;
180 QSettings settings("Underground Software", "Warehouse Man Deluxe");
181 settings.setValue("pos", pos());
182 settings.setValue("size", size());
185 settings.setValue("CardBack", nCardBack);
186 settings.setValue("Background", m_nBackground);
187 settings.setValue("EnableSound", bSoundOn);
188 settings.setValue("EnableAnimations", m_bAnimationsOn);
189 settings.setValue("AutoRemove", bAutoRemove);
190 settings.setValue("EnableScoring", scoringOn);
191 settings.setValue("CumulativeScore", m_bCumulativeOn);
192 settings.setValue("VegasScoring", m_bVegasStyle);
193 settings.setValue("DrawThree", m_bDrawThree);
194 settings.setValue("NumWins", m_nWins);
195 settings.setValue("NumLosses", m_nLosses);
196 settings.setValue("HiScore", m_nHiScore);
197 settings.setValue("VegasHiScore", m_nVHiScore);
198 settings.setValue("WinStreak", m_nStreakW);
199 settings.setValue("LoseStreak", m_nStreakL);
200 settings.setValue("CurrentStreak", m_nStreakC);
201 settings.setValue("WonLastGame", m_bWonLastGame);
202 settings.setValue("LastScore", m_nScore);*/
209 void MainWin::OnUpdateScore(int n)
217 s = QString(tr("Score: $%1")).arg(n);
219 s = QString(tr("Score: %1")).arg(n);
221 gameBoard->score->setText(s);
222 printf("OUS: n=%i, s=%s\n", n, s.toAscii().data());
226 void MainWin::ResetGame(void)
228 gameWidget->level = 1;
232 for(int i=0; i<7; i++)
233 for(int j=0; j<20; j++)
234 solBoard[i][j] = -1; // Empty the board...
237 myDeck.SetAllFaceDown();
239 for(int i=0; i<7; i++) // Fill the tableaux
241 for(int j=i; j<7; j++)
243 solBoard[6 - i][6 - j] = card;
246 myDeck.SetCardFaceUp(card);
252 for(int i=0; i<24; i++) // Fill the stack
257 nAce[0] = nAce[1] = nAce[2] = nAce[3] = -1;
259 hitStack = hitDiscard = false;
261 m_bTouchedGame = false;
267 if (!m_bCumulativeOn)
273 m_nExhaustedDeck = 0;
277 OnUpdateScore(m_nScore);*/
281 void MainWin::AboutGame(void)
283 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"));
287 void MainWin::WeHaveAWinner(void)
289 QMessageBox::information(this, "Warehouse Man Deluxe", "Congratulations!\nYou beat this level!\nNow try the next level!");
290 gameWidget->NextLevel();
294 void MainWin::HandleReset(void)
296 gameWidget->ResetLevel();
300 void MainWin::HandleSkipLevel(void)
302 gameWidget->NextLevel();
306 void MainWin::HandleUndo(void)
308 gameWidget->UndoLastMove();
313 void MainWin::OnNewGame(void)
315 if (allowUserInput && m_bTouchedGame) // Player didn't win...
317 gameBoard->HandleStatistics();
318 m_bWonLastGame = false;
323 allowUserInput = true;
328 PlaySound(IDW_CARDKNOCK);
329 gameBoard->Pause(300);
330 PlaySound(IDW_SHUFFLE);
336 void MainWin::OnGameOptions(void)
340 dlg.m_cardBack = nCardBack - BACK1;
341 dlg.m_nBackground = m_nBackground;
342 dlg.m_bCheck1 = bSoundOn;
343 dlg.m_bCheck2 = m_bAnimationsOn;
344 dlg.m_bCheck3 = bAutoRemove;
345 dlg.m_bCheck4 = scoringOn;
346 dlg.m_bCheck5 = m_bCumulativeOn;
347 dlg.m_nRadio1 = m_bVegasStyle;
348 dlg.m_nRadio3 = m_bDrawThree;
352 if (dlg.exec() == QDialog::Rejected)
357 nCardBack = dlg.m_cardBack + BACK1;
358 m_nBackground = dlg.m_nBackground;
359 bSoundOn = (bool)dlg.m_bCheck1;
360 m_bAnimationsOn = (bool)dlg.m_bCheck2;
361 bAutoRemove = (bool)dlg.m_bCheck3;
362 m_bCumulativeOn = (bool)dlg.m_bCheck5;
364 // Reset game if Vegas Style/Draw Three changes at all...
365 bool bChanged = (bool)((m_bVegasStyle != (bool)dlg.m_nRadio1)
366 || (m_bDrawThree != (bool)dlg.m_nRadio3) || (scoringOn != (bool)dlg.m_bCheck4));
368 scoringOn = (bool)dlg.m_bCheck4;
369 m_bVegasStyle = (bool)dlg.m_nRadio1;
370 m_bDrawThree = (bool)dlg.m_nRadio3;
372 if (bChanged && m_bTouchedGame)
373 OnNewGame(); // Probably should warn of this...
375 gameBoard->CreateBackground();
380 void MainWin::OnGameStats(void)
384 /* dlg.m_nWins = m_nWins;
385 dlg.m_nLosses = m_nLosses;
386 dlg.m_nHiScore = m_nHiScore;
387 dlg.m_nVHiScore = m_nVHiScore;
388 dlg.m_nStreakW = m_nStreakW;
389 dlg.m_nStreakL = m_nStreakL;
390 dlg.m_nStreakC = m_nStreakC;*/
394 // Since it's possible to reset the stats, we grab the fields back here...
395 /* m_nWins = dlg.m_nWins;
396 m_nLosses = dlg.m_nLosses;
397 m_nHiScore = dlg.m_nHiScore;
398 m_nVHiScore = dlg.m_nVHiScore;
399 m_nStreakW = dlg.m_nStreakW;
400 m_nStreakL = dlg.m_nStreakL;
401 m_nStreakC = dlg.m_nStreakC;*/
405 void MainWin::OnundoAction(void)
409 for(int i=0; i<7; i++)
410 for(int j=0; j<20; j++)
411 solBoard[i][j] = solBoardUndo[i][j];
413 for(int i=0; i<24; i++)
414 stack1[i] = stack1Undo[i], stack2[i] = stack2Undo[i];
416 for(int i=0; i<4; i++)
417 nAce[i] = nAceUndo[i];
419 stack1p = stack1pUndo, stack2p = stack2pUndo;
420 m_nScore = m_nScoreUndo;
421 m_nExhaustedDeck = m_nExhaustedDeckUndo;
422 m_nNumToSplay = m_nNumToSplayUndo;
423 m_bShowX = m_bShowXUndo;
425 OnUpdateScore(m_nScore);
429 gameBoard->update(); // wil wok?
433 void MainWin::OnGamePlay(void)
435 // Play a card from discard deck...
436 //NOTE: can reduce size by eliminating duplicate code in OnLButtonDown...
439 if (stack1p == -1) // I.e. it's empty...
442 if ((m_bDrawThree && (m_nExhaustedDeck == 3))
443 || (!m_bDrawThree && (m_nExhaustedDeck == 1)))
447 m_nExhaustedDeck = 0;
448 m_nScore -= (m_bDrawThree ? 20 : 100);
453 OnUpdateScore(m_nScore);
457 if (!m_bVegasStyle || (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck < 3))
458 || (!m_bDrawThree && (m_nExhaustedDeck < 1)))))
460 for(; stack2p!=-1; stack2p--)
461 stack1[++stack1p] = stack2[stack2p];
465 PlaySound(IDW_CARDKNOCK);
473 for(int i=0; i<(m_bDrawThree ? 3 : 1); i++)
475 if (stack1p != -1) // I.e., there are cards left...
477 stack2[++stack2p] = stack1[stack1p--];
482 PlaySound(IDW_CARDFLIP);
484 gameBoard->Pause(55);
492 if (stack1p == -1) // This is done here because it's right!
496 if (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck == 3))
497 || (!m_bDrawThree && (m_nExhaustedDeck == 1))))
503 gameBoard->HandleAutoRemove();