--- /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);
+}
--- /dev/null
+#include <QtGui/QGraphicsView>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QVBoxLayout>
+#include "flipscene.h"
+#include "mainwidget.h"
+
+class MainWidgetPrivate
+{
+public:
+ MainWidgetPrivate(MainWidget *widget) : widget_(widget)
+ {
+ setupUi();
+ }
+
+ FlipScene *scene_;
+ MainWidget *widget_;
+ QGraphicsView *graphicsView_;
+ QLineEdit *columnEdit_;
+ QLineEdit *rowEdit_;
+ QPushButton *startButton_;
+
+private:
+ void setupUi()
+ {
+ widget_->setWindowTitle(QObject::tr("Flip"));
+
+ QHBoxLayout *layout = new QHBoxLayout(widget_);
+ layout->setAlignment(Qt::AlignCenter);
+
+ QVBoxLayout *leftLayout = new QVBoxLayout;
+ layout->addLayout(leftLayout);
+ leftLayout->addWidget(new QLabel(QObject::tr("Columns (2-9):")));
+ columnEdit_ = new QLineEdit;
+ columnEdit_->setInputMask("D");
+ leftLayout->addWidget(columnEdit_);
+ leftLayout->addWidget(new QLabel(QObject::tr("Rows (2-9):")));
+ rowEdit_ = new QLineEdit;
+ rowEdit_->setInputMask("D");
+ leftLayout->addWidget(rowEdit_);
+ startButton_ = new QPushButton(QObject::tr("Start"));
+ leftLayout->addWidget(startButton_);
+
+ scene_ = new FlipScene(widget_);
+ graphicsView_ = new QGraphicsView(scene_);
+ layout->addWidget(graphicsView_);
+ }
+};
+
+MainWidget::MainWidget(QWidget *parent) :
+ QWidget(parent),
+ d_(new MainWidgetPrivate(this))
+{
+ connect(d_->startButton_, SIGNAL(clicked()), this, SLOT(startGame()));
+ connect(d_->scene_, SIGNAL(win(int)), this, SLOT(winGame(int)));
+
+ d_->columnEdit_->setText("5");
+ d_->rowEdit_->setText("5");
+ startGame();
+}
+
+MainWidget::~MainWidget()
+{
+ delete d_;
+}
+
+void MainWidget::startGame()
+{
+ d_->scene_->setBoard(d_->columnEdit_->text().toInt(), d_->rowEdit_->text().toInt());
+}
+
+void MainWidget::winGame(int clicks)
+{
+ QMessageBox::information(NULL, tr("You Win!"),
+ tr(QString().sprintf("Congratulations! You made it with only %d clicks!", clicks).toLocal8Bit().data()));
+}