big ugly commit
- renamed library - added support for saving loading current game - added (still crappy) nonogram solver - some code cleanups
This commit is contained in:
parent
6aa6b59c88
commit
8ebd6975d7
@ -22,7 +22,7 @@
|
|||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
//public:
|
//public:
|
||||||
CCrossPackage::CCrossPackage() {}
|
CCrossPackage::CCrossPackage() {}
|
||||||
CCrossPackage::CCrossPackage(QString fileName) : m_FileName(fileName) {}
|
CCrossPackage::CCrossPackage(QString fileName) : m_FileName(fileName) {}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CNonogram;
|
class CNonogram;
|
||||||
|
|
||||||
typedef QList<CNonogram *> QMonoPictureList;
|
typedef QList<CNonogram *> QMonoPictureList;
|
||||||
|
@ -22,10 +22,10 @@
|
|||||||
#include "cnonogram.h"
|
#include "cnonogram.h"
|
||||||
#include "ccrosspackagelistmodel.h"
|
#include "ccrosspackagelistmodel.h"
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
//public:
|
//public:
|
||||||
CCrossPackageListModel::CCrossPackageListModel(QString dataPath, QObject * parent) : QAbstractItemModel(parent),
|
CCrossPackageListModel::CCrossPackageListModel(QString dataPath, QString dataFilter, QObject * parent) : QAbstractItemModel(parent),
|
||||||
m_DataPath(dataPath) {
|
m_DataPath(dataPath), m_DataFilter(dataFilter) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ namespace libqcross {
|
|||||||
CCrossPackage * newPackage;
|
CCrossPackage * newPackage;
|
||||||
|
|
||||||
QDir workDir(m_DataPath);
|
QDir workDir(m_DataPath);
|
||||||
QStringList fileNames = workDir.entryList(QStringList("*.cpk"), QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
|
QStringList fileNames = workDir.entryList(QStringList(m_DataFilter), QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
|
||||||
foreach (QString fileName, fileNames) {
|
foreach (QString fileName, fileNames) {
|
||||||
newPackage = new CCrossPackage(workDir.filePath(fileName));
|
newPackage = new CCrossPackage(workDir.filePath(fileName));
|
||||||
if (newPackage->open())
|
if (newPackage->open())
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CCrossPackage;
|
class CCrossPackage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,7 +32,7 @@ namespace libqcross {
|
|||||||
class CCrossPackageListModel : public QAbstractItemModel {
|
class CCrossPackageListModel : public QAbstractItemModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CCrossPackageListModel(QString dataPath, QObject * parent = 0);
|
CCrossPackageListModel(QString dataPath, QString dataFilter, QObject * parent = 0);
|
||||||
~CCrossPackageListModel();
|
~CCrossPackageListModel();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
@ -47,8 +47,9 @@ namespace libqcross {
|
|||||||
virtual bool hasChildren(const QModelIndex & parent = QModelIndex()) const;
|
virtual bool hasChildren(const QModelIndex & parent = QModelIndex()) const;
|
||||||
private:
|
private:
|
||||||
QString m_DataPath;
|
QString m_DataPath;
|
||||||
|
QString m_DataFilter;
|
||||||
|
|
||||||
QList<libqcross::CCrossPackage *> m_PackageList;
|
QList<libqnono::CCrossPackage *> m_PackageList;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define COL_NAME 0
|
#define COL_NAME 0
|
||||||
#define COL_TIME 1
|
#define COL_TIME 1
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
QString formatedTime(quint32 seconds, bool showSeconds = false) {
|
QString formatedTime(quint32 seconds, bool showSeconds = false) {
|
||||||
quint32 strippedSeconds = seconds % 60;
|
quint32 strippedSeconds = seconds % 60;
|
||||||
quint8 minutes = seconds / 60;
|
quint8 minutes = seconds / 60;
|
||||||
@ -67,7 +67,7 @@ namespace libqcross {
|
|||||||
setPackage(NULL);
|
setPackage(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCrossPackageModel::setPackage(libqcross::CCrossPackage * package) {
|
void CCrossPackageModel::setPackage(libqnono::CCrossPackage * package) {
|
||||||
if (m_Package)
|
if (m_Package)
|
||||||
m_Package->pictures().clear();
|
m_Package->pictures().clear();
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CCrossPackage;
|
class CCrossPackage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +34,7 @@ namespace libqcross {
|
|||||||
CCrossPackageModel(QObject * parent = 0);
|
CCrossPackageModel(QObject * parent = 0);
|
||||||
~CCrossPackageModel();
|
~CCrossPackageModel();
|
||||||
|
|
||||||
void setPackage(libqcross::CCrossPackage * package);
|
void setPackage(libqnono::CCrossPackage * package);
|
||||||
|
|
||||||
virtual QModelIndex index(int row, int column = 0, const QModelIndex & parent = QModelIndex()) const;
|
virtual QModelIndex index(int row, int column = 0, const QModelIndex & parent = QModelIndex()) const;
|
||||||
virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||||
@ -53,7 +53,7 @@ namespace libqcross {
|
|||||||
virtual bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex());
|
virtual bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex());
|
||||||
virtual bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex());
|
virtual bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex());
|
||||||
protected:
|
protected:
|
||||||
libqcross::CCrossPackage * m_Package;
|
libqnono::CCrossPackage * m_Package;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "cnonogram.h"
|
#include "cnonogram.h"
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
CNonogram::CNonogram()
|
CNonogram::CNonogram()
|
||||||
: m_Size(0, 0),
|
: m_Size(0, 0),
|
||||||
m_Data(NULL),
|
m_Data(NULL),
|
||||||
@ -32,6 +32,14 @@ namespace libqcross {
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CNonogram::CNonogram(QImage & image) : m_Data(NULL), m_MaximumNumberCount(0) {
|
||||||
|
loadFromImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
CNonogram::CNonogram(QDataStream & stream) : m_Data(NULL), m_MaximumNumberCount(0) {
|
||||||
|
loadFromStream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
CNonogram::~CNonogram() {
|
CNonogram::~CNonogram() {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
@ -42,9 +50,24 @@ namespace libqcross {
|
|||||||
|
|
||||||
resize(image.size());
|
resize(image.size());
|
||||||
|
|
||||||
for (int i = 0; i < m_Size.width(); i++)
|
for (int iy = 0; iy < m_Size.height(); iy++)
|
||||||
for (int j = 0; j < m_Size.height(); j++)
|
for (int ix = 0; ix < m_Size.width(); ix++)
|
||||||
m_Data[i][j] = !(image.pixel(i, j) & 0x00FFFFFF);
|
m_Data[ix][iy] = !(image.pixel(ix, iy) & 0x00FFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNonogram::loadFromStream(QDataStream & stream) {
|
||||||
|
qDebug("loading picture from stream...");
|
||||||
|
stream >> m_Name; qDebug("m_Name = %s", qPrintable(m_Name));
|
||||||
|
int imageWidth, imageHeight;
|
||||||
|
stream >> imageWidth; qDebug("imageWidth = %i", imageWidth);
|
||||||
|
stream >> imageHeight; qDebug("imageHeight = %i", imageHeight);
|
||||||
|
resize(QSize(imageWidth, imageHeight));
|
||||||
|
|
||||||
|
stream >> m_Timeout;
|
||||||
|
|
||||||
|
for (int iy = 0; iy < m_Size.height(); iy++)
|
||||||
|
for (int ix = 0; ix < m_Size.width(); ix++)
|
||||||
|
stream >> m_Data[ix][iy];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNonogram::resize(QSize size) {
|
void CNonogram::resize(QSize size) {
|
||||||
@ -130,4 +153,23 @@ namespace libqcross {
|
|||||||
m_RowNumbers = new NumbersVector[m_Size.height()];
|
m_RowNumbers = new NumbersVector[m_Size.height()];
|
||||||
m_ColumnNumbers = new NumbersVector[m_Size.width()];
|
m_ColumnNumbers = new NumbersVector[m_Size.width()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDataStream & operator<<(QDataStream & stream, CNonogram & nonogram) {
|
||||||
|
stream << nonogram.name();
|
||||||
|
stream << nonogram.width();
|
||||||
|
stream << nonogram.height();
|
||||||
|
stream << nonogram.timeout();
|
||||||
|
|
||||||
|
for (int iy = 0; iy < nonogram.height(); iy++)
|
||||||
|
for (int ix = 0; ix < nonogram.width(); ix++)
|
||||||
|
stream << nonogram.pixel(ix, iy);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream & operator>>(QDataStream & stream, CNonogram & nonogram) {
|
||||||
|
nonogram.loadFromStream(stream);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2008 by Oliver Groß *
|
* Copyright (C) 2008 by Oliver Groß *
|
||||||
* z.o.gross@gmx.de *
|
* z.o.gross@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU General Public License as published by *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
@ -26,36 +26,40 @@
|
|||||||
|
|
||||||
class QImage;
|
class QImage;
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CNonogram {
|
class CNonogram {
|
||||||
public:
|
public:
|
||||||
typedef QVector<quint16> NumbersVector;
|
typedef QVector<quint16> NumbersVector;
|
||||||
|
|
||||||
CNonogram();
|
CNonogram();
|
||||||
CNonogram(QSize size);
|
CNonogram(QSize size);
|
||||||
|
CNonogram(QImage & image);
|
||||||
|
CNonogram(QDataStream & stream);
|
||||||
~CNonogram();
|
~CNonogram();
|
||||||
|
|
||||||
void loadFromImage(QImage & image);
|
void loadFromImage(QImage & image);
|
||||||
|
void loadFromStream(QDataStream & stream);
|
||||||
void resize(QSize size);
|
void resize(QSize size);
|
||||||
|
|
||||||
QString name() const { return m_Name; }
|
inline QString name() const { return m_Name; }
|
||||||
void setName(QString value) { m_Name = value; }
|
inline void setName(QString value) { m_Name = value; }
|
||||||
|
|
||||||
quint16 timeout() const { return m_Timeout; }
|
inline quint16 timeout() const { return m_Timeout; }
|
||||||
void setTimeout(quint16 value) { m_Timeout = value; }
|
void setTimeout(quint16 value) { m_Timeout = value; }
|
||||||
|
|
||||||
int width() const { return m_Size.width(); }
|
inline QSize size() const { return m_Size; }
|
||||||
int height() const { return m_Size.height(); }
|
inline int width() const { return m_Size.width(); }
|
||||||
|
inline int height() const { return m_Size.height(); }
|
||||||
|
|
||||||
bool pixel(int x, int y) const { return m_Data[x][y]; }
|
inline bool pixel(int x, int y) const { return m_Data[x][y]; }
|
||||||
void setPixel(int x, int y, bool value);
|
void setPixel(int x, int y, bool value);
|
||||||
|
|
||||||
NumbersVector & rowNumbers(int index) const { return m_RowNumbers[index]; }
|
NumbersVector & rowNumbers(int index) const { return m_RowNumbers[index]; }
|
||||||
NumbersVector & columnNumbers(int index) const { return m_ColumnNumbers[index]; }
|
NumbersVector & columnNumbers(int index) const { return m_ColumnNumbers[index]; }
|
||||||
|
|
||||||
int maximumNumberCount() const { return m_MaximumNumberCount; }
|
inline int maximumNumberCount() const { return m_MaximumNumberCount; }
|
||||||
|
|
||||||
quint32 blackPixels() const { return m_BlackPixels; }
|
inline quint32 blackPixels() const { return m_BlackPixels; }
|
||||||
|
|
||||||
void updateNumbers();
|
void updateNumbers();
|
||||||
|
|
||||||
@ -79,6 +83,9 @@ namespace libqcross {
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
void init();
|
void init();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QDataStream & operator<<(QDataStream & stream, CNonogram & nonogram);
|
||||||
|
QDataStream & operator>>(QDataStream & stream, CNonogram & nonogram);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,12 +1,65 @@
|
|||||||
#include "cnonogramsolver.h"
|
#include "cnonogramsolver.h"
|
||||||
#include "cnonogram.h"
|
#include "cnonogram.h"
|
||||||
|
|
||||||
namespace libqcross {
|
#include <QString>
|
||||||
CNonogramSolver::CNonogramSolver(QObject * parent) : QObject(parent), m_Nonogram(NULL), m_OverlayData(NULL) {
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace libqnono {
|
||||||
|
CNonogramSolver::CNonogramSolver(QObject * parent) : QObject(parent),
|
||||||
|
m_Nonogram(NULL),
|
||||||
|
|
||||||
|
m_RowsOverlay(NULL),
|
||||||
|
m_ColumnsOverlay(NULL),
|
||||||
|
|
||||||
|
m_OverlayData(NULL)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CNonogramSolver::~CNonogramSolver() {
|
CNonogramSolver::~CNonogramSolver() {
|
||||||
cleanup();
|
if (m_Nonogram)
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNonogramSolver::setNonogram(CNonogram * nonogram) {
|
||||||
|
if (m_Nonogram)
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
m_Nonogram = nonogram;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNonogramSolver::printOverlays() {
|
||||||
|
qDebug("row overlays:");
|
||||||
|
QString debugoutput;
|
||||||
|
for (int i = 0; i < m_Nonogram->height(); i++) {
|
||||||
|
if (i) debugoutput += '\n';
|
||||||
|
for (int e = 0; e < m_RowsOverlay[i].numbersSize; e++) {
|
||||||
|
debugoutput += ' ' + QString::number(m_RowsOverlay[i].numbers[e].borderLeft)
|
||||||
|
+ '-' + QString::number(m_RowsOverlay[i].numbers[e].borderRight - 1);
|
||||||
|
|
||||||
|
if (m_RowsOverlay[i].numbers[e].finished)
|
||||||
|
debugoutput += '*';
|
||||||
|
|
||||||
|
debugoutput += ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug(qPrintable(debugoutput));
|
||||||
|
|
||||||
|
debugoutput.clear();
|
||||||
|
|
||||||
|
qDebug("column overlays:");
|
||||||
|
for (int i = 0; i < m_Nonogram->width(); i++) {
|
||||||
|
if (i) debugoutput += '\n';
|
||||||
|
for (int e = 0; e < m_ColumnsOverlay[i].numbersSize; e++) {
|
||||||
|
debugoutput += ' ' + QString::number(m_ColumnsOverlay[i].numbers[e].borderLeft)
|
||||||
|
+ '-' + QString::number(m_ColumnsOverlay[i].numbers[e].borderRight - 1);
|
||||||
|
|
||||||
|
if (m_ColumnsOverlay[i].numbers[e].finished)
|
||||||
|
debugoutput += '*';
|
||||||
|
|
||||||
|
debugoutput += ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug(qPrintable(debugoutput));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNonogramSolver::solve() {
|
bool CNonogramSolver::solve() {
|
||||||
@ -14,52 +67,461 @@ namespace libqcross {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
prepare();
|
||||||
|
|
||||||
m_OverlayData = new int *[m_Nonogram->width()];
|
qDebug("clearing trivial lines ...");
|
||||||
for (int i = 0; i < m_Nonogram->width(); i++) {
|
|
||||||
m_OverlayData[i] = new int[m_Nonogram->height()];
|
// nach trivial lösbaren Reihen suchen und diese füllen bzw. abkreuzen
|
||||||
for (int j = 0; j < m_Nonogram->height(); j++)
|
for (int i = 0; i < m_Nonogram->height(); i++) {
|
||||||
m_OverlayData[i][j] = 0;
|
if (m_RowsOverlay[i].numbersSize == 1) {
|
||||||
|
if (m_RowsOverlay[i].numbers[0].entry == 0) {
|
||||||
|
fillRow(i, CMT_CROSSED);
|
||||||
|
m_RowsOverlay[i].numbers[0].finished = true;
|
||||||
|
}
|
||||||
|
else if (m_RowsOverlay[i].numbers[0].entry == m_Nonogram->height()) {
|
||||||
|
fillRow(i, CMT_MARKED);
|
||||||
|
m_RowsOverlay[i].numbers[0].finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < m_Nonogram->height(); i++)
|
for (int i = 0; i < m_Nonogram->width(); i++) {
|
||||||
solveRow(i);
|
if (m_ColumnsOverlay[i].numbersSize == 1) {
|
||||||
|
if (m_ColumnsOverlay[i].numbers[0].entry == 0) {
|
||||||
|
fillColumn(i, CMT_CROSSED);
|
||||||
|
m_ColumnsOverlay[i].numbers[0].finished = true;
|
||||||
|
}
|
||||||
|
else if (m_ColumnsOverlay[i].numbers[0].entry == m_Nonogram->width()) {
|
||||||
|
fillColumn(i, CMT_MARKED);
|
||||||
|
m_ColumnsOverlay[i].numbers[0].finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printOverlays();
|
||||||
|
|
||||||
|
qDebug("processing non-trivial lines...");
|
||||||
|
|
||||||
|
bool changed;
|
||||||
|
int iter = 0;
|
||||||
|
const int iter_max = 10;
|
||||||
|
do {
|
||||||
|
changed = false;
|
||||||
|
|
||||||
|
for (int l = 0; l < m_Nonogram->height(); l++)
|
||||||
|
if (solveLine_ng(l, true))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_Nonogram->width(); i++)
|
||||||
|
if (solveLine_ng(i, false))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
iter++;
|
||||||
|
} while (changed && iter < iter_max);
|
||||||
|
|
||||||
|
// qDebug("needed %i iterations", iter);
|
||||||
|
|
||||||
|
printOverlays();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CNonogramSolver::solveLine_ng(int index, bool isRow) {
|
||||||
|
LineOverlay * overlay = isRow ? &(m_RowsOverlay[index]) : &(m_ColumnsOverlay[index]);
|
||||||
|
int rightMax = isRow ? m_Nonogram->width() : m_Nonogram->height();
|
||||||
|
|
||||||
|
NumberOverlay * number;
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < overlay->numbersSize; i++) {
|
||||||
|
number = &(overlay->numbers[i]);
|
||||||
|
|
||||||
|
if (number->finished)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* |-start- null
|
||||||
|
*
|
||||||
|
* null -marked-> markierung
|
||||||
|
* null -crossed-> kreuze
|
||||||
|
* null -unmarked-> keine
|
||||||
|
*
|
||||||
|
* kreuze -marked-> markierung
|
||||||
|
* kreuze -crossed-> kreuze
|
||||||
|
* kreuze -unmarked-> keine
|
||||||
|
*
|
||||||
|
* keine -marked-> markierung
|
||||||
|
* keine -crossed-> kreuzstop
|
||||||
|
* keine -unmarked-> keine
|
||||||
|
*
|
||||||
|
* markierung -marked-> markierung
|
||||||
|
* markierung -crossed-> kreuzstop
|
||||||
|
* markierung -unmarked-> keine
|
||||||
|
*
|
||||||
|
* kreuzstop -stop-|
|
||||||
|
* fertig -stop-|
|
||||||
|
*
|
||||||
|
* null : keine aktion
|
||||||
|
* fertig : rechten rand stzen, als fertig markieren und stop
|
||||||
|
* kreuze : linken rand anpassen
|
||||||
|
* keine : keine aktion
|
||||||
|
*
|
||||||
|
* markierung : rechten rand anpassen
|
||||||
|
* kreuzstop : rechten rand setzen und stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
enum{ST_NULL = 0, ST_NONE = 1, ST_CROSSES = 2, ST_MARK = 3, ST_FINISHED = 4, ST_CROSS_STOP = 5} state = ST_NULL;
|
||||||
|
int f = number->borderLeft;
|
||||||
|
MarkerType marker;
|
||||||
|
while (f < number->borderRight && state < ST_FINISHED) {
|
||||||
|
marker = static_cast<MarkerType>(m_OverlayData[isRow ? f : index][isRow ? index : f]);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case ST_NULL:
|
||||||
|
case ST_CROSSES:
|
||||||
|
switch (marker) {
|
||||||
|
case CMT_MARKED: state = ST_MARK; break;
|
||||||
|
case CMT_CROSSED: state = ST_CROSSES; break;
|
||||||
|
case CMT_UNMARKED: state = ST_NONE; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_NONE:
|
||||||
|
case ST_MARK:
|
||||||
|
switch (marker) {
|
||||||
|
case CMT_MARKED: state = ST_MARK; break;
|
||||||
|
case CMT_CROSSED: state = ST_CROSS_STOP; break;
|
||||||
|
case CMT_UNMARKED: state = ST_NONE; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_FINISHED:
|
||||||
|
case ST_CROSS_STOP:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case ST_NONE:
|
||||||
|
case ST_NULL:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case ST_CROSSES:
|
||||||
|
number->borderLeft = f + 1;
|
||||||
|
break;
|
||||||
|
case ST_MARK:
|
||||||
|
if ((f < overlay->borderLeftDef(i + i, rightMax)) &&
|
||||||
|
(overlay->borderRightDef(i - 1, 0) < f) &&
|
||||||
|
(f + number->entry < number->borderRight))
|
||||||
|
number->borderRight = f + number->entry;
|
||||||
|
break;
|
||||||
|
case ST_FINISHED:
|
||||||
|
number->finished = true;
|
||||||
|
number->borderRight = f + number->entry;
|
||||||
|
if (i + 1 < overlay->numbersSize && overlay->numbers[i+1].borderLeft < number->borderRight + 1)
|
||||||
|
overlay->numbers[i+1].borderLeft = number->borderRight + 1;
|
||||||
|
break;
|
||||||
|
case ST_CROSS_STOP:
|
||||||
|
number->borderRight = f;
|
||||||
|
if (i + 1 < overlay->numbersSize && overlay->numbers[i+1].borderLeft < number->borderRight + 1)
|
||||||
|
overlay->numbers[i+1].borderLeft = number->borderRight + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sicher markierbare Steine
|
||||||
|
r - l < 2m - 1
|
||||||
|
0 < l + m - r + m - 1
|
||||||
|
0 < (l + m - 1) - (r - m)
|
||||||
|
*/
|
||||||
|
for (int k = number->borderRight - number->entry; k < number->borderLeft + number->entry; k++)
|
||||||
|
mark(isRow ? k : index, isRow ? index : k, CMT_MARKED);
|
||||||
|
|
||||||
|
if (!number->finished && number->borderRight - number->borderLeft == number->entry)
|
||||||
|
number->finished = true;
|
||||||
|
|
||||||
|
for (int g = overlay->borderRightDef(i - 1, 0); g < number->borderLeft; g++)
|
||||||
|
mark(isRow ? g : index, isRow ? index : g, CMT_CROSSED);
|
||||||
|
|
||||||
|
for (int g = number->borderRight; g < overlay->borderLeftDef(i + 1, rightMax); g++)
|
||||||
|
mark(isRow ? g : index, isRow ? index : g, CMT_CROSSED);
|
||||||
|
|
||||||
|
|
||||||
|
result = result || overlay->dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void CNonogramSolver::cleanup() {
|
void CNonogramSolver::cleanup() {
|
||||||
if (m_OverlayData && m_Nonogram) {
|
if (m_OverlayData) {
|
||||||
for (int i = 0; i < m_Nonogram->width(); i++)
|
for (int i = 0; i < m_Nonogram->width(); i++)
|
||||||
delete[] m_OverlayData[i];
|
delete[] m_OverlayData[i];
|
||||||
delete[] m_OverlayData;
|
delete[] m_OverlayData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_RowsOverlay)
|
||||||
|
delete[] m_RowsOverlay;
|
||||||
|
|
||||||
|
if (m_ColumnsOverlay)
|
||||||
|
delete[] m_ColumnsOverlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNonogramSolver::solveRow(int /*y*/) {
|
inline void CNonogramSolver::mark(int x, int y, int marker) {
|
||||||
return false;
|
if ((x < 0) || (y < 0) || (x > m_Nonogram->width() - 1) || (y > m_Nonogram->height() - 1) || m_OverlayData[x][y] == marker)
|
||||||
// int left = 0;
|
return;
|
||||||
// int right = m_Nonogram->width()-1;
|
|
||||||
//
|
|
||||||
// foreach (int k, m_Nonogram->rowNumbers(y)) {
|
|
||||||
// if (k == m_Nonogram->width())
|
|
||||||
// for (int i = 0; )
|
|
||||||
// m_OverlayData[i][y] = 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
emit markRequested(x, y, marker);
|
||||||
// while (m_OverlayData[right][y] && left < right)
|
m_OverlayData[x][y] = marker;
|
||||||
// right++;
|
|
||||||
//
|
m_RowsOverlay[y].dirty = true;
|
||||||
// if (left == right)
|
m_ColumnsOverlay[x].dirty = true;
|
||||||
// return true;
|
}
|
||||||
//
|
|
||||||
// if (m_Nonogram->rowNumbers(y)[0] == 0)
|
inline void CNonogramSolver::fillRow(int index, int marker) {
|
||||||
// for (int i = left; i <= right; i++)
|
for (int i = 0; i < m_Nonogram->width(); i++)
|
||||||
// m_OverlayData[i][y] = MT_CROSSED;
|
mark(i, index, marker);
|
||||||
//
|
}
|
||||||
// foreach (int k, m_Nonogram->rowNumbers(y)) {
|
|
||||||
//
|
inline void CNonogramSolver::fillColumn(int index, int marker) {
|
||||||
// }
|
for (int i = 0; i < m_Nonogram->height(); i++)
|
||||||
|
mark(index, i, marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNonogramSolver::prepare() {
|
||||||
|
m_OverlayData = new int *[m_Nonogram->width()];
|
||||||
|
|
||||||
|
for (int i = 0; i < m_Nonogram->width(); i++) {
|
||||||
|
m_OverlayData[i] = new int[m_Nonogram->height()];
|
||||||
|
for (int j = 0; j < m_Nonogram->height(); j++)
|
||||||
|
m_OverlayData[i][j] = static_cast<int>(CMT_UNMARKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
int leftSum, rightSum, numSize;
|
||||||
|
|
||||||
|
m_RowsOverlay = new LineOverlay [m_Nonogram->height()];
|
||||||
|
|
||||||
|
for (int i = 0; i < m_Nonogram->height(); i++) {
|
||||||
|
m_RowsOverlay[i].numbersSize = m_Nonogram->rowNumbers(i).size();
|
||||||
|
m_RowsOverlay[i].numbers = new NumberOverlay [m_RowsOverlay[i].numbersSize];
|
||||||
|
|
||||||
|
numSize = m_Nonogram->rowNumbers(i).size();
|
||||||
|
|
||||||
|
leftSum = 0;
|
||||||
|
for (int j = 0; j < numSize; j++) {
|
||||||
|
m_RowsOverlay[i].numbers[j].entry = m_Nonogram->rowNumbers(i).at(j);
|
||||||
|
m_RowsOverlay[i].numbers[j].finished = false;
|
||||||
|
m_RowsOverlay[i].numbers[j].borderRight = m_Nonogram->width();
|
||||||
|
|
||||||
|
m_RowsOverlay[i].numbers[j].borderLeft = leftSum + j;
|
||||||
|
leftSum += m_RowsOverlay[i].numbers[j].entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
rightSum = 0;
|
||||||
|
for (int j = numSize - 1; j > -1; j--) {
|
||||||
|
m_RowsOverlay[i].numbers[j].borderRight -= rightSum;
|
||||||
|
rightSum += m_RowsOverlay[i].numbers[j].entry + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ColumnsOverlay = new LineOverlay [m_Nonogram->width()];
|
||||||
|
|
||||||
|
for (int i = 0; i < m_Nonogram->width(); i++) {
|
||||||
|
m_ColumnsOverlay[i].numbersSize = m_Nonogram->columnNumbers(i).size();
|
||||||
|
m_ColumnsOverlay[i].numbers = new NumberOverlay [m_ColumnsOverlay[i].numbersSize];
|
||||||
|
|
||||||
|
numSize = m_Nonogram->columnNumbers(i).size();
|
||||||
|
|
||||||
|
leftSum = 0;
|
||||||
|
for (int j = 0; j < numSize; j++) {
|
||||||
|
m_ColumnsOverlay[i].numbers[j].borderRight = m_Nonogram->height();
|
||||||
|
m_ColumnsOverlay[i].numbers[j].finished = false;
|
||||||
|
m_ColumnsOverlay[i].numbers[j].entry = m_Nonogram->columnNumbers(i).at(j);
|
||||||
|
|
||||||
|
m_ColumnsOverlay[i].numbers[j].borderLeft = leftSum + j;
|
||||||
|
leftSum += m_ColumnsOverlay[i].numbers[j].entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
rightSum = 0;
|
||||||
|
for (int j = numSize - 1; j > -1; j--) {
|
||||||
|
m_ColumnsOverlay[i].numbers[j].borderRight -= rightSum;
|
||||||
|
rightSum += m_ColumnsOverlay[i].numbers[j].entry + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CNonogramSolver::solveLine(int index, bool isRow) {
|
||||||
|
LineOverlay * overlay = isRow ? &(m_RowsOverlay[index]) : &(m_ColumnsOverlay[index]);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
QString dbgOut;
|
||||||
|
QTextStream dbg(&dbgOut);
|
||||||
|
|
||||||
|
dbg << "overlay ";
|
||||||
|
if (isRow)
|
||||||
|
dbg << "row ";
|
||||||
|
else
|
||||||
|
dbg << "col ";
|
||||||
|
|
||||||
|
dbg << index << ": ";
|
||||||
|
|
||||||
|
int length = 0;
|
||||||
|
int offset = 0;
|
||||||
|
for (int i = 0; i < overlay->numbersSize; i++) {
|
||||||
|
if (overlay->numbers[i].finished) {
|
||||||
|
dbg << "(fin)";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg << '(' << overlay->numbers[i].borderLeft << ", " << overlay->numbers[i].borderRight << "; ";
|
||||||
|
|
||||||
|
length = safeLength(&(overlay->numbers[i]));
|
||||||
|
offset = overlay->numbers[i].entry - length + overlay->numbers[i].borderLeft;
|
||||||
|
|
||||||
|
dbg << length << ", " << offset << ") ";
|
||||||
|
|
||||||
|
if (length > 0) {
|
||||||
|
if (isRow) {
|
||||||
|
for (int j = 0; j < length; j++)
|
||||||
|
mark(offset + j, index, CMT_MARKED);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int j = 0; j < length; j++)
|
||||||
|
mark(index, offset + j, CMT_MARKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == overlay->numbers[i].entry) {
|
||||||
|
if (isRow) {
|
||||||
|
mark(overlay->numbers[i].borderLeft - 1, index, CMT_CROSSED);
|
||||||
|
mark(overlay->numbers[i].borderRight, index, CMT_CROSSED);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mark(index, overlay->numbers[i].borderLeft - 1, CMT_CROSSED);
|
||||||
|
mark(index, overlay->numbers[i].borderRight, CMT_CROSSED);
|
||||||
|
}
|
||||||
|
overlay->numbers[i].finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << dbgOut;
|
||||||
|
|
||||||
|
if (fillGaps(index, isRow))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CNonogramSolver::fillGaps(int index, bool isRow) {
|
||||||
|
LineOverlay * overlay = isRow ? &(m_RowsOverlay[index]) : &(m_ColumnsOverlay[index]);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (isRow) {
|
||||||
|
for (int i = 0; i < overlay->numbersSize + 1; i++) {
|
||||||
|
for (int j = overlay->borderRightDef(i - 1, 0); j < overlay->borderLeftDef(i, m_Nonogram->width()); j++) {
|
||||||
|
if (m_OverlayData[j][index] == 0) {
|
||||||
|
mark(j, index, CMT_CROSSED);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < overlay->numbersSize + 1; i++) {
|
||||||
|
for (int j = overlay->borderRightDef(i - 1, 0); j < overlay->borderLeftDef(i, m_Nonogram->height()); j++) {
|
||||||
|
if (m_OverlayData[index][j] == 0) {
|
||||||
|
mark(index, j, CMT_CROSSED);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void gtSet(int & target, int value) {
|
||||||
|
if (target > value)
|
||||||
|
target = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ltSet(int & target, int value) {
|
||||||
|
if (target < value)
|
||||||
|
target = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CNonogramSolver::prepareBorders(LineOverlay * overlay) {
|
||||||
|
for (int i = 1; i < overlay->numbersSize; i++)
|
||||||
|
ltSet(overlay->numbers[i].borderLeft, overlay->numbers[i - 1].borderLeft + overlay->numbers[i - 1].entry + 1);
|
||||||
|
|
||||||
|
for (int i = overlay->numbersSize - 1; i > 0; i--)
|
||||||
|
gtSet(overlay->numbers[i - 1].borderRight, overlay->numbers[i].borderRight - overlay->numbers[i].entry - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CNonogramSolver::updateBorders(int index, bool isRow) {
|
||||||
|
LineOverlay * overlay = isRow ? &(m_RowsOverlay[index]) : &(m_ColumnsOverlay[index]);
|
||||||
|
|
||||||
|
if (!overlay->dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int marker = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < overlay->numbersSize; i++) {
|
||||||
|
if (overlay->numbers[i].finished)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int j = overlay->numbers[i].borderLeft;
|
||||||
|
// int markedCount = 0;
|
||||||
|
while (j < overlay->numbers[i].borderRight) {
|
||||||
|
marker = (isRow ? m_OverlayData[j][index] : m_OverlayData[index][j]);
|
||||||
|
switch (marker) {
|
||||||
|
case CMT_CROSSED:
|
||||||
|
if (overlay->numbers[i].borderLeft == j)
|
||||||
|
overlay->numbers[i].borderLeft = j+1;
|
||||||
|
else {
|
||||||
|
if (j - overlay->numbers[i].borderLeft + 1 < j + overlay->numbers[i].entry)
|
||||||
|
overlay->numbers[i].borderLeft = j+1;
|
||||||
|
else
|
||||||
|
overlay->numbers[i].borderRight = j;
|
||||||
|
if (i < overlay->numbersSize-1)
|
||||||
|
ltSet(overlay->numbers[i + 1].borderLeft, j);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMT_MARKED:
|
||||||
|
gtSet(overlay->numbers[i].borderRight, j + overlay->numbers[i].entry);
|
||||||
|
/* if (markedCount != -1)
|
||||||
|
markedCount++;*/
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* if (markedCount > 0) {
|
||||||
|
markedCount = -1;
|
||||||
|
ltSet(overlay->numbers[i].borderLeft, j - overlay->numbers[i].entry + 1);
|
||||||
|
}*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay->dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNonogramSolver::updateBorders() {
|
||||||
|
for (int i = 0; i < m_Nonogram->height(); i++)
|
||||||
|
updateBorders(i, true);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_Nonogram->width(); i++)
|
||||||
|
updateBorders(i, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CNonogram;
|
class CNonogram;
|
||||||
|
|
||||||
class CNonogramSolver : public QObject {
|
class CNonogramSolver : public QObject {
|
||||||
@ -12,27 +12,67 @@ namespace libqcross {
|
|||||||
CNonogramSolver(QObject * parent = 0);
|
CNonogramSolver(QObject * parent = 0);
|
||||||
~CNonogramSolver();
|
~CNonogramSolver();
|
||||||
|
|
||||||
void setNonogram(CNonogram * nonogram) { m_Nonogram = nonogram; }
|
void setNonogram(CNonogram * nonogram);
|
||||||
|
public slots:
|
||||||
bool solve();
|
bool solve();
|
||||||
signals:
|
signals:
|
||||||
void markRequested(int x, int y, int type);
|
void markRequested(int x, int y, int type);
|
||||||
protected:
|
protected:
|
||||||
// struct Range {
|
enum MarkerType {CMT_UNMARKED = 0, CMT_MARKED = 1, CMT_CROSSED = 2, CMT_NONE = 3};
|
||||||
// int left;
|
|
||||||
// int right;
|
struct NumberOverlay {
|
||||||
//
|
int borderLeft;
|
||||||
// Range() : left(-1), right(-1) {}
|
int borderRight;
|
||||||
// bool isNULL() { return left == -1; }
|
|
||||||
// };
|
quint16 entry;
|
||||||
|
bool finished;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LineOverlay {
|
||||||
|
NumberOverlay * numbers;
|
||||||
|
int numbersSize;
|
||||||
|
|
||||||
|
bool dirty;
|
||||||
|
|
||||||
|
inline int borderLeftDef(int index, int def) {
|
||||||
|
return (index > -1 && index < numbersSize) ? numbers[index].borderLeft : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int borderRightDef(int index, int def) {
|
||||||
|
return (index > -1 && index < numbersSize) ? numbers[index].borderRight : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
LineOverlay() : numbers(NULL), dirty(false) {}
|
||||||
|
~LineOverlay() { if (numbers) delete[] numbers; }
|
||||||
|
};
|
||||||
|
|
||||||
CNonogram * m_Nonogram;
|
CNonogram * m_Nonogram;
|
||||||
|
|
||||||
|
LineOverlay * m_RowsOverlay;
|
||||||
|
LineOverlay * m_ColumnsOverlay;
|
||||||
|
|
||||||
int ** m_OverlayData;
|
int ** m_OverlayData;
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
void prepare();
|
||||||
|
|
||||||
bool solveRow(int y);
|
inline void mark(int x, int y, int marker);
|
||||||
bool solveColumn(int x);
|
inline void fillRow(int index, int marker);
|
||||||
|
inline void fillColumn(int index, int marker);
|
||||||
|
|
||||||
|
void printOverlays();
|
||||||
|
bool solveLine_ng(int index, bool isRow);
|
||||||
|
|
||||||
|
inline bool solveLine(int index, bool isRow);
|
||||||
|
inline bool fillGaps(int index, bool isRow);
|
||||||
|
inline void prepareBorders(LineOverlay * overlay);
|
||||||
|
inline void updateBorders(int index, bool isRow);
|
||||||
|
|
||||||
|
void updateBorders();
|
||||||
|
|
||||||
|
inline int safeLength(NumberOverlay * overlay) {
|
||||||
|
return (overlay->entry * 2) + overlay->borderLeft - overlay->borderRight;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "ccrossfieldwidget.h"
|
#include "ccrossfieldwidget.h"
|
||||||
#include <libqcross/cnonogram.h>
|
|
||||||
|
#include <libqnono/cnonogram.h>
|
||||||
|
#include <libqnono/cnonogramsolver.h>
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QLCDNumber>
|
#include <QLCDNumber>
|
||||||
@ -30,7 +33,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
namespace qcross {
|
namespace qcross {
|
||||||
using namespace libqcross;
|
using namespace libqnono;
|
||||||
|
|
||||||
int min(int a, int b) {
|
int min(int a, int b) {
|
||||||
return (a < b) ? a : b;
|
return (a < b) ? a : b;
|
||||||
@ -54,28 +57,28 @@ namespace qcross {
|
|||||||
m_MessageTimeoutId(-1),
|
m_MessageTimeoutId(-1),
|
||||||
m_Clock(NULL),
|
m_Clock(NULL),
|
||||||
m_ErrorCount(0),
|
m_ErrorCount(0),
|
||||||
m_LastErrorMark(-1,-1)
|
m_LastErrorMark(-1, -1)
|
||||||
{
|
{
|
||||||
m_Notifier = new QFrame(this);
|
// m_Notifier = new QFrame(this);
|
||||||
m_Notifier->setLineWidth(10);
|
// m_Notifier->setLineWidth(10);
|
||||||
m_Notifier->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
|
// m_Notifier->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
|
||||||
QPalette notifierPalette(QApplication::palette().color(QPalette::ToolTipBase));
|
QPalette notifierPalette(QApplication::palette().color(QPalette::ToolTipBase));
|
||||||
notifierPalette.setColor(QPalette::Text, QApplication::palette().color(QPalette::ToolTipText));
|
notifierPalette.setColor(QPalette::Text, QApplication::palette().color(QPalette::ToolTipText));
|
||||||
|
|
||||||
m_Notifier->setPalette(notifierPalette);
|
// m_Notifier->setPalette(notifierPalette);
|
||||||
m_Notifier->setAutoFillBackground(true);
|
// m_Notifier->setAutoFillBackground(true);
|
||||||
|
|
||||||
QHBoxLayout * notifierLayout = new QHBoxLayout(m_Notifier);
|
// QHBoxLayout * notifierLayout = new QHBoxLayout(m_Notifier);
|
||||||
m_NotifierIcon = new QLabel(m_Notifier);
|
// m_NotifierIcon = new QLabel(m_Notifier);
|
||||||
m_NotifierText = new QLabel(m_Notifier);
|
// m_NotifierText = new QLabel(m_Notifier);
|
||||||
|
|
||||||
m_NotifierText->setWordWrap(true);
|
// m_NotifierText->setWordWrap(true);
|
||||||
notifierLayout->addWidget(m_NotifierIcon);
|
// notifierLayout->addWidget(m_NotifierIcon);
|
||||||
notifierLayout->addWidget(m_NotifierText);
|
// notifierLayout->addWidget(m_NotifierText);
|
||||||
notifierLayout->addStretch();
|
// notifierLayout->addStretch();
|
||||||
m_Notifier->setLayout(notifierLayout);
|
// m_Notifier->setLayout(notifierLayout);
|
||||||
|
|
||||||
m_Notifier->hide();
|
// m_Notifier->hide();
|
||||||
|
|
||||||
m_Clock = new QLCDNumber(8, this);
|
m_Clock = new QLCDNumber(8, this);
|
||||||
m_Clock->setVisible(m_Picture);
|
m_Clock->setVisible(m_Picture);
|
||||||
@ -92,12 +95,15 @@ namespace qcross {
|
|||||||
CCrossFieldWidget::~CCrossFieldWidget() {
|
CCrossFieldWidget::~CCrossFieldWidget() {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
delete m_Clock;
|
// delete m_Clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCrossFieldWidget::setPicture(CNonogram * picture) {
|
void CCrossFieldWidget::setPicture(CNonogram * picture) {
|
||||||
cleanup();
|
if (m_Picture)
|
||||||
|
cleanup();
|
||||||
|
|
||||||
m_Picture = picture;
|
m_Picture = picture;
|
||||||
|
|
||||||
if (m_Picture) {
|
if (m_Picture) {
|
||||||
m_LastErrorMark.setX(-1);
|
m_LastErrorMark.setX(-1);
|
||||||
m_LastErrorMark.setY(-1);
|
m_LastErrorMark.setY(-1);
|
||||||
@ -120,7 +126,7 @@ namespace qcross {
|
|||||||
}
|
}
|
||||||
m_Clock->setVisible(m_Picture);
|
m_Clock->setVisible(m_Picture);
|
||||||
}
|
}
|
||||||
//beim Laden eines neuen Spiels nach einem beendeten wird das neue nicht automatisch gestartet (Restart nötig)
|
|
||||||
void CCrossFieldWidget::showMessage(const QString message, int timeout, MessageType type) {
|
void CCrossFieldWidget::showMessage(const QString message, int timeout, MessageType type) {
|
||||||
if (!message.isEmpty()) {
|
if (!message.isEmpty()) {
|
||||||
Message newMessage;
|
Message newMessage;
|
||||||
@ -134,15 +140,85 @@ namespace qcross {
|
|||||||
nextMessage();
|
nextMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCrossFieldWidget::applyState(QDataStream & stream) {
|
||||||
|
qDebug("trying to apply state...");
|
||||||
|
qDebug("reading basic stuff:");
|
||||||
|
|
||||||
|
// error state
|
||||||
|
stream >> m_ErrorAware; qDebug("m_ErrorAware = %i", int(m_ErrorAware));
|
||||||
|
stream >> m_ErrorCount; qDebug("m_ErrorCount = %i", m_ErrorCount);
|
||||||
|
|
||||||
|
// time(out)
|
||||||
|
stream >> m_Time; qDebug("m_Time = %i", m_Time);
|
||||||
|
updateTimeDisplay();
|
||||||
|
emit timeChanged(m_Time);
|
||||||
|
|
||||||
|
// messages
|
||||||
|
int messageCount;
|
||||||
|
stream >> messageCount; qDebug("messageCount = %i", messageCount);
|
||||||
|
|
||||||
|
m_Messages.clear();
|
||||||
|
|
||||||
|
unsigned char byteBuffer;
|
||||||
|
for (int i = 0; i < messageCount; i++) {
|
||||||
|
qDebug("message #%i:", i);
|
||||||
|
stream >> byteBuffer; qDebug("type = %i", byteBuffer);
|
||||||
|
m_Message.type = MessageType(byteBuffer);
|
||||||
|
if (m_Message.type != Invalid) {
|
||||||
|
stream >> m_Message.timeout; qDebug("timeout = %i", m_Message.timeout);
|
||||||
|
stream >> m_Message.text; qDebug("text = %s", qPrintable(m_Message.text));
|
||||||
|
|
||||||
|
m_Messages.enqueue(m_Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextMessage();
|
||||||
|
|
||||||
|
// overlaydata
|
||||||
|
for (int iy = 0; iy < m_Picture->height(); iy++) {
|
||||||
|
for (int ix = 0; ix < m_Picture->width(); ix++) {
|
||||||
|
stream >> byteBuffer;
|
||||||
|
m_OverlayData[ix][iy] = MarkerType(byteBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCrossFieldWidget::dumpState(QDataStream & stream) {
|
||||||
|
if (!m_OverlayData || !m_Picture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// error state
|
||||||
|
stream << m_ErrorAware;
|
||||||
|
stream << m_ErrorCount;
|
||||||
|
|
||||||
|
// time(out)
|
||||||
|
stream << m_Time;
|
||||||
|
|
||||||
|
// messages
|
||||||
|
// actually we should dump the message queue
|
||||||
|
// for now only dump last displayed
|
||||||
|
// TODO dump message queue
|
||||||
|
stream << 1; // dummy message count
|
||||||
|
stream << (unsigned char)(m_Message.type);
|
||||||
|
if (m_Message.type != Invalid) {
|
||||||
|
stream << m_Message.timeout;
|
||||||
|
stream << m_Message.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overlaydata
|
||||||
|
for (int iy = 0; iy < m_Picture->height(); iy++) {
|
||||||
|
for (int ix = 0; ix < m_Picture->width(); ix++)
|
||||||
|
stream << (unsigned char)(m_OverlayData[ix][iy]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//public slots
|
//public slots
|
||||||
void CCrossFieldWidget::mark(int x, int y, qcross::MarkerType type) {
|
void CCrossFieldWidget::mark(int x, int y, int type) {
|
||||||
if (type == CMT_NONE || x < 0 || x >= m_Picture->width() || y < 0 || y >= m_Picture->height())
|
if (type == CMT_NONE || x < 0 || x >= m_Picture->width() || y < 0 || y >= m_Picture->height())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type == CMT_MARKED && checkNoError(x, y))
|
MarkerType marker = static_cast<qcross::MarkerType>(type);
|
||||||
m_OverlayData[x][y] = CMT_MARKED;
|
|
||||||
else
|
execMark(x, y, marker);
|
||||||
m_OverlayData[x][y] = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCrossFieldWidget::setTime(int value) {
|
void CCrossFieldWidget::setTime(int value) {
|
||||||
@ -154,6 +230,7 @@ namespace qcross {
|
|||||||
|
|
||||||
if (m_ErrorAware && !m_Time) {
|
if (m_ErrorAware && !m_Time) {
|
||||||
killTimer(m_TimerId);
|
killTimer(m_TimerId);
|
||||||
|
m_TimerId = -1;
|
||||||
m_Paused = true;
|
m_Paused = true;
|
||||||
emit timeUp();
|
emit timeUp();
|
||||||
}
|
}
|
||||||
@ -182,6 +259,17 @@ namespace qcross {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
killTimer(m_TimerId);
|
killTimer(m_TimerId);
|
||||||
|
m_TimerId = -1;
|
||||||
|
|
||||||
|
if (m_Message.type != Invalid) {
|
||||||
|
m_Messages.enqueue(m_Message);
|
||||||
|
|
||||||
|
if (m_MessageTimeoutId != -1) {
|
||||||
|
killTimer(m_MessageTimeoutId);
|
||||||
|
m_MessageTimeoutId = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_Paused = true;
|
m_Paused = true;
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -205,31 +293,33 @@ namespace qcross {
|
|||||||
|
|
||||||
if (m_Messages.isEmpty()) {
|
if (m_Messages.isEmpty()) {
|
||||||
m_Message.type = Invalid;
|
m_Message.type = Invalid;
|
||||||
|
// m_Notifier->hide();
|
||||||
|
// updateMetrics();
|
||||||
update();
|
update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Message m_Next = m_Messages.dequeue();
|
m_Message = m_Messages.dequeue();
|
||||||
update();
|
update();
|
||||||
|
|
||||||
// switch (next.type) {
|
/* switch (m_Message.type) {
|
||||||
// case Information:
|
case Information:
|
||||||
// m_NotifierIcon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxInformation).pixmap(22, 22));
|
m_NotifierIcon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxInformation).pixmap(22, 22));
|
||||||
// break;
|
break;
|
||||||
// case Warning:
|
case Warning:
|
||||||
// m_NotifierIcon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(22, 22));
|
m_NotifierIcon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(22, 22));
|
||||||
// break;
|
break;
|
||||||
// case Critical:
|
case Critical:
|
||||||
// m_NotifierIcon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(22, 22));
|
m_NotifierIcon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(22, 22));
|
||||||
// break;
|
break;
|
||||||
// default:
|
default:
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// m_NotifierText->setText(next.text);
|
m_NotifierText->setText(m_Message.text);
|
||||||
|
|
||||||
// m_Notifier->show();
|
m_Notifier->show();
|
||||||
// updateMetrics();
|
updateMetrics();*/
|
||||||
|
|
||||||
if (m_Message.timeout)
|
if (m_Message.timeout)
|
||||||
m_MessageTimeoutId = startTimer(m_Message.timeout);
|
m_MessageTimeoutId = startTimer(m_Message.timeout);
|
||||||
@ -259,8 +349,16 @@ namespace qcross {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CCrossFieldWidget::cleanup() {
|
void CCrossFieldWidget::cleanup() {
|
||||||
killTimer(m_TimerId);
|
qDebug("m_TimerId = %i m_MessageTimeoutId = %i", m_TimerId, m_MessageTimeoutId);
|
||||||
killTimer(m_MessageTimeoutId);
|
if (m_TimerId != -1) {
|
||||||
|
killTimer(m_TimerId);
|
||||||
|
m_TimerId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_MessageTimeoutId != -1) {
|
||||||
|
killTimer(m_MessageTimeoutId);
|
||||||
|
m_MessageTimeoutId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_OverlayData) {
|
if (m_OverlayData) {
|
||||||
for (int i = 0; i < m_Picture->width(); i++)
|
for (int i = 0; i < m_Picture->width(); i++)
|
||||||
@ -321,27 +419,24 @@ namespace qcross {
|
|||||||
m_Clock->display(time);
|
m_Clock->display(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCrossFieldWidget::execMark(int x, int y) {
|
void CCrossFieldWidget::execMark(int x, int y, MarkerType & marker) {
|
||||||
/* if (m_OverlayData[x][y] == m_MouseMark)
|
switch (marker) {
|
||||||
return;*/
|
|
||||||
|
|
||||||
switch (m_MouseMark) {
|
|
||||||
case CMT_MARKED:
|
case CMT_MARKED:
|
||||||
if (m_Picture->pixel(x, y)) {
|
if (m_Picture->pixel(x, y)) {
|
||||||
m_RemainingPixels--;
|
m_RemainingPixels--;
|
||||||
m_OverlayData[x][y] = m_MouseMark;
|
m_OverlayData[x][y] = marker;
|
||||||
}
|
|
||||||
else if (m_ErrorAware) {
|
|
||||||
m_ErrorCount++;
|
|
||||||
m_MouseMark = CMT_NONE;
|
|
||||||
m_OverlayData[x][y] = CMT_CROSSED;
|
|
||||||
m_LastErrorMark.setX(x);
|
|
||||||
m_LastErrorMark.setY(y);
|
|
||||||
emit markError();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_ErrorCount++;
|
m_ErrorCount++;
|
||||||
m_OverlayData[x][y] = m_MouseMark;
|
if (m_ErrorAware) {
|
||||||
|
m_OverlayData[x][y] = CMT_CROSSED;
|
||||||
|
marker = CMT_NONE;
|
||||||
|
m_LastErrorMark.setX(x);
|
||||||
|
m_LastErrorMark.setY(y);
|
||||||
|
emit markError();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_OverlayData[x][y] = marker;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CMT_CROSSED:
|
case CMT_CROSSED:
|
||||||
@ -354,11 +449,11 @@ namespace qcross {
|
|||||||
if (m_OverlayData[x][y] == CMT_MARKED) {
|
if (m_OverlayData[x][y] == CMT_MARKED) {
|
||||||
if (m_Picture->pixel(x, y))
|
if (m_Picture->pixel(x, y))
|
||||||
m_RemainingPixels++;
|
m_RemainingPixels++;
|
||||||
else
|
else if (!m_ErrorAware)
|
||||||
m_ErrorCount--;
|
m_ErrorCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_OverlayData[x][y] = m_MouseMark;
|
m_OverlayData[x][y] = marker;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -366,6 +461,7 @@ namespace qcross {
|
|||||||
|
|
||||||
if (!m_RemainingPixels && (m_ErrorAware || !m_ErrorCount)) {
|
if (!m_RemainingPixels && (m_ErrorAware || !m_ErrorCount)) {
|
||||||
killTimer(m_TimerId);
|
killTimer(m_TimerId);
|
||||||
|
m_TimerId = -1;
|
||||||
m_Paused = true;
|
m_Paused = true;
|
||||||
m_Solved = true;
|
m_Solved = true;
|
||||||
emit solved();
|
emit solved();
|
||||||
@ -387,6 +483,7 @@ namespace qcross {
|
|||||||
int gridWidth = m_RasterWidth - m_HeaderWidth;
|
int gridWidth = m_RasterWidth - m_HeaderWidth;
|
||||||
int gridHeight = m_RasterHeight - m_HeaderHeight;
|
int gridHeight = m_RasterHeight - m_HeaderHeight;
|
||||||
|
|
||||||
|
// draw background
|
||||||
{
|
{
|
||||||
const int delta = 5 * m_BoxSize;
|
const int delta = 5 * m_BoxSize;
|
||||||
|
|
||||||
@ -395,76 +492,81 @@ namespace qcross {
|
|||||||
int deltaX = delta;
|
int deltaX = delta;
|
||||||
int deltaY;
|
int deltaY;
|
||||||
|
|
||||||
bool useBase = false;
|
bool useBaseX;
|
||||||
|
bool useBaseY = true;
|
||||||
|
|
||||||
while (offsetX < gridWidth) {
|
while (offsetX < gridWidth) {
|
||||||
offsetY = 0;
|
|
||||||
deltaY = delta;
|
|
||||||
while (offsetY < gridHeight) {
|
|
||||||
painter.fillRect(originX + offsetX, originY + offsetY, deltaX, deltaY,
|
|
||||||
palette().color(useBase ? QPalette::Base : QPalette::AlternateBase));
|
|
||||||
|
|
||||||
useBase = !useBase;
|
|
||||||
|
|
||||||
offsetY += delta;
|
|
||||||
|
|
||||||
if (gridWidth - offsetY < delta)
|
|
||||||
deltaY = gridWidth - offsetY;
|
|
||||||
}
|
|
||||||
|
|
||||||
useBase = !useBase;
|
|
||||||
|
|
||||||
offsetX += delta;
|
|
||||||
|
|
||||||
if (gridWidth - offsetX < delta)
|
if (gridWidth - offsetX < delta)
|
||||||
deltaX = gridWidth - offsetX;
|
deltaX = gridWidth - offsetX;
|
||||||
|
|
||||||
|
offsetY = 0;
|
||||||
|
deltaY = delta;
|
||||||
|
|
||||||
|
useBaseX = useBaseY;
|
||||||
|
while (offsetY < gridHeight) {
|
||||||
|
if (gridHeight - offsetY < delta)
|
||||||
|
deltaY = gridHeight - offsetY;
|
||||||
|
|
||||||
|
painter.fillRect(originX + offsetX, originY + offsetY, deltaX, deltaY,
|
||||||
|
palette().color(useBaseX ? QPalette::Base : QPalette::AlternateBase));
|
||||||
|
|
||||||
|
useBaseX = !useBaseX;
|
||||||
|
|
||||||
|
offsetY += deltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
useBaseY = !useBaseY;
|
||||||
|
|
||||||
|
offsetX += deltaX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
painter.setBrush(palette().color(QPalette::Highlight));
|
// draw markers and crosses
|
||||||
|
|
||||||
QFont font = painter.font();
|
|
||||||
font.setPixelSize(m_MarkerSize * 0.9);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
QPen pen;
|
QPen pen;
|
||||||
|
pen.setWidth(m_MarkerSize / 8);
|
||||||
pen.setWidth(m_MarkerSize / 10);
|
|
||||||
|
|
||||||
painter.setPen(pen);
|
painter.setPen(pen);
|
||||||
}
|
|
||||||
|
|
||||||
QRectF markerRect(m_MarkerOffset, m_MarkerOffset, m_MarkerSize, m_MarkerSize);
|
QRectF markerRect(m_MarkerOffset, m_MarkerOffset, m_MarkerSize, m_MarkerSize);
|
||||||
|
|
||||||
for (int i = 0; i < m_Picture->width(); i++) {
|
QColor markerColor = palette().color(QPalette::Highlight);
|
||||||
originX = m_OffsetX + m_HeaderWidth + i * m_BoxSize;
|
QColor errorColor = markerColor;
|
||||||
markerRect.moveLeft(originX + m_MarkerOffset);
|
errorColor.setAlpha(128);
|
||||||
|
|
||||||
for (int j = 0; j < m_Picture->height(); j++) {
|
painter.setBrush(markerColor);
|
||||||
originY = m_OffsetY + m_HeaderHeight + j * m_BoxSize;
|
for (int i = 0; i < m_Picture->width(); i++) {
|
||||||
markerRect.moveTop(originY + m_MarkerOffset);
|
originX = m_OffsetX + m_HeaderWidth + i * m_BoxSize;
|
||||||
|
markerRect.moveLeft(originX + m_MarkerOffset);
|
||||||
|
|
||||||
switch (m_OverlayData[i][j]) {
|
for (int j = 0; j < m_Picture->height(); j++) {
|
||||||
case CMT_MARKED:
|
originY = m_OffsetY + m_HeaderHeight + j * m_BoxSize;
|
||||||
painter.fillRect(markerRect, painter.brush());
|
markerRect.moveTop(originY + m_MarkerOffset);
|
||||||
break;
|
|
||||||
case CMT_CROSSED:
|
|
||||||
if (m_Solved)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (m_ErrorAware && m_ErrorCount && i == m_LastErrorMark.x() && j == m_LastErrorMark.y()) {
|
switch (m_OverlayData[i][j]) {
|
||||||
|
case CMT_MARKED:
|
||||||
painter.fillRect(markerRect, painter.brush());
|
painter.fillRect(markerRect, painter.brush());
|
||||||
}
|
break;
|
||||||
|
case CMT_CROSSED:
|
||||||
|
if (m_Solved)
|
||||||
|
break;
|
||||||
|
|
||||||
painter.drawLine(markerRect.topLeft(), markerRect.bottomRight());
|
if (m_ErrorAware && m_ErrorCount && i == m_LastErrorMark.x() && j == m_LastErrorMark.y()) {
|
||||||
painter.drawLine(markerRect.bottomLeft(), markerRect.topRight());
|
painter.setBrush(errorColor);
|
||||||
break;
|
painter.fillRect(markerRect, painter.brush());
|
||||||
default:
|
painter.setBrush(markerColor);
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
painter.drawLine(markerRect.topLeft(), markerRect.bottomRight());
|
||||||
|
painter.drawLine(markerRect.bottomLeft(), markerRect.topRight());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw grid lines
|
||||||
painter.setPen(palette().color(QPalette::Dark));
|
painter.setPen(palette().color(QPalette::Dark));
|
||||||
|
|
||||||
for (int i = m_OffsetX + m_HeaderWidth; i < m_OffsetX + m_RasterWidth; i += m_BoxSize) {
|
for (int i = m_OffsetX + m_HeaderWidth; i < m_OffsetX + m_RasterWidth; i += m_BoxSize) {
|
||||||
@ -475,9 +577,13 @@ namespace qcross {
|
|||||||
painter.drawLine(m_OffsetX + m_HeaderWidth, i, m_OffsetX + m_RasterWidth-1, i);
|
painter.drawLine(m_OffsetX + m_HeaderWidth, i, m_OffsetX + m_RasterWidth-1, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw numbers area
|
||||||
if (m_Paused)
|
if (m_Paused)
|
||||||
painter.setPen(palette().color(QPalette::Shadow));
|
painter.setPen(palette().color(QPalette::Shadow));
|
||||||
|
|
||||||
|
QFont font = painter.font();
|
||||||
|
font.setPixelSize(m_MarkerSize * 0.9);
|
||||||
|
|
||||||
painter.setFont(font);
|
painter.setFont(font);
|
||||||
|
|
||||||
for (int i = 0; i < m_Picture->width(); i++) {
|
for (int i = 0; i < m_Picture->width(); i++) {
|
||||||
@ -514,10 +620,19 @@ namespace qcross {
|
|||||||
painter.drawLine(m_OffsetX, originY, m_OffsetX + m_RasterWidth-1, originY);
|
painter.drawLine(m_OffsetX, originY, m_OffsetX + m_RasterWidth-1, originY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw message if needed
|
||||||
if (m_Message.type != Invalid) {
|
if (m_Message.type != Invalid) {
|
||||||
painter.drawText(m_HeaderWidth + m_OffsetX, m_HeaderHeight + m_OffsetY, m_Message.text);
|
QRect boxrect(m_HeaderWidth + m_OffsetX, m_HeaderHeight + m_OffsetY, m_RasterWidth - m_HeaderWidth, m_RasterHeight - m_HeaderHeight);
|
||||||
|
|
||||||
|
QColor fillColor = palette().color(QPalette::Base);
|
||||||
|
fillColor.setAlpha(220);
|
||||||
|
painter.fillRect(boxrect, fillColor);
|
||||||
|
|
||||||
|
font.setPixelSize(font.pixelSize() * 2);
|
||||||
|
|
||||||
|
painter.setFont(font);
|
||||||
|
painter.drawText(boxrect, Qt::AlignVCenter | Qt::AlignCenter | Qt::TextWordWrap, m_Message.text);
|
||||||
}
|
}
|
||||||
// painter.drawLine(m_OffsetX, m_OffsetY + m_RasterHeight, m_OffsetX + m_RasterWidth, m_OffsetY + m_RasterHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* void CCrossFieldWidget::updateCell(int x, int y) {
|
/* void CCrossFieldWidget::updateCell(int x, int y) {
|
||||||
@ -570,12 +685,12 @@ namespace qcross {
|
|||||||
m_OffsetX = (width() - m_RasterWidth) / 2;
|
m_OffsetX = (width() - m_RasterWidth) / 2;
|
||||||
m_OffsetY = (height() - m_RasterHeight) / 2;
|
m_OffsetY = (height() - m_RasterHeight) / 2;
|
||||||
|
|
||||||
int clockHeight = m_Notifier->isVisible() ? m_HeaderHeight - m_Notifier->sizeHint().height() /* * 3.0 / 4.0 */ : m_HeaderHeight;
|
int clockHeight = /*m_Notifier->isVisible() ? m_HeaderHeight - m_Notifier->sizeHint().height()*/ /* * 3.0 / 4.0 */ /*:*/ m_HeaderHeight;
|
||||||
|
|
||||||
if (m_Clock)
|
if (m_Clock)
|
||||||
m_Clock->setGeometry(m_OffsetX, m_OffsetY, m_HeaderWidth, clockHeight);
|
m_Clock->setGeometry(m_OffsetX, m_OffsetY, m_HeaderWidth, clockHeight);
|
||||||
if (m_Notifier && m_Notifier->isVisible())
|
// if (m_Notifier && m_Notifier->isVisible())
|
||||||
m_Notifier->setGeometry(m_OffsetX, m_OffsetY + clockHeight, m_HeaderWidth, m_Notifier->sizeHint().height());
|
// m_Notifier->setGeometry(m_OffsetX, m_OffsetY + clockHeight, m_HeaderWidth, m_Notifier->sizeHint().height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCrossFieldWidget::mousePressEvent(QMouseEvent * event) {
|
void CCrossFieldWidget::mousePressEvent(QMouseEvent * event) {
|
||||||
@ -600,7 +715,7 @@ namespace qcross {
|
|||||||
if (m_OverlayData[pressedX][pressedY] == m_MouseMark)
|
if (m_OverlayData[pressedX][pressedY] == m_MouseMark)
|
||||||
m_MouseMark = CMT_UNMARKED;
|
m_MouseMark = CMT_UNMARKED;
|
||||||
|
|
||||||
execMark(pressedX, pressedY);
|
execMark(pressedX, pressedY, m_MouseMark);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,7 +736,7 @@ namespace qcross {
|
|||||||
pressedY = (pressedY - m_HeaderHeight) / m_BoxSize;
|
pressedY = (pressedY - m_HeaderHeight) / m_BoxSize;
|
||||||
|
|
||||||
if (m_OverlayData[pressedX][pressedY] != m_MouseMark) {
|
if (m_OverlayData[pressedX][pressedY] != m_MouseMark) {
|
||||||
execMark(pressedX, pressedY);
|
execMark(pressedX, pressedY, m_MouseMark);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,9 @@ class QLCDNumber;
|
|||||||
class QFrame;
|
class QFrame;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CNonogram;
|
class CNonogram;
|
||||||
|
class CNonogramSolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace qcross {
|
namespace qcross {
|
||||||
@ -37,7 +38,7 @@ namespace qcross {
|
|||||||
class CCrossFieldWidget : public QWidget {
|
class CCrossFieldWidget : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum MessageType {Information, Warning, Critical, Invalid};
|
enum MessageType {Information = 1, Warning = 2, Critical = 3, Invalid = 0};
|
||||||
|
|
||||||
bool isPaused() const { return m_Paused; }
|
bool isPaused() const { return m_Paused; }
|
||||||
bool isSolved() const { return m_Solved; }
|
bool isSolved() const { return m_Solved; }
|
||||||
@ -46,17 +47,20 @@ namespace qcross {
|
|||||||
int time() const { return m_Time; }
|
int time() const { return m_Time; }
|
||||||
qint32 errorCount() const { return m_ErrorCount; }
|
qint32 errorCount() const { return m_ErrorCount; }
|
||||||
|
|
||||||
CCrossFieldWidget(libqcross::CNonogram * picture, QWidget * parent = 0);
|
CCrossFieldWidget(libqnono::CNonogram * picture, QWidget * parent = 0);
|
||||||
~CCrossFieldWidget();
|
~CCrossFieldWidget();
|
||||||
|
|
||||||
QPoint lastErrorMark() const { return m_LastErrorMark; }
|
QPoint lastErrorMark() const { return m_LastErrorMark; }
|
||||||
|
|
||||||
void setPicture(libqcross::CNonogram * picture);
|
void setPicture(libqnono::CNonogram * picture);
|
||||||
|
|
||||||
void showMessage(const QString message = QString(), int timeout = 0, MessageType type = Information);
|
void showMessage(const QString message = QString(), int timeout = 0, MessageType type = Information);
|
||||||
|
|
||||||
|
void applyState(QDataStream & stream);
|
||||||
|
void dumpState(QDataStream & stream);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void mark(int x, int y, qcross::MarkerType type);
|
void mark(int x, int y, int type);
|
||||||
void setTime(int value);
|
void setTime(int value);
|
||||||
void setErrorAware(bool value);
|
void setErrorAware(bool value);
|
||||||
void setNumbersMarkable(bool value);
|
void setNumbersMarkable(bool value);
|
||||||
@ -81,7 +85,7 @@ namespace qcross {
|
|||||||
|
|
||||||
QQueue<Message> m_Messages;
|
QQueue<Message> m_Messages;
|
||||||
|
|
||||||
libqcross::CNonogram * m_Picture;
|
libqnono::CNonogram * m_Picture;
|
||||||
MarkerType ** m_OverlayData;
|
MarkerType ** m_OverlayData;
|
||||||
quint32 m_RemainingPixels;
|
quint32 m_RemainingPixels;
|
||||||
|
|
||||||
@ -107,9 +111,9 @@ namespace qcross {
|
|||||||
|
|
||||||
QLCDNumber * m_Clock;
|
QLCDNumber * m_Clock;
|
||||||
|
|
||||||
QFrame * m_Notifier;
|
// QFrame * m_Notifier;
|
||||||
QLabel * m_NotifierIcon;
|
// QLabel * m_NotifierIcon;
|
||||||
QLabel * m_NotifierText;
|
// QLabel * m_NotifierText;
|
||||||
|
|
||||||
qint32 m_ErrorCount;
|
qint32 m_ErrorCount;
|
||||||
QPoint m_LastErrorMark;
|
QPoint m_LastErrorMark;
|
||||||
@ -126,7 +130,7 @@ namespace qcross {
|
|||||||
void timerEvent(QTimerEvent * event);
|
void timerEvent(QTimerEvent * event);
|
||||||
inline void updateTimeDisplay();
|
inline void updateTimeDisplay();
|
||||||
|
|
||||||
inline void execMark(int x, int y);
|
inline void execMark(int x, int y, MarkerType & marker);
|
||||||
|
|
||||||
void paintEvent(QPaintEvent * event);
|
void paintEvent(QPaintEvent * event);
|
||||||
|
|
||||||
|
@ -28,16 +28,18 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
|
||||||
#include <libqcross/cnonogram.h>
|
#include <libqnono/cnonogram.h>
|
||||||
#include <libqcross/ccrosspackage.h>
|
#include <libqnono/cnonogramsolver.h>
|
||||||
|
#include <libqnono/ccrosspackage.h>
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
#include "cgamewindow.h"
|
#include "cgamewindow.h"
|
||||||
#include "ccrossfieldwidget.h"
|
#include "ccrossfieldwidget.h"
|
||||||
#include "cnewgamedialog.h"
|
#include "cnewgamedialog.h"
|
||||||
#include "chighscore.h"
|
#include "chighscore.h"
|
||||||
|
|
||||||
namespace qcross {
|
namespace qcross {
|
||||||
using namespace libqcross;
|
using namespace libqnono;
|
||||||
//public
|
//public
|
||||||
CGameWindow::CGameWindow(QWidget * parent) : QMainWindow(parent) {
|
CGameWindow::CGameWindow(QWidget * parent) : QMainWindow(parent) {
|
||||||
m_Highscore = NULL;
|
m_Highscore = NULL;
|
||||||
@ -49,11 +51,13 @@ namespace qcross {
|
|||||||
m_Field->setTime(42 * 60 + 23);
|
m_Field->setTime(42 * 60 + 23);
|
||||||
|
|
||||||
setCentralWidget(m_Field);
|
setCentralWidget(m_Field);
|
||||||
// m_Field->showMessage(tr("Welcome to QCross!"));
|
m_Field->showMessage(tr("Welcome to QCross!"));
|
||||||
|
|
||||||
createActions();
|
createActions();
|
||||||
// statusBar()->show();
|
// statusBar()->show();
|
||||||
|
m_Solver = new CNonogramSolver(this);
|
||||||
|
|
||||||
|
connect(m_Solver, SIGNAL(markRequested(int, int, int)), m_Field, SLOT(mark(int, int, int)));
|
||||||
connect(m_Field, SIGNAL(solved()), this, SLOT(wonGame()));
|
connect(m_Field, SIGNAL(solved()), this, SLOT(wonGame()));
|
||||||
connect(m_Field, SIGNAL(timeUp()), this, SLOT(lostGame()));
|
connect(m_Field, SIGNAL(timeUp()), this, SLOT(lostGame()));
|
||||||
connect(m_Field, SIGNAL(markError()), this, SLOT(handleErrorMark()));
|
connect(m_Field, SIGNAL(markError()), this, SLOT(handleErrorMark()));
|
||||||
@ -73,6 +77,9 @@ namespace qcross {
|
|||||||
currentMenu = menuBar()->addMenu(tr("&Game"));
|
currentMenu = menuBar()->addMenu(tr("&Game"));
|
||||||
currentMenu->addAction(tr("&New..."), this, SLOT(newGame()), Qt::CTRL + Qt::Key_N);
|
currentMenu->addAction(tr("&New..."), this, SLOT(newGame()), Qt::CTRL + Qt::Key_N);
|
||||||
currentMenu->addSeparator();
|
currentMenu->addSeparator();
|
||||||
|
currentMenu->addAction(tr("&Save..."), this, SLOT(saveGame()), Qt::CTRL + Qt::Key_N);
|
||||||
|
currentMenu->addAction(tr("&Load..."), this, SLOT(loadGame()), Qt::CTRL + Qt::Key_N);
|
||||||
|
currentMenu->addSeparator();
|
||||||
m_RestartGameAction = currentMenu->addAction(tr("&Restart"), this, SLOT(restartGame()), Qt::CTRL + Qt::Key_R);
|
m_RestartGameAction = currentMenu->addAction(tr("&Restart"), this, SLOT(restartGame()), Qt::CTRL + Qt::Key_R);
|
||||||
m_RestartGameAction->setEnabled(false);
|
m_RestartGameAction->setEnabled(false);
|
||||||
m_PauseGameAction = currentMenu->addAction(tr("&Pause"));
|
m_PauseGameAction = currentMenu->addAction(tr("&Pause"));
|
||||||
@ -82,8 +89,8 @@ namespace qcross {
|
|||||||
m_PauseGameAction->setEnabled(false);
|
m_PauseGameAction->setEnabled(false);
|
||||||
currentMenu->addSeparator();
|
currentMenu->addSeparator();
|
||||||
currentMenu->addAction(tr("&Quit"), this, SLOT(close()), Qt::CTRL + Qt::Key_Q);
|
currentMenu->addAction(tr("&Quit"), this, SLOT(close()), Qt::CTRL + Qt::Key_Q);
|
||||||
// currentMenu->addSeparator();
|
currentMenu->addSeparator();
|
||||||
// currentMenu->addAction(tr("debug: win"), this, SLOT(wonGame()));
|
currentMenu->addAction(tr("debug: solve"), this, SLOT(startSolver()));
|
||||||
|
|
||||||
currentToolBar = addToolBar(currentMenu->title());
|
currentToolBar = addToolBar(currentMenu->title());
|
||||||
currentToolBar->addActions(currentMenu->actions());
|
currentToolBar->addActions(currentMenu->actions());
|
||||||
@ -97,33 +104,119 @@ namespace qcross {
|
|||||||
void CGameWindow::newGame() {
|
void CGameWindow::newGame() {
|
||||||
bool notPaused = !m_Field->isPaused();
|
bool notPaused = !m_Field->isPaused();
|
||||||
if (notPaused)
|
if (notPaused)
|
||||||
m_Field->pause();
|
pauseGame(true);
|
||||||
|
|
||||||
CNewGameDialog dialog;
|
CNewGameDialog dialog;
|
||||||
if (dialog.exec() == QDialog::Accepted) {
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
if (m_Highscore)
|
if (m_Highscore)
|
||||||
delete m_Highscore;
|
delete m_Highscore;
|
||||||
|
|
||||||
m_Field->setPicture(NULL);
|
|
||||||
if (m_Picture)
|
|
||||||
delete m_Picture;
|
|
||||||
|
|
||||||
m_Highscore = dialog.takeHighscore();
|
m_Highscore = dialog.takeHighscore();
|
||||||
m_PictureIndex = m_Highscore ? dialog.nonogramIndex() : -1;
|
m_PictureIndex = m_Highscore ? dialog.nonogramIndex() : -1;
|
||||||
|
|
||||||
m_Picture = dialog.takeNonogram();
|
CNonogram * newPicture = dialog.takeNonogram();
|
||||||
m_Picture->updateNumbers();
|
newPicture->updateNumbers();
|
||||||
|
|
||||||
m_PauseGameAction->setEnabled(true);
|
m_PauseGameAction->setEnabled(true);
|
||||||
m_RestartGameAction->setEnabled(true);
|
m_RestartGameAction->setEnabled(true);
|
||||||
|
|
||||||
m_Field->setPicture(m_Picture);
|
m_Field->setPicture(newPicture);
|
||||||
|
|
||||||
|
if (m_Picture)
|
||||||
|
delete m_Picture;
|
||||||
|
|
||||||
|
m_Picture = newPicture;
|
||||||
|
|
||||||
m_Field->resume();
|
m_Field->resume();
|
||||||
m_Field->showMessage(tr("Game started!"), 1000);
|
m_Field->showMessage(tr("Game started!"), 1000);
|
||||||
}
|
}
|
||||||
else if (notPaused)
|
else
|
||||||
m_Field->resume();
|
pauseGame(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char magicSaveGameHeader[] = {'C', 'R', 'S', 'V'};
|
||||||
|
|
||||||
|
void CGameWindow::saveGame() {
|
||||||
|
if (!m_Field->isPaused())
|
||||||
|
m_PauseGameAction->setChecked(true);
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Save current game"),
|
||||||
|
QDir::homePath(), tr("QCross Saved games (*.csg)"));
|
||||||
|
|
||||||
|
qDebug("saving game state file: %s", fileName.toAscii().data());
|
||||||
|
QFile file(fileName);
|
||||||
|
if (!file.open(QIODevice::WriteOnly))
|
||||||
|
return;
|
||||||
|
|
||||||
|
QDataStream out(&file);
|
||||||
|
out.setVersion(QDataStream::Qt_4_0);
|
||||||
|
|
||||||
|
out.writeRawData(magicSaveGameHeader, 4);
|
||||||
|
|
||||||
|
out << int(-1); // debug: m_PicutreIndex
|
||||||
|
|
||||||
|
out << *m_Picture;
|
||||||
|
|
||||||
|
m_Field->dumpState(out);
|
||||||
|
|
||||||
|
m_PauseGameAction->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameWindow::loadGame() {
|
||||||
|
if (!m_Field->isPaused())
|
||||||
|
m_PauseGameAction->setChecked(true);
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open saved game"),
|
||||||
|
QDir::homePath(), tr("QCross Saved games (*.csg)"));
|
||||||
|
|
||||||
|
qDebug("opening game state file: %s", fileName.toAscii().data());
|
||||||
|
QFile file(fileName);
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
return;
|
||||||
|
|
||||||
|
QDataStream in(&file);
|
||||||
|
in.setVersion(QDataStream::Qt_4_0);
|
||||||
|
|
||||||
|
char magicHeader[4];
|
||||||
|
in.readRawData(magicHeader, 4);
|
||||||
|
|
||||||
|
qDebug("checking magic header");
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (magicHeader[i] != magicSaveGameHeader[i])
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// picture index
|
||||||
|
in >> m_PictureIndex; qDebug("m_PictureIndex = %i", m_PictureIndex);
|
||||||
|
|
||||||
|
// delete current highscore
|
||||||
|
if (m_Highscore)
|
||||||
|
delete m_Highscore;
|
||||||
|
|
||||||
|
// package name
|
||||||
|
if (m_PictureIndex > -1) {
|
||||||
|
QString highscoreFileName, packageName;
|
||||||
|
in >> packageName; qDebug("packageName = %s", qPrintable(packageName));
|
||||||
|
in >> highscoreFileName; qDebug("highscoreFileName = %s", qPrintable(highscoreFileName));
|
||||||
|
|
||||||
|
// TODO handle save game porting correctly
|
||||||
|
m_Highscore = new CHighscore(0);
|
||||||
|
m_Highscore->setFileName(QCROSS_STRING_DATAPATH + QDir::separator() + highscoreFileName);
|
||||||
|
m_Highscore->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// picture
|
||||||
|
CNonogram * newPicture = new CNonogram(in);
|
||||||
|
|
||||||
|
m_Field->setPicture(newPicture);
|
||||||
|
if (m_Picture)
|
||||||
|
delete m_Picture;
|
||||||
|
|
||||||
|
m_Picture = newPicture;
|
||||||
|
m_Field->applyState(in);
|
||||||
|
|
||||||
|
m_PauseGameAction->setEnabled(true);
|
||||||
|
m_PauseGameAction->setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameWindow::restartGame() {
|
void CGameWindow::restartGame() {
|
||||||
@ -137,8 +230,8 @@ namespace qcross {
|
|||||||
|
|
||||||
void CGameWindow::pauseGame(bool value) {
|
void CGameWindow::pauseGame(bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
m_Field->showMessage(tr("Game paused."));
|
|
||||||
m_Field->pause();
|
m_Field->pause();
|
||||||
|
m_Field->showMessage(tr("Game paused."));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_Field->showMessage(tr("Game resumed."), 1000);
|
m_Field->showMessage(tr("Game resumed."), 1000);
|
||||||
@ -172,4 +265,12 @@ namespace qcross {
|
|||||||
void CGameWindow::about() {
|
void CGameWindow::about() {
|
||||||
QMessageBox::about(this, tr("About"), tr("This is a still unfancy gui for solving nonograms."));
|
QMessageBox::about(this, tr("About"), tr("This is a still unfancy gui for solving nonograms."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameWindow::startSolver() {
|
||||||
|
m_Solver->setNonogram(m_Picture);
|
||||||
|
|
||||||
|
restartGame();
|
||||||
|
|
||||||
|
m_Solver->solve();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,9 @@
|
|||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CNonogram;
|
class CNonogram;
|
||||||
|
class CNonogramSolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace qcross {
|
namespace qcross {
|
||||||
@ -40,8 +41,10 @@ namespace qcross {
|
|||||||
~CGameWindow();
|
~CGameWindow();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
libqnono::CNonogramSolver * m_Solver;
|
||||||
|
|
||||||
CCrossFieldWidget * m_Field;
|
CCrossFieldWidget * m_Field;
|
||||||
libqcross::CNonogram * m_Picture;
|
libqnono::CNonogram * m_Picture;
|
||||||
|
|
||||||
CHighscore * m_Highscore;
|
CHighscore * m_Highscore;
|
||||||
int m_PictureIndex;
|
int m_PictureIndex;
|
||||||
@ -53,8 +56,10 @@ namespace qcross {
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void newGame();
|
void newGame();
|
||||||
// void createPackage();
|
|
||||||
// void openPackageImage();
|
void saveGame();
|
||||||
|
void loadGame();
|
||||||
|
|
||||||
void restartGame();
|
void restartGame();
|
||||||
void pauseGame(bool value);
|
void pauseGame(bool value);
|
||||||
|
|
||||||
@ -64,6 +69,8 @@ namespace qcross {
|
|||||||
void handleErrorMark();
|
void handleErrorMark();
|
||||||
|
|
||||||
void about();
|
void about();
|
||||||
|
|
||||||
|
void startSolver();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <libqcross/ccrosspackage.h>
|
#include <libqnono/ccrosspackage.h>
|
||||||
#include <libqcross/cnonogram.h>
|
#include <libqnono/cnonogram.h>
|
||||||
|
|
||||||
#include "cmaskedcrosspackagemodel.h"
|
#include "cmaskedcrosspackagemodel.h"
|
||||||
#include "chighscore.h"
|
#include "chighscore.h"
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#define COL_TIME 1
|
#define COL_TIME 1
|
||||||
|
|
||||||
namespace qcross {
|
namespace qcross {
|
||||||
using namespace libqcross;
|
using namespace libqnono;
|
||||||
//public:
|
//public:
|
||||||
CMaskedCrossPackageModel::CMaskedCrossPackageModel(QObject * parent) :
|
CMaskedCrossPackageModel::CMaskedCrossPackageModel(QObject * parent) :
|
||||||
CCrossPackageModel(parent), m_Highscore(NULL) {}
|
CCrossPackageModel(parent), m_Highscore(NULL) {}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#ifndef QCROSS_CMASKEDCROSSPACKAGEMODEL_H
|
#ifndef QCROSS_CMASKEDCROSSPACKAGEMODEL_H
|
||||||
#define QCROSS_CMASKEDCROSSPACKAGEMODEL_H
|
#define QCROSS_CMASKEDCROSSPACKAGEMODEL_H
|
||||||
|
|
||||||
#include <libqcross/ccrosspackagemodel.h>
|
#include <libqnono/ccrosspackagemodel.h>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
namespace qcross {
|
namespace qcross {
|
||||||
@ -29,7 +29,7 @@ namespace qcross {
|
|||||||
/**
|
/**
|
||||||
@author Oliver Groß <z.o.gross@gmx.de>
|
@author Oliver Groß <z.o.gross@gmx.de>
|
||||||
*/
|
*/
|
||||||
class CMaskedCrossPackageModel : public libqcross::CCrossPackageModel {
|
class CMaskedCrossPackageModel : public libqnono::CCrossPackageModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CMaskedCrossPackageModel(QObject * parent = 0);
|
CMaskedCrossPackageModel(QObject * parent = 0);
|
||||||
|
@ -25,10 +25,9 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
|
||||||
#include <libqcross/ccrosspackagelistmodel.h>
|
#include <libqnono/ccrosspackagelistmodel.h>
|
||||||
// #include <libqcross/ccrosspackagemodel.h>
|
#include <libqnono/ccrosspackage.h>
|
||||||
#include <libqcross/ccrosspackage.h>
|
#include <libqnono/cnonogram.h>
|
||||||
#include <libqcross/cnonogram.h>
|
|
||||||
#include "cmaskedcrosspackagemodel.h"
|
#include "cmaskedcrosspackagemodel.h"
|
||||||
#include "chighscore.h"
|
#include "chighscore.h"
|
||||||
#include "cnewgamedialog.h"
|
#include "cnewgamedialog.h"
|
||||||
@ -36,12 +35,12 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
namespace qcross {
|
namespace qcross {
|
||||||
using namespace libqcross;
|
using namespace libqnono;
|
||||||
|
|
||||||
//public:
|
//public:
|
||||||
CNewGameDialog::CNewGameDialog(QWidget * parent, Qt::WindowFlags f) :
|
CNewGameDialog::CNewGameDialog(QWidget * parent, Qt::WindowFlags f) :
|
||||||
QDialog(parent, f),
|
QDialog(parent, f),
|
||||||
m_Highscore(new CHighscore(0)),
|
m_Highscore(NULL),
|
||||||
m_Nonogram(NULL)
|
m_Nonogram(NULL)
|
||||||
{
|
{
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
@ -56,7 +55,7 @@ namespace qcross {
|
|||||||
ui.buttonBox->addButton(importButton, QDialogButtonBox::ActionRole);
|
ui.buttonBox->addButton(importButton, QDialogButtonBox::ActionRole);
|
||||||
ui.buttonBox->addButton(openPicFileButton, QDialogButtonBox::ActionRole);
|
ui.buttonBox->addButton(openPicFileButton, QDialogButtonBox::ActionRole);
|
||||||
|
|
||||||
ui.packageList->setModel(new CCrossPackageListModel(QCROSS_STRING_DATAPATH));
|
ui.packageList->setModel(new CCrossPackageListModel(QCROSS_STRING_DATAPATH, "*" QCROSS_STRING_PACKAGE_EXT));
|
||||||
m_PicModel = new CMaskedCrossPackageModel();
|
m_PicModel = new CMaskedCrossPackageModel();
|
||||||
m_PicProxyModel = new CMaskedCrossPackageProxyModel();
|
m_PicProxyModel = new CMaskedCrossPackageProxyModel();
|
||||||
m_PicProxyModel->setSourceModel(m_PicModel);
|
m_PicProxyModel->setSourceModel(m_PicModel);
|
||||||
@ -84,7 +83,7 @@ namespace qcross {
|
|||||||
delete m_Nonogram;
|
delete m_Nonogram;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* libqcross::CNonogram * CNewGameDialog::selectedNonogramData() const {
|
/* libqnono::CNonogram * CNewGameDialog::selectedNonogramData() const {
|
||||||
QModelIndex selected = ui.picList->selectionModel()->selectedIndexes()[0];
|
QModelIndex selected = ui.picList->selectionModel()->selectedIndexes()[0];
|
||||||
return static_cast<CNonogram *>(selected.internalPointer());
|
return static_cast<CNonogram *>(selected.internalPointer());
|
||||||
}*/
|
}*/
|
||||||
@ -94,13 +93,13 @@ namespace qcross {
|
|||||||
return selected.row();
|
return selected.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
libqcross::CCrossPackage * CNewGameDialog::selectedPackage() const {
|
libqnono::CCrossPackage * CNewGameDialog::selectedPackage() const {
|
||||||
QModelIndex selected = ui.packageList->selectionModel()->selectedIndexes()[0];
|
QModelIndex selected = ui.packageList->selectionModel()->selectedIndexes()[0];
|
||||||
return static_cast<CCrossPackage *>(selected.internalPointer());
|
return static_cast<CCrossPackage *>(selected.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
libqcross::CNonogram * CNewGameDialog::takeNonogram() {
|
libqnono::CNonogram * CNewGameDialog::takeNonogram() {
|
||||||
libqcross::CNonogram * result;
|
libqnono::CNonogram * result;
|
||||||
|
|
||||||
if (m_Nonogram) {
|
if (m_Nonogram) {
|
||||||
result = m_Nonogram;
|
result = m_Nonogram;
|
||||||
@ -134,6 +133,9 @@ namespace qcross {
|
|||||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select a package to import"),
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Select a package to import"),
|
||||||
QDir::homePath(), tr("QCross Package (*.cpk)"));
|
QDir::homePath(), tr("QCross Package (*.cpk)"));
|
||||||
if (!fileName.isEmpty()) {
|
if (!fileName.isEmpty()) {
|
||||||
|
/* if (!File::exists(QCROSS_STRING_DATAPATH))
|
||||||
|
QDir::mkpath(QCROSS_STRING_DATAPATH);*/
|
||||||
|
|
||||||
QString newFileName = QCROSS_STRING_DATAPATH + QDir::separator() + fileName.section(QDir::separator(), -1);
|
QString newFileName = QCROSS_STRING_DATAPATH + QDir::separator() + fileName.section(QDir::separator(), -1);
|
||||||
if (QFile::copy(fileName, newFileName))
|
if (QFile::copy(fileName, newFileName))
|
||||||
dynamic_cast<CCrossPackageListModel *>(ui.packageList->model())->update();
|
dynamic_cast<CCrossPackageListModel *>(ui.packageList->model())->update();
|
||||||
@ -169,6 +171,9 @@ namespace qcross {
|
|||||||
m_PicModel->setHighscore(NULL);
|
m_PicModel->setHighscore(NULL);
|
||||||
m_PicModel->setPackage(package);
|
m_PicModel->setPackage(package);
|
||||||
|
|
||||||
|
if (!m_Highscore)
|
||||||
|
m_Highscore = new CHighscore(0);
|
||||||
|
|
||||||
m_Highscore->setFileName(getHighscoreFileName(package->fileName()));
|
m_Highscore->setFileName(getHighscoreFileName(package->fileName()));
|
||||||
if (!m_Highscore->open()) {
|
if (!m_Highscore->open()) {
|
||||||
qDebug("opening highscore file failed. will create a new one when nonogram is solved");
|
qDebug("opening highscore file failed. will create a new one when nonogram is solved");
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "ui_picselect.h"
|
#include "ui_picselect.h"
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CNonogram;
|
class CNonogram;
|
||||||
class CCrossPackage;
|
class CCrossPackage;
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ namespace qcross {
|
|||||||
~CNewGameDialog();
|
~CNewGameDialog();
|
||||||
|
|
||||||
int nonogramIndex() const;
|
int nonogramIndex() const;
|
||||||
libqcross::CCrossPackage * selectedPackage() const;
|
libqnono::CCrossPackage * selectedPackage() const;
|
||||||
|
|
||||||
libqcross::CNonogram * takeNonogram();
|
libqnono::CNonogram * takeNonogram();
|
||||||
CHighscore * takeHighscore();
|
CHighscore * takeHighscore();
|
||||||
protected slots:
|
protected slots:
|
||||||
void importPackage();
|
void importPackage();
|
||||||
@ -53,7 +53,7 @@ namespace qcross {
|
|||||||
private:
|
private:
|
||||||
Ui::picselect ui;
|
Ui::picselect ui;
|
||||||
CHighscore * m_Highscore;
|
CHighscore * m_Highscore;
|
||||||
libqcross::CNonogram * m_Nonogram;
|
libqnono::CNonogram * m_Nonogram;
|
||||||
CMaskedCrossPackageModel * m_PicModel;
|
CMaskedCrossPackageModel * m_PicModel;
|
||||||
CMaskedCrossPackageProxyModel * m_PicProxyModel;
|
CMaskedCrossPackageProxyModel * m_PicProxyModel;
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
#ifndef QCROSS_CONSTANTS_H
|
#ifndef QCROSS_CONSTANTS_H
|
||||||
#define QCROSS_CONSTANTS_H
|
#define QCROSS_CONSTANTS_H
|
||||||
|
|
||||||
#include <libqcross/constants.h>
|
#include <libqnono/constants.h>
|
||||||
|
|
||||||
#define QCROSS_STRING_DATAPATH ((QDir::homePath() + QDir::separator()) + ".qcross")
|
#define QCROSS_STRING_DATAPATH ((QDir::homePath() + QDir::separator()) + ".qcross")
|
||||||
|
#define QCROSS_STRING_PACKAGE_EXT ".cpk"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
|
||||||
#include <libqcross/ccrosspackagemodel.h>
|
#include <libqnono/ccrosspackagemodel.h>
|
||||||
#include <libqcross/ccrosspackage.h>
|
#include <libqnono/ccrosspackage.h>
|
||||||
|
|
||||||
#include "cmainwindow.h"
|
#include "cmainwindow.h"
|
||||||
|
|
||||||
namespace qcrossedit {
|
namespace qcrossedit {
|
||||||
using namespace libqcross;
|
using namespace libqnono;
|
||||||
//public:
|
//public:
|
||||||
CMainWindow::CMainWindow(QWidget *parent) :
|
CMainWindow::CMainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
@ -60,9 +60,11 @@ namespace qcrossedit {
|
|||||||
//edit menu
|
//edit menu
|
||||||
menu = menuBar()->addMenu("&Edit");
|
menu = menuBar()->addMenu("&Edit");
|
||||||
menu->addAction("&Create empty nonogram...", this, SLOT(editCreateEmpty()));
|
menu->addAction("&Create empty nonogram...", this, SLOT(editCreateEmpty()));
|
||||||
menu->addAction("&Create nonogram from picture...", this, SLOT(editCreateFromPicture()));
|
menu->addAction("Create nonogram from &picture...", this, SLOT(editCreateFromPicture()));
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addAction("&Delete nongram", this, SLOT(editDelete()));
|
menu->addAction("&Rename nonogram", this, SLOT(editRename()));
|
||||||
|
menu->addAction("Set nonogram &time-out", this, SLOT(editSetTimeout()));
|
||||||
|
menu->addAction("&Delete nonogram", this, SLOT(editDelete()));
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addAction("Set Package&name...", this, SLOT(editSetPackageName()));
|
menu->addAction("Set Package&name...", this, SLOT(editSetPackageName()));
|
||||||
|
|
||||||
@ -180,6 +182,13 @@ namespace qcrossedit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMainWindow::editRename() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMainWindow::editSetTimeout() {
|
||||||
|
QInputDialog::getInt(this, tr("Set time-out for selected nonogram (in minutes)"));
|
||||||
|
}
|
||||||
|
|
||||||
void CMainWindow::editDelete() {
|
void CMainWindow::editDelete() {
|
||||||
QModelIndexList selectedIndexes = m_PicListView->selectionModel()->selectedIndexes();
|
QModelIndexList selectedIndexes = m_PicListView->selectionModel()->selectedIndexes();
|
||||||
foreach (QModelIndex i, selectedIndexes)
|
foreach (QModelIndex i, selectedIndexes)
|
||||||
|
@ -14,7 +14,7 @@ class QTreeView;
|
|||||||
// class QBitmap;
|
// class QBitmap;
|
||||||
//class QMenu;
|
//class QMenu;
|
||||||
|
|
||||||
namespace libqcross {
|
namespace libqnono {
|
||||||
class CCrossPackage;
|
class CCrossPackage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ namespace qcrossedit {
|
|||||||
// QString m_File;
|
// QString m_File;
|
||||||
bool m_Unsaved;
|
bool m_Unsaved;
|
||||||
|
|
||||||
libqcross::CCrossPackage * m_Package;
|
libqnono::CCrossPackage * m_Package;
|
||||||
|
|
||||||
/* QBitmap * m_Pics;
|
/* QBitmap * m_Pics;
|
||||||
QString * m_PackName;*/
|
QString * m_PackName;*/
|
||||||
@ -51,6 +51,8 @@ namespace qcrossedit {
|
|||||||
|
|
||||||
void editCreateEmpty();
|
void editCreateEmpty();
|
||||||
void editCreateFromPicture();
|
void editCreateFromPicture();
|
||||||
|
void editRename();
|
||||||
|
void editSetTimeout();
|
||||||
void editDelete();
|
void editDelete();
|
||||||
void editSetPackageName();
|
void editSetPackageName();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user