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 // We create the EditorWindow 1st because the GameWidget will crash if there
29 // is no level data loaded...
30 editorWindow = new EditorWindow(this);
31 gameWidget = new GameWidget(this);
32 setCentralWidget(gameWidget);
33 gameWidget->setFocusPolicy(Qt::StrongFocus); // Without this, it gets no keys
34 setWindowTitle("Warehouse Man Deluxe");
35 setWindowIcon(QIcon(":/wmd-icon.png"));
39 newGame = CreateAction(tr("&New"), tr("New Game"), tr("Start a new game of Warehouse Man Deluxe"), QIcon(), QKeySequence(tr("ctrl+n")));
40 connect(newGame, SIGNAL(triggered()), this, SLOT(HandleNewGame()));
42 undoAction = CreateAction(tr("&Undo"), tr(""), tr(""), QIcon(), QKeySequence(tr("ctrl+z")));
43 connect(undoAction, SIGNAL(triggered()), this, SLOT(HandleUndo()));
45 resetLevel = CreateAction(tr("&Reset Level"), tr("Reset Level"), tr("Start the current level over"), QIcon(), QKeySequence(tr("ctrl+r")));
46 connect(resetLevel, SIGNAL(triggered()), this, SLOT(HandleReset()));
48 skipLevel = CreateAction(tr("&Skip Level"), tr("Skip Level"), tr("Skip the current level"), QIcon(), QKeySequence(tr("ctrl+k")));
49 connect(skipLevel, SIGNAL(triggered()), this, SLOT(HandleSkipLevel()));
51 gameOptions = CreateAction(tr("&Options..."), tr("Options"), tr("Configure Warehouse Man Deluxe's options"), QIcon(), QKeySequence(tr("ctrl+o")));
52 // connect(gameOptions, SIGNAL(triggered()), this, SLOT(OnGameOptions()));
54 gameStats = CreateAction(tr("&Stats..."), tr("Game Stats"), tr("Show game stats"), QIcon(), QKeySequence(tr("ctrl+s")));
55 // connect(gameStats, SIGNAL(triggered()), this, SLOT(OnGameStats()));
57 appExit = CreateAction(tr("E&xit"), tr("Exit"), tr("Quit playing Warehouse Man Deluxe..."), QIcon(), QKeySequence(tr("ctrl+q")));
58 connect(appExit, SIGNAL(triggered()), this, SLOT(close()));
60 appAbout = CreateAction(tr("&About"), tr("About"), tr("Display program information..."), QIcon(), QKeySequence(tr("")));
61 connect(appAbout, SIGNAL(triggered()), this, SLOT(AboutGame()));
63 // Get signals from the gameboard to update scores...
64 // connect(gameBoard, SIGNAL(UpdateScore(int)), this, SLOT(OnUpdateScore(int)));
65 connect(gameWidget, SIGNAL(GameWasWon()), this, SLOT(WeHaveAWinner()));
67 // Connect editor to game widget...
68 connect(editorWindow, SIGNAL(SetupLevel(Level *)), gameWidget,
69 SLOT(HandlePlayGameFromEditor(Level *)));
72 QMenu * menu = menuBar()->addMenu(tr("&Game"));
73 menu->addAction(newGame);
75 // menu->addAction(gamePlay);
76 menu->addAction(undoAction);
77 menu->addAction(resetLevel);
78 menu->addAction(skipLevel);
80 menu->addAction(gameOptions);
81 menu->addAction(gameStats);
83 menu->addAction(appExit);
85 menu = menuBar()->addMenu(tr("&Help"));
86 menu->addAction(appAbout);
88 // statusBar()->addPermanentWidget(gameBoard->score);
89 statusBar()->showMessage(tr("Ready"));
91 QSettings settings("Underground Software", "Warehouse Man Deluxe");
92 QPoint mainWinPosition = settings.value("pos", QPoint(200, 100)).toPoint();
93 move(mainWinPosition);
94 QSize mainWinSize = settings.value("size", QSize(500, 500)).toSize();
97 /* nCardBack = settings.value("CardBack", BACK4).toInt();
98 m_nBackground = settings.value("Background", 0).toInt();
99 bSoundOn = settings.value("EnableSound", true).toBool();
100 m_bAnimationsOn = settings.value("EnableAnimations", true).toBool();
101 bAutoRemove = settings.value("AutoRemove", true).toBool();
102 scoringOn = settings.value("EnableScoring", false).toBool();
103 m_bCumulativeOn = settings.value("CumulativeScore", false).toBool();
104 m_bVegasStyle = settings.value("VegasScoring", false).toBool();
105 m_bDrawThree = settings.value("DrawThree", false).toBool();
106 m_nWins = settings.value("NumWins", 0).toInt();
107 m_nLosses = settings.value("NumLosses", 0).toInt();
108 m_nHiScore = settings.value("HiScore", 0).toInt();
109 m_nVHiScore = settings.value("VegasHiScore", 0).toInt();
110 m_nStreakW = settings.value("WinStreak", 0).toInt();
111 m_nStreakL = settings.value("LoseStreak", 0).toInt();
112 m_nStreakC = settings.value("CurrentStreak", 0).toInt();
113 m_bWonLastGame = settings.value("WonLastGame", false).toBool();
114 m_nScore = settings.value("LastScore", -52).toInt();*/
116 // gameBoard->CreateBackground();
117 // InitializeAudio();
119 // mouseDown = false;
120 // myDeck.SetCardWidth(CARD_WIDTH);
121 // myDeck.SetCardHeight(CARD_HEIGHT);
123 // for(int i=0; i<52; i++)
124 // myDeck.SetCardPosition(i, QPoint(0, 0));
127 // allowUserInput = true;
128 // m_bFreeCard = false;
129 // m_pFirstCard = NULL;
141 // Consolidates action creation from a multi-step process to a single-step one.
143 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
144 QIcon icon, QKeySequence key, bool checkable/*= false*/)
146 QAction * action = new QAction(icon, name, this);
147 action->setToolTip(tooltip);
148 action->setStatusTip(statustip);
149 action->setShortcut(key);
150 action->setCheckable(checkable);
157 // This is essentially the same as the previous function, but this allows more
158 // than one key sequence to be added as key shortcuts.
160 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
161 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
163 QAction * action = new QAction(icon, name, this);
164 action->setToolTip(tooltip);
165 action->setStatusTip(statustip);
166 QList<QKeySequence> keyList;
167 keyList.append(key1);
168 keyList.append(key2);
169 action->setShortcuts(keyList);
170 action->setCheckable(checkable);
176 void MainWin::closeEvent(QCloseEvent * event)
178 /* if (allowUserInput && m_bTouchedGame)
180 gameBoard->HandleStatistics();
181 m_bWonLastGame = false;
184 QSettings settings("Underground Software", "Warehouse Man Deluxe");
185 settings.setValue("pos", pos());
186 settings.setValue("size", size());
189 settings.setValue("CardBack", nCardBack);
190 settings.setValue("Background", m_nBackground);
191 settings.setValue("EnableSound", bSoundOn);
192 settings.setValue("EnableAnimations", m_bAnimationsOn);
193 settings.setValue("AutoRemove", bAutoRemove);
194 settings.setValue("EnableScoring", scoringOn);
195 settings.setValue("CumulativeScore", m_bCumulativeOn);
196 settings.setValue("VegasScoring", m_bVegasStyle);
197 settings.setValue("DrawThree", m_bDrawThree);
198 settings.setValue("NumWins", m_nWins);
199 settings.setValue("NumLosses", m_nLosses);
200 settings.setValue("HiScore", m_nHiScore);
201 settings.setValue("VegasHiScore", m_nVHiScore);
202 settings.setValue("WinStreak", m_nStreakW);
203 settings.setValue("LoseStreak", m_nStreakL);
204 settings.setValue("CurrentStreak", m_nStreakC);
205 settings.setValue("WonLastGame", m_bWonLastGame);
206 settings.setValue("LastScore", m_nScore);*/
213 void MainWin::OnUpdateScore(int n)
221 s = QString(tr("Score: $%1")).arg(n);
223 s = QString(tr("Score: %1")).arg(n);
225 gameBoard->score->setText(s);
226 printf("OUS: n=%i, s=%s\n", n, s.toUtf8().data());
230 void MainWin::ResetGame(void)
232 gameWidget->level = 1;
236 for(int i=0; i<7; i++)
237 for(int j=0; j<20; j++)
238 solBoard[i][j] = -1; // Empty the board...
241 myDeck.SetAllFaceDown();
243 for(int i=0; i<7; i++) // Fill the tableaux
245 for(int j=i; j<7; j++)
247 solBoard[6 - i][6 - j] = card;
250 myDeck.SetCardFaceUp(card);
256 for(int i=0; i<24; i++) // Fill the stack
261 nAce[0] = nAce[1] = nAce[2] = nAce[3] = -1;
263 hitStack = hitDiscard = false;
265 m_bTouchedGame = false;
271 if (!m_bCumulativeOn)
277 m_nExhaustedDeck = 0;
281 OnUpdateScore(m_nScore);*/
285 void MainWin::HandleNewGame(void)
288 gameWidget->level = 0;
289 gameWidget->NextLevel();
293 void MainWin::AboutGame(void)
295 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 Hammons"));
299 void MainWin::WeHaveAWinner(void)
301 QMessageBox::information(this, "Warehouse Man Deluxe", "Congratulations!\nYou beat this level!\nNow try the next level!");
302 gameWidget->NextLevel();
306 void MainWin::HandleReset(void)
308 gameWidget->ResetLevel();
312 void MainWin::HandleSkipLevel(void)
314 gameWidget->NextLevel();
318 void MainWin::HandleUndo(void)
320 gameWidget->UndoLastMove();
325 void MainWin::OnNewGame(void)
327 if (allowUserInput && m_bTouchedGame) // Player didn't win...
329 gameBoard->HandleStatistics();
330 m_bWonLastGame = false;
335 allowUserInput = true;
340 PlaySound(IDW_CARDKNOCK);
341 gameBoard->Pause(300);
342 PlaySound(IDW_SHUFFLE);
348 void MainWin::OnGameOptions(void)
352 dlg.m_cardBack = nCardBack - BACK1;
353 dlg.m_nBackground = m_nBackground;
354 dlg.m_bCheck1 = bSoundOn;
355 dlg.m_bCheck2 = m_bAnimationsOn;
356 dlg.m_bCheck3 = bAutoRemove;
357 dlg.m_bCheck4 = scoringOn;
358 dlg.m_bCheck5 = m_bCumulativeOn;
359 dlg.m_nRadio1 = m_bVegasStyle;
360 dlg.m_nRadio3 = m_bDrawThree;
364 if (dlg.exec() == QDialog::Rejected)
369 nCardBack = dlg.m_cardBack + BACK1;
370 m_nBackground = dlg.m_nBackground;
371 bSoundOn = (bool)dlg.m_bCheck1;
372 m_bAnimationsOn = (bool)dlg.m_bCheck2;
373 bAutoRemove = (bool)dlg.m_bCheck3;
374 m_bCumulativeOn = (bool)dlg.m_bCheck5;
376 // Reset game if Vegas Style/Draw Three changes at all...
377 bool bChanged = (bool)((m_bVegasStyle != (bool)dlg.m_nRadio1)
378 || (m_bDrawThree != (bool)dlg.m_nRadio3) || (scoringOn != (bool)dlg.m_bCheck4));
380 scoringOn = (bool)dlg.m_bCheck4;
381 m_bVegasStyle = (bool)dlg.m_nRadio1;
382 m_bDrawThree = (bool)dlg.m_nRadio3;
384 if (bChanged && m_bTouchedGame)
385 OnNewGame(); // Probably should warn of this...
387 gameBoard->CreateBackground();
392 void MainWin::OnGameStats(void)
396 /* dlg.m_nWins = m_nWins;
397 dlg.m_nLosses = m_nLosses;
398 dlg.m_nHiScore = m_nHiScore;
399 dlg.m_nVHiScore = m_nVHiScore;
400 dlg.m_nStreakW = m_nStreakW;
401 dlg.m_nStreakL = m_nStreakL;
402 dlg.m_nStreakC = m_nStreakC;*/
406 // Since it's possible to reset the stats, we grab the fields back here...
407 /* m_nWins = dlg.m_nWins;
408 m_nLosses = dlg.m_nLosses;
409 m_nHiScore = dlg.m_nHiScore;
410 m_nVHiScore = dlg.m_nVHiScore;
411 m_nStreakW = dlg.m_nStreakW;
412 m_nStreakL = dlg.m_nStreakL;
413 m_nStreakC = dlg.m_nStreakC;*/
417 void MainWin::OnundoAction(void)
421 for(int i=0; i<7; i++)
422 for(int j=0; j<20; j++)
423 solBoard[i][j] = solBoardUndo[i][j];
425 for(int i=0; i<24; i++)
426 stack1[i] = stack1Undo[i], stack2[i] = stack2Undo[i];
428 for(int i=0; i<4; i++)
429 nAce[i] = nAceUndo[i];
431 stack1p = stack1pUndo, stack2p = stack2pUndo;
432 m_nScore = m_nScoreUndo;
433 m_nExhaustedDeck = m_nExhaustedDeckUndo;
434 m_nNumToSplay = m_nNumToSplayUndo;
435 m_bShowX = m_bShowXUndo;
437 OnUpdateScore(m_nScore);
441 gameBoard->update(); // wil wok?
445 void MainWin::OnGamePlay(void)
447 // Play a card from discard deck...
448 //NOTE: can reduce size by eliminating duplicate code in OnLButtonDown...
451 if (stack1p == -1) // I.e. it's empty...
454 if ((m_bDrawThree && (m_nExhaustedDeck == 3))
455 || (!m_bDrawThree && (m_nExhaustedDeck == 1)))
459 m_nExhaustedDeck = 0;
460 m_nScore -= (m_bDrawThree ? 20 : 100);
465 OnUpdateScore(m_nScore);
469 if (!m_bVegasStyle || (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck < 3))
470 || (!m_bDrawThree && (m_nExhaustedDeck < 1)))))
472 for(; stack2p!=-1; stack2p--)
473 stack1[++stack1p] = stack2[stack2p];
477 PlaySound(IDW_CARDKNOCK);
485 for(int i=0; i<(m_bDrawThree ? 3 : 1); i++)
487 if (stack1p != -1) // I.e., there are cards left...
489 stack2[++stack2p] = stack1[stack1p--];
494 PlaySound(IDW_CARDFLIP);
496 gameBoard->Pause(55);
504 if (stack1p == -1) // This is done here because it's right!
508 if (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck == 3))
509 || (!m_bDrawThree && (m_nExhaustedDeck == 1))))
515 gameBoard->HandleAutoRemove();