move dividerLoc into model and use to limit sorting to tiles to its

right
This commit is contained in:
Eric House 2014-09-30 05:57:21 -07:00
parent 1346aa6ee5
commit c98a5cd5f0
7 changed files with 58 additions and 24 deletions

View file

@ -256,7 +256,9 @@ board_makeFromStream( MPFORMAL XWStreamCtxt* stream, ModelCtxt* model,
arrow->vert = (XP_Bool)stream_getBits( stream, 1 ); arrow->vert = (XP_Bool)stream_getBits( stream, 1 );
arrow->visible = (XP_Bool)stream_getBits( stream, 1 ); arrow->visible = (XP_Bool)stream_getBits( stream, 1 );
pti->dividerLoc = (XP_U8)stream_getBits( stream, NTILES_NBITS ); if ( STREAM_VERS_MULTIADDR > version ) {
(void)stream_getBits( stream, NTILES_NBITS );
}
pti->traySelBits = (TileBit)stream_getBits( stream, pti->traySelBits = (TileBit)stream_getBits( stream,
MAX_TRAY_TILES ); MAX_TRAY_TILES );
pti->tradeInProgress = (XP_Bool)stream_getBits( stream, 1 ); pti->tradeInProgress = (XP_Bool)stream_getBits( stream, 1 );
@ -343,7 +345,6 @@ board_writeToStream( const BoardCtxt* board, XWStreamCtxt* stream )
stream_putBits( stream, 1, arrow->vert ); stream_putBits( stream, 1, arrow->vert );
stream_putBits( stream, 1, arrow->visible ); stream_putBits( stream, 1, arrow->visible );
stream_putBits( stream, NTILES_NBITS, pti->dividerLoc );
stream_putBits( stream, MAX_TRAY_TILES, pti->traySelBits ); stream_putBits( stream, MAX_TRAY_TILES, pti->traySelBits );
stream_putBits( stream, 1, pti->tradeInProgress ); stream_putBits( stream, 1, pti->tradeInProgress );
@ -383,7 +384,6 @@ board_reset( BoardCtxt* board )
PerTurnInfo* pti = &board->pti[ii]; PerTurnInfo* pti = &board->pti[ii];
pti->traySelBits = 0; pti->traySelBits = 0;
pti->tradeInProgress = XP_FALSE; pti->tradeInProgress = XP_FALSE;
pti->dividerLoc = 0;
XP_MEMSET( &pti->boardArrow, 0, sizeof(pti->boardArrow) ); XP_MEMSET( &pti->boardArrow, 0, sizeof(pti->boardArrow) );
} }
board->gameOver = XP_FALSE; board->gameOver = XP_FALSE;
@ -2026,6 +2026,7 @@ board_requestHint( BoardCtxt* board,
EngineCtxt* engine = server_getEngineFor( board->server, selPlayer ); EngineCtxt* engine = server_getEngineFor( board->server, selPlayer );
const TrayTileSet* tileSet; const TrayTileSet* tileSet;
ModelCtxt* model = board->model; ModelCtxt* model = board->model;
XP_U16 dividerLoc = model_getDividerLoc( model, selPlayer );
if ( !!engine && preflight( board, XP_TRUE ) ) { if ( !!engine && preflight( board, XP_TRUE ) ) {
@ -2047,7 +2048,7 @@ board_requestHint( BoardCtxt* board,
} }
tileSet = model_getPlayerTiles( model, selPlayer ); tileSet = model_getPlayerTiles( model, selPlayer );
nTiles = tileSet->nTiles - pti->dividerLoc; nTiles = tileSet->nTiles - dividerLoc;
result = nTiles > 0; result = nTiles > 0;
} }
@ -2063,7 +2064,7 @@ board_requestHint( BoardCtxt* board,
(void)board_replaceTiles( board ); (void)board_replaceTiles( board );
tiles = tileSet->tiles + pti->dividerLoc; tiles = tileSet->tiles + dividerLoc;
board_pushTimerSave( board ); board_pushTimerSave( board );
@ -2080,7 +2081,7 @@ board_requestHint( BoardCtxt* board,
#ifdef XWFEATURE_BONUSALL #ifdef XWFEATURE_BONUSALL
XP_U16 allTilesBonus = 0; XP_U16 allTilesBonus = 0;
# ifdef XWFEATURE_BONUSALLHINT # ifdef XWFEATURE_BONUSALLHINT
if ( 0 == pti->dividerLoc ) { if ( 0 == dividerLoc ) {
allTilesBonus = server_figureFinishBonus( board->server, allTilesBonus = server_figureFinishBonus( board->server,
selPlayer ); selPlayer );
} }
@ -3219,7 +3220,7 @@ invalFocusOwner( BoardCtxt* board )
case OBJ_TRAY: case OBJ_TRAY:
if ( board->focusHasDived ) { if ( board->focusHasDived ) {
XP_S16 loc = pti->trayCursorLoc; XP_S16 loc = pti->trayCursorLoc;
if ( loc == pti->dividerLoc ) { if ( loc == model_getDividerLoc(board->model, board->selPlayer)) {
board->dividerInvalid = XP_TRUE; board->dividerInvalid = XP_TRUE;
} else { } else {
adjustForDivider( board, &loc ); adjustForDivider( board, &loc );

View file

@ -111,7 +111,6 @@ typedef struct _PerTurnInfo {
#endif #endif
BoardArrow boardArrow; BoardArrow boardArrow;
XP_U16 scoreDims; XP_U16 scoreDims;
XP_U8 dividerLoc; /* 0 means left of 0th tile, etc. */
TileBit traySelBits; TileBit traySelBits;
#ifdef XWFEATURE_SEARCHLIMIT #ifdef XWFEATURE_SEARCHLIMIT
BdHintLimits limits; BdHintLimits limits;

View file

@ -156,7 +156,8 @@ ddStartTray( BoardCtxt* board, XP_U16 x, XP_U16 y )
if ( canDrag ) { if ( canDrag ) {
if ( onDivider ) { if ( onDivider ) {
board->dividerInvalid = XP_TRUE; board->dividerInvalid = XP_TRUE;
ds->start.u.tray.index = board->selInfo->dividerLoc; ds->start.u.tray.index =
model_getDividerLoc( board->model, board->selPlayer );
ds->dtype = DT_DIVIDER; ds->dtype = DT_DIVIDER;
} else { } else {

View file

@ -1822,6 +1822,23 @@ model_moveTileOnTray( ModelCtxt* model, XP_S16 turn, XP_S16 indexCur,
notifyTrayListeners( model, turn, indexCur, indexNew ); notifyTrayListeners( model, turn, indexCur, indexNew );
} /* model_moveTileOnTray */ } /* model_moveTileOnTray */
XP_U16
model_getDividerLoc( const ModelCtxt* model, XP_S16 turn )
{
XP_ASSERT( turn >= 0 );
PlayerCtxt* player = &model->players[turn];
return player->dividerLoc;
}
void
model_setDividerLoc( const ModelCtxt* model, XP_S16 turn, XP_U16 loc )
{
XP_ASSERT( turn >= 0 );
PlayerCtxt* player = &model->players[turn];
XP_ASSERT( loc < 0xFF );
player->dividerLoc = (XP_U8)loc;
}
static void static void
assignPlayerTiles( ModelCtxt* model, XP_S16 turn, const TrayTileSet* tiles ) assignPlayerTiles( ModelCtxt* model, XP_S16 turn, const TrayTileSet* tiles )
{ {
@ -1851,7 +1868,8 @@ model_sortTiles( ModelCtxt* model, XP_S16 turn )
TrayTileSet sorted; TrayTileSet sorted;
const TrayTileSet* curTiles = model_getPlayerTiles( model, turn ); const TrayTileSet* curTiles = model_getPlayerTiles( model, turn );
sortTiles( &sorted, curTiles, XP_MIN( 3, curTiles->nTiles) ); XP_U16 dividerLoc = model_getDividerLoc( model, turn );
sortTiles( &sorted, curTiles, dividerLoc );
nTiles = sorted.nTiles; nTiles = sorted.nTiles;
while ( nTiles > 0 ) { while ( nTiles > 0 ) {
@ -2441,6 +2459,10 @@ loadPlayerCtxt( const ModelCtxt* model, XWStreamCtxt* stream, XP_U16 version,
} else { } else {
XP_ASSERT( 0 == pc->nUndone ); XP_ASSERT( 0 == pc->nUndone );
} }
XP_ASSERT( 0 == pc->dividerLoc );
if ( STREAM_VERS_MULTIADDR <= version ) {
pc->dividerLoc = stream_getBits( stream, NTILES_NBITS );
}
nTiles = pc->nPending + pc->nUndone; nTiles = pc->nPending + pc->nUndone;
for ( pt = pc->pendingTiles; nTiles-- > 0; ++pt ) { for ( pt = pc->pendingTiles; nTiles-- > 0; ++pt ) {
@ -2475,6 +2497,7 @@ writePlayerCtxt( const ModelCtxt* model, XWStreamCtxt* stream,
stream_putBits( stream, NTILES_NBITS, pc->nPending ); stream_putBits( stream, NTILES_NBITS, pc->nPending );
stream_putBits( stream, NTILES_NBITS, pc->nUndone ); stream_putBits( stream, NTILES_NBITS, pc->nUndone );
stream_putBits( stream, NTILES_NBITS, pc->dividerLoc );
nTiles = pc->nPending + pc->nUndone; nTiles = pc->nPending + pc->nUndone;
for ( pt = pc->pendingTiles; nTiles-- > 0; ++pt ) { for ( pt = pc->pendingTiles; nTiles-- > 0; ++pt ) {

View file

@ -152,6 +152,8 @@ void model_addPlayerTile( ModelCtxt* model, XP_S16 turn, XP_S16 index,
Tile tile ); Tile tile );
void model_moveTileOnTray( ModelCtxt* model, XP_S16 turn, XP_S16 indexCur, void model_moveTileOnTray( ModelCtxt* model, XP_S16 turn, XP_S16 indexCur,
XP_S16 indexNew ); XP_S16 indexNew );
XP_U16 model_getDividerLoc( const ModelCtxt* model, XP_S16 turn );
void model_setDividerLoc( const ModelCtxt* model, XP_S16 turn, XP_U16 loc );
/* As an optimization, return a pointer to the model's array of tiles for a /* As an optimization, return a pointer to the model's array of tiles for a
player. Don't even think about modifying the array!!!! */ player. Don't even think about modifying the array!!!! */

View file

@ -41,6 +41,7 @@ typedef struct PlayerCtxt {
TrayTileSet trayTiles; TrayTileSet trayTiles;
XP_U8 nPending; /* still in tray but "on board" */ XP_U8 nPending; /* still in tray but "on board" */
XP_U8 nUndone; /* tiles above nPending we can reuse */ XP_U8 nUndone; /* tiles above nPending we can reuse */
XP_U8 dividerLoc;
PendingTile pendingTiles[MAX_TRAY_TILES]; PendingTile pendingTiles[MAX_TRAY_TILES];
} PlayerCtxt; } PlayerCtxt;

View file

@ -48,6 +48,12 @@ trayLocToIndex( BoardCtxt* board, XP_U16 loc )
return loc; return loc;
} /* trayLocToIndex */ } /* trayLocToIndex */
static XP_U16
getDividerLoc( const BoardCtxt* board )
{
return model_getDividerLoc( board->model, board->selPlayer );
}
XP_S16 XP_S16
pointToTileIndex( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_Bool* onDividerP ) pointToTileIndex( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_Bool* onDividerP )
{ {
@ -96,7 +102,7 @@ figureTrayTileRect( BoardCtxt* board, XP_U16 index, XP_Rect* rect )
rect->width = board->trayScaleH; rect->width = board->trayScaleH;
rect->height = board->trayScaleV; rect->height = board->trayScaleV;
if ( board->selInfo->dividerLoc <= index ) { if ( getDividerLoc( board ) <= index ) {
rect->left += board->dividerWidth; rect->left += board->dividerWidth;
} }
} /* figureTileRect */ } /* figureTileRect */
@ -143,7 +149,7 @@ drawTray( BoardCtxt* board )
#ifdef KEYBOARD_NAV #ifdef KEYBOARD_NAV
XP_S16 cursorTile = pti->trayCursorLoc; XP_S16 cursorTile = pti->trayCursorLoc;
if ( (board->focussed == OBJ_TRAY) && !board->hideFocus ) { if ( (board->focussed == OBJ_TRAY) && !board->hideFocus ) {
cursorOnDivider = pti->dividerLoc == cursorTile; cursorOnDivider = getDividerLoc(board) == cursorTile;
if ( board->focusHasDived ) { if ( board->focusHasDived ) {
if ( !cursorOnDivider ) { if ( !cursorOnDivider ) {
adjustForDivider( board, &cursorTile ); adjustForDivider( board, &cursorTile );
@ -348,7 +354,8 @@ drawPendingScore( BoardCtxt* board, XP_S16 turnScore, XP_Bool hasCursor )
static void static void
figureDividerRect( BoardCtxt* board, XP_Rect* rect ) figureDividerRect( BoardCtxt* board, XP_Rect* rect )
{ {
figureTrayTileRect( board, board->selInfo->dividerLoc, rect ); XP_U16 dividerLoc = getDividerLoc( board );
figureTrayTileRect( board, dividerLoc, rect );
rect->left -= board->dividerWidth; rect->left -= board->dividerWidth;
rect->width = board->dividerWidth; rect->width = board->dividerWidth;
} /* figureDividerRect */ } /* figureDividerRect */
@ -495,10 +502,10 @@ indexForBits( XP_U8 bits )
XP_Bool XP_Bool
dividerMoved( BoardCtxt* board, XP_U8 newLoc ) dividerMoved( BoardCtxt* board, XP_U8 newLoc )
{ {
XP_U8 oldLoc = board->selInfo->dividerLoc; XP_U8 oldLoc = getDividerLoc( board );
XP_Bool moved = oldLoc != newLoc; XP_Bool moved = oldLoc != newLoc;
if ( moved ) { if ( moved ) {
board->selInfo->dividerLoc = newLoc; model_setDividerLoc( board->model, board->selPlayer, newLoc );
/* This divider's index corresponds to the tile it's to the left of, and /* This divider's index corresponds to the tile it's to the left of, and
there's no need to invalidate any tiles to the left of the uppermore there's no need to invalidate any tiles to the left of the uppermore
@ -562,7 +569,7 @@ board_juggleTray( BoardCtxt* board )
if ( checkRevealTray( board ) ) { if ( checkRevealTray( board ) ) {
XP_S16 nTiles; XP_S16 nTiles;
XP_U16 dividerLoc = board->selInfo->dividerLoc; XP_U16 dividerLoc = getDividerLoc( board );
ModelCtxt* model = board->model; ModelCtxt* model = board->model;
nTiles = model_getNumTilesInTray( model, turn ) - dividerLoc; nTiles = model_getNumTilesInTray( model, turn ) - dividerLoc;
@ -597,7 +604,7 @@ board_juggleTray( BoardCtxt* board )
void void
adjustForDivider( const BoardCtxt* board, XP_S16* index ) adjustForDivider( const BoardCtxt* board, XP_S16* index )
{ {
XP_U16 dividerLoc = board->selInfo->dividerLoc; XP_U16 dividerLoc = getDividerLoc( board );
if ( dividerLoc <= *index ) { if ( dividerLoc <= *index ) {
--*index; --*index;
} }
@ -630,7 +637,8 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly,
XP_U16 nTiles = board->trayVisState == TRAY_REVEALED XP_U16 nTiles = board->trayVisState == TRAY_REVEALED
? model_getNumTilesInTray( board->model, selPlayer ) ? model_getNumTilesInTray( board->model, selPlayer )
: MAX_TRAY_TILES; : MAX_TRAY_TILES;
XP_Bool cursorOnDivider = trayCursorLoc == pti->dividerLoc; XP_U16 dividerLoc = getDividerLoc( board );
XP_Bool cursorOnDivider = trayCursorLoc == dividerLoc;
XP_Bool cursorObjSelected; XP_Bool cursorObjSelected;
XP_S16 newTileLoc; XP_S16 newTileLoc;
@ -642,13 +650,13 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly,
/* nothing to do */ /* nothing to do */
} else if ( cursorOnDivider ) { } else if ( cursorOnDivider ) {
/* just drag the divider */ /* just drag the divider */
pti->dividerLoc = newLoc; model_setDividerLoc( board->model, board->selPlayer, newLoc );
resetEngine = XP_TRUE; resetEngine = XP_TRUE;
} else if ( pti->tradeInProgress ) { } else if ( pti->tradeInProgress ) {
/* nothing to do */ /* nothing to do */
} else { } else {
/* drag the tile, skipping over the divider if needed */ /* drag the tile, skipping over the divider if needed */
if ( (newLoc == pti->dividerLoc) && (newLoc > 0) ) { if ( (newLoc == dividerLoc) && (newLoc > 0) ) {
newLoc += delta; newLoc += delta;
resetEngine = XP_TRUE; resetEngine = XP_TRUE;
} }
@ -675,7 +683,7 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly,
adjustForDivider( board, &newTileLoc ); adjustForDivider( board, &newTileLoc );
if ( (newTileLoc > nTiles) if ( (newTileLoc > nTiles)
&& (newLoc != pti->dividerLoc) && (newLoc != dividerLoc)
&& (newTileLoc < MAX_TRAY_TILES-1) ) { && (newTileLoc < MAX_TRAY_TILES-1) ) {
continue; continue;
} }
@ -702,9 +710,8 @@ getFocussedTileCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp )
XP_Rect rect; XP_Rect rect;
PerTurnInfo* pti = board->selInfo; PerTurnInfo* pti = board->selInfo;
XP_S16 cursorTile = pti->trayCursorLoc; XP_S16 cursorTile = pti->trayCursorLoc;
XP_Bool cursorOnDivider = pti->dividerLoc == cursorTile;
if ( cursorOnDivider ) { if ( getDividerLoc( board ) == cursorTile ) { /* cursor on divider? */
figureDividerRect( board, &rect ); figureDividerRect( board, &rect );
} else { } else {
XP_S16 indx = pti->trayCursorLoc; XP_S16 indx = pti->trayCursorLoc;
@ -723,7 +730,7 @@ board_moveDivider( BoardCtxt* board, XP_Bool right )
{ {
XP_Bool result = board->trayVisState == TRAY_REVEALED; XP_Bool result = board->trayVisState == TRAY_REVEALED;
if ( result ) { if ( result ) {
XP_U8 loc = board->selInfo->dividerLoc; XP_U8 loc = getDividerLoc( board );
loc += MAX_TRAY_TILES + 1; loc += MAX_TRAY_TILES + 1;
loc += right? 1:-1; loc += right? 1:-1;
loc %= MAX_TRAY_TILES + 1; loc %= MAX_TRAY_TILES + 1;