mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-27 07:58:49 +01:00
Merge branch 'android_branch' into android_browsedict
This commit is contained in:
commit
4818a2919d
4 changed files with 308 additions and 103 deletions
|
@ -639,6 +639,30 @@ dict_super_follow( const DictionaryCtxt* dict, array_edge* in )
|
|||
return result;
|
||||
} /* dict_super_follow */
|
||||
|
||||
static array_edge*
|
||||
dict_super_edge_with_tile( const DictionaryCtxt* dict, array_edge* from,
|
||||
Tile tile )
|
||||
{
|
||||
for ( ; ; ) {
|
||||
Tile candidate = EDGETILE(dict,from);
|
||||
if ( candidate == tile ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( IS_LAST_EDGE(dict, from ) ) {
|
||||
from = NULL;
|
||||
break;
|
||||
}
|
||||
#ifdef NODE_CAN_4
|
||||
from += dict->nodeSize;
|
||||
#else
|
||||
from += 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
return from;
|
||||
} /* edge_with_tile */
|
||||
|
||||
void
|
||||
dict_super_init( DictionaryCtxt* dict )
|
||||
{
|
||||
|
@ -647,6 +671,7 @@ dict_super_init( DictionaryCtxt* dict )
|
|||
dict->func_dict_getTopEdge = dict_super_getTopEdge;
|
||||
dict->func_dict_index_from = dict_super_index_from;
|
||||
dict->func_dict_follow = dict_super_follow;
|
||||
dict->func_dict_edge_with_tile = dict_super_edge_with_tile;
|
||||
dict->func_dict_getShortName = dict_getName;
|
||||
} /* dict_super_init */
|
||||
|
||||
|
@ -657,27 +682,33 @@ dict_getLangName( const DictionaryCtxt* ctxt )
|
|||
}
|
||||
|
||||
#ifdef XWFEATURE_WALKDICT
|
||||
typedef struct _EdgeArray {
|
||||
array_edge* edges[MAX_COLS];
|
||||
XP_U16 nEdges;
|
||||
} EdgeArray;
|
||||
|
||||
static void
|
||||
edgesToIndices( const DictionaryCtxt* dict, XP_U16 nEdges,
|
||||
array_edge** edges, DictWord* word )
|
||||
edgesToIndices( const DictionaryCtxt* dict, const EdgeArray* edges,
|
||||
DictWord* word )
|
||||
{
|
||||
XP_U16 ii;
|
||||
|
||||
word->nTiles = nEdges;
|
||||
for ( ii = 0; ii < nEdges; ++ii ) {
|
||||
word->indices[ii] = edges[ii] - dict->base;
|
||||
word->nTiles = edges->nEdges;
|
||||
for ( ii = 0; ii < edges->nEdges; ++ii ) {
|
||||
word->indices[ii] = edges->edges[ii] - dict->base;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
indicesToEdges( const DictionaryCtxt* dict,
|
||||
const DictWord* word, array_edge** edges )
|
||||
const DictWord* word, EdgeArray* edges )
|
||||
{
|
||||
XP_U16 nEdges = word->nTiles;
|
||||
XP_U16 ii;
|
||||
for ( ii = 0; ii < nEdges; ++ii ) {
|
||||
edges[ii] = &dict->base[word->indices[ii]];
|
||||
edges->edges[ii] = &dict->base[word->indices[ii]];
|
||||
}
|
||||
edges->nEdges = nEdges;
|
||||
}
|
||||
|
||||
/* On entry and exit, edge at end of array should be ACCEPTING. The job of
|
||||
|
@ -688,28 +719,28 @@ indicesToEdges( const DictionaryCtxt* dict,
|
|||
* LAST_EDGE, try with its next-letter neighbor.
|
||||
*/
|
||||
static XP_Bool
|
||||
nextWord( const DictionaryCtxt* dict, array_edge** edges, XP_U16* nTilesP )
|
||||
nextWord( const DictionaryCtxt* dict, EdgeArray* edges )
|
||||
{
|
||||
XP_U16 nTiles = *nTilesP;
|
||||
XP_U16 nTiles = edges->nEdges;
|
||||
XP_Bool success = XP_FALSE;
|
||||
while ( 0 < nTiles && ! success ) {
|
||||
array_edge* next = dict_follow( dict, edges[nTiles-1] );
|
||||
array_edge* next = dict_follow( dict, edges->edges[nTiles-1] );
|
||||
if ( !!next ) {
|
||||
edges[nTiles++] = next;
|
||||
edges->edges[nTiles++] = next;
|
||||
success = ISACCEPTING( dict, next );
|
||||
continue; /* try with longer word */
|
||||
}
|
||||
|
||||
while ( IS_LAST_EDGE( dict, edges[nTiles-1] ) && 0 < --nTiles ) {
|
||||
while ( IS_LAST_EDGE( dict, edges->edges[nTiles-1] ) && 0 < --nTiles ) {
|
||||
}
|
||||
|
||||
if ( 0 < nTiles ) {
|
||||
edges[nTiles-1] += dict->nodeSize;
|
||||
success = ISACCEPTING( dict, edges[nTiles-1] );
|
||||
edges->edges[nTiles-1] += dict->nodeSize;
|
||||
success = ISACCEPTING( dict, edges->edges[nTiles-1] );
|
||||
}
|
||||
}
|
||||
|
||||
*nTilesP = nTiles;
|
||||
edges->nEdges = nTiles;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -724,64 +755,88 @@ isFirstEdge( const DictionaryCtxt* dict, array_edge* edge )
|
|||
}
|
||||
|
||||
static XP_Bool
|
||||
lastEdges( const DictionaryCtxt* dict, array_edge** edges, XP_U16* nEdgesP )
|
||||
lastEdges( const DictionaryCtxt* dict, EdgeArray* edges )
|
||||
{
|
||||
XP_U16 nEdges = *nEdgesP;
|
||||
array_edge* edge = edges[nEdges-1];
|
||||
array_edge* edge = edges->edges[edges->nEdges-1];
|
||||
for ( ; ; ) {
|
||||
while ( !IS_LAST_EDGE( dict, edge ) ) {
|
||||
edge += dict->nodeSize;
|
||||
}
|
||||
edges[nEdges-1] = edge;
|
||||
edges->edges[edges->nEdges-1] = edge;
|
||||
|
||||
edge = dict_follow( dict, edge );
|
||||
if ( NULL == edge ) {
|
||||
break;
|
||||
}
|
||||
++nEdges;
|
||||
++edges->nEdges;
|
||||
}
|
||||
*nEdgesP = nEdges;
|
||||
return ISACCEPTING( dict, edges[nEdges-1] );
|
||||
return ISACCEPTING( dict, edges->edges[edges->nEdges-1] );
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
prevWord( const DictionaryCtxt* dict, array_edge** edges, XP_U16* nEdgesP )
|
||||
prevWord( const DictionaryCtxt* dict, EdgeArray* edges )
|
||||
{
|
||||
XP_U16 nEdges = *nEdgesP;
|
||||
XP_Bool success = XP_FALSE;
|
||||
while ( 0 < nEdges && ! success ) {
|
||||
if ( isFirstEdge( dict, edges[nEdges-1] ) ) {
|
||||
--nEdges;
|
||||
success = 0 < nEdges && ISACCEPTING( dict, edges[nEdges-1] );
|
||||
while ( 0 < edges->nEdges && ! success ) {
|
||||
if ( isFirstEdge( dict, edges->edges[edges->nEdges-1] ) ) {
|
||||
--edges->nEdges;
|
||||
success = 0 < edges->nEdges && ISACCEPTING( dict, edges->edges[edges->nEdges-1] );
|
||||
continue;
|
||||
}
|
||||
edges[nEdges-1] -= dict->nodeSize;
|
||||
array_edge* next = dict_follow( dict, edges[nEdges-1] );
|
||||
edges->edges[edges->nEdges-1] -= dict->nodeSize;
|
||||
array_edge* next = dict_follow( dict, edges->edges[edges->nEdges-1] );
|
||||
if ( NULL != next ) {
|
||||
edges[nEdges++] = next;
|
||||
success = lastEdges( dict, edges, &nEdges );
|
||||
edges->edges[edges->nEdges++] = next;
|
||||
success = lastEdges( dict, edges );
|
||||
if ( success ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
success = ISACCEPTING( dict, edges[nEdges-1] );
|
||||
success = ISACCEPTING( dict, edges->edges[edges->nEdges-1] );
|
||||
}
|
||||
*nEdgesP = nEdges;
|
||||
return success;
|
||||
}
|
||||
|
||||
typedef XP_Bool (*WordFinder)(const DictionaryCtxt* dict, array_edge** edges,
|
||||
XP_U16* nTilesP );
|
||||
typedef XP_Bool (*WordFinder)(const DictionaryCtxt* dict, EdgeArray* edges );
|
||||
|
||||
static XP_Bool
|
||||
dict_getWord( const DictionaryCtxt* dict, DictWord* word, WordFinder finder )
|
||||
{
|
||||
XP_U16 nTiles = word->nTiles;
|
||||
array_edge* edges[MAX_COLS];
|
||||
indicesToEdges( dict, word, edges );
|
||||
XP_Bool success = (*finder)( dict, edges, &nTiles );
|
||||
EdgeArray edges;
|
||||
indicesToEdges( dict, word, &edges );
|
||||
XP_Bool success = (*finder)( dict, &edges );
|
||||
if ( success ) {
|
||||
edgesToIndices( dict, nTiles, edges, word );
|
||||
edgesToIndices( dict, &edges, word );
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
findStartsWith( const DictionaryCtxt* dict, Tile* tiles, XP_U16 nTiles, EdgeArray* edges )
|
||||
{
|
||||
XP_Bool success = XP_TRUE;
|
||||
array_edge* edge = dict_getTopEdge( dict );
|
||||
|
||||
while ( nTiles-- > 0 ) {
|
||||
Tile tile = *tiles++;
|
||||
edge = dict_edge_with_tile( dict, edge, tile );
|
||||
if ( NULL == edge ) {
|
||||
success = XP_FALSE;
|
||||
break;
|
||||
}
|
||||
edges->edges[edges->nEdges++] = edge;
|
||||
edge = dict_follow( dict, edge );
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
wordsEqual( EdgeArray* word1, EdgeArray* word2 )
|
||||
{
|
||||
XP_Bool success = word1->nEdges == word2->nEdges;
|
||||
if ( success ) {
|
||||
success = 0 == memcmp( word1->edges, word2->edges,
|
||||
word1->nEdges * sizeof(word1->edges[0]) );
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -789,32 +844,129 @@ dict_getWord( const DictionaryCtxt* dict, DictWord* word, WordFinder finder )
|
|||
XP_U32
|
||||
dict_countWords( const DictionaryCtxt* dict )
|
||||
{
|
||||
array_edge* edges[MAX_COLS];
|
||||
XP_U16 nEdges = 0;
|
||||
EdgeArray edges = { .nEdges = 0 };
|
||||
XP_U32 count = 0;
|
||||
edges[nEdges++] = dict_getTopEdge( dict );
|
||||
if ( ISACCEPTING( dict, edges[0] ) ) {
|
||||
edges.edges[edges.nEdges++] = dict_getTopEdge( dict );
|
||||
if ( ISACCEPTING( dict, edges.edges[0] ) ) {
|
||||
++count;
|
||||
}
|
||||
while ( nextWord( dict, edges, &nEdges ) ) {
|
||||
while ( nextWord( dict, &edges ) ) {
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
indexOne( const DictionaryCtxt* dict, XP_U16 depth, Tile* tiles,
|
||||
DictIndex* indices, XP_U16* nextIndex,
|
||||
XWStreamCtxt* stream, EdgeArray* prevEdges, DictIndex* prevIndex )
|
||||
{
|
||||
EdgeArray curEdges = { .nEdges = 0 };
|
||||
if ( findStartsWith( dict, tiles, depth, &curEdges ) ) {
|
||||
XP_ASSERT( curEdges.nEdges == depth );
|
||||
if ( ! ISACCEPTING( dict, curEdges.edges[curEdges.nEdges-1] ) ) {
|
||||
if ( !nextWord( dict, &curEdges ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
if ( wordsEqual( &curEdges, prevEdges ) ) {
|
||||
XP_ASSERT( *prevIndex == 0 );
|
||||
} else {
|
||||
/* Walk the prev word forward until they're the same */
|
||||
while ( nextWord( dict, prevEdges ) ) {
|
||||
++*prevIndex;
|
||||
if ( wordsEqual( &curEdges, prevEdges ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
indices[(*nextIndex)++] = *prevIndex;
|
||||
|
||||
if ( NULL != stream ) {
|
||||
XP_UCHAR prefix[8];
|
||||
(void)dict_tilesToString( dict, tiles, depth, prefix, VSIZE(prefix) );
|
||||
stream_catString( stream, prefix );
|
||||
stream_catString( stream, "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
doOneDepth( const DictionaryCtxt* dict,
|
||||
const Tile* allTiles, XP_U16 nTiles, Tile* prefix,
|
||||
XP_U16 curDepth, XP_U16 maxDepth,
|
||||
DictIndex* indices, XP_U16* nextEntry,
|
||||
XWStreamCtxt* stream, EdgeArray* prevEdges, DictIndex* prevIndex )
|
||||
{
|
||||
XP_U16 ii;
|
||||
for ( ii = 0; ii < nTiles; ++ii ) {
|
||||
prefix[curDepth] = allTiles[ii];
|
||||
if ( curDepth + 1 == maxDepth ) {
|
||||
indexOne( dict, maxDepth, prefix, indices, nextEntry,
|
||||
stream, prevEdges, prevIndex );
|
||||
} else {
|
||||
doOneDepth( dict, allTiles, nTiles, prefix, curDepth+1, maxDepth,
|
||||
indices, nextEntry, stream, prevEdges, prevIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XP_U16
|
||||
dict_makeIndex( const DictionaryCtxt* dict, XP_U16 depth,
|
||||
DictIndex* indices, XP_U16 count, XWStreamCtxt* stream )
|
||||
{
|
||||
XP_ASSERT( depth < MAX_COLS );
|
||||
XP_U16 ii, needCount, nTiles;
|
||||
XP_U16 nFaces = dict_numTileFaces( dict );
|
||||
XP_Bool hasBlank = dict_hasBlankTile( dict );
|
||||
if ( hasBlank ) {
|
||||
--nFaces;
|
||||
}
|
||||
for ( ii = 1, needCount = nFaces; ii < depth; ++ii ) {
|
||||
needCount *= nFaces;
|
||||
}
|
||||
XP_ASSERT( needCount <= count );
|
||||
|
||||
Tile allTiles[nFaces];
|
||||
nTiles = 0;
|
||||
for ( ii = 0; ii < nFaces; ++ii ) {
|
||||
if ( hasBlank && ii == dict_getBlankTile( dict ) ) {
|
||||
continue;
|
||||
}
|
||||
allTiles[nTiles++] = (Tile)ii;
|
||||
}
|
||||
|
||||
/* For each tile string implied by depth (A if depth == 1, AAA if == 3 ),
|
||||
* find the first word starting with that IF EXISTS. If it does, find its
|
||||
* index. As an optimization, find index starting with the previous word.
|
||||
*/
|
||||
XP_U16 nextIndex = 0;
|
||||
DictWord firstWord;
|
||||
if ( dict_firstWord( dict, &firstWord ) ) {
|
||||
EdgeArray prevEdges;
|
||||
DictIndex prevIndex = 0;
|
||||
Tile prefix[depth];
|
||||
indicesToEdges( dict, &firstWord, &prevEdges );
|
||||
|
||||
doOneDepth( dict, allTiles, nFaces, prefix, 0, depth,
|
||||
indices, &nextIndex, stream, &prevEdges, &prevIndex );
|
||||
|
||||
}
|
||||
return nextIndex;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
dict_firstWord( const DictionaryCtxt* dict, DictWord* word )
|
||||
{
|
||||
array_edge* edges[MAX_COLS];
|
||||
XP_U16 nEdges = 0;
|
||||
edges[nEdges++] = dict_getTopEdge( dict );
|
||||
EdgeArray edges = { .nEdges = 0 };
|
||||
edges.edges[edges.nEdges++] = dict_getTopEdge( dict );
|
||||
|
||||
XP_Bool success = ISACCEPTING( dict, edges[0] )
|
||||
|| nextWord( dict, edges, &nEdges );
|
||||
XP_Bool success = ISACCEPTING( dict, edges.edges[0] )
|
||||
|| nextWord( dict, &edges );
|
||||
if ( success ) {
|
||||
word->wordCount = dict_getWordCount( dict );
|
||||
|
||||
edgesToIndices( dict, nEdges, edges, word );
|
||||
edgesToIndices( dict, &edges, word );
|
||||
word->index = 0;
|
||||
}
|
||||
|
||||
|
@ -834,15 +986,14 @@ dict_getNextWord( const DictionaryCtxt* dict, DictWord* word )
|
|||
XP_Bool
|
||||
dict_lastWord( const DictionaryCtxt* dict, DictWord* word )
|
||||
{
|
||||
array_edge* edges[MAX_COLS];
|
||||
XP_U16 nEdges = 0;
|
||||
edges[nEdges++] = dict_getTopEdge( dict );
|
||||
EdgeArray edges = { .nEdges = 0 };
|
||||
edges.edges[edges.nEdges++] = dict_getTopEdge( dict );
|
||||
|
||||
XP_Bool success = lastEdges( dict, edges, &nEdges );
|
||||
XP_Bool success = lastEdges( dict, &edges );
|
||||
if ( success ) {
|
||||
word->wordCount = dict_getWordCount( dict );
|
||||
|
||||
edgesToIndices( dict, nEdges, edges, word );
|
||||
edgesToIndices( dict, &edges, word );
|
||||
word->index = word->wordCount - 1;
|
||||
}
|
||||
|
||||
|
@ -893,23 +1044,22 @@ dict_getNthWord( const DictionaryCtxt* dict, DictWord* word, XP_U32 nn )
|
|||
}
|
||||
}
|
||||
|
||||
array_edge* edges[MAX_COLS];
|
||||
XP_U16 nEdges = word->nTiles;
|
||||
indicesToEdges( dict, word, edges );
|
||||
EdgeArray edges;
|
||||
indicesToEdges( dict, word, &edges );
|
||||
if ( word->index < nn ) {
|
||||
for ( ii = nn - word->index; ii > 0; --ii ) {
|
||||
if ( !nextWord( dict, edges, &nEdges ) ) {
|
||||
if ( !nextWord( dict, &edges ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
} else if ( word->index > nn ) {
|
||||
for ( ii = word->index - nn; ii > 0; --ii ) {
|
||||
if ( !prevWord( dict, edges, &nEdges ) ) {
|
||||
if ( !prevWord( dict, &edges ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
edgesToIndices( dict, nEdges, edges, word );
|
||||
edgesToIndices( dict, &edges, word );
|
||||
word->index = nn;
|
||||
}
|
||||
return success;
|
||||
|
@ -920,15 +1070,16 @@ dict_wordToString( const DictionaryCtxt* dict, const DictWord* word,
|
|||
XP_UCHAR* buf, XP_U16 buflen )
|
||||
{
|
||||
XP_U16 ii;
|
||||
array_edge* edges[MAX_COLS];
|
||||
const XP_U16 nTiles = word->nTiles;
|
||||
Tile tiles[MAX_COLS];
|
||||
EdgeArray edges;
|
||||
|
||||
indicesToEdges( dict, word, edges );
|
||||
indicesToEdges( dict, word, &edges );
|
||||
|
||||
for ( ii = 0; ii < word->nTiles; ++ii ) {
|
||||
tiles[ii] = EDGETILE( dict, edges[ii] );
|
||||
for ( ii = 0; ii < nTiles; ++ii ) {
|
||||
tiles[ii] = EDGETILE( dict, edges.edges[ii] );
|
||||
}
|
||||
(void)dict_tilesToString( dict, tiles, word->nTiles, buf, buflen );
|
||||
(void)dict_tilesToString( dict, tiles, nTiles, buf, buflen );
|
||||
}
|
||||
#endif /* XWFEATURE_WALKDICT */
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ struct DictionaryCtxt {
|
|||
array_edge* p_edge );
|
||||
array_edge* (*func_dict_follow)( const DictionaryCtxt* dict,
|
||||
array_edge* in );
|
||||
array_edge* (*func_dict_edge_with_tile)( const DictionaryCtxt* dict,
|
||||
array_edge* from, Tile tile );
|
||||
const XP_UCHAR* (*func_dict_getShortName)( const DictionaryCtxt* dict );
|
||||
|
||||
array_edge* topEdge;
|
||||
|
@ -135,6 +137,7 @@ struct DictionaryCtxt {
|
|||
#define dict_getTopEdge(d) (*((d)->func_dict_getTopEdge))(d)
|
||||
#define dict_index_from(d,e) (*((d)->func_dict_index_from))(d,e)
|
||||
#define dict_follow(d,e) (*((d)->func_dict_follow))(d,e)
|
||||
#define dict_edge_with_tile(d,e,t) (*((d)->func_dict_edge_with_tile))(d,e,t)
|
||||
#define dict_getShortName(d) (*((d)->func_dict_getShortName))(d)
|
||||
|
||||
#ifdef NODE_CAN_4
|
||||
|
@ -206,14 +209,19 @@ void dict_splitFaces( DictionaryCtxt* dict, const XP_U8* bytes,
|
|||
#ifdef XWFEATURE_WALKDICT
|
||||
|
||||
/* API for iterating over a dict */
|
||||
typedef XP_U32 DictIndex;
|
||||
#define NO_INDEX 0xFFFFFFFF
|
||||
typedef struct _DictWord {
|
||||
XP_U32 wordCount;
|
||||
XP_U32 index;
|
||||
DictIndex index;
|
||||
XP_U16 nTiles;
|
||||
XP_U32 indices[MAX_COLS];
|
||||
} DictWord;
|
||||
|
||||
XP_U32 dict_countWords( const DictionaryCtxt* dict );
|
||||
XP_U16 dict_makeIndex( const DictionaryCtxt* dict, XP_U16 depth,
|
||||
DictIndex* indices, XP_U16 count,
|
||||
XWStreamCtxt* stream );
|
||||
XP_Bool dict_firstWord( const DictionaryCtxt* dict, DictWord* word );
|
||||
XP_Bool dict_lastWord( const DictionaryCtxt* dict, DictWord* word );
|
||||
XP_Bool dict_getNextWord( const DictionaryCtxt* dict, DictWord* word );
|
||||
|
@ -223,7 +231,7 @@ XP_Bool dict_getNthWord( const DictionaryCtxt* dict, DictWord* word,
|
|||
void dict_wordToString( const DictionaryCtxt* dict, const DictWord* word,
|
||||
XP_UCHAR* buf, XP_U16 buflen );
|
||||
|
||||
#endif
|
||||
#endif /* XWFEATURE_WALKDICT */
|
||||
|
||||
#ifdef CPLUS
|
||||
}
|
||||
|
|
|
@ -121,8 +121,6 @@ struct EngineCtxt {
|
|||
static void findMovesOneRow( EngineCtxt* engine );
|
||||
static Tile localGetBoardTile( EngineCtxt* engine, XP_U16 col,
|
||||
XP_U16 row, XP_Bool substBlank );
|
||||
static array_edge* edge_with_tile( const DictionaryCtxt* dict,
|
||||
array_edge* from, Tile tile );
|
||||
static XP_Bool scoreQualifies( EngineCtxt* engine, XP_U16 score );
|
||||
static void findMovesForAnchor( EngineCtxt* engine, XP_S16* prevAnchor,
|
||||
XP_U16 col, XP_U16 row ) ;
|
||||
|
@ -590,7 +588,7 @@ lookup( const DictionaryCtxt* dict, array_edge* edge, Tile* buf,
|
|||
{
|
||||
while ( edge != NULL ) {
|
||||
Tile targetTile = buf[tileIndex];
|
||||
edge = edge_with_tile( dict, edge, targetTile );
|
||||
edge = dict_edge_with_tile( dict, edge, targetTile );
|
||||
if ( edge == NULL ) { /* tile not available out of this node */
|
||||
return XP_FALSE;
|
||||
} else {
|
||||
|
@ -982,7 +980,7 @@ extendRight( EngineCtxt* engine, Tile* tiles, XP_U16 tileLength,
|
|||
}
|
||||
}
|
||||
|
||||
} else if ( (edge = edge_with_tile( dict, edge, tile ) ) != NULL ) {
|
||||
} else if ( (edge = dict_edge_with_tile( dict, edge, tile ) ) != NULL ) {
|
||||
accepting = ISACCEPTING( dict, edge );
|
||||
extendRight( engine, tiles, tileLength, dict_follow(dict, edge),
|
||||
accepting, firstCol, col+1, row );
|
||||
|
@ -1334,34 +1332,10 @@ scoreQualifies( EngineCtxt* engine, XP_U16 score )
|
|||
return qualifies;
|
||||
} /* scoreQualifies */
|
||||
|
||||
static array_edge*
|
||||
edge_with_tile( const DictionaryCtxt* dict, array_edge* from, Tile tile )
|
||||
{
|
||||
for ( ; ; ) {
|
||||
Tile candidate = EDGETILE(dict,from);
|
||||
if ( candidate == tile ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( IS_LAST_EDGE(dict, from ) ) {
|
||||
from = NULL;
|
||||
break;
|
||||
}
|
||||
#ifdef NODE_CAN_4
|
||||
from += dict->nodeSize;
|
||||
#else
|
||||
from += 3;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return from;
|
||||
} /* edge_with_tile */
|
||||
|
||||
static array_edge*
|
||||
edge_from_tile( const DictionaryCtxt* dict, array_edge* from, Tile tile )
|
||||
{
|
||||
array_edge* edge = edge_with_tile( dict, from, tile );
|
||||
array_edge* edge = dict_edge_with_tile( dict, from, tile );
|
||||
if ( edge != NULL ) {
|
||||
edge = dict_follow( dict, edge );
|
||||
}
|
||||
|
|
|
@ -893,9 +893,39 @@ tmp_noop_sigintterm( int XP_UNUSED(sig) )
|
|||
}
|
||||
|
||||
#ifdef XWFEATURE_WALKDICT
|
||||
static void
|
||||
walk_dict_test( const DictionaryCtxt* dict )
|
||||
#if 0
|
||||
static char*
|
||||
mkPrefix( const DictionaryCtxt* dict, int index, int depth, char* buf, int len )
|
||||
{
|
||||
Tile tiles[depth];
|
||||
Tile blank;
|
||||
XP_U16 nTiles = dict_numTileFaces( dict );
|
||||
if ( dict_hasBlankTile( dict ) ) {
|
||||
blank = dict_getBlankTile( dict );
|
||||
--nTiles;
|
||||
} else {
|
||||
blank = -1;
|
||||
}
|
||||
int ii;
|
||||
|
||||
for ( ii = depth-1; ii >= 0; --ii ) {
|
||||
Tile tile = index % nTiles;
|
||||
if ( -1 != blank && blank <= tile ) {
|
||||
++tile;
|
||||
}
|
||||
tiles[ii] = tile;
|
||||
index /= nTiles;
|
||||
}
|
||||
|
||||
dict_tilesToString( dict, tiles, depth, buf, len );
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
walk_dict_test( const LaunchParams* params )
|
||||
{
|
||||
const DictionaryCtxt* dict = params->dict;
|
||||
/* This is just to test that the dict-iterating code works. The words are
|
||||
meant to be printed e.g. in a scrolling dialog on Android. */
|
||||
DictWord word;
|
||||
|
@ -955,7 +985,7 @@ walk_dict_test( const DictionaryCtxt* dict )
|
|||
|
||||
fprintf( stderr, "testing getNth\n" );
|
||||
int ii;
|
||||
for ( ii = 0 ; ii < 1000; ++ii ) {
|
||||
for ( ii = 0 ; ii < 100; ++ii ) {
|
||||
long index = XP_RANDOM() % count;
|
||||
if ( dict_getNthWord( dict, &word, index ) ) {
|
||||
XP_ASSERT( word.index == index );
|
||||
|
@ -967,6 +997,48 @@ walk_dict_test( const DictionaryCtxt* dict )
|
|||
}
|
||||
}
|
||||
|
||||
XP_U16 depth = 2;
|
||||
DictIndex indices[26*26]; /* pow(26,depth) */
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(params->util->mpool)
|
||||
params->vtMgr,
|
||||
NULL, CHANNEL_NONE, NULL );
|
||||
XP_U16 nIndices = dict_makeIndex( dict, depth, indices, VSIZE(indices), stream );
|
||||
const char* ptr = (char*)stream_getPtr( stream );
|
||||
for ( ii = 0; ii < nIndices; ++ii ) {
|
||||
char* next = strstr( (char*)ptr, "\n" );
|
||||
XP_ASSERT( !!next );
|
||||
if ( next > ptr && indices[ii] != NO_INDEX ) {
|
||||
if ( !dict_getNthWord( dict, &word, indices[ii] ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
XP_ASSERT( word.index == indices[ii] );
|
||||
XP_UCHAR buf1[64];
|
||||
dict_wordToString( dict, &word, buf1, VSIZE(buf1) );
|
||||
XP_UCHAR buf2[64] = {0};
|
||||
if ( ii > 0 && dict_getNthWord( dict, &word, indices[ii]-1 ) ) {
|
||||
dict_wordToString( dict, &word, buf2, VSIZE(buf2) );
|
||||
}
|
||||
char prfx[8];
|
||||
snprintf( prfx, depth+1, "%s", ptr );
|
||||
prfx[depth] = '\0';
|
||||
fprintf( stderr,
|
||||
"%d: index: %ld; prefix: %s; word: %s (prev: %s)\n",
|
||||
ii, indices[ii], prfx, buf1, buf2 );
|
||||
} else if ( next == ptr && indices[ii] == NO_INDEX ) {
|
||||
} else {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
ptr = next + 1;
|
||||
}
|
||||
|
||||
/* for ( ii = 0; ii < VSIZE(indices); ++ii ) { */
|
||||
/* DictIndex index = indices[ii]; */
|
||||
/* if ( NO_INDEX == index ) { */
|
||||
/* continue; */
|
||||
/* } */
|
||||
/* catOnClose( stream, NULL ); */
|
||||
stream_destroy( stream );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
#else
|
||||
|
@ -1362,7 +1434,7 @@ main( int argc, char** argv )
|
|||
/* } */
|
||||
/* } */
|
||||
|
||||
walk_dict_test( mainParams.dict );
|
||||
walk_dict_test( &mainParams );
|
||||
|
||||
if ( 0 ) {
|
||||
#ifdef XWFEATURE_RELAY
|
||||
|
|
Loading…
Add table
Reference in a new issue