Makefile
warehousemandeluxe
res/*.xcf
+pix/
\ No newline at end of file
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>wmd-icon.png</file>
+ <file>bg_marble_g.bmp</file>
</qresource>
</RCC>
};
+static const struct {
+ unsigned int width, height;
+ unsigned char state[9 * 7 + 1]; } board013 = { 9, 7,
+ " @@@@@ "
+ "@@@@ @@"
+ "@ X X X @"
+ "@o......@"
+ "@ X X X @"
+ "@@@@ @@"
+ " @@@@@ "
+};
+
+
+static const struct {
+ unsigned int width, height;
+ unsigned char state[8 * 7 + 1]; } board014 = { 8, 7,
+ " @@@@@ "
+ "@@@ o@ "
+ "@ X. @@"
+ "@ .X. @"
+ "@@@ +X @"
+ " @ @@"
+ " @@@@@ "
+};
+
+
+static const struct {
+ unsigned int width, height;
+ unsigned char state[8 * 7 + 1]; } board015 = { 8, 7,
+ "@@@@@@@ "
+ "@ .X. @@"
+ "@ X X @"
+ "@ .X. @"
+ "@ @@@ @@"
+ "@ o @ "
+ "@@@@@@@ "
+};
+
+
+static const struct {
+ unsigned int width, height;
+ unsigned char state[10 * 7 + 1]; } board016 = { 10, 7,
+ " @@@@@@ "
+ " @@@ @ "
+ "@@. X@@ @@"
+ "@..X X o@"
+ "@.. X X @@"
+ "@@@@@@ @ "
+ " @@@@ "
+};
+
+
+static const struct {
+ unsigned int width, height;
+ unsigned char state[7 * 7 + 1]; } board017 = { 7, 7,
+ " @@@@@ "
+ "@@ . @@"
+ "@ X.X @"
+ "@ .Xo@"
+ "@ X.X @"
+ "@@ . @@"
+ " @@@@@ "
+};
+
+
+static const struct {
+ unsigned int width, height;
+ unsigned char state[12 * 6 + 1]; } board018 = { 12, 6,
+ " @@@@@@@@@@ "
+ "@@ @o @@"
+ "@ X ....X @"
+ "@ X@@@@ X @"
+ "@ @ @ @@"
+ "@@@@@ @@@@ "
+};
+
+
const void * boards[] = {
&board001, &board002, &board003, &board004, &board005, &board006, &board007, &board008,
- &board009, &board010, &board011, &board012, //&board013, &board014, &board015, &board016,
+ &board009, &board010, &board011, &board012, &board013, &board014, &board015, &board016,
+ &board017, &board018, //&board019, &board020, &board021, &board022, &board023, &board024,
};
unsigned char state[]; // Board data
};
-#define NUMBER_OF_BOARDS 12
+#define NUMBER_OF_BOARDS 18
extern const void * boards[];
#endif // __BOARDS_H__
{
memcpy(board, initialBoard, boardLength);
playerX = initialX, playerY = initialY;
+ numMoves = 0;
}
char cell1 = board[playerX + ((playerY - 1) * width)] & ~GTBoxSpot;
char cell2 = board[playerX + ((playerY - 2) * width)] & ~GTBoxSpot;
- return Move(playerY, -1, cell1, cell2);
+ return Move(0, -1, cell1, cell2);
}
char cell1 = board[playerX + ((playerY + 1) * width)] & ~GTBoxSpot;
char cell2 = board[playerX + ((playerY + 2) * width)] & ~GTBoxSpot;
- return Move(playerY, +1, cell1, cell2);
+ return Move(0, +1, cell1, cell2);
}
char cell1 = board[(playerX + 1) + (playerY * width)] & ~GTBoxSpot;
char cell2 = board[(playerX + 2) + (playerY * width)] & ~GTBoxSpot;
- return Move(playerX, +1, cell1, cell2);
+ return Move(+1, 0, cell1, cell2);
}
char cell1 = board[(playerX - 1) + (playerY * width)] & ~GTBoxSpot;
char cell2 = board[(playerX - 2) + (playerY * width)] & ~GTBoxSpot;
- return Move(playerX, -1, cell1, cell2);
+ return Move(-1, 0, cell1, cell2);
}
-int GameBoard::Move(int & var, int direction, char cell1, char cell2)
+int GameBoard::Move(int dx, int dy, char cell1, char cell2)
{
// Player is moving into an unoccupied space...
if (cell1 == GTSpace)
{
- var += direction;
+// var += direction;
+ playerX += dx, playerY += dy;
+ undo[numMoves].dx = dx, undo[numMoves].dy = dy, undo[numMoves].type = PMWalk;
+ numMoves++;
return PMWalk;
}
// Player is pushing a box into an unoccupied space...
else if ((cell1 == GTBox) && (cell2 == GTSpace))
{
- var += direction;
+// var += direction;
+ playerX += dx, playerY += dy;
board[playerX + (playerY * width)] &= GTBoxSpot;
- var += direction;
+// var += direction;
+ playerX += dx, playerY += dy;
board[playerX + (playerY * width)] |= GTBox;
- var -= direction;
+// var -= direction;
+ playerX -= dx, playerY -= dy;
+ undo[numMoves].dx = dx, undo[numMoves].dy = dy, undo[numMoves].type = PMPush;
+ numMoves++;
return PMPush;
}
}
+bool GameBoard::UndoLastMove(int & dx, int & dy, int & type)
+{
+ if (numMoves == 0)
+ return false;
+
+ numMoves--;
+ dx = undo[numMoves].dx;
+ dy = undo[numMoves].dy;
+ type = undo[numMoves].type;
+
+ // Undo the box's move (if any)
+ if (type == PMPush)
+ {
+ int boxPosition = (playerX + dx) + ((playerY + dy) * width);
+ int newBoxPosition = playerX + (playerY * width);
+
+ board[boxPosition] &= GTBoxSpot;
+// board[newBoxPosition] &= GTBoxSpot; // This is extraneous
+ board[newBoxPosition] |= GTBox;
+ }
+
+ // Undo the player's move
+ playerX += -dx;
+ playerY += -dy;
+
+ return true;
+}
+
enum { GTSpace=0x00, GTWall=0x01, GTBox=0x02, GTBoxSpot=0x04 };
enum { PMInvalid, PMWalk, PMPush };
+struct UndoMove
+{
+ int dx, dy, type;
+};
+
class GameBoard
{
public:
bool IsBoxSOfPlayer(void);
bool IsBoxEOfPlayer(void);
bool IsBoxWOfPlayer(void);
+ bool UndoLastMove(int &, int &, int &);
private:
- int Move(int & var, int direction, char, char);
+ int Move(int dx, int dy, char, char);
public:
int playerX, playerY; // Player X/Y are zero-based
char * initialBoard;
int initialX, initialY;
int boardLength;
+ int numMoves;
+ UndoMove undo[8192]; // 8K moves ought to be enough for anybody
};
#endif // __GAMEBOARD_H__
animating(false), boxMoving(false)
// score(new QLabel)
{
+ CreateBackground();
// score->setTextFormat(Qt::PlainText);
- setFixedSize(580, 520);
+// setFixedSize(580, 520);
// gameBoard = new GameBoard(1);
}
// QRect rcUpdate = dc.m_ps.rcPaint; // Update rect...
// QRect rcUpdate = QRect(0, 0, 580, 520); // Update rect?
- maxLength = 60;
+ painter.translate(QPoint(offsetX, offsetY));
+// maxLength = 60;
int ptr = 0;
for(int y=0; y<gameBoard->height; y++)
int tile = gameBoard->board[ptr++];
painter.setPen(QPen(Qt::black, 2.0, Qt::SolidLine));
painter.setBrush(QBrush(Qt::black));
+ int tileType = tile & (~GTBoxSpot);
- if (tile == GTWall)
+ if (tileType == GTWall)
{
painter.setBrush(QBrush(Qt::white));
painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
}
- else if (tile == GTBox)
+ else if ((tileType == GTBox)
+ && (!(boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
{
- if (!(boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y)))
- {
- painter.setBrush(QBrush(Qt::red));
- painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
- }
+ painter.setBrush(QBrush(tile & GTBoxSpot ? Qt::green : Qt::red));
+ painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
}
+#if 0
else if (tile == GTBoxSpot)
{
painter.setBrush(QBrush(Qt::magenta));
- painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
+// painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
+ painter.drawRect((x * maxLength) + (int)(20.0/60.0*(float)maxLength), (y * maxLength) + (int)(20.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength));
}
else if (tile == (GTBox | GTBoxSpot))
{
else
{
painter.setBrush(QBrush(Qt::magenta));
- painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
+// painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
+ painter.drawRect((x * maxLength) + (int)(20.0/60.0*(float)maxLength), (y * maxLength) + (int)(20.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength));
+ }
+ }
+#endif
+ else if ((tileType == GTSpace)
+ || ((tileType == GTBox) && (boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
+ {
+ painter.setBrush(QBrush(QPixmap(":/bg_marble_g.bmp")));
+ painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
+
+ if (tile & GTBoxSpot)
+ {
+ painter.setBrush(QBrush(Qt::magenta));
+// painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
+ painter.drawRect((x * maxLength) + (int)(20.0/60.0*(float)maxLength), (y * maxLength) + (int)(20.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength));
}
}
if ((gameBoard->playerX == x) && (gameBoard->playerY == y) && !animating)
{
painter.setBrush(QBrush(Qt::yellow));
- painter.drawEllipse((x * maxLength) + 10, (y * maxLength) + 10, maxLength - 20, maxLength - 20);
+// painter.drawEllipse((x * maxLength) + 10, (y * maxLength) + 10, maxLength - 20, maxLength - 20);
+ painter.drawEllipse((x * maxLength) + (int)(10.0/60.0*(float)maxLength), (y * maxLength) + (int)(10.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength));
}
}
if (animating)
{
painter.setBrush(QBrush(Qt::yellow));
- painter.drawEllipse(playerX + 10, playerY + 10, maxLength - 20, maxLength - 20);
+// painter.drawEllipse(playerX + 10, playerY + 10, maxLength - 20, maxLength - 20);
+ painter.drawEllipse(playerX + (int)(10.0/60.0*(float)maxLength), playerY + (int)(10.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength));
}
if (boxMoving)
painter.drawRect(boxX, boxY, maxLength, maxLength);
}
}
-
-
-#if 0
- DrawBoard(&painter, rcUpdate);
-
- // Draw the "loose" cards....
-
- if (hitStack)
- {
- for(int i=stackStart.y(); i<19; i++)
- {
- int card = solBoard[stackStart.x()][i];
-
- if (card != -1)
- {
- if (solBoard[stackStart.x()][i + 1] == -1) // Draw full card
- cdtDraw(&painter, stackPos.x(), stackPos.y() + ((i - stackStart.y()) * 18),
- myDeck.GetCardAtPos(card), FACEUP);
- else // Draw partial card
- cdtDraw(&painter, stackPos.x(), stackPos.y() + ((i - stackStart.y()) * 18),
- myDeck.GetCardAtPos(card), FACEUP, 20);
- }
- }
- }
-
- if (hitDiscard)
- cdtDraw(&painter, stackPos.x(), stackPos.y(), myDeck.GetCardAtPos(stack2[stack2p]),
- FACEUP);
-
- if (nHitAce != 0)
- cdtDraw(&painter, stackPos.x(), stackPos.y(), nAce[nHitAce - 1], FACEUP);
-
- if (m_bFreeCard) // For card animations...
- {
- for(SCardInfo * pCard=m_pFirstCard; pCard; pCard=pCard->pNext)
- cdtDraw(&painter, pCard->nXPos, pCard->nYPos, pCard->nCard, FACEUP);
- }
-#endif
}
{
if (event->button() == Qt::LeftButton)
{
-// OnLButtonDown(event->pos());
event->accept();
}
}
{
if (event->buttons() & Qt::LeftButton)
{
-// OnMouseMove(event->pos());
event->accept();
}
}
{
if (event->button() == Qt::LeftButton)
{
-// OnLButtonUp(event->pos());
event->accept();
}
}
{
if (event->button() == Qt::LeftButton)
{
-// OnLButtonDblClk(event->pos());
event->accept();
}
}
return;
animating = true;
- update();
+// update();
if (boxMoving)
{
}
-void GameWidget::keyReleaseEvent(QKeyEvent * event)
+void GameWidget::keyReleaseEvent(QKeyEvent * /*event*/)
{
}
-void GameWidget::NextLevel(void)
+void GameWidget::resizeEvent(QResizeEvent * /*event*/)
{
- level++;
- delete gameBoard;
- gameBoard = new GameBoard(level);
- update();
-}
+// QSize s = event->size();
+//printf("Size of window is: %i x %i\n", s.width(), s.height());
+//printf("Size of game grid is: %i x %i\n", gameBoard->width, gameBoard->height);
+#if 0
+ // Find the constraints
+ float boxSizeX = s.width() / gameBoard->width;
+ float boxSizeY = s.height() / gameBoard->height;
-void GameWidget::ResetLevel(void)
-{
- gameBoard->ResetGame();
- update();
+ maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
+#else
+ ResizeGrid();
+#endif
}
-#if 0
-bool GameWidget::CreateBackground(void)
+void GameWidget::CreateBackground(void)
{
+#if 0
char BGRes[27][64] = {
":/res/grfttile.bmp",
":/res/cloth_6.bmp",
setPalette(pal);
return true; // Ignore errors for now...
+#else
+// QPalette pal = palette();
+// pal.setBrush(backgroundRole(), QBrush(QPixmap(":/bg_marble_g.bmp")));
+// setAutoFillBackground(true);
+// setPalette(pal);
+#endif
}
+void GameWidget::NextLevel(void)
+{
+ level++;
+ delete gameBoard;
+ gameBoard = new GameBoard(level);
+ ResizeGrid();
+ update();
+}
+
+
+void GameWidget::ResetLevel(void)
+{
+ gameBoard->ResetGame();
+ update();
+}
+
+
+void GameWidget::UndoLastMove(void)
+{
+ int dx, dy, type;
+
+ float deltaX = 0, deltaY = 0;
+ float px = (float)(gameBoard->playerX * maxLength);
+ float py = (float)(gameBoard->playerY * maxLength);
+ float bx = px, by = py;
+
+ // Return if nothing to undo
+ if (!gameBoard->UndoLastMove(dx, dy, type))
+ return;
+
+ deltaX = (float)-dx;
+ deltaY = (float)-dy;
+
+ if (type == PMPush)
+ boxMoving = true;
+
+ animating = true;
+// update();
+
+ if (boxMoving)
+ {
+// movingBoxPositionX = gameBoard->playerX + (int)deltaX;
+// movingBoxPositionY = gameBoard->playerY + (int)deltaY;
+ movingBoxPositionX = gameBoard->playerX + dx;
+ movingBoxPositionY = gameBoard->playerY + dy;
+// bx += deltaX * (float)maxLength;
+// by += deltaY * (float)maxLength;
+ bx += (float)(dx * maxLength);
+ by += (float)(dy * maxLength);
+ }
+
+ int steps = 15;
+ float stepSize = (float)maxLength / (float)steps;
+ deltaX *= stepSize, deltaY *= stepSize;
+
+ for(int i=0; i<steps; i++)
+ {
+ px += deltaX;
+ py += deltaY;
+ playerX = (int)px;
+ playerY = (int)py;
+ bx += deltaX;
+ by += deltaY;
+ boxX = (int)bx;
+ boxY = (int)by;
+ repaint();
+ Pause(3);
+ }
+
+ animating = boxMoving = false;
+ update();
+}
+
+
+#if 0
void GameWidget::DrawBoard(QPainter * painter, QRect r)
{
// Use "r" as clipping rect--only draw what's necessary
#endif
+void GameWidget::ResizeGrid(void)
+{
+ QSize s = size();
+
+ // Find the constraints
+ float boxSizeX = s.width() / gameBoard->width;
+ float boxSizeY = s.height() / gameBoard->height;
+
+ maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
+
+ offsetX = (s.width() - (maxLength * gameBoard->width)) / 2;
+ offsetY = (s.height() - (maxLength * gameBoard->height)) / 2;
+}
+
+
//
// Halt processing for 'count' milliseconds
//
void mouseDoubleClickEvent(QMouseEvent * event);
void keyPressEvent(QKeyEvent * event);
void keyReleaseEvent(QKeyEvent * event);
+ void resizeEvent(QResizeEvent * event);
signals:
void UpdateScore(int);
void GameWasWon(void);
public:
+ void CreateBackground(void);
void NextLevel(void);
void ResetLevel(void);
+ void UndoLastMove(void);
/*
void DrawBoard(QPainter * painter, QRect r);
- bool CreateBackground(void);
- void OnLButtonDown(QPoint point);
- void OnLButtonUp(QPoint point);
- void OnMouseMove(QPoint point);
- void OnLButtonDblClk(QPoint point);
void HandleAutoRemove(void);
void AnimateCards(int nCard, int nAce, int nTabX, int nTabY);
bool IsValidMoveToAce(int nAceM);
bool PlayerWon(void);
void HandleStatistics(void);*/
private:
+ void ResizeGrid(void);
void Pause(int);
public:
int boxX, boxY;
int movingBoxPositionX;
int movingBoxPositionY;
+ int offsetX, offsetY;
};
#endif // __GAMEWIDGET_H__
#include <stdlib.h> // For rand()
#include <time.h> // For time()
+#include "gameboard.h"
#include "gamewidget.h" // Actual mouse/drawing window
//#include "resource.h"
//#include "optiondlg.h" // Options dialog class
newGame = CreateAction(tr("&New"), tr("New Game"), tr("Start a new game of Warehouse Man Deluxe"), QIcon(), QKeySequence(tr("ctrl+n")));
// connect(newGame, SIGNAL(triggered()), this, SLOT(OnNewGame()));
- gamePlay = CreateAction(tr("&Play"), tr(""), tr(""), QIcon(), QKeySequence(tr("ctrl+a")));
-// connect(gamePlay, SIGNAL(triggered()), this, SLOT(OnGamePlay()));
-
- helpUndo = CreateAction(tr("&Undo"), tr(""), tr(""), QIcon(), QKeySequence(tr("ctrl+z")));
-// connect(helpUndo, SIGNAL(triggered()), this, SLOT(OnHelpUndo()));
+ undoAction = CreateAction(tr("&Undo"), tr(""), tr(""), QIcon(), QKeySequence(tr("ctrl+z")));
+ connect(undoAction, SIGNAL(triggered()), this, SLOT(HandleUndo()));
resetLevel = CreateAction(tr("&Reset Level"), tr("Reset Level"), tr("Start the current level over"), QIcon(), QKeySequence(tr("ctrl+r")));
- connect(resetLevel, SIGNAL(triggered()), this, SLOT(ResetCurrentLevel()));
+ connect(resetLevel, SIGNAL(triggered()), this, SLOT(HandleReset()));
+
+ skipLevel = CreateAction(tr("&Skip Level"), tr("Skip Level"), tr("Skip the current level"), QIcon(), QKeySequence(tr("ctrl+k")));
+ connect(skipLevel, SIGNAL(triggered()), this, SLOT(HandleSkipLevel()));
gameOptions = CreateAction(tr("&Options..."), tr("Options"), tr("Configure Warehouse Man Deluxe's options"), QIcon(), QKeySequence(tr("ctrl+o")));
// connect(gameOptions, SIGNAL(triggered()), this, SLOT(OnGameOptions()));
QMenu * menu = menuBar()->addMenu(tr("&Game"));
menu->addAction(newGame);
menu->addSeparator();
- menu->addAction(gamePlay);
- menu->addAction(helpUndo);
+// menu->addAction(gamePlay);
+ menu->addAction(undoAction);
menu->addAction(resetLevel);
+ menu->addAction(skipLevel);
menu->addSeparator();
menu->addAction(gameOptions);
menu->addAction(gameStats);
QSettings settings("Underground Software", "Warehouse Man Deluxe");
QPoint mainWinPosition = settings.value("pos", QPoint(200, 100)).toPoint();
move(mainWinPosition);
+ QSize mainWinSize = settings.value("size", QSize(500, 500)).toSize();
+ resize(mainWinSize);
/* nCardBack = settings.value("CardBack", BACK4).toInt();
m_nBackground = settings.value("Background", 0).toInt();
QSettings settings("Underground Software", "Warehouse Man Deluxe");
settings.setValue("pos", pos());
+ settings.setValue("size", size());
/*
settings.setValue("CardBack", nCardBack);
}
-void MainWin::ResetCurrentLevel(void)
+void MainWin::HandleReset(void)
{
gameWidget->ResetLevel();
}
+void MainWin::HandleSkipLevel(void)
+{
+ gameWidget->NextLevel();
+}
+
+
+void MainWin::HandleUndo(void)
+{
+ gameWidget->UndoLastMove();
+}
+
+
#if 0
void MainWin::OnNewGame(void)
{
}
-void MainWin::OnHelpUndo(void)
+void MainWin::OnundoAction(void)
{
if (m_bCanUndo)
{
protected slots:
void closeEvent(QCloseEvent * event);
-// void QuitGame(void);
void AboutGame(void);
void WeHaveAWinner(void);
- void ResetCurrentLevel(void);
+ void HandleReset(void);
+ void HandleSkipLevel(void);
+ void HandleUndo(void);
/* void OnNewGame(void);
void OnGameOptions(void);
void OnGameStats(void);
- void OnHelpUndo(void);
- void OnUpdateScore(int);
- void OnGamePlay(void);
- void OnAppAbout(void);*/
+ void OnUpdateScore(int);*/
private:
GameWidget * gameWidget;
QAction * newGame;
- QAction * gamePlay;
- QAction * helpUndo;
+ QAction * undoAction;
+
QAction * gameOptions;
QAction * gameStats;
+
QAction * appExit;
QAction * appAbout;
QAction * resetLevel;
+ QAction * skipLevel;
};
#endif // __MAINWIN_H__