first commit
[flip] / src / flipscene.cpp
1 #include <QtGui/QPen>
2 #include <QtGui/QGraphicsPixmapItem>
3 #include <QtGui/QGraphicsSceneMouseEvent>
4 #include "flipscene.h"
5
6 struct Chess
7 {
8     QGraphicsPixmapItem *item_;
9     bool isWhite_;
10 };
11
12 class FlipScenePrivate
13 {
14 public:
15     static const int MAX_COLUMNS = 9;
16     static const int MAX_ROWS = 9;
17     static const int MIN_COLUMNS = 2;
18     static const int MIN_ROWS = 2;
19     static const int LATTICE_SIZE = 40;
20     static const int GRID_WIDTH = 2;
21     static const int CHESS_SIZE = 30;
22     static const QColor BACKGROUND_COLOR;
23     static const QColor LATTICE_COLOR;
24
25     Chess board_[MAX_COLUMNS][MAX_ROWS];
26     int column_;
27     int row_;
28     int clicks_;
29 };
30
31 const QColor FlipScenePrivate::BACKGROUND_COLOR = QColor(255, 241, 189);
32 const QColor FlipScenePrivate::LATTICE_COLOR = QColor(138, 48, 5);
33
34 FlipScene::FlipScene(QObject *parent) :
35     QGraphicsScene(parent),
36     d_(new FlipScenePrivate)
37 {
38     // do nothing
39 }
40
41 FlipScene::~FlipScene()
42 {
43     delete d_;
44 }
45
46 void FlipScene::setBoard(int column, int row)
47 {
48     clear();
49
50     d_->column_ = column;
51     d_->row_ = row;
52     d_->clicks_ = 0;
53
54     int width = FlipScenePrivate::LATTICE_SIZE * d_->column_;
55     int height = FlipScenePrivate::LATTICE_SIZE * d_->row_;
56
57     // draw the background
58     addRect(0, 0, width, height, QPen(d_->BACKGROUND_COLOR), QBrush(d_->BACKGROUND_COLOR));
59     setSceneRect(0, 0, width, height);
60
61     // draw the lattice grids
62     QPen pen(FlipScenePrivate::LATTICE_COLOR);
63     pen.setWidth(FlipScenePrivate::GRID_WIDTH);
64     int temp = 0;
65     for (int i = 0; i <= d_->column_; i++) {
66         addLine(temp, 0, temp, height, pen);
67         temp += FlipScenePrivate::LATTICE_SIZE;
68     }
69     temp = 0;
70     for (int i = 0; i <= d_->row_; i++) {
71         addLine(0, temp, width, temp, pen);
72         temp += FlipScenePrivate::LATTICE_SIZE;
73     }
74
75     // add the chessmen
76     QGraphicsPixmapItem *p = NULL;
77     QPixmap pixmap(":/imgs/white.png");
78     int x = (FlipScenePrivate::LATTICE_SIZE - FlipScenePrivate::CHESS_SIZE) >> 1;
79     int y = 0;
80     Chess chess;
81     for (int i = 0; i < d_->column_; i++) {
82         y = (FlipScenePrivate::LATTICE_SIZE - FlipScenePrivate::CHESS_SIZE) >> 1;
83         for (int j = 0; j < d_->row_; j++)
84         {
85             p = addPixmap(pixmap);
86             p->moveBy(x, y);
87             chess.isWhite_ = true;
88             chess.item_ = p;
89             d_->board_[i][j] = chess;
90             y += FlipScenePrivate::LATTICE_SIZE;
91         }
92         x += FlipScenePrivate::LATTICE_SIZE;
93     }
94 }
95
96 void FlipScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
97 {
98     QGraphicsPixmapItem *item = reinterpret_cast<QGraphicsPixmapItem*>(itemAt(mouseEvent->lastScenePos()));
99     for (int i = 0; i < d_->column_; i++) {
100         for (int j = 0; j < d_->row_; j++) {
101             if (item == d_->board_[i][j].item_) {
102                 d_->clicks_++;
103
104                 QPixmap black(":/imgs/black.png");
105                 QPixmap white(":/imgs/white.png");
106
107                 // flip
108                 d_->board_[i][j].isWhite_ = !d_->board_[i][j].isWhite_;
109                 d_->board_[i][j].item_->setPixmap((d_->board_[i][j].isWhite_) ? (white) : (black));
110
111                 if (i > 0) {
112                     d_->board_[i - 1][j].isWhite_ = !d_->board_[i - 1][j].isWhite_;
113                     d_->board_[i - 1][j].item_->setPixmap((d_->board_[i - 1][j].isWhite_) ? (white) : (black));
114                 }
115
116                 if (i < d_->column_ - 1) {
117                     d_->board_[i + 1][j].isWhite_ = !d_->board_[i + 1][j].isWhite_;
118                     d_->board_[i + 1][j].item_->setPixmap((d_->board_[i + 1][j].isWhite_) ? (white) : (black));
119                 }
120
121                 if (j > 0) {
122                     d_->board_[i][j - 1].isWhite_ = !d_->board_[i][j - 1].isWhite_;
123                     d_->board_[i][j - 1].item_->setPixmap((d_->board_[i][j - 1].isWhite_) ? (white) : (black));
124                 }
125
126                 if (j < d_->row_ - 1) {
127                     d_->board_[i][j + 1].isWhite_ = !d_->board_[i][j + 1].isWhite_;
128                     d_->board_[i][j + 1].item_->setPixmap((d_->board_[i][j + 1].isWhite_) ? (white) : (black));
129                 }
130
131                 // check if all turned to black
132                 for (int i2 = 0; i2 < d_->column_; i2++) {
133                     for (int j2 = 0; j2 < d_->row_; j2++) {
134                         if (d_->board_[i2][j2].isWhite_)
135                             return;
136                     }
137                 }
138                 emit win(d_->clicks_);
139                 return;
140             }
141         }
142     }
143
144     QGraphicsScene::mousePressEvent(mouseEvent);
145 }