mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
add option to limit number of tiles used by robot
This commit is contained in:
parent
d3c06219c1
commit
07a43ddaa0
4 changed files with 62 additions and 39 deletions
|
@ -1376,7 +1376,7 @@ preflight( BoardCtxt* board )
|
|||
* any redrawing to be done.
|
||||
*/
|
||||
XP_Bool
|
||||
board_requestHint( BoardCtxt* board, XP_Bool* workRemainsP )
|
||||
board_requestHint( BoardCtxt* board, XP_U16 nTilesToUse, XP_Bool* workRemainsP )
|
||||
{
|
||||
MoveInfo newMove;
|
||||
XP_Bool result = XP_FALSE;
|
||||
|
@ -1422,7 +1422,8 @@ board_requestHint( BoardCtxt* board, XP_Bool* workRemainsP )
|
|||
|
||||
searchComplete = engine_findMove(engine, model,
|
||||
model_getDictionary(model),
|
||||
tiles, nTiles, NO_SCORE_LIMIT,
|
||||
tiles, nTiles, nTilesToUse,
|
||||
NO_SCORE_LIMIT,
|
||||
&canMove, &newMove );
|
||||
board_popTimerSave( board );
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ XP_Bool board_getShowColors( BoardCtxt* board );
|
|||
XP_Bool board_setShowColors( BoardCtxt* board, XP_Bool showColors );
|
||||
XP_Bool board_replaceTiles( BoardCtxt* board );
|
||||
|
||||
XP_Bool board_requestHint( BoardCtxt* board, XP_Bool* workRemainsP );
|
||||
XP_Bool board_requestHint( BoardCtxt* board, XP_U16 nTilesToUse, XP_Bool* workRemainsP );
|
||||
|
||||
void board_setScale( BoardCtxt* board, XP_U16 hScale, XP_U16 vScale );
|
||||
void board_getScale( BoardCtxt* board, XP_U16* hScale, XP_U16* vScale );
|
||||
|
|
|
@ -62,6 +62,7 @@ struct EngineCtxt {
|
|||
XW_UtilCtxt* util;
|
||||
|
||||
Engine_rack rack;
|
||||
XP_U16 nTilesToUse;
|
||||
Tile blankTile;
|
||||
XP_Bool searchInProgress;
|
||||
XP_Bool searchHorizontal;
|
||||
|
@ -320,15 +321,26 @@ chooseMove( EngineCtxt* engine, PossibleMove** move )
|
|||
XP_Bool
|
||||
engine_findMove( EngineCtxt* engine, ModelCtxt* model,
|
||||
DictionaryCtxt* dict, const Tile* tiles,
|
||||
XP_U16 numTiles, XP_U16 targetScore, XP_Bool* canMoveP,
|
||||
XP_U16 nTiles, XP_U16 nTilesToUse,
|
||||
XP_U16 targetScore, XP_Bool* canMoveP,
|
||||
MoveInfo* newMove )
|
||||
{
|
||||
XP_Bool result = XP_TRUE;
|
||||
XP_Bool firstMove;
|
||||
XP_U16 star_row;
|
||||
|
||||
if ( nTilesToUse == 0 ) {
|
||||
nTilesToUse = nTiles;
|
||||
}
|
||||
|
||||
if ( nTilesToUse != engine->nTilesToUse ) {
|
||||
/* invalidate the cache; it may contain bad results */
|
||||
engine_reset( engine );
|
||||
}
|
||||
|
||||
engine->model = model;
|
||||
engine->dict = dict;
|
||||
engine->nTilesToUse = nTilesToUse;
|
||||
engine->blankTile = dict_getBlankTile( dict );
|
||||
engine->returnNOW = XP_FALSE;
|
||||
|
||||
|
@ -340,7 +352,7 @@ engine_findMove( EngineCtxt* engine, ModelCtxt* model,
|
|||
dictionary's emtpy or there are no tiles, still return TRUE so we don't
|
||||
get scheduled again. Fixes infinite loop with empty dict and a
|
||||
robot. */
|
||||
*canMoveP = dict_getTopEdge(dict) != NULL && initTray( engine, tiles, numTiles );
|
||||
*canMoveP = dict_getTopEdge(dict) != NULL && initTray( engine, tiles, nTiles );
|
||||
if ( *canMoveP ) {
|
||||
|
||||
util_engineStarting( engine->util );
|
||||
|
@ -740,26 +752,28 @@ leftPart( EngineCtxt* engine, Tile* tiles, XP_U16 tileLength,
|
|||
#ifdef NODE_CAN_4
|
||||
XP_U16 nodeSize = engine->dict->nodeSize;
|
||||
#endif
|
||||
for ( ; ; ) {
|
||||
XP_Bool isBlank;
|
||||
Tile tile = EDGETILE( engine->dict, edge );
|
||||
if ( rack_remove( engine, tile, &isBlank ) ) {
|
||||
tiles[tileLength] = tile;
|
||||
leftPart( engine, tiles, tileLength+1,
|
||||
follow( engine->dict, edge ),
|
||||
limit-1, firstCol-1, anchorCol, row );
|
||||
rack_replace( engine, tile, isBlank );
|
||||
}
|
||||
if ( engine->nTilesToUse > 0 ) {
|
||||
for ( ; ; ) {
|
||||
XP_Bool isBlank;
|
||||
Tile tile = EDGETILE( engine->dict, edge );
|
||||
if ( rack_remove( engine, tile, &isBlank ) ) {
|
||||
tiles[tileLength] = tile;
|
||||
leftPart( engine, tiles, tileLength+1,
|
||||
follow( engine->dict, edge ),
|
||||
limit-1, firstCol-1, anchorCol, row );
|
||||
rack_replace( engine, tile, isBlank );
|
||||
}
|
||||
|
||||
if ( IS_LAST_EDGE( dict, edge ) || engine->returnNOW ) {
|
||||
break;
|
||||
}
|
||||
if ( IS_LAST_EDGE( dict, edge ) || engine->returnNOW ) {
|
||||
break;
|
||||
}
|
||||
#ifdef NODE_CAN_4
|
||||
edge += nodeSize;
|
||||
edge += nodeSize;
|
||||
#else
|
||||
edge += 3;
|
||||
edge += 3;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -785,30 +799,32 @@ extendRight( EngineCtxt* engine, Tile* tiles, XP_U16 tileLength,
|
|||
} else if ( tile == EMPTY_TILE ) {
|
||||
Crosscheck check = engine->rowChecks[col]; /* make a local copy */
|
||||
|
||||
for ( ; ; ) {
|
||||
tile = EDGETILE( dict, edge );
|
||||
if ( CROSSCHECK_CONTAINS( check, tile ) ) {
|
||||
XP_Bool isBlank;
|
||||
if ( rack_remove( engine, tile, &isBlank ) ) {
|
||||
tiles[tileLength] = tile;
|
||||
extendRight( engine, tiles, tileLength+1,
|
||||
edge_from_tile( dict, edge, tile ),
|
||||
ISACCEPTING( dict, edge ), firstCol, col+1, row );
|
||||
rack_replace( engine, tile, isBlank );
|
||||
if ( engine->returnNOW ) {
|
||||
return;
|
||||
if ( engine->nTilesToUse > 0 ) {
|
||||
for ( ; ; ) {
|
||||
tile = EDGETILE( dict, edge );
|
||||
if ( CROSSCHECK_CONTAINS( check, tile ) ) {
|
||||
XP_Bool isBlank;
|
||||
if ( rack_remove( engine, tile, &isBlank ) ) {
|
||||
tiles[tileLength] = tile;
|
||||
extendRight( engine, tiles, tileLength+1,
|
||||
edge_from_tile( dict, edge, tile ),
|
||||
ISACCEPTING( dict, edge ), firstCol, col+1, row );
|
||||
rack_replace( engine, tile, isBlank );
|
||||
if ( engine->returnNOW ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( IS_LAST_EDGE( dict, edge ) ) {
|
||||
break;
|
||||
}
|
||||
if ( IS_LAST_EDGE( dict, edge ) ) {
|
||||
break;
|
||||
}
|
||||
#ifdef NODE_CAN_4
|
||||
edge += dict->nodeSize;
|
||||
edge += dict->nodeSize;
|
||||
#else
|
||||
edge += 3;
|
||||
edge += 3;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( (edge = edge_with_tile( dict, edge, tile ) ) != NULL ) {
|
||||
|
@ -832,6 +848,7 @@ rack_remove( EngineCtxt* engine, Tile tile, XP_Bool* isBlank )
|
|||
|
||||
XP_ASSERT( tile < 32 );
|
||||
XP_ASSERT( tile != blankIndex );
|
||||
XP_ASSERT( engine->nTilesToUse > 0 );
|
||||
|
||||
if ( engine->rack[(short)tile] > 0 ) { /* we have the tile itself */
|
||||
--engine->rack[(short)tile];
|
||||
|
@ -844,6 +861,8 @@ rack_remove( EngineCtxt* engine, Tile tile, XP_Bool* isBlank )
|
|||
} else { /* we can't satisfy the request */
|
||||
return XP_FALSE;
|
||||
}
|
||||
|
||||
--engine->nTilesToUse;
|
||||
return XP_TRUE;
|
||||
} /* rack_remove */
|
||||
|
||||
|
@ -855,6 +874,8 @@ rack_replace( EngineCtxt* engine, Tile tile, XP_Bool isBlank )
|
|||
tile = engine->blankTile;
|
||||
}
|
||||
++engine->rack[(short)tile];
|
||||
|
||||
++engine->nTilesToUse;
|
||||
} /* rack_replace */
|
||||
|
||||
static void
|
||||
|
|
|
@ -48,7 +48,8 @@ void engine_destroy( EngineCtxt* ctxt );
|
|||
#define NO_SCORE_LIMIT 10000 /* for targetScore */
|
||||
XP_Bool engine_findMove( EngineCtxt* ctxt, ModelCtxt* model,
|
||||
DictionaryCtxt* dict, const Tile* tiles,
|
||||
XP_U16 numTiles, XP_U16 targetScore, XP_Bool* canMove,
|
||||
XP_U16 nTiles, XP_U16 nTilesToUse,
|
||||
XP_U16 targetScore, XP_Bool* canMove,
|
||||
MoveInfo* result );
|
||||
XP_Bool engine_check( DictionaryCtxt* dict, Tile* buf, XP_U16 buflen );
|
||||
|
||||
|
|
Loading…
Reference in a new issue