--- /dev/null
+#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);
+}