mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-03 23:04:08 +01:00
handle two-letter tiles better
Choose the two-letter tile where possible. Not sure though if this is always the right move.
This commit is contained in:
parent
dc4fcada2a
commit
d0f5d9949a
1 changed files with 48 additions and 31 deletions
|
@ -258,35 +258,56 @@ parseCounts( ParseState* ps, int elemIndex )
|
|||
}
|
||||
|
||||
typedef struct _FoundData {
|
||||
PatErr err;
|
||||
const DictionaryCtxt* dict;
|
||||
int nCalls;
|
||||
PatElem* elem;
|
||||
int nChars;
|
||||
Tile tile;
|
||||
} FoundData;
|
||||
|
||||
static XP_Bool
|
||||
onFoundTiles( void* closure, const Tile* tiles, int len )
|
||||
onFoundTiles( void* closure, const Tile* tiles, int nTiles )
|
||||
{
|
||||
XP_ASSERT( len == 1 );
|
||||
FoundData* data = (FoundData*)closure;
|
||||
if ( 1 == len ) {
|
||||
XP_ASSERT( 0 == data->nCalls );
|
||||
++data->nCalls;
|
||||
for ( int ii = 0; ii < len; ++ii ) {
|
||||
Tile tile = tiles[ii];
|
||||
#ifdef MULTI_SET
|
||||
++data->elem->u.child.tiles.cnts[tile];
|
||||
#else
|
||||
TileSet mask = 1 << tile;
|
||||
if ( 0 == (data->elem->u.child.tiles & mask ) ) {
|
||||
data->elem->u.child.tiles |= mask;
|
||||
} else {
|
||||
data->err = PatErrDupInSet;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if ( 1 == nTiles ) {
|
||||
XP_UCHAR buf[16];
|
||||
XP_U16 len = dict_tilesToString( data->dict, tiles, nTiles,
|
||||
buf, VSIZE(buf), NULL );
|
||||
if ( 0 == data->nCalls || data->nChars < len ) {
|
||||
data->nChars = len;
|
||||
data->tile = tiles[0];
|
||||
}
|
||||
++data->nCalls;
|
||||
}
|
||||
return 1 == len && PatErrNone == data->err;
|
||||
return XP_TRUE;
|
||||
}
|
||||
|
||||
static PatErr
|
||||
checkData( FoundData* data, ParseState* ps )
|
||||
{
|
||||
PatErr result = PatErrBogusTiles;
|
||||
|
||||
if ( 1 <= data->nCalls ) {
|
||||
result = PatErrNone;
|
||||
|
||||
Tile tile = data->tile;
|
||||
PatElem* elem = &ps->elems[ps->elemIndex];
|
||||
#ifdef MULTI_SET
|
||||
++elem->u.child.tiles.cnts[tile];
|
||||
#else
|
||||
TileSet mask = 1 << tile;
|
||||
if ( 0 == (elem->u.child.tiles & mask ) ) {
|
||||
elem->u.child.tiles |= mask;
|
||||
} else {
|
||||
result = PatErrDupInSet;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( PatErrNone == result ) {
|
||||
ps->patIndex += data->nChars;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PatErr
|
||||
|
@ -317,18 +338,14 @@ parseTile( ParseState* ps )
|
|||
} else {
|
||||
err = PatErrBogusTiles; /* in case we fail */
|
||||
XP_U16 maxLen = XP_STRLEN( &ps->pat[ps->patIndex] );
|
||||
FoundData data = { .dict = ps->dict };
|
||||
for ( int nChars = 1; nChars <= maxLen; ++nChars ) {
|
||||
FoundData data = { .err = PatErrNone,
|
||||
.elem = &ps->elems[ps->elemIndex],
|
||||
.nCalls = 0,
|
||||
};
|
||||
dict_tilesForString( ps->dict, &ps->pat[ps->patIndex], nChars, onFoundTiles, &data );
|
||||
if ( 1 == data.nCalls ) { /* found something? We can proceed */
|
||||
ps->patIndex += nChars;
|
||||
err = PatErrNone;
|
||||
break;
|
||||
}
|
||||
XP_UCHAR buf[24];
|
||||
XP_MEMCPY( buf, &ps->pat[ps->patIndex], nChars * sizeof(buf[0]) );
|
||||
buf[nChars] = '\0';
|
||||
dict_tilesForString( ps->dict, buf, nChars, onFoundTiles, &data );
|
||||
}
|
||||
err = checkData( &data, ps );
|
||||
}
|
||||
|
||||
return err; /* nothing can go wrong? */
|
||||
|
|
Loading…
Reference in a new issue