static void LESQWordPuzzle_WORDPUZZLE(void)
{
AcArray<AcString> words;
words.append(_T("BOX"));
words.append(_T("MAD"));
words.append(_T("AMASS"));
words.append(_T("LSP"));
words.append(_T("EGG"));
words.append(_T("AXE"));
words.append(_T("ATTIC"));
words.append(_T("GLAD"));
ads_name ss;
resbuf *rbFilter = acutBuildList(RTDXF0, _T("TEXT"), RTNONE);
if (acedSSGet(NULL, NULL, NULL, rbFilter, ss) != RTNORM)
{
acutRelRb(rbFilter); return;
}
acutRelRb(rbFilter);
long length = 0;
if ((acedSSLength(ss, &length) != RTNORM) || (length == 0))
{
acedSSFree(ss); return;
}
AcArray<std::pair<AcString, AcGePoint3d>> allCharacters;
AcArray<std::pair<AcString, AcGePoint3d>> characters;
AcGePoint3dArray pts;
AcDbExtents ext;
AcDbObjectId id; ads_name ename;
for (int i = 0; i < length; i++)
{
if (acedSSName(ss, i, ename) == RTNORM)
{
if (acdbGetObjectId(id, ename) == Acad::eOk)
{
AcDbObjectPointer<AcDbText> pText(id, AcDb::kForRead);
if (pText.openStatus() == Acad::eOk)
{
AcString s = pText->textString();
for (int j = 0; j < words.length(); j++)
{
AcString word = words[j];
if (word.find(s) != -1)
{
pts.append(pText->alignmentPoint());
ext.addPoint(pText->alignmentPoint());
allCharacters.append(make_pair(s, pText->alignmentPoint()));
}
}
}
}
}
}
if (allCharacters.length() > 0)
{
AcDbBlockTableRecordPointer pBTR(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
if (pBTR.openStatus() != Acad::eOk) return;
AcGePoint3d p1 = ext.minPoint();
AcGePoint3d p3 = ext.maxPoint();
AcGePoint3d p2(p3.x, p1.y, p1.z);
AcGePoint3d p4(p1.x, p3.y, p1.z);
AcGePoint3dArray pts_hor_top, pts_ver_left, pts_hor_bottom;
for (int i = 0; i < pts.length(); i++)
{
if (pts[i].y == p4.y)
{
if (!pts_hor_top.contains(pts[i]))
{
pts_hor_top.append(pts[i]);
}
}
if (pts[i].x == p4.x)
{
if (!pts_ver_left.contains(pts[i]))
{
pts_ver_left.append(pts[i]);
}
}
if (pts[i].y == p1.y)
{
if (!pts_hor_bottom.contains(pts[i]))
{
pts_hor_bottom.append(pts[i]);
}
}
}
std::sort(pts_hor_top.asArrayPtr(), pts_hor_top.asArrayPtr() + pts_hor_top.length(), comparePoints);
std::sort(pts_ver_left.asArrayPtr(), pts_ver_left.asArrayPtr() + pts_ver_left.length(), comparePoints);
std::sort(pts_hor_bottom.asArrayPtr(), pts_hor_bottom.asArrayPtr() + pts_hor_bottom.length(), comparePoints);
// not same rows and columns
if (pts_hor_top.length() != pts_ver_left.length()) return;
int rows = pts_hor_top.length();
double d = p4.distanceTo(p3) / (rows - 1);
AcArray<AcArray<std::pair<AcString, AcGePoint3d>>> horizontals, verticals, diagonals;
AcArray<std::pair<AcString, AcGePoint3d>> horizontal, vertical, diagonal;
// save horizontals up-down
AcGePoint3d pt = p4;
HorizontalSearch(rows, allCharacters, pt, horizontal, horizontals, d);
// save verticals up-down
pt = p4;
VerticalSearch(rows, allCharacters, pt, vertical, verticals, d);
AcGeVector3d v1 = (p2 - p4).normalize();
AcGeVector3d v2 = (p3 - p1).normalize();
AcGePoint3d ptx(p4.x - d, p4.y - d, p4.z);
double ddiag = p4.distanceTo(ptx);
// save diagonals
pts_hor_top.reverse();
DiagonalSearch(pts_hor_top, pt, rows, allCharacters, diagonal, v1, ddiag, diagonals);
pts_ver_left.removeAt(0); // remove first spot
DiagonalSearch(pts_ver_left, pt, rows, allCharacters, diagonal, v1, ddiag, diagonals);
pts_hor_bottom.reverse();
DiagonalSearch(pts_hor_bottom, pt, rows, allCharacters, diagonal, v2, ddiag, diagonals);
DiagonalSearch(pts_ver_left, pt, rows, allCharacters, diagonal, v2, ddiag, diagonals);
for (int i = 0; i < words.length(); i++)
{
AcString word = words[i];
AcGePoint3d sp, ep;
bool found = false;
// search on horizontals
SearchOn(horizontals, word, sp, ep, found);
if (found)
{
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
// search on verticals
SearchOn(verticals, word, sp, ep, found);
if (found)
{
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
SearchOn(diagonals, word, sp, ep, found);
if (found)
{
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
}
}
}