Skip to content

Commit

Permalink
Correct behavior with void boxes. Add a test script in Python
Browse files Browse the repository at this point in the history
  • Loading branch information
jsgonsette committed May 16, 2019
1 parent 8230943 commit c643265
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 102 deletions.
Binary file modified Pictures/Crosswords.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ Assuming CMake and Visual Studio are installed on your machine,
* Run the command ```cmake --build . --config Release --target install```
* The DLL should be created in the ```./Binaries/Windows``` directory.

### Compile with CMake on Linux

Assuming CMake in installed on your machine,

* Step in ```cmake``` directory
* Run the command ```cmake ..\Sources\```
* Run the command ```cmake --build .```


## Wrappers

Expand All @@ -40,4 +48,17 @@ Assuming CMake and Visual Studio are installed on your machine,

This class provides the following API:

* **DIC_Clear:** Flush the dictionary content;
* **dic_clear:** Flush the dictionary content;
* **dic_add_entries:** Add entries to the dictionary;
* **dic_find_random_entry:** Find a random entry in the dictionary, matching a mask;
* **dic_find_entry:** Find a random entry in the dictionary, matching a mask;
* **dic_gen_num_words:** Return the number of words in the dictionary;
* **grid_erase:** Erase the grid content;
* **grid_set_size:** Set the grid size. Content can be lost when shrinking;
* **grid_set_box:** Set the type of box at a given grid coordinate;
* **grid_write:** Write a word on the grid;
* **grid_read:** Read the whole content of the grid;
* **solver_start:** Start the grid generation process;
* **solver_step:** Move a few steps in the grid generation process;
* **solver_stop:** Stop the grid generation process;

63 changes: 61 additions & 2 deletions Sources/Grid/Grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ void Grid::Erase ()
{
int i, j;
numBlackCases = 0;
numVoidBoxes = 0;

for (j = 0; j < mSy; j ++)
{
Expand All @@ -118,6 +119,62 @@ void Grid::Erase ()
Box* box = this->operator ()(i,j);
box->MakeLetter ();
if (box->IsBloc ()) numBlackCases ++;
if (box->IsVoid ()) numVoidBoxes ++;
}
}
}


// ===========================================================================
/// \brief Lock the current content of the grid
// ===========================================================================
void Grid::LockContent ()
{
int x, y;
int count = 0;
numBlackCases = 0;
numVoidBoxes = 0;

for (y = 0; y < mSy; y ++)
{
for (x = 0; x < mSx; x ++)
{
Box* box = this->operator ()(x, y);

// Lock box if it contains something
if (box->IsLetter () == false || box->GetLetter () != 0)
{
box->Lock (true);
if (box->IsBloc ()) numBlackCases ++;
if (box->IsVoid ()) numVoidBoxes ++;
}

// Otherwise, put number of non locked previous boxes in the 'tag' field
else
{
box->Lock (false);
box->tag = count;
count ++;
}
}
}
}



// ===========================================================================
/// \brief Unlock every box
// ===========================================================================
void Grid::Unlock ()
{
int x, y;

for (y = 0; y < mSy; y ++)
{
for (x = 0; x < mSx; x ++)
{
Box* box = this->operator ()(x, y);
box->Lock (false);
}
}
}
Expand Down Expand Up @@ -593,21 +650,23 @@ Grid::Space Grid::GetSpace (int x, int y) const
int Grid::GetFillRate () const
{
int notVoid = 0;
int numVoid = 0;

for (int j = 0; j < mSy; j ++)
{
for (int i = 0; i < mSx; i ++)
{
if ( this->operator ()(i,j)->IsBloc ()) notVoid ++;
if ( this->operator ()(i,j)->IsLetter ())
else if ( this->operator ()(i,j)->IsLetter ())
{
uint8_t c = (this->operator ()(i,j))->GetLetter ();
if (c != 0) notVoid ++;
}
else numVoid ++;
}
}

return (int) (100 * notVoid / (mSx*mSy));
return (int) (100 * notVoid / (mSx*mSy - numVoid));
}

// End
4 changes: 4 additions & 0 deletions Sources/Grid/Grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,15 @@ public :
void Grow (uint8_t sx, uint8_t sy);
void Draw ();
void Erase ();
void LockContent ();
void Unlock ();

uint8_t GetWidth () const {return static_cast<uint8_t>(mSx);}
uint8_t GetHeight () const { return static_cast<uint8_t>(mSy); }
void SetDensityMode (BlocDensityMode density) { this->densityMode = density; }

int GetNumBlackCases () const {return numBlackCases;}
int GetNumVoidBoxes () const { return numVoidBoxes; }
int GetFillRate () const;

void AddBloc (uint8_t x, uint8_t y);
Expand All @@ -89,6 +92,7 @@ private :

enum BlocDensityMode densityMode; ///< Allowed bloc density
int numBlackCases; ///< Total number of black boxes
int numVoidBoxes; ///< Total number of void boxes
};


Expand Down
44 changes: 7 additions & 37 deletions Sources/Solvers/SolverDynamic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ SolverDynamic::~SolverDynamic ()
// ===========================================================================
void SolverDynamic::Solve_Start (Grid &grid, const Dictionary &dico)
{
int x, y;
int count = 0;
Box *box = nullptr;

Expand All @@ -83,28 +82,7 @@ void SolverDynamic::Solve_Start (Grid &grid, const Dictionary &dico)
this->pGrid->SetDensityMode (this->densityMode);

// Lock non empty boxes
for (y = 0; y < mSy; y ++)
{
for (x = 0; x < mSx; x ++)
{
box = pGrid->operator ()(x, y);

// Lock box if it contains something
if (box->IsLetter () == false || box->GetLetter () != 0)
box->Lock (true);

// Otherwise, put number of non locked previous boxes in the 'tag' field
else
{
box->tag = count;
box->Lock (false);
count ++;
}
}
}

// Reset grid, but locked boxes
pGrid->Erase ();
pGrid->LockContent ();

// Get initial number of black boxes
initialBlackCases = pGrid->GetNumBlackCases ();
Expand All @@ -121,17 +99,7 @@ void SolverDynamic::Solve_Start (Grid &grid, const Dictionary &dico)
void SolverDynamic::Solve_Stop ()
{
// Unlock all grid boxes
if (pGrid != nullptr)
{
for (int y = 0; y < mSy; y ++)
{
for (int x = 0; x < mSx; x ++)
{
Box* box = pGrid->operator ()(x, y);
box->Lock (false);
}
}
}
if (pGrid != nullptr) pGrid->Unlock ();

this->pDict = nullptr;
this->pGrid = nullptr;
Expand Down Expand Up @@ -226,6 +194,7 @@ Status SolverDynamic::Solve_Step (int32_t maxTimeMs, int32_t maxSteps)
{
FreeItems ();
pDict = nullptr;
pGrid->Erase ();
break;
}

Expand Down Expand Up @@ -622,7 +591,7 @@ Grid::Space SolverDynamic::CheckGridBlock (int x, int y)

// Already a block ?
Box *box = pGrid->operator ()(x, y);
if (box->IsBloc () == true) return space;
if (box->IsBloc () == true || box->IsVoid ()) return space;

// A letter is already here, we can't put a block
if (box->IsLetter () && box->GetLetter () != 0)
Expand Down Expand Up @@ -812,7 +781,7 @@ bool SolverDynamic::CheckItemLength (const DynamicItem *pItem)

// Also possible to push a black box if it already exists
Box *box = pGrid->operator ()(x, y);
if (box->IsBloc () == true) return true;
if (box->IsBloc () == true || box->IsVoid ()) return true;

// Fail if not possible to add a single black box
if (maxBlackCases == 0) return false;
Expand All @@ -834,7 +803,8 @@ bool SolverDynamic::CheckItemLength (const DynamicItem *pItem)
int boxNumber = box->tag;

// - Black boxes fill rate at this point, according to our curve
float fillrate = (float)boxNumber / (float)(mSx*mSy - 1 - initialBlackCases);
float fillrate = (float)boxNumber /
(float)(mSx*mSy - 1 - initialBlackCases - pGrid->GetNumVoidBoxes ());
fillrate = a * fillrate*fillrate + b * fillrate;

// - Derive max number of black cases up to (x, y)
Expand Down
45 changes: 3 additions & 42 deletions Sources/Solvers/SolverStatic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,7 @@ void SolverStatic::SetHeurestic (bool state, int backTreshold)
void SolverStatic::Solve_Stop ()
{
// Unlock all grid boxes
if (pGrid != nullptr)
{
for (int y = 0; y < mSy; y ++)
{
for (int x = 0; x < mSx; x ++)
{
Box* box = pGrid->operator ()(x, y);
box->Lock (false);
}
}
}
if (pGrid != nullptr) pGrid->Unlock ();

this->pDict = nullptr;
this->pGrid = nullptr;
Expand All @@ -128,8 +118,6 @@ void SolverStatic::Solve_Stop ()
// ===========================================================================
void SolverStatic::Solve_Start (Grid &grid, const Dictionary &dico)
{
int x, y;
int count = 0;
Box *box = nullptr;

Solve_Stop ();
Expand All @@ -144,28 +132,7 @@ void SolverStatic::Solve_Start (Grid &grid, const Dictionary &dico)
this->pGrid->SetDensityMode (Grid::BlocDensityMode::NONE);

// Lock non empty boxes
for (y = 0; y < mSy; y ++)
{
for (x = 0; x < mSx; x ++)
{
box = pGrid->operator ()(x,y);

// Lock the box if not empty
if (box->IsLetter () == false || box->GetLetter() != 0)
box->Lock (true);

// If empty, store the number of preceding unlocked boxes
else
{
box->tag = count;
box->Lock (false);
count ++;
}
}
}

// Erase the grid, except the locked boxes (why ?)
pGrid->Erase ();
this->pGrid->LockContent ();

// Establish a static ordered list of word slots for whose we must find a solution
if (m_pItemList != nullptr) delete [] m_pItemList;
Expand Down Expand Up @@ -206,13 +173,6 @@ Status SolverStatic::Solve_Step (int32_t maxTimeMs, int32_t maxSteps)
// Main search loop, we have finished when we have found something for every slots in our list
while (m_idxCurrentItem < m_numItems)
{
// Skip slots tagged so
//if (m_pItemList [m_idxCurrentItem].dictStep == C_StaticItem2::Ce_Skip)
//{
// m_idxCurrentItem ++;
// continue;
//}

// Get item to solve during this iteration
StaticItem *pItem = &m_pItemList [m_idxCurrentItem];

Expand All @@ -238,6 +198,7 @@ Status SolverStatic::Solve_Step (int32_t maxTimeMs, int32_t maxSteps)
if (m_idxCurrentItem < 0)
{
pDict = nullptr;
pGrid->Erase ();
break;
}

Expand Down
Loading

0 comments on commit c643265

Please sign in to comment.