2010-06-16 12:53:56 +00:00
|
|
|
#include "cnonogramsolver.h"
|
|
|
|
#include "cnonogram.h"
|
|
|
|
|
2011-12-21 11:49:33 +00:00
|
|
|
#include <QString>
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
namespace libqnono {
|
|
|
|
CNonogramSolver::CNonogramSolver(QObject * parent) : QObject(parent),
|
|
|
|
m_Nonogram(NULL),
|
|
|
|
|
|
|
|
m_RowsOverlay(NULL),
|
|
|
|
m_ColumnsOverlay(NULL),
|
|
|
|
|
|
|
|
m_OverlayData(NULL)
|
|
|
|
{
|
2010-06-16 12:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CNonogramSolver::~CNonogramSolver() {
|
2011-12-21 11:49:33 +00:00
|
|
|
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));
|
2010-06-16 12:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CNonogramSolver::solve() {
|
|
|
|
if (!m_Nonogram)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
cleanup();
|
2011-12-21 11:49:33 +00:00
|
|
|
prepare();
|
|
|
|
|
|
|
|
qDebug("clearing trivial lines ...");
|
|
|
|
|
|
|
|
// nach trivial lösbaren Reihen suchen und diese füllen bzw. abkreuzen
|
|
|
|
for (int i = 0; i < m_Nonogram->height(); i++) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-06-16 12:53:56 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < m_Nonogram->width(); i++) {
|
2011-12-21 11:49:33 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2010-06-16 12:53:56 +00:00
|
|
|
}
|
|
|
|
|
2011-12-21 11:49:33 +00:00
|
|
|
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();
|
2010-06-16 12:53:56 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-12-21 11:49:33 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-06-16 12:53:56 +00:00
|
|
|
void CNonogramSolver::cleanup() {
|
2011-12-21 11:49:33 +00:00
|
|
|
if (m_OverlayData) {
|
2010-06-16 12:53:56 +00:00
|
|
|
for (int i = 0; i < m_Nonogram->width(); i++)
|
|
|
|
delete[] m_OverlayData[i];
|
|
|
|
delete[] m_OverlayData;
|
|
|
|
}
|
2011-12-21 11:49:33 +00:00
|
|
|
|
|
|
|
if (m_RowsOverlay)
|
|
|
|
delete[] m_RowsOverlay;
|
|
|
|
|
|
|
|
if (m_ColumnsOverlay)
|
|
|
|
delete[] m_ColumnsOverlay;
|
2010-06-16 12:53:56 +00:00
|
|
|
}
|
|
|
|
|
2011-12-21 11:49:33 +00:00
|
|
|
inline void CNonogramSolver::mark(int x, int y, int marker) {
|
|
|
|
if ((x < 0) || (y < 0) || (x > m_Nonogram->width() - 1) || (y > m_Nonogram->height() - 1) || m_OverlayData[x][y] == marker)
|
|
|
|
return;
|
|
|
|
|
|
|
|
emit markRequested(x, y, marker);
|
|
|
|
m_OverlayData[x][y] = marker;
|
|
|
|
|
|
|
|
m_RowsOverlay[y].dirty = true;
|
|
|
|
m_ColumnsOverlay[x].dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void CNonogramSolver::fillRow(int index, int marker) {
|
|
|
|
for (int i = 0; i < m_Nonogram->width(); i++)
|
|
|
|
mark(i, index, marker);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2010-06-16 12:53:56 +00:00
|
|
|
}
|
|
|
|
}
|