Merge branch 'android_branch' into relay_noconn

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
This commit is contained in:
Eric House 2015-08-19 07:44:17 -07:00
commit e5cf0ee4fb
3 changed files with 67 additions and 51 deletions

View file

@ -528,10 +528,9 @@ public class DelegateBase implements DlgClickNotify,
m_dlgDelegate.eventOccurred( event, args ); m_dlgDelegate.eventOccurred( event, args );
break; break;
default: default:
if ( BuildConfig.DEBUG ) { DbgUtils.logdf( "DelegateBase.eventOccurred(event=%s) (DROPPED)",
DbgUtils.logf( "DelegateBase.eventOccurred(event=%s) (DROPPED)",
event.toString() ); event.toString() );
} break;
} }
if ( 0 != fmtId ) { if ( 0 != fmtId ) {

View file

@ -345,9 +345,6 @@ chooseMove( EngineCtxt* engine, PossibleMove** move )
result = (NULL != chosen) && (chosen->score > 0); result = (NULL != chosen) && (chosen->score > 0);
if ( !result ) {
engine_reset( engine );
}
return result; return result;
} /* chooseMove */ } /* chooseMove */
@ -381,7 +378,7 @@ normalizeIQ( EngineCtxt* engine, XP_U16 iq )
XP_Bool XP_Bool
engine_findMove( EngineCtxt* engine, const ModelCtxt* model, engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
XP_U16 turn, const Tile* tiles, XP_U16 turn, const Tile* tiles,
XP_U16 nTiles, XP_Bool usePrev, const XP_U16 nTiles, XP_Bool usePrev,
#ifdef XWFEATURE_BONUSALL #ifdef XWFEATURE_BONUSALL
XP_U16 allTilesBonus, XP_U16 allTilesBonus,
#endif #endif
@ -394,7 +391,9 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
XP_Bool result = XP_TRUE; XP_Bool result = XP_TRUE;
XP_U16 star_row; XP_U16 star_row;
XP_Bool canMove = XP_FALSE; XP_Bool canMove = XP_FALSE;
XP_Bool isRetry = XP_FALSE;
retry:
engine->nTilesMax = XP_MIN( MAX_TRAY_TILES, nTiles ); engine->nTilesMax = XP_MIN( MAX_TRAY_TILES, nTiles );
#ifdef XWFEATURE_BONUSALL #ifdef XWFEATURE_BONUSALL
engine->allTilesBonus = allTilesBonus; engine->allTilesBonus = allTilesBonus;
@ -542,6 +541,22 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
newMove->nTiles = 0; newMove->nTiles = 0;
} }
/* Gross hack alert: there's an elusive bug in move cacheing that means
when we move forward or back from the highest-scoring move to the
lowest (or vice-versa) no move is found. But the next try succeeds,
because an engine_reset clears the state that makes that happen. So as
a workaround, try doing that when no moves are found. If none is found
for some other reason, e.g. no tiles, at least the search should be
quick. */
if ( !canMove ) {
engine_reset( engine );
if ( !isRetry ) {
isRetry = XP_TRUE;
XP_LOGF( "%s: no moves found so retrying", __func__ );
goto retry;
}
}
*canMoveP = canMove; *canMoveP = canMove;
return result; return result;
} /* engine_findMove */ } /* engine_findMove */
@ -1146,23 +1161,24 @@ considerScoreWordHasBlanks( EngineCtxt* engine, XP_U16 blanksLeft,
static void static void
saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove ) saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
{ {
XP_S16 mostest = 0; XP_S16 mostest;
XP_S16 cmpVal; XP_S16 cmpVal;
XP_Bool usePrev = engine->usePrev; XP_Bool usePrev = engine->usePrev;
XP_Bool foundEmpty = XP_FALSE; XP_Bool foundEmpty = XP_FALSE;
MoveIterationData* miData = &engine->miData;
if ( 1 == engine->nMovesToSave ) { /* only saving one */ if ( 1 == engine->nMovesToSave ) { /* only saving one */
mostest = 0; mostest = 0;
} else { } else {
mostest = -1; mostest = -1;
/* we're not interested if we've seen this */ /* we're not interested if we've seen this */
cmpVal = CMPMOVES( posmove, &engine->miData.lastSeenMove ); cmpVal = CMPMOVES( posmove, &miData->lastSeenMove );
if ( !usePrev && cmpVal >= 0 ) { if ( !usePrev && cmpVal >= 0 ) {
/* XP_LOGF( "%s: dropping %d: higher than %d", __func__, */ /* XP_LOGF( "%s: dropping %d: >= %d", __func__, */
/* posmove->score, engine->miData.lastSeenMove.score ); */ /* posmove->score, miData->lastSeenMove.score ); */
} else if ( usePrev && cmpVal <= 0 ) { } else if ( usePrev && cmpVal <= 0 ) {
/* XP_LOGF( "%s: dropping %d: lower than %d", __func__, */ /* XP_LOGF( "%s: dropping %d: <= %d", __func__, */
/* posmove->score, engine->miData.lastSeenMove.score ); */ /* posmove->score, miData->lastSeenMove.score ); */
} else { } else {
XP_S16 ii; XP_S16 ii;
/* terminate i at 1 because mostest starts at 0 */ /* terminate i at 1 because mostest starts at 0 */
@ -1178,19 +1194,19 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
/* 1/20/2001 I don't see that this assertion is valid. I /* 1/20/2001 I don't see that this assertion is valid. I
simply don't understand why it isn't tripped all the time simply don't understand why it isn't tripped all the time
in the old crosswords. */ in the old crosswords. */
/* XP_ASSERT( (engine->miData.lastSeenMove.score == 0x7fff) */ /* XP_ASSERT( (miData->lastSeenMove.score == 0x7fff) */
/* || (engine->miData.savedMoves[i].score */ /* || (miData->savedMoves[i].score */
/* <= posmove->score) ); */ /* <= posmove->score) ); */
if ( 0 == engine->miData.savedMoves[ii].score ) { if ( 0 == miData->savedMoves[ii].score ) {
foundEmpty = XP_TRUE; foundEmpty = XP_TRUE;
mostest = ii; mostest = ii;
break; break;
} else if ( -1 == mostest ) { } else if ( -1 == mostest ) {
mostest = ii; mostest = ii;
} else { } else {
cmpVal = CMPMOVES( &engine->miData.savedMoves[mostest], cmpVal = CMPMOVES( &miData->savedMoves[mostest],
&engine->miData.savedMoves[ii] ); &miData->savedMoves[ii] );
if ( !usePrev && cmpVal > 0 ) { if ( !usePrev && cmpVal > 0 ) {
mostest = ii; mostest = ii;
} else if ( usePrev && cmpVal < 0 ) { } else if ( usePrev && cmpVal < 0 ) {
@ -1204,14 +1220,14 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
while ( mostest >= 0 ) { /* while: so we can break */ while ( mostest >= 0 ) { /* while: so we can break */
/* record the score we're dumping. No point in considering any scores /* record the score we're dumping. No point in considering any scores
lower than this for the rest of this round. */ lower than this for the rest of this round. */
/* engine->miData.lowestSavedScore = */ /* miData->lowestSavedScore = */
/* engine->miData.savedMoves[lowest].score; */ /* miData->savedMoves[lowest].score; */
/* XP_DEBUGF( "lowestSavedScore now %d\n", */ /* XP_DEBUGF( "lowestSavedScore now %d\n", */
/* engine->miData.lowestSavedScore ); */ /* miData->lowestSavedScore ); */
if ( foundEmpty ) { if ( foundEmpty ) {
/* we're good */ /* we're good */
} else { } else {
cmpVal = CMPMOVES( posmove, &engine->miData.savedMoves[mostest]); cmpVal = CMPMOVES( posmove, &miData->savedMoves[mostest]);
if ( !usePrev && cmpVal <= 0 ) { if ( !usePrev && cmpVal <= 0 ) {
break; break;
} else if ( usePrev && cmpVal >= 0 ) { } else if ( usePrev && cmpVal >= 0 ) {
@ -1220,9 +1236,9 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
} }
/* XP_LOGF( "saving move with score %d at %d (replacing %d)\n", */ /* XP_LOGF( "saving move with score %d at %d (replacing %d)\n", */
/* posmove->score, mostest, */ /* posmove->score, mostest, */
/* engine->miData.savedMoves[mostest].score ); */ /* miData->savedMoves[mostest].score ); */
XP_MEMCPY( &engine->miData.savedMoves[mostest], posmove, XP_MEMCPY( &miData->savedMoves[mostest], posmove,
sizeof(engine->miData.savedMoves[mostest]) ); sizeof(miData->savedMoves[mostest]) );
break; break;
} }
} /* saveMoveIfQualifies */ } /* saveMoveIfQualifies */
@ -1230,15 +1246,16 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
static void static void
set_search_limits( EngineCtxt* engine ) set_search_limits( EngineCtxt* engine )
{ {
MoveIterationData* miData = &engine->miData;
/* If we're going to be searching backwards we want our highest cached /* If we're going to be searching backwards we want our highest cached
move as the limit; otherwise the lowest */ move as the limit; otherwise the lowest */
if ( 0 < engine->miData.nInMoveCache ) { if ( 0 < miData->nInMoveCache ) {
XP_U16 srcIndx = engine->usePrev XP_U16 srcIndx = engine->usePrev
? engine->nMovesToSave-1 : engine->miData.bottom; ? engine->nMovesToSave-1 : miData->bottom;
XP_MEMCPY( &engine->miData.lastSeenMove, XP_MEMCPY( &miData->lastSeenMove,
&engine->miData.savedMoves[srcIndx], &miData->savedMoves[srcIndx],
sizeof(engine->miData.lastSeenMove) ); sizeof(miData->lastSeenMove) );
//engine->miData.lowestSavedScore = 0; //miData->lowestSavedScore = 0;
} else { } else {
/* we're doing this for first time */ /* we're doing this for first time */
engine_reset( engine ); engine_reset( engine );
@ -1249,41 +1266,40 @@ static void
init_move_cache( EngineCtxt* engine ) init_move_cache( EngineCtxt* engine )
{ {
XP_U16 nInMoveCache = engine->nMovesToSave; XP_U16 nInMoveCache = engine->nMovesToSave;
MoveIterationData* miData = &engine->miData;
XP_U16 ii; XP_U16 ii;
XP_ASSERT( engine->nMovesToSave == NUM_SAVED_ENGINE_MOVES ); XP_ASSERT( engine->nMovesToSave == NUM_SAVED_ENGINE_MOVES );
for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES; ++ii ) { for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES; ++ii ) {
if ( 0 == engine->miData.savedMoves[ii].score ) { if ( 0 == miData->savedMoves[ii].score ) {
--nInMoveCache; --nInMoveCache;
} else { } else {
break; break;
} }
} }
engine->miData.nInMoveCache = nInMoveCache; miData->nInMoveCache = nInMoveCache;
engine->miData.bottom = NUM_SAVED_ENGINE_MOVES - nInMoveCache; miData->bottom = NUM_SAVED_ENGINE_MOVES - nInMoveCache;
if ( engine->usePrev ) { miData->curCacheIndex = engine->usePrev
engine->miData.curCacheIndex = ? NUM_SAVED_ENGINE_MOVES - nInMoveCache - 1
NUM_SAVED_ENGINE_MOVES - nInMoveCache - 1; : NUM_SAVED_ENGINE_MOVES;
} else {
engine->miData.curCacheIndex = NUM_SAVED_ENGINE_MOVES;
}
} }
static PossibleMove* static PossibleMove*
next_from_cache( EngineCtxt* engine ) next_from_cache( EngineCtxt* engine )
{ {
MoveIterationData* miData = &engine->miData;
PossibleMove* move; PossibleMove* move;
if ( move_cache_empty( engine ) ) { if ( move_cache_empty( engine ) ) {
move = NULL; move = NULL;
} else { } else {
if ( engine->usePrev ) { if ( engine->usePrev ) {
++engine->miData.curCacheIndex; ++miData->curCacheIndex;
} else { } else {
--engine->miData.curCacheIndex; --miData->curCacheIndex;
} }
move = &engine->miData.savedMoves[engine->miData.curCacheIndex]; move = &miData->savedMoves[miData->curCacheIndex];
} }
return move; return move;
} }
@ -1309,21 +1325,22 @@ scoreQualifies( EngineCtxt* engine, XP_U16 score )
{ {
XP_Bool qualifies = XP_FALSE; XP_Bool qualifies = XP_FALSE;
XP_Bool usePrev = engine->usePrev; XP_Bool usePrev = engine->usePrev;
MoveIterationData* miData = &engine->miData;
if ( usePrev && score < engine->miData.lastSeenMove.score ) { if ( usePrev && score < miData->lastSeenMove.score ) {
/* drop it */ /* drop it */
} else if ( !usePrev && score > engine->miData.lastSeenMove.score } else if ( !usePrev && score > miData->lastSeenMove.score
/* || (score < engine->miData.lowestSavedScore) */ ) { /* || (score < miData->lowestSavedScore) */ ) {
/* drop it */ /* drop it */
} else { } else {
XP_S16 ii; XP_S16 ii;
PossibleMove* savedMoves = engine->miData.savedMoves; PossibleMove* savedMoves = miData->savedMoves;
/* Look at each saved score, and return true as soon as one's found /* Look at each saved score, and return true as soon as one's found
with a lower or equal score to this. <eeh> As an optimization, with a lower or equal score to this. <eeh> As an optimization,
consider remembering what the lowest score is *once there are consider remembering what the lowest score is *once there are
NUM_SAVED_ENGINE_MOVES moves in here* and doing a quick test on NUM_SAVED_ENGINE_MOVES moves in here* and doing a quick test on
that. Or better, keeping the list in sorted order. */ that. Or better, keeping the list in sorted order. */
for ( ii = 0, savedMoves = engine->miData.savedMoves; for ( ii = 0, savedMoves = miData->savedMoves;
ii < engine->nMovesToSave; ++ii, ++savedMoves ) { ii < engine->nMovesToSave; ++ii, ++savedMoves ) {
if ( savedMoves->score == 0 ) { /* empty slot */ if ( savedMoves->score == 0 ) { /* empty slot */
qualifies = XP_TRUE; qualifies = XP_TRUE;

View file

@ -2119,7 +2119,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
/* send any events that need to get off before the event loop begins */ /* send any events that need to get off before the event loop begins */
if ( !isServer ) { if ( !!cGlobals->game.comms && !isServer ) {
(void)server_initClientConnection( cGlobals->game.server, (void)server_initClientConnection( cGlobals->game.server,
mem_stream_make( MEMPOOL mem_stream_make( MEMPOOL
params->vtMgr, params->vtMgr,