color flooding, renames, fixes
authorSerge Ziryukin <ftrvxmtrx@gmail.com>
Tue, 13 Apr 2010 07:28:38 +0000 (10:28 +0300)
committerSerge Ziryukin <ftrvxmtrx@gmail.com>
Tue, 13 Apr 2010 07:28:38 +0000 (10:28 +0300)
colorflood/src/field.cpp
colorflood/src/field.hpp

index 26c3c66..6348d8f 100644 (file)
 #include <QTime>
 #include <QPainter>
 #include <QPaintEvent>
 #include <QTime>
 #include <QPainter>
 #include <QPaintEvent>
+#include <QMessageBox>
 #include "field.hpp"
 #include "colorscheme.hpp"
 
 static const int fieldWidth = 420;
 
 #include "field.hpp"
 #include "colorscheme.hpp"
 
 static const int fieldWidth = 420;
 
-const int Field::rects[Field::NUM_SIZES] = { 14, 21, 28 };
-const int Field::turns[Field::NUM_SIZES] = { 25, 35, 50 };
+const int Field::numRects[Field::NUM_SIZES] = { 14, 21, 28 };
+const int Field::numTurns[Field::NUM_SIZES] = { 25, 35, 50 };
 
 // we declare out QVector<FieldRect> metatype
 // and stream operators to save whole field to settings
 
 // we declare out QVector<FieldRect> metatype
 // and stream operators to save whole field to settings
@@ -59,9 +60,12 @@ static QDataStream &operator>> (QDataStream &in, Field::RectVector &rv)
     return in;
 }
 
     return in;
 }
 
-Field::Field (QWidget *parent)
-    : QWidget (parent)
+Field::Field (QWidget *parent, int *turns)
+    : QWidget (parent),
+      finished(false)
 {
 {
+    Q_ASSERT(parent);
+
     setFixedSize(fieldWidth, fieldWidth);
 
     // restore field size and field itself from settings
     setFixedSize(fieldWidth, fieldWidth);
 
     // restore field size and field itself from settings
@@ -71,7 +75,7 @@ Field::Field (QWidget *parent)
 
     QSettings settings;
 
 
     QSettings settings;
 
-    int size = settings.value("field/fieldSize", SIZE_SMALL).toInt();
+    int size = settings.value("field/size", SIZE_SMALL).toInt();
 
     if (size < SIZE_SMALL || size >= NUM_SIZES)
         size = SIZE_SMALL;
 
     if (size < SIZE_SMALL || size >= NUM_SIZES)
         size = SIZE_SMALL;
@@ -81,19 +85,28 @@ Field::Field (QWidget *parent)
     if (settings.contains("field/data"))
         data = settings.value("field/data").value<RectVector>();
 
     if (settings.contains("field/data"))
         data = settings.value("field/data").value<RectVector>();
 
-    if (data.size() != rects[size] * rects[size])
+    this->turns = settings.value("field/turns", 0).toInt();
+
+    if (data.size() != numRects[size] * numRects[size])
         randomize();
         randomize();
+
+    *turns = this->turns;
 }
 
 Field::~Field ()
 {
 }
 
 Field::~Field ()
 {
-    QSettings settings;
+    if (!finished)
+    {
+        QSettings settings;
+
+        settings.setValue("field/size", size);
 
 
-    settings.setValue("field/size", size);
+        QVariant v;
+        v.setValue(data);
+        settings.setValue("field/data", v);
 
 
-    QVariant v;
-    v.setValue(data);
-    settings.setValue("field/data", v);
+        settings.setValue("field/turns", turns);
+    }
 }
 
 Field::FieldSize Field::getSize () const
 }
 
 Field::FieldSize Field::getSize () const
@@ -107,7 +120,7 @@ void Field::randomize ()
     rect.flood = false;
 
     data.clear();
     rect.flood = false;
 
     data.clear();
-    data = RectVector(rects[size] * rects[size], rect);
+    data = RectVector(numRects[size] * numRects[size], rect);
 
     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
 
 
     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
 
@@ -120,22 +133,66 @@ void Field::randomize ()
         (*rect).brush = qrand() % numBrushes;
     }
 
         (*rect).brush = qrand() % numBrushes;
     }
 
+    turns = 0;
+    finished = false;
+    emit turnsChanged(turns);
+
+    // flood from top-left
+    data[0].flood = true;
+    floodNeighbours(data[0].brush, 0, 0);
+
     update();
 }
 
 int Field::getNumRectsOfSize (FieldSize size)
 {
     update();
 }
 
 int Field::getNumRectsOfSize (FieldSize size)
 {
-    return rects[size];
+    return numRects[size];
 }
 
 int Field::getNumTurnsOfSize (FieldSize size)
 {
 }
 
 int Field::getNumTurnsOfSize (FieldSize size)
 {
-    return turns[size];
+    return numTurns[size];
 }
 
 int Field::getRectSize (FieldSize size)
 {
 }
 
 int Field::getRectSize (FieldSize size)
 {
-    return fieldWidth / rects[size];
+    return fieldWidth / numRects[size];
+}
+
+void Field::tryFloodRecurse (quint8 brush, int x, int y)
+{
+    FieldRect &rect = data[x + y*numRects[size]];
+
+    if (!rect.flood && rect.brush == brush)
+    {
+        rect.flood = true;
+        floodNeighbours(brush, x, y);
+    }
+}
+
+void Field::floodNeighbours (quint8 brush, int x, int y)
+{
+    int s = numRects[size];
+
+    data[x + y*s].brush = brush;
+
+    if (x > 0)
+        tryFloodRecurse(brush, x - 1, y);
+
+    if (y > 0)
+        tryFloodRecurse(brush, x, y - 1);
+
+    if (x < s - 1)
+        tryFloodRecurse(brush, x + 1, y);
+        
+    if (y < s - 1)
+        tryFloodRecurse(brush, x, y + 1);
+}
+
+void Field::mousePressEvent (QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton)
+        randomize();
 }
 
 void Field::paintEvent (QPaintEvent *event)
 }
 
 void Field::paintEvent (QPaintEvent *event)
@@ -147,11 +204,11 @@ void Field::paintEvent (QPaintEvent *event)
 
     const QVector<QBrush> &scheme = ColorScheme::instance().getScheme();
 
 
     const QVector<QBrush> &scheme = ColorScheme::instance().getScheme();
 
-    for (int y = 0; y < rects[size] ;y++)
+    for (int y = 0; y < numRects[size] ;y++)
     {
     {
-        int n = y * rects[size];
+        int n = y * numRects[size];
 
 
-        for (int x = 0; x < rects[size] ;x++, n++)
+        for (int x = 0; x < numRects[size] ;x++, n++)
         {
             rect.moveTo(x * rect.width(), y * rect.height());
 
         {
             rect.moveTo(x * rect.width(), y * rect.height());
 
@@ -162,3 +219,60 @@ void Field::paintEvent (QPaintEvent *event)
 
     painter.end();
 }
 
     painter.end();
 }
+
+void Field::flood (int colorIndex)
+{
+    // don't fill with the same color over and over again
+    if (colorIndex == data[0].brush)
+        return;
+
+    if (finished)
+        return;
+
+    emit turnsChanged(++turns);
+
+    // flood with new color
+    for (int y = 0; y < numRects[size] ;y++)
+    {
+        int n = y * numRects[size];
+
+        for (int x = 0; x < numRects[size] ;x++, n++)
+        {
+            if (data[n].flood)
+                floodNeighbours(colorIndex, x, y);
+        }
+    }
+
+    update();
+
+    bool allFlooded = true;
+
+    // check if all field flooded
+    for (QVector<Field::FieldRect>::const_iterator rect = data.begin();
+         rect != data.end();
+         rect++)
+    {
+        if (!(*rect).flood)
+        {
+            allFlooded = false;
+            break;
+        }
+    }
+
+    if (allFlooded)
+    {
+        finished = true;
+
+        QMessageBox box;
+        box.setText(tr("You won!"));
+        box.exec();
+    }
+    else if (getNumTurnsOfSize(size) == turns)
+    {
+        finished = true;
+
+        QMessageBox box;
+        box.setText(tr("You lost!"));
+        box.exec();
+    }
+}
index 0d78d34..9009857 100644 (file)
@@ -19,6 +19,7 @@
 #include <QBrush>
 
 class QPaintEvent;
 #include <QBrush>
 
 class QPaintEvent;
+class QMouseEvent;
 
 class Field : public QWidget
 {
 
 class Field : public QWidget
 {
@@ -41,27 +42,37 @@ public:
 
     typedef QVector<Field::FieldRect> RectVector;
 
 
     typedef QVector<Field::FieldRect> RectVector;
 
-    Field (QWidget *parent);
+    Field (QWidget *parent, int *turns);
     ~Field ();
 
     FieldSize getSize () const;
     ~Field ();
 
     FieldSize getSize () const;
-    void randomize ();
 
     static int getNumRectsOfSize (FieldSize size);
     static int getNumTurnsOfSize (FieldSize size);
 
 private:
 
     static int getNumRectsOfSize (FieldSize size);
     static int getNumTurnsOfSize (FieldSize size);
 
 private:
-    static const int rects[NUM_SIZES];
-    static const int turns[NUM_SIZES];
+    static const int numRects[NUM_SIZES];
+    static const int numTurns[NUM_SIZES];
 
 
-    void init (const QVector<QBrush> &brushes, FieldSize size);
+    void randomize ();
     static int getRectSize (FieldSize size);
     static int getRectSize (FieldSize size);
+    void tryFloodRecurse (quint8 brush, int x, int y);
+    void floodNeighbours (quint8 brush, int x, int y);
 
     FieldSize  size;
     RectVector data;
 
     FieldSize  size;
     RectVector data;
+    int        turns;
+    bool       finished;
 
 protected:
 
 protected:
+    void mousePressEvent (QMouseEvent *event);
     void paintEvent (QPaintEvent *event);
     void paintEvent (QPaintEvent *event);
+
+signals:
+    void turnsChanged (int turns);
+
+public slots:
+    void flood (int colorIndex);
 };
 
 #endif // !_FIELD_HPP
 };
 
 #endif // !_FIELD_HPP