improve stack_redo() to return the redone move, and use that to avoid

making a copy of the move stack in model_listWordsThrough()
This commit is contained in:
Andy2 2011-10-17 18:16:19 -07:00
parent 9109396ae9
commit 3b7532aba8
3 changed files with 92 additions and 71 deletions

View file

@ -38,9 +38,9 @@ extern "C" {
#define MAX_PASSES 2 /* how many times can all players pass? */
/****************************** prototypes ******************************/
typedef void (*MovePrintFuncPre)(ModelCtxt*, XP_U16, StackEntry*, void*);
typedef void (*MovePrintFuncPost)(ModelCtxt*, XP_U16, StackEntry*, XP_S16,
void*);
typedef void (*MovePrintFuncPre)(ModelCtxt*, XP_U16, const StackEntry*, void*);
typedef void (*MovePrintFuncPost)(ModelCtxt*, XP_U16, const StackEntry*,
XP_S16, void*);
static void incrPendingTileCountAt( ModelCtxt* model, XP_U16 col,
XP_U16 row );
@ -61,9 +61,10 @@ static void setModelTileRaw( ModelCtxt* model, XP_U16 col, XP_U16 row,
static void assignPlayerTiles( ModelCtxt* model, XP_S16 turn,
const TrayTileSet* tiles );
static void makeTileTrade( ModelCtxt* model, XP_S16 player,
TrayTileSet* oldTiles, TrayTileSet* newTiles );
const TrayTileSet* oldTiles,
const TrayTileSet* newTiles );
static XP_S16 commitTurn( ModelCtxt* model, XP_S16 turn,
TrayTileSet* newTiles, XWStreamCtxt* stream,
const TrayTileSet* newTiles, XWStreamCtxt* stream,
WordNotifierInfo* wni, XP_Bool useStack );
static void buildModelFromStack( ModelCtxt* model, StackCtxt* stack,
XP_Bool useStack, XP_U16 initial,
@ -143,7 +144,8 @@ model_makeFromStream( MPFORMAL XWStreamCtxt* stream, DictionaryCtxt* dict,
buildModelFromStack( model, model->vol.stack, XP_FALSE, 0,
(XWStreamCtxt*)NULL, (WordNotifierInfo*)NULL,
(MovePrintFuncPre)NULL, (MovePrintFuncPost)NULL, NULL );
(MovePrintFuncPre)NULL, (MovePrintFuncPost)NULL,
NULL );
for ( i = 0; i < model->nPlayers; ++i ) {
loadPlayerCtxt( stream, version, &model->players[i] );
@ -249,6 +251,53 @@ model_destroy( ModelCtxt* model )
XP_FREE( model->vol.mpool, model );
} /* model_destroy */
static void
modelAddEntry( ModelCtxt* model, XP_U16 indx, const StackEntry* entry,
XP_Bool useStack, XWStreamCtxt* stream,
WordNotifierInfo* wni, MovePrintFuncPre mpf_pre,
MovePrintFuncPost mpf_post, void* closure )
{
XP_S16 moveScore = 0; /* keep compiler happy */
if ( !!mpf_pre ) {
(*mpf_pre)( model, indx, entry, closure );
}
switch ( entry->moveType ) {
case MOVE_TYPE:
model_makeTurnFromMoveInfo( model, entry->playerNum,
&entry->u.move.moveInfo);
moveScore = commitTurn( model, entry->playerNum,
&entry->u.move.newTiles,
stream, wni, useStack );
break;
case TRADE_TYPE:
makeTileTrade( model, entry->playerNum, &entry->u.trade.oldTiles,
&entry->u.trade.newTiles );
break;
case ASSIGN_TYPE:
assignPlayerTiles( model, entry->playerNum,
&entry->u.assign.tiles );
break;
case PHONY_TYPE: /* nothing to add */
model_makeTurnFromMoveInfo( model, entry->playerNum,
&entry->u.phony.moveInfo);
/* do something here to cause it to print */
(void)getCurrentMoveScoreIfLegal( model, entry->playerNum, stream,
wni, &moveScore );
moveScore = 0;
model_resetCurrentTurn( model, entry->playerNum );
break;
default:
XP_ASSERT(0);
}
if ( !!mpf_post ) {
(*mpf_post)( model, indx, entry, moveScore, closure );
}
} /* modelAddEntry */
static void
buildModelFromStack( ModelCtxt* model, StackCtxt* stack, XP_Bool useStack,
XP_U16 initial, XWStreamCtxt* stream,
@ -257,48 +306,10 @@ buildModelFromStack( ModelCtxt* model, StackCtxt* stack, XP_Bool useStack,
{
StackEntry entry;
XP_U16 ii;
XP_S16 moveScore = 0; /* keep compiler happy */
for ( ii = initial; stack_getNthEntry( stack, ii, &entry ); ++ii ) {
if ( !!mpf_pre ) {
(*mpf_pre)( model, ii, &entry, closure );
}
switch ( entry.moveType ) {
case MOVE_TYPE:
model_makeTurnFromMoveInfo( model, entry.playerNum,
&entry.u.move.moveInfo);
moveScore = commitTurn( model, entry.playerNum,
&entry.u.move.newTiles,
stream, wni, useStack );
break;
case TRADE_TYPE:
makeTileTrade( model, entry.playerNum, &entry.u.trade.oldTiles,
&entry.u.trade.newTiles );
break;
case ASSIGN_TYPE:
assignPlayerTiles( model, entry.playerNum,
&entry.u.assign.tiles );
break;
case PHONY_TYPE: /* nothing to add */
model_makeTurnFromMoveInfo( model, entry.playerNum,
&entry.u.phony.moveInfo);
/* do something here to cause it to print */
(void)getCurrentMoveScoreIfLegal( model, entry.playerNum, stream,
wni, &moveScore );
moveScore = 0;
model_resetCurrentTurn( model, entry.playerNum );
break;
default:
XP_ASSERT(0);
}
if ( !!mpf_post ) {
(*mpf_post)( model, ii, &entry, moveScore, closure );
}
modelAddEntry( model, ii, &entry, useStack, stream, wni,
mpf_pre, mpf_post, closure );
}
} /* buildModelFromStack */
@ -789,7 +800,7 @@ model_undoLatestMoves( ModelCtxt* model, PoolContext* pool,
while ( nMovesUndone-- ) {
/* undo isn't enough here: pool's got tiles in it!! */
XP_ASSERT( 0 );
stack_redo( stack );
(void)stack_redo( stack, NULL );
}
}
@ -1401,7 +1412,7 @@ putBackOtherPlayersTiles( ModelCtxt* model, XP_U16 notMyTurn,
* in their trays.
*/
static XP_S16
commitTurn( ModelCtxt* model, XP_S16 turn, TrayTileSet* newTiles,
commitTurn( ModelCtxt* model, XP_S16 turn, const TrayTileSet* newTiles,
XWStreamCtxt* stream, WordNotifierInfo* wni, XP_Bool useStack )
{
XP_U16 ii;
@ -1409,7 +1420,7 @@ commitTurn( ModelCtxt* model, XP_S16 turn, TrayTileSet* newTiles,
PendingTile* pt;
XP_S16 score;
XP_Bool inLine, isHorizontal;
Tile* newTilesP;
const Tile* newTilesP;
XP_U16 nTiles;
nTiles = newTiles->nTiles;
@ -1495,8 +1506,8 @@ model_commitTurn( ModelCtxt* model, XP_S16 turn, TrayTileSet* newTiles )
* in-place change.
*/
static void
makeTileTrade( ModelCtxt* model, XP_S16 player, TrayTileSet* oldTiles,
TrayTileSet* newTiles )
makeTileTrade( ModelCtxt* model, XP_S16 player, const TrayTileSet* oldTiles,
const TrayTileSet* newTiles )
{
XP_U16 i;
XP_U16 nTiles;
@ -1755,7 +1766,7 @@ typedef struct MovePrintClosure {
} MovePrintClosure;
static void
printMovePre( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), StackEntry* entry,
printMovePre( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), const StackEntry* entry,
void* p_closure )
{
XWStreamCtxt* stream;
@ -1779,7 +1790,7 @@ printMovePre( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), StackEntry* entry,
XP_UCHAR letter[2] = {'\0','\0'};
XP_Bool isHorizontal = entry->u.move.moveInfo.isHorizontal;
XP_U16 col, row;
MoveInfo* mi;
const MoveInfo* mi;
XP_Bool isPass = XP_FALSE;
if ( entry->moveType == PHONY_TYPE ) {
@ -1827,8 +1838,9 @@ printMovePre( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), StackEntry* entry,
} /* printMovePre */
static void
printMovePost( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), StackEntry* entry,
XP_S16 XP_UNUSED(score), void* p_closure )
printMovePost( ModelCtxt* model, XP_U16 XP_UNUSED(moveN),
const StackEntry* entry, XP_S16 XP_UNUSED(score),
void* p_closure )
{
MovePrintClosure* closure = (MovePrintClosure*)p_closure;
XWStreamCtxt* stream = closure->stream;
@ -1839,7 +1851,7 @@ printMovePost( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), StackEntry* entry,
XP_UCHAR buf[100];
XP_UCHAR traybuf1[MAX_TRAY_TILES+1];
XP_UCHAR traybuf2[MAX_TRAY_TILES+1];
MoveInfo* mi;
const MoveInfo* mi;
if ( entry->moveType == ASSIGN_TYPE ) {
return;
@ -2113,7 +2125,6 @@ model_listWordsThrough( ModelCtxt* model, XP_U16 col, XP_U16 row,
{
XP_ASSERT( !!stream );
StackCtxt* stack = model->vol.stack;
StackCtxt* tmpStack = stack_copy( stack );
XP_U16 nEntries = stack_getNEntries( stack );
XP_U16 nUndone;
@ -2136,12 +2147,17 @@ model_listWordsThrough( ModelCtxt* model, XP_U16 col, XP_U16 row,
/* Now push the undone moves back into the model one at a time.
recordWord() will add each played word to the stream as it's
scored */
buildModelFromStack( model, tmpStack, XP_TRUE, nEntries - nUndone,
(XWStreamCtxt*)NULL, &ni, (MovePrintFuncPre)NULL,
(MovePrintFuncPost)NULL, NULL );
while ( nUndone-- > 0 ) {
StackEntry entry;
if ( ! stack_redo( stack, &entry ) ) {
XP_ASSERT( 0 );
break;
}
modelAddEntry( model, nEntries - nUndone, &entry, XP_FALSE, NULL, &ni,
NULL, NULL, NULL );
}
}
stack_destroy( tmpStack );
}
} /* model_listWordsThrough */
#endif
XP_Bool

View file

@ -265,8 +265,8 @@ readEntry( StackCtxt* stack, StackEntry* entry )
} /* readEntry */
void
stack_addMove( StackCtxt* stack, XP_U16 turn, MoveInfo* moveInfo,
TrayTileSet* newTiles )
stack_addMove( StackCtxt* stack, XP_U16 turn, const MoveInfo* moveInfo,
const TrayTileSet* newTiles )
{
StackEntry move;
@ -387,14 +387,19 @@ stack_popEntry( StackCtxt* stack, StackEntry* entry )
return found;
} /* stack_popEntry */
void
stack_redo( StackCtxt* stack )
XP_Bool
stack_redo( StackCtxt* stack, StackEntry* entry )
{
if( (stack->nEntries + 1) <= stack->highWaterMark ) {
XP_Bool canRedo = (stack->nEntries + 1) <= stack->highWaterMark;
if ( canRedo ) {
++stack->nEntries;
if ( NULL != entry ) {
stack_getNthEntry( stack, stack->nEntries-1, entry );
}
setCacheReadyFor( stack, stack->nEntries );
stack->top = stack->cachedPos;
}
return canRedo;
} /* stack_redo */
#ifdef CPLUS

View file

@ -75,8 +75,8 @@ void stack_loadFromStream( StackCtxt* stack, XWStreamCtxt* stream );
void stack_writeToStream( const StackCtxt* stack, XWStreamCtxt* stream );
StackCtxt* stack_copy( const StackCtxt* stack );
void stack_addMove( StackCtxt* stack, XP_U16 turn, MoveInfo* moveInfo,
TrayTileSet* newTiles );
void stack_addMove( StackCtxt* stack, XP_U16 turn, const MoveInfo* moveInfo,
const TrayTileSet* newTiles );
void stack_addPhony( StackCtxt* stack, XP_U16 turn, MoveInfo* moveInfo );
void stack_addTrade( StackCtxt* stack, XP_U16 turn,
TrayTileSet* oldTiles, TrayTileSet* newTiles );
@ -88,8 +88,8 @@ XP_U16 stack_getNEntries( StackCtxt* stack );
XP_Bool stack_getNthEntry( StackCtxt* stack, XP_U16 n, StackEntry* entry );
XP_Bool stack_popEntry( StackCtxt* stack, StackEntry* entry );
void stack_redo( StackCtxt* stack );
XP_Bool stack_redo( StackCtxt* stack, StackEntry* entry );
#ifdef CPLUS
}
#endif