diff options
Diffstat (limited to 'q15/src/gameboard.cpp')
-rw-r--r-- | q15/src/gameboard.cpp | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/q15/src/gameboard.cpp b/q15/src/gameboard.cpp new file mode 100644 index 00000000..d973e4e8 --- /dev/null +++ b/q15/src/gameboard.cpp @@ -0,0 +1,450 @@ +/* + * $Id: gameboard.cpp,v 0.1 2005/08/14 12:10:05 denis Exp $ + * + * Author: Denis Kozadaev (denis@tambov.ru) + * Description: + * + * See also: style(9) + * + * Hacked by: + */ + +#include <stdlib.h> + +#if QT_VERSION >= 0x040000 +#include <QtGui/QApplication> +#include <QtGui/QPainter> +#include <QtGui/QCursor> +#include <QtGui/QMessageBox> +#include <QtGui/QFileDialog> +#include <QtCore/QDateTime> +#else +#include <ntqapplication.h> +#include <ntqpainter.h> +#include <ntqcursor.h> +#include <ntqmessagebox.h> +#include <ntqfiledialog.h> +#include <ntqdatetime.h> +#include <ntqwmatrix.h> +#endif + +#include "gameboard.h" + + +#define DELAY 10 +#define STEP 5 + + +#if QT_VERSION >= 0x040000 +BoardItem::BoardItem(int n, QWidget *parent) + :QLabel(parent) +#else +BoardItem::BoardItem(int n, TQWidget *parent, const char *name) + :TQLabel(parent, name) +#endif +{ + + num = n; +} + +BoardItem::~BoardItem() +{ +} + + +void +BoardItem::paintEvent(TQPaintEvent *e) +{ + TQPainter *p; + int w = width() - 1, + h = height() - 1; + + TQLabel::paintEvent(e); + p = new TQPainter(this); + + p->setPen(TQt::black); + p->drawRect(0, 0, w, h); + p->setPen(TQt::magenta); + p->drawText(0, 0, w, h, TQt::AlignCenter, + TQString::number(item() + 1)); + + delete p; +} + +//------------------------------------------------------------------------------ + +#if QT_VERSION >= 0x040000 +GameBoard::GameBoard(QWidget *parent) + :QWidget(parent) +#else +GameBoard::GameBoard(TQWidget *parent, const char *name) + :TQWidget(parent, name) +#endif +{ +#include "cat.xpm" + TQPixmap xpm(cat_xpm); + + memset(map, 0, sizeof(map)); + nt = n = xt = yt = -1; + dx = dy = 0; + + tmr = new TQTimer(this); + TQObject::connect(tmr, SIGNAL(timeout()), this, SLOT(moveItem())); + setEnabled(FALSE); + origin = xpm; +} + +GameBoard::~GameBoard() +{ + int i; + + for (i = 0; i < 16; ++i) + if (map[i] != NULL) + delete map[i]; + + delete tmr; +} + + +void +GameBoard::resizeEvent(TQResizeEvent *e) +{ + + TQWidget::resizeEvent(e); + initMap(); +} + + +void +GameBoard::initMap() +{ + const int num = 15; + int i, x, y, + w = width() / 4, + h = height() / 4; + TQFont fnt("Antiqua", 18); + TQPixmap xpm; + + if (!origin.isNull()) { +#if QT_VERSION >= 0x040000 + xpm = origin.scaled(width(), height(), + Qt::KeepAspectRatioByExpanding); +#else + TQWMatrix mtx; + mtx.scale((float)width() / (float)origin.width(), + (float)height() / (float)origin.height()); + xpm = origin.xForm(mtx); +#endif + } + + for (i = 0; i < num; ++i) { + if (map[i] != NULL) + delete map[i]; + map[i] = new BoardItem(i, this); + map[i]->setFont(fnt); + map[i]->resize(w, h); + map[i]->setAlignment(TQt::AlignCenter); + if (!xpm.isNull()) { + y = (i >> 2); + x = i - (y << 2); + map[i]->move(x * w, y * h); +#if QT_VERSION >= 0x040000 + map[i]->setPixmap(xpm.copy(map[i]->x(), map[i]->y(), + w, h)); +#else + TQPixmap xpm1(map[i]->size()); + copyBlt(&xpm1, 0, 0, &xpm, + map[i]->x(), map[i]->y(), w, h); + map[i]->setPixmap(xpm1); +#endif + } + } + if (map[num] != NULL) + delete map[num]; + map[num] = NULL; +} + + +void +GameBoard::mousePressEvent(TQMouseEvent *e) +{ + int x = e->x(), + y = e->y(), + i, it; + + i = index(x, y); + if (mayMove(i) && (n == -1)) { + for (it = 0; (it < 16) && (map[it] != NULL); ++it); + startMoving(i, it); + } +} + + +int +GameBoard::mayMove(int n) +{ + int res = 0; + + if ((n >= 0) && (n < 16)) { + switch (n) { + case 0: + res = (map[n + 1] == NULL) || + (map[n + 4] == NULL); + break; + + case 1: + case 2: + res = (map[n - 1] == NULL) || + (map[n + 1] == NULL) || + (map[n + 4] == NULL); + break; + + case 3: + res = (map[n - 1] == NULL) || + (map[n + 4] == NULL); + break; + + case 4: + case 8: + res = (map[n + 1] == NULL) || + (map[n - 4] == NULL) || + (map[n + 4] == NULL); + break; + + case 5: + case 6: + case 9: + case 10: + res = (map[n - 1] == NULL) || + (map[n + 1] == NULL) || + (map[n - 4] == NULL) || + (map[n + 4] == NULL); + break; + + case 7: + case 11: + res = (map[n - 1] == NULL) || + (map[n - 4] == NULL) || + (map[n + 4] == NULL); + break; + + case 12: + res = (map[n + 1] == NULL) || + (map[n - 4] == NULL); + break; + + case 13: + case 14: + res = (map[n - 1] == NULL) || + (map[n + 1] == NULL) || + (map[n - 4] == NULL); + break; + + case 15: + res = (map[n - 1] == NULL) || + (map[n - 4] == NULL); + break; + } + } + + return (res); +} + + +int +GameBoard::index(int x, int y) +{ + int ndx = -1, + i, x1, y1; + + if ((map[0] != NULL) || (map[1] != NULL)) { + for (i = 0; i < 16; ++i) { + if (map[i] != NULL) { + x1 = map[i]->x(); + y1 = map[i]->y(); + if ((x >= x1) && (y >= y1) && + (x < (x1 + map[i]->width())) && + (y < (y1 + map[i]->height()))) { + ndx = i; + break; + } + } + } + } + + return (ndx); +} + + +void +GameBoard::startMoving(int i, int t) +{ + + n = i; nt = t; + xt = (t - (t & ~3)) * map[n]->width(); + yt = (t >> 2) * map[n]->height(); + dx = step(xt, map[n]->x()); + dy = step(yt, map[n]->y()); + tmr->start(DELAY); + TQApplication::setOverrideCursor(TQCursor(TQt::WaitCursor)); +} + + +int +GameBoard::step(int t, int f) +{ + int res; + + if (t > f) + res = STEP; + else if (t < f) + res = -STEP; + else + res = 0; + + return (res); +} + + +void +GameBoard::moveItem() +{ + int x, y, stp, a; + + if ((n != -1) && (nt != -1) && (map[n] != NULL)) { + x = map[n]->x(); + y = map[n]->y(); + stp = 0; + if (dx != 0) { + stp = (x == xt); + if (!stp) { + a = abs(x - xt); + if (a < abs(dx)) + dx = sign(dx) * a; + x += dx; + } + } else if (dy != 0) { + stp = (y == yt); + if (!stp) { + a = abs(y - yt); + if (a < abs(dy)) + dy = sign(dy) * a; + y += dy; + } + } + map[n]->move(x, y); + if (stp) { + map[nt] = map[n]; + map[n] = NULL; + nt = n = -1; + xt = yt = -1; + dx = dy = 0; + tmr->stop(); + TQApplication::restoreOverrideCursor(); + checkEndGame(); + } + } +} + +int +GameBoard::sign(int x) +{ + int res; + + if (x > 0) + res = 1; + else if (x < 0) + res = -1; + else + res = 0; + + return (res); +} + + +void +GameBoard::checkEndGame() +{ + int i, n; + TQString txt; + + for (n = i = 0; i < 15; ++i) + if ((map[i] != NULL) && (map[i]->item() == i)) + n++; + if (n == 15) { + txt = tr("Game Over"); + TQMessageBox::information(this, txt, txt); + setEnabled(FALSE); + } +} + + +void +GameBoard::newGame() +{ + + setEnabled(TRUE); + initMap(); + newTask(); +} + + +void +GameBoard::newTask() +{ + int i, n, stp, x, y; + BoardItem *tmp; + + srandom(TQDateTime::currentDateTime().toTime_t()); + do { + stp = (random() % 13) & 0xF; + if ((stp & 1) == 0) + stp++; + } while (stp % 5 == 0); + + n = random() & 0xF; + + for (i = 0; i < 16; ++i) { + n += stp; + if (n > 15) + n -= 16; + tmp = map[i]; + map[i] = map[n]; + map[n] = tmp; + } + + for (i = 0; i < 16; ++i) + if (map[i] != NULL) { + y = (i >> 2); + x = i - (y << 2); + map[i]->move(x * map[i]->width(), y * map[i]->height()); + map[i]->show(); + } +} + + +void +GameBoard::loadImage() +{ + TQString str; + TQPixmap img; + +#if QT_VERSION >= 0x040000 + str = QFileDialog::getOpenFileName(this, tr("Open an image..."), + QString::null, "*"); +#else + str = TQFileDialog::getOpenFileName(TQString::null, "*", this, NULL, + tr("Open an image...")); +#endif + + if (!str.isEmpty()) { + if (img.load(str)) { + origin = img; + initMap(); + } else + TQMessageBox::critical(this, tr("Error loading..."), + tr("Cannot load the image ") + str); + } +} + +#include "gameboard.moc" |