first commit
[flip] / src / flipscene.cpp
diff --git a/src/flipscene.cpp b/src/flipscene.cpp
new file mode 100644 (file)
index 0000000..186e12f
--- /dev/null
@@ -0,0 +1,145 @@
+#include <QtGui/QPen>
+#include <QtGui/QGraphicsPixmapItem>
+#include <QtGui/QGraphicsSceneMouseEvent>
+#include "flipscene.h"
+
+struct Chess
+{
+    QGraphicsPixmapItem *item_;
+    bool isWhite_;
+};
+
+class FlipScenePrivate
+{
+public:
+    static const int MAX_COLUMNS = 9;
+    static const int MAX_ROWS = 9;
+    static const int MIN_COLUMNS = 2;
+    static const int MIN_ROWS = 2;
+    static const int LATTICE_SIZE = 40;
+    static const int GRID_WIDTH = 2;
+    static const int CHESS_SIZE = 30;
+    static const QColor BACKGROUND_COLOR;
+    static const QColor LATTICE_COLOR;
+
+    Chess board_[MAX_COLUMNS][MAX_ROWS];
+    int column_;
+    int row_;
+    int clicks_;
+};
+
+const QColor FlipScenePrivate::BACKGROUND_COLOR = QColor(255, 241, 189);
+const QColor FlipScenePrivate::LATTICE_COLOR = QColor(138, 48, 5);
+
+FlipScene::FlipScene(QObject *parent) :
+    QGraphicsScene(parent),
+    d_(new FlipScenePrivate)
+{
+    // do nothing
+}
+
+FlipScene::~FlipScene()
+{
+    delete d_;
+}
+
+void FlipScene::setBoard(int column, int row)
+{
+    clear();
+
+    d_->column_ = column;
+    d_->row_ = row;
+    d_->clicks_ = 0;
+
+    int width = FlipScenePrivate::LATTICE_SIZE * d_->column_;
+    int height = FlipScenePrivate::LATTICE_SIZE * d_->row_;
+
+    // draw the background
+    addRect(0, 0, width, height, QPen(d_->BACKGROUND_COLOR), QBrush(d_->BACKGROUND_COLOR));
+    setSceneRect(0, 0, width, height);
+
+    // draw the lattice grids
+    QPen pen(FlipScenePrivate::LATTICE_COLOR);
+    pen.setWidth(FlipScenePrivate::GRID_WIDTH);
+    int temp = 0;
+    for (int i = 0; i <= d_->column_; i++) {
+        addLine(temp, 0, temp, height, pen);
+        temp += FlipScenePrivate::LATTICE_SIZE;
+    }
+    temp = 0;
+    for (int i = 0; i <= d_->row_; i++) {
+        addLine(0, temp, width, temp, pen);
+        temp += FlipScenePrivate::LATTICE_SIZE;
+    }
+
+    // add the chessmen
+    QGraphicsPixmapItem *p = NULL;
+    QPixmap pixmap(":/imgs/white.png");
+    int x = (FlipScenePrivate::LATTICE_SIZE - FlipScenePrivate::CHESS_SIZE) >> 1;
+    int y = 0;
+    Chess chess;
+    for (int i = 0; i < d_->column_; i++) {
+        y = (FlipScenePrivate::LATTICE_SIZE - FlipScenePrivate::CHESS_SIZE) >> 1;
+        for (int j = 0; j < d_->row_; j++)
+        {
+            p = addPixmap(pixmap);
+            p->moveBy(x, y);
+            chess.isWhite_ = true;
+            chess.item_ = p;
+            d_->board_[i][j] = chess;
+            y += FlipScenePrivate::LATTICE_SIZE;
+        }
+        x += FlipScenePrivate::LATTICE_SIZE;
+    }
+}
+
+void FlipScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
+    QGraphicsPixmapItem *item = reinterpret_cast<QGraphicsPixmapItem*>(itemAt(mouseEvent->lastScenePos()));
+    for (int i = 0; i < d_->column_; i++) {
+        for (int j = 0; j < d_->row_; j++) {
+            if (item == d_->board_[i][j].item_) {
+                d_->clicks_++;
+
+                QPixmap black(":/imgs/black.png");
+                QPixmap white(":/imgs/white.png");
+
+                // flip
+                d_->board_[i][j].isWhite_ = !d_->board_[i][j].isWhite_;
+                d_->board_[i][j].item_->setPixmap((d_->board_[i][j].isWhite_) ? (white) : (black));
+
+                if (i > 0) {
+                    d_->board_[i - 1][j].isWhite_ = !d_->board_[i - 1][j].isWhite_;
+                    d_->board_[i - 1][j].item_->setPixmap((d_->board_[i - 1][j].isWhite_) ? (white) : (black));
+                }
+
+                if (i < d_->column_ - 1) {
+                    d_->board_[i + 1][j].isWhite_ = !d_->board_[i + 1][j].isWhite_;
+                    d_->board_[i + 1][j].item_->setPixmap((d_->board_[i + 1][j].isWhite_) ? (white) : (black));
+                }
+
+                if (j > 0) {
+                    d_->board_[i][j - 1].isWhite_ = !d_->board_[i][j - 1].isWhite_;
+                    d_->board_[i][j - 1].item_->setPixmap((d_->board_[i][j - 1].isWhite_) ? (white) : (black));
+                }
+
+                if (j < d_->row_ - 1) {
+                    d_->board_[i][j + 1].isWhite_ = !d_->board_[i][j + 1].isWhite_;
+                    d_->board_[i][j + 1].item_->setPixmap((d_->board_[i][j + 1].isWhite_) ? (white) : (black));
+                }
+
+                // check if all turned to black
+                for (int i2 = 0; i2 < d_->column_; i2++) {
+                    for (int j2 = 0; j2 < d_->row_; j2++) {
+                        if (d_->board_[i2][j2].isWhite_)
+                            return;
+                    }
+                }
+                emit win(d_->clicks_);
+                return;
+            }
+        }
+    }
+
+    QGraphicsScene::mousePressEvent(mouseEvent);
+}