[code]
#include "StdAfx.h"
#include "resource.h"
using namespace std;
using std::map;
#include <algorithm>
#include <vector>
bool comparePoints (const AcGePoint3d a, const AcGePoint3d b)
{
if (a.x == b.x)
{
if (a.y == b.y)
return (a.z > b.z);
else
return (a.y > b.y);
}
else
return (a.x > b.x);
}
bool compare(std::pair<AcString, AcGePoint3d> pairOne, std::pair<AcString, AcGePoint3d> pairTwo)
{
//return pairOne.first < pairTwo.first; // sort alphabetically
AcGePoint3d a = pairOne.second, b = pairTwo.second;
if (a.x == b.x)
{
if (a.y == b.y)
return (a.z > b.z);
else
return (a.y > b.y);
}
else
return (a.x > b.x);
}
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;
AcArray<AcString> justStrings;
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);
int rows = pts_hor_top.length();
int columns = rows;
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;
for (int row = 0; row < rows; row++)
{
for (int i = 0; i < allCharacters.length(); i++)
{
AcGePoint3d ptSearch = allCharacters[i].second;
if (pt.y == ptSearch.y)
{
if (!horizontal.contains(allCharacters[i]) && (horizontal.length() < rows))
{
horizontal.append(allCharacters[i]);
}
}
}
if (!horizontals.contains(horizontal))
{
std::sort(horizontal.asArrayPtr(), horizontal.asArrayPtr() + horizontal.length(), compare);
horizontal.reverse();
horizontals.append(horizontal);
}
horizontal.removeAll();
pt.set(pt.x, pt.y - d, pt.z); // move down
}
// save verticals up-down
pt = p4;
for (int row = 0; row < rows; row++)
{
for (int i = 0; i < allCharacters.length(); i++)
{
AcGePoint3d ptSearch = allCharacters[i].second;
if (pt.x == ptSearch.x)
{
if (!vertical.contains(allCharacters[i]) && (vertical.length() < rows))
{
vertical.append(allCharacters[i]);
}
}
}
if (!verticals.contains(vertical))
{
std::sort(vertical.asArrayPtr(), vertical.asArrayPtr() + vertical.length(), compare);
verticals.append(vertical);
}
vertical.removeAll();
pt.set(pt.x + d, pt.y - d, pt.z);
}
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();
for (int j = 0; j < pts_hor_top.length(); j++)
{
pt = pts_hor_top[j];
for (int row = 0; row < rows; row++)
{
for (int i = 0; i < allCharacters.length(); i++)
{
AcGePoint3d ptSearch = allCharacters[i].second;
if (pt.isEqualTo(ptSearch))
{
if (!diagonal.contains(allCharacters[i]))
{
diagonal.append(allCharacters[i]);
}
break;
}
}
pt = pt + (v1 * ddiag);
}
if (!diagonals.contains(diagonal))
{
diagonals.append(diagonal);
}
diagonal.removeAll();
}
pts_ver_left.removeAt(0); // remove first spot
for (int j = 0; j < pts_ver_left.length(); j++)
{
pt = pts_ver_left[j];
diagonal.removeAll();
for (int row = 0; row < rows; row++)
{
for (int i = 0; i < allCharacters.length(); i++)
{
AcGePoint3d ptSearch = allCharacters[i].second;
if (pt.isEqualTo(ptSearch))
{
if (!diagonal.contains(allCharacters[i]))
{
diagonal.append(allCharacters[i]);
}
break;
}
}
pt = pt + (v1 * ddiag);
}
if (!diagonals.contains(diagonal))
{
diagonals.append(diagonal);
}
diagonal.removeAll();
}
// save diagonals
pts_hor_bottom.reverse();
for (int j = 0; j < pts_hor_bottom.length(); j++)
{
pt = pts_hor_bottom[j];
diagonal.removeAll();
for (int row = 0; row < rows; row++)
{
for (int i = 0; i < allCharacters.length(); i++)
{
AcGePoint3d ptSearch = allCharacters[i].second;
if (pt.isEqualTo(ptSearch))
{
if (!diagonal.contains(allCharacters[i]))
{
diagonal.append(allCharacters[i]);
}
break;
}
}
pt = pt + (v2 * ddiag);
}
if (!diagonals.contains(diagonal))
{
diagonals.append(diagonal);
}
diagonal.removeAll();
}
for (int j = 0; j < pts_ver_left.length(); j++)
{
pt = pts_ver_left[j];
diagonal.removeAll();
for (int row = 0; row < rows; row++)
{
for (int i = 0; i < allCharacters.length(); i++)
{
AcGePoint3d ptSearch = allCharacters[i].second;
if (pt.isEqualTo(ptSearch))
{
if (!diagonal.contains(allCharacters[i]))
{
diagonal.append(allCharacters[i]);
}
break;
}
}
pt = pt + (v2 * ddiag);
}
if (!diagonals.contains(diagonal))
{
diagonals.append(diagonal);
}
diagonal.removeAll();
}
// look for the word
for (int k = 0; k < words.length(); k++)
{
AcString word = words[k];
AcArray<AcString> temp;
AcGePoint3d sp, ep;
bool found = false;
AcString firstChar = word.substr(0, 1);
AcString lastChar = word.substr(word.length() - 1, 1);
// search on horizontals
for (int i = 0; i < horizontals.length(); i++)
{
AcArray<std::pair<AcString, AcGePoint3d>> row_horizontal = horizontals[i];
temp.removeAll();
for (int j = 0; j < row_horizontal.length(); j++)
{
AcString s = row_horizontal[j].first;
if (word.find(s) != -1)
{
temp.append(s);
}
}
int counter = 0;
bool hasDupplicates = false;
bool atTheEnd = false;
bool startLeftRight = false;
AcArray<AcString> chars;
for (int c = 0; c < word.length(); c++)
{
AcString ch = word.substr(c, 1);
chars.append(ch);
if (temp.contains(ch))
{
counter++;
}
}
for (int i = 0; i < chars.length(); i++)
{
AcString s = chars[i];
for (int ii = 0; ii < chars.length(); ii++)
{
if (chars[ii] == s)
{
if (chars[ii+1] == s)
{
hasDupplicates = true;
if (ii+1 == (chars.length() - 1))
{
atTheEnd = true;
}
break;
}
}
}
}
if (temp.length() >= word.length() && counter >= word.length())
{
if (temp[0] == firstChar && temp[1] == word.substr(1, 1))
{
startLeftRight = true;
}
else
{
startLeftRight = false;
}
bool foundSP = false;
bool foundEP = false;
for (int i = 0; i < row_horizontal.length(); i++)
{
if (row_horizontal[i].first == firstChar)
{
sp = row_horizontal[i].second;
foundSP = true;
break;
}
}
for (int i = 0; i < row_horizontal.length(); i++)
{
if (row_horizontal[i].first == lastChar)
{
ep = row_horizontal[i].second;
if (atTheEnd)
{
ep = row_horizontal[i+1].second;
}
foundEP = true;
break;
}
}
if (foundSP && foundEP && startLeftRight)
{
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
else
{
row_horizontal.reverse();
for (int i = 0; i < row_horizontal.length(); i++)
{
if (row_horizontal[i].first == firstChar)
{
sp = row_horizontal[i].second;
break;
}
}
for (int i = 0; i < row_horizontal.length(); i++)
{
if (row_horizontal[i].first == lastChar)
{
ep = row_horizontal[i].second;
if (atTheEnd)
{
ep = row_horizontal[i+1].second;
}
break;
}
}
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
break;
}
}
// search on verticals
for (int i = 0; i < verticals.length(); i++)
{
AcArray<std::pair<AcString, AcGePoint3d>> row_vertical = verticals[i];
temp.removeAll();
for (int j = 0; j < row_vertical.length(); j++)
{
AcString s = row_vertical[j].first;
if (word.find(s) != -1)
{
temp.append(s);
}
}
int counter = 0;
bool hasDupplicates = false;
bool atTheEnd = false;
bool startLeftRight = false;
AcArray<AcString> chars;
for (int c = 0; c < word.length(); c++)
{
AcString ch = word.substr(c, 1);
chars.append(ch);
if (temp.contains(ch))
{
counter++;
}
}
for (int i = 0; i < chars.length(); i++)
{
AcString s = chars[i];
for (int ii = 0; ii < chars.length(); ii++)
{
if (chars[ii] == s)
{
if (chars[ii+1] == s)
{
hasDupplicates = true;
if (ii+1 == (chars.length() - 1))
{
atTheEnd = true;
}
break;
}
}
}
}
if (temp.length() >= word.length() && counter >= word.length())
{
if (temp[0] == firstChar && temp[1] == word.substr(1, 1))
{
startLeftRight = true;
}
else
{
startLeftRight = false;
}
bool foundSP = false;
bool foundEP = false;
for (int i = 0; i < row_vertical.length(); i++)
{
if (row_vertical[i].first == firstChar)
{
sp = row_vertical[i].second;
foundSP = true;
break;
}
}
for (int i = 0; i < row_vertical.length(); i++)
{
if (row_vertical[i].first == lastChar)
{
ep = row_vertical[i].second;
if (atTheEnd)
{
ep = row_vertical[i+1].second;
}
foundEP = true;
break;
}
}
if (foundSP && foundEP && startLeftRight)
{
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
else
{
row_vertical.reverse();
for (int i = 0; i < row_vertical.length(); i++)
{
if (row_vertical[i].first == firstChar)
{
sp = row_vertical[i].second;
break;
}
}
for (int i = 0; i < row_vertical.length(); i++)
{
if (row_vertical[i].first == lastChar)
{
ep = row_vertical[i].second;
if (atTheEnd)
{
ep = row_vertical[i+1].second;
}
break;
}
}
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
}
temp.removeAll();
}
// search on diagonals
for (int i = 0; i < diagonals.length(); i++)
{
AcArray<std::pair<AcString, AcGePoint3d>> row_diagonal = diagonals[i];
temp.removeAll();
for (int j = 0; j < row_diagonal.length(); j++)
{
AcString s = row_diagonal[j].first;
if (word.find(s) != -1)
{
temp.append(s);
}
}
int counter = 0;
bool hasDupplicates = false;
bool atTheEnd = false;
bool startLeftRight = false;
AcArray<AcString> chars;
for (int c = 0; c < word.length(); c++)
{
AcString ch = word.substr(c, 1);
chars.append(ch);
if (temp.contains(ch))
{
counter++;
}
}
for (int i = 0; i < chars.length(); i++)
{
AcString s = chars[i];
for (int ii = 0; ii < chars.length(); ii++)
{
if (chars[ii] == s)
{
if (chars[ii+1] == s)
{
hasDupplicates = true;
if (ii+1 == (chars.length() - 1))
{
atTheEnd = true;
}
break;
}
}
}
}
if (temp.length() >= word.length() && counter >= word.length())
{
if (temp[0] == firstChar && temp[1] == word.substr(1, 1))
{
startLeftRight = true;
}
else
{
startLeftRight = false;
}
bool foundSP = false;
bool foundEP = false;
for (int i = 0; i < row_diagonal.length(); i++)
{
if (row_diagonal[i].first == firstChar)
{
sp = row_diagonal[i].second;
foundSP = true;
break;
}
}
for (int i = 0; i < row_diagonal.length(); i++)
{
if (row_diagonal[i].first == lastChar)
{
ep = row_diagonal[i].second;
if (atTheEnd)
{
ep = row_diagonal[i+1].second;
}
foundEP = true;
break;
}
}
if (foundSP && foundEP && startLeftRight)
{
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
else
{
row_diagonal.reverse();
for (int i = 0; i < row_diagonal.length(); i++)
{
if (row_diagonal[i].first == firstChar)
{
sp = row_diagonal[i].second;
break;
}
}
for (int i = 0; i < row_diagonal.length(); i++)
{
if (row_diagonal[i].first == lastChar)
{
ep = row_diagonal[i].second;
if (atTheEnd)
{
ep = row_diagonal[i+1].second;
}
break;
}
}
AcDbObjectPointer<AcDbLine> pLine;
pLine.create();
pLine->setStartPoint(sp);
pLine->setEndPoint(ep);
pBTR->appendAcDbEntity(pLine);
}
}
temp.removeAll();
}
}
}
}