diff --git a/xwords4/android/XWords4/res/layout/game_config.xml b/xwords4/android/XWords4/res/layout/game_config.xml
index 20ff24f73..26a2fe507 100644
--- a/xwords4/android/XWords4/res/layout/game_config.xml
+++ b/xwords4/android/XWords4/res/layout/game_config.xml
@@ -25,6 +25,13 @@
android:layout_height="fill_parent"
android:orientation="vertical">
+
+
key_notagain_zoom
key_notagain_undo
key_notagain_done
+ key_notagain_unlock
+ key_notagain_conndall
+ key_notagain_conndfirst
+ key_notagain_conndmid
org.eehouse.android.xw4.relayids_extra
diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml
index 69a1b5c86..eaa89a403 100644
--- a/xwords4/android/XWords4/res/values/strings.xml
+++ b/xwords4/android/XWords4/res/values/strings.xml
@@ -79,8 +79,8 @@
Turn done
Shuffle
Flip
- Exchange
- Hide tray
+ Exchange tiles
+ Hide rack
Undo
Undo current
Undo last
@@ -112,7 +112,7 @@
- %d [time]
move (from %s across)
move (from %s down)
- Tray at start: %s
+ Rack at start: %s
Exchanged %s for %s.
Illegal word in move; turn lost!
Cumulative score: %d
@@ -153,6 +153,7 @@
Players
Players (%d local, %d off-device)
Players -- local only
+ Lock settings
Add player
Shuffle players
@@ -184,8 +185,14 @@
This game is in play. If you
save these changes it must be restarted. Do you want to save
these changes?
- Are you sure you want to
- delete all games? This action cannot be undone.
+ Are you sure you want to delete this
+ game?
+ Are you sure you want to delete
+ all games?
+ Are you sure you want to reset this
+ game? Resetting erases all moves and any connection
+ information.
+
Are you sure you want to delete
this dictionary? You will not be able to open any games that use
it.
@@ -197,8 +204,8 @@
Draw tiles using color of
player who played them
Show board arrow
- Tapped tray tiles land on this
- arrow when it is visible
+ Tapped rack tiles land on this
+ arrow when it is visible
Explain robot moves
Display score summary after
every robot turn
@@ -206,8 +213,8 @@
Do NOT display score
summary after every human turn
Sort new tiles
- Sort trays whenever new tiles
- are added
+ Sort racks whenever new tiles
+ are added
Volume keys zoom
Zoom board using volume keys
Hide titlebar
@@ -292,8 +299,8 @@
SMS (broken)
Bluetooth (pending)
- Connected to relay in room
- \"%s\". Waiting for %d player[s].
+ Device %d connected to relay in
+ room \"%s\". Waiting for %d player[s].
All players are here in room
\"%s\".
Connection status.
@@ -418,9 +425,15 @@
Or try joining or creating a public room.
The new game you have created has
- two players, the first a robot, both on this device. To play
- the game, tap it; to change its configuration or for other
- options, long-tap it.
+ two players, the first a robot, both on this device. Tap it to
+ play; long-tap it to change its configuration or for other
+ options.
+ The new game you have created
+ has two players but only one is on this device. To play the
+ game, tap it, and it will begin by connecting over the internet
+ looking for that other player in the default no-name
+ room. Long-tap it to configure - e.g. change the room name - or
+ for other options.
This button shows all possible
moves in ascending order (using tiles to the right of the rack
@@ -438,9 +451,25 @@
This button undos or redoes the
current turn.
- The new game you have created
- The \"pts\" counter that appears at
- the right end of the rack is an alternative to this menu
- item.
+ Tapping the \"pts\" counter that
+ appears at the right end of the rack is the easiest way to
+ commit a move. (There is no shortcut for ending a
+ trade.)
+ This game is in play. Some
+ settings, e.g. the number of players, cannot be changed without
+ restarting it. When you leave this page you will have a chance
+ to discard changes to avoid a restart.
+
+ You have connected and joined a
+ game on the relay; the room is now full. The device that
+ created the room will now assign your initial tiles and play can
+ begin.
+ You have connected and started
+ a game in a new room. Once the remaining devices have joined
+ your room and Crosswords has assigned them tiles the game can
+ begin.
+ You have connected and joined a
+ game on the relay. You will be notified when the remaining
+ device[s] have joined your room and play can begin.
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java
index fb5d1b3bf..8de6abfc3 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java
@@ -471,7 +471,7 @@ public class BoardActivity extends XWActivity implements UtilCtxt {
// cmd = JNIThread.JNICmd.CMD_FLIP;
// break;
case R.id.board_menu_trade:
- cmd = JNIThread.JNICmd.CMD_TOGGLE_TRADE;
+ cmd = JNIThread.JNICmd.CMD_TRADE;
break;
case R.id.board_menu_tray:
cmd = JNIThread.JNICmd.CMD_TOGGLE_TRAY;
@@ -625,7 +625,9 @@ public class BoardActivity extends XWActivity implements UtilCtxt {
{
CommsTransport.ConndMsg cndmsg =
(CommsTransport.ConndMsg)msg.obj;
- Utils.logf( "handleConndMessage: devOrder=%d", cndmsg.m_devOrder );
+
+ int naMsg = 0;
+ int naKey = 0;
String str = null;
if ( cndmsg.m_allHere ) {
// All players have now joined the game. The device that
@@ -633,16 +635,38 @@ public class BoardActivity extends XWActivity implements UtilCtxt {
// the first player's turn
String fmt = getString( R.string.msg_relay_all_heref );
str = String.format( fmt, cndmsg.m_room );
+ if ( cndmsg.m_devOrder > 1 ) {
+ naMsg = R.string.not_again_conndall;
+ naKey = R.string.key_notagain_conndall;
+ }
} else if ( cndmsg.m_nMissing > 0 ) {
String fmt = getString( R.string.msg_relay_waiting );
- str = String.format( fmt, cndmsg.m_room, cndmsg.m_nMissing );
+ str = String.format( fmt, cndmsg.m_devOrder,
+ cndmsg.m_room, cndmsg.m_nMissing );
+ if ( cndmsg.m_devOrder == 1 ) {
+ naMsg = R.string.not_again_conndfirst;
+ naKey = R.string.key_notagain_conndfirst;
+ } else {
+ naMsg = R.string.not_again_conndmid;
+ naKey = R.string.key_notagain_conndmid;
+ }
}
if ( null != str ) {
- Toast.makeText( BoardActivity.this, str,
- Toast.LENGTH_SHORT).show();
+ final String fstr = str;
+ Runnable proc = new Runnable() {
+ public void run() {
+ Toast.makeText( BoardActivity.this, fstr,
+ Toast.LENGTH_SHORT).show();
+ }
+ };
+ if ( naMsg == 0 ) {
+ proc.run();
+ } else {
+ showNotAgainDlgThen( naMsg, naKey, proc );
+ }
}
- }
+ } // handleConndMessage
//////////////////////////////////////////
// XW_UtilCtxt interface implementation //
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java
index 065d50ae7..9c474fe10 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java
@@ -69,6 +69,8 @@ public class GameConfig extends XWActivity
private static final int NO_NAME_FOUND = PLAYER_EDIT + 4;
private CheckBox m_joinPublicCheck;
+ private CheckBox m_gameLockedCheck;
+ private boolean m_isLocked;
private LinearLayout m_publicRoomsSet;
private LinearLayout m_privateRoomsSet;
@@ -98,9 +100,23 @@ public class GameConfig extends XWActivity
private CommonPrefs m_cp;
private boolean m_canDoSMS = false;
private boolean m_canDoBT = false;
- private int m_nMoves = 0;
+ private boolean m_gameStarted = false;
private CommsAddrRec.CommsConnType[] m_types;
private String[] m_connStrings;
+ private static final int[] s_disabledWhenLocked = { R.id.juggle_players
+ ,R.id.add_player
+ ,R.id.dict_spinner
+ ,R.id.join_public_room_check
+ ,R.id.room_edit
+ ,R.id.advertise_new_room_check
+ ,R.id.room_spinner
+ ,R.id.refresh_button
+ ,R.id.hints_allowed
+ ,R.id.use_timer
+ ,R.id.timer_minutes_edit
+ ,R.id.smart_robot
+ ,R.id.phonies_spinner
+ };
class RemoteChoices extends XWListAdapter {
public RemoteChoices() { super( GameConfig.this, m_gi.nPlayers ); }
@@ -127,7 +143,7 @@ public class GameConfig extends XWActivity
}
@Override
- protected Dialog onCreateDialog( int id )
+ protected Dialog onCreateDialog( final int id )
{
Dialog dialog = super.onCreateDialog( id );
if ( null == dialog ) {
@@ -199,41 +215,40 @@ public class GameConfig extends XWActivity
}
});
break;
- case CONFIRM_CHANGE:
- dialog = new AlertDialog.Builder( this )
- .setTitle( R.string.confirm_save_title )
- .setMessage( R.string.confirm_save )
- .setPositiveButton( R.string.button_save,
- new DialogInterface.OnClickListener() {
- public void onClick( DialogInterface dlg,
- int whichButton ) {
- applyChanges( true );
- finish();
- }
- })
- .setNegativeButton( R.string.button_discard,
- new DialogInterface.OnClickListener() {
- public void onClick( DialogInterface dlg,
- int whichButton ) {
- finish();
- }
- })
- .create();
- break;
case CONFIRM_CHANGE_PLAY:
- dialog = new AlertDialog.Builder( this )
+ case CONFIRM_CHANGE:
+ dlpos = new DialogInterface.OnClickListener() {
+ public void onClick( DialogInterface dlg,
+ int whichButton ) {
+ applyChanges( true );
+ if ( CONFIRM_CHANGE_PLAY == id ) {
+ launchGame();
+ }
+ }
+ };
+ ab = new AlertDialog.Builder( this )
.setTitle( R.string.confirm_save_title )
.setMessage( R.string.confirm_save )
- .setPositiveButton( R.string.button_save,
- new DialogInterface.OnClickListener() {
- public void onClick( DialogInterface dlg,
- int whichButton ) {
- applyChanges( true );
- launchGame();
- }
- })
- .setNegativeButton( R.string.button_cancel, null )
- .create();
+ .setPositiveButton( R.string.button_save, dlpos );
+ if ( CONFIRM_CHANGE_PLAY == id ) {
+ dlpos = new DialogInterface.OnClickListener() {
+ public void onClick( DialogInterface dlg,
+ int whichButton ) {
+ launchGame();
+ }
+ };
+ } else {
+ dlpos = null;
+ }
+ ab.setNegativeButton( R.string.button_discard, dlpos );
+ dialog = ab.create();
+
+ dialog.setOnDismissListener( new DialogInterface.
+ OnDismissListener() {
+ public void onDismiss( DialogInterface di ) {
+ finish();
+ }
+ });
break;
case NO_NAME_FOUND:
dialog = new AlertDialog.Builder( this )
@@ -350,11 +365,23 @@ public class GameConfig extends XWActivity
m_path = m_path.substring( 1 );
}
+ setContentView(R.layout.game_config);
+
int gamePtr = XwJNI.initJNI();
m_giOrig = new CurGameInfo( this );
GameUtils.loadMakeGame( this, gamePtr, m_giOrig, m_path );
- m_nMoves = XwJNI.model_getNMoves( gamePtr );
- m_giOrig.setInProgress( 0 < m_nMoves );
+ m_gameStarted = XwJNI.model_getNMoves( gamePtr ) > 0
+ || XwJNI.comms_isConnected( gamePtr );
+ m_giOrig.setInProgress( m_gameStarted );
+
+ if ( m_gameStarted ) {
+ m_gameLockedCheck = (CheckBox)findViewById( R.id.game_locked_check );
+ m_gameLockedCheck.setVisibility( View.VISIBLE );
+ m_gameLockedCheck.setChecked( true );
+ m_gameLockedCheck.setOnClickListener( this );
+ handleLockedChange();
+ }
+
int curSel = listAvailableDicts( m_giOrig.dictName );
m_giOrig.dictLang =
DictLangCache.getLangCode( this,
@@ -373,8 +400,6 @@ public class GameConfig extends XWActivity
m_car = new CommsAddrRec( m_carOrig );
- setContentView(R.layout.game_config);
-
m_notNetworkedGame = DeviceRole.SERVER_STANDALONE == m_gi.serverRole;
if ( !m_notNetworkedGame ) {
@@ -463,6 +488,14 @@ public class GameConfig extends XWActivity
loadPlayers();
} else if ( m_joinPublicCheck == view ) {
adjustConnectStuff();
+ } else if ( m_gameLockedCheck == view ) {
+ showNotAgainDlgThen( R.string.not_again_unlock,
+ R.string.key_notagain_unlock,
+ new Runnable() {
+ public void run() {
+ handleLockedChange();
+ }
+ });
} else if ( m_refreshRoomsButton == view ) {
refreshNames();
} else if ( m_playButton == view ) {
@@ -471,7 +504,7 @@ public class GameConfig extends XWActivity
// from here if there's no confirmation needed, or launch
// a new dialog whose OK button does the same thing.
saveChanges();
- if ( 0 >= m_nMoves ) { // no confirm needed
+ if ( !m_gameStarted ) { // no confirm needed
applyChanges( true );
launchGame();
} else if ( m_giOrig.changesMatter(m_gi)
@@ -494,7 +527,7 @@ public class GameConfig extends XWActivity
boolean consumed = false;
if ( keyCode == KeyEvent.KEYCODE_BACK ) {
saveChanges();
- if ( 0 >= m_nMoves ) { // no confirm needed
+ if ( !m_gameStarted ) { // no confirm needed
applyChanges( true );
} else if ( m_giOrig.changesMatter(m_gi)
|| (! m_notNetworkedGame
@@ -544,6 +577,7 @@ public class GameConfig extends XWActivity
}
} );
m_playerLayout.addView( view );
+ view.setEnabled( !m_isLocked );
View divider = factory.inflate( R.layout.divider_view, null );
divider.setVisibility( View.VISIBLE );
@@ -700,6 +734,26 @@ public class GameConfig extends XWActivity
m_publicRoomsSet.setVisibility( View.GONE );
}
}
+
+ // User's toggling whether everything's locked. That should mean
+ // we enable/disable a bunch of widgits. And if we're going from
+ // unlocked to locked we need to confirm that everything can be
+ // reverted.
+ private void handleLockedChange()
+ {
+ boolean locking = m_gameLockedCheck.isChecked();
+ m_isLocked = locking;
+ for ( int id : s_disabledWhenLocked ) {
+ View view = findViewById( id );
+ view.setEnabled( !m_isLocked );
+ }
+ if ( null != m_playerLayout ) {
+ for ( int ii = m_playerLayout.getChildCount()-1; ii >= 0; --ii ) {
+ View view = m_playerLayout.getChildAt( ii );
+ view.setEnabled( !m_isLocked );
+ }
+ }
+ }
private int connTypeToPos( CommsAddrRec.CommsConnType typ )
{
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java
index 2c463a474..4fa3ebd91 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java
@@ -274,15 +274,32 @@ public class GamesList extends XWListActivity
private boolean handleMenuItem( int menuID, int position )
{
boolean handled = true;
- byte[] stream;
- String invalPath = null;
- String path = GameUtils.gamesList( this )[position];
+ final String path = GameUtils.gamesList( this )[position];
if ( R.id.list_item_delete == menuID ) {
- GameUtils.deleteGame( this, path );
- invalPath = path;
+ DialogInterface.OnClickListener lstnr =
+ new DialogInterface.OnClickListener() {
+ public void onClick( DialogInterface dlg, int ii ) {
+ GameUtils.deleteGame( GamesList.this, path );
+ m_adapter.inval( path );
+ onContentChanged();
+ }
+ };
+ showConfirmThen( R.string.confirm_delete, lstnr );
+ } else if ( R.id.list_item_reset == menuID ) {
+ DialogInterface.OnClickListener lstnr =
+ new DialogInterface.OnClickListener() {
+ public void onClick( DialogInterface dlg, int ii ) {
+ GameUtils.resetGame( GamesList.this,
+ path, path );
+ m_adapter.inval( path );
+ onContentChanged();
+ }
+ };
+ showConfirmThen( R.string.confirm_reset, lstnr );
} else {
+ String invalPath = null;
String[] missingName = new String[1];
int[] missingLang = new int[1];
boolean hasDict = GameUtils.gameDictHere( this, path,
@@ -296,11 +313,6 @@ public class GamesList extends XWListActivity
m_invalPath = path;
break;
- case R.id.list_item_reset:
- // TODO confirm_data_loss();
- GameUtils.resetGame( this, path, path );
- invalPath = path;
- break;
case R.id.list_item_new_from:
String newName = GameUtils.resetGame( this, path );
invalPath = newName;
@@ -311,7 +323,7 @@ public class GamesList extends XWListActivity
if ( summary.inNetworkGame() ) {
showOKOnlyDialog( R.string.no_copy_network );
} else {
- stream = GameUtils.savedGame( this, path );
+ byte[] stream = GameUtils.savedGame( this, path );
newName = GameUtils.saveGame( this, stream );
DBUtils.saveSummary( this, newName, summary );
}
@@ -331,14 +343,13 @@ public class GamesList extends XWListActivity
break;
}
}
- }
- if ( null != invalPath ) {
- m_adapter.inval( invalPath );
- }
-
- if ( handled ) {
- onContentChanged();
+ if ( null != invalPath ) {
+ m_adapter.inval( invalPath );
+ }
+ if ( handled ) {
+ onContentChanged();
+ }
}
return handled;
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWListItem.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWListItem.java
index 64bc15331..791e39a30 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWListItem.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWListItem.java
@@ -30,7 +30,6 @@ import android.graphics.Rect;
public class XWListItem extends LinearLayout {
private int m_position;
- private ImageButton m_button;
private Context m_context;
DeleteCallback m_cb;
@@ -64,4 +63,15 @@ public class XWListItem extends LinearLayout {
} );
button.setVisibility( View.VISIBLE );
}
+
+ @Override
+ public void setEnabled( boolean enabled )
+ {
+ ImageButton button = (ImageButton)getChildAt( 1 );
+ button.setEnabled( enabled );
+ // calling super here means the list item can't be opened for
+ // the user to inspect data. Might want to reconsider this.
+ // PENDING
+ super.setEnabled( enabled );
+ }
}
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java
index a4f05f1f6..81a0ebb61 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java
@@ -61,7 +61,7 @@ public class JNIThread extends Thread {
CMD_JUGGLE,
CMD_FLIP,
CMD_TOGGLE_TRAY,
- CMD_TOGGLE_TRADE,
+ CMD_TRADE,
CMD_UNDO_CUR,
CMD_UNDO_LAST,
CMD_HINT,
@@ -365,7 +365,7 @@ public class JNIThread extends Thread {
case CMD_TOGGLE_TRAY:
draw = toggleTray();
break;
- case CMD_TOGGLE_TRADE:
+ case CMD_TRADE:
draw = XwJNI.board_beginTrade( m_jniGamePtr );
break;
case CMD_UNDO_CUR:
diff --git a/xwords4/common/board.c b/xwords4/common/board.c
index 3832b47c9..b0d3fb250 100644
--- a/xwords4/common/board.c
+++ b/xwords4/common/board.c
@@ -1215,10 +1215,8 @@ invalCellsWithTiles( BoardCtxt* board )
*/
for ( row = model_numRows( model )-1; row >= 0; --row ) {
for ( col = model_numCols( model )-1; col >= 0; --col ) {
- Tile tile;
- XP_Bool ignore;
if ( model_getTile( model, col, row, includePending,
- turn, &tile, &ignore, &ignore, &ignore ) ) {
+ turn, NULL, NULL, NULL, NULL ) ) {
XP_U16 boardCol, boardRow;
flipIf( board, col, row, &boardCol, &boardRow );
invalCell( board, boardCol, boardRow );
@@ -2327,13 +2325,12 @@ cellOccupied( const BoardCtxt* board, XP_U16 col, XP_U16 row,
XP_Bool inclPending )
{
Tile tile;
- XP_Bool ignr;
XP_Bool result;
flipIf( board, col, row, &col, &row );
result = model_getTile( board->model, col, row, inclPending,
board->selPlayer, &tile,
- &ignr, &ignr, &ignr );
+ NULL, NULL, NULL );
return result;
} /* cellOccupied */
@@ -2379,13 +2376,13 @@ XP_Bool
holdsPendingTile( BoardCtxt* board, XP_U16 pencol, XP_U16 penrow )
{
Tile tile;
- XP_Bool ignore, isPending;
+ XP_Bool isPending;
XP_U16 modcol, modrow;
flipIf( board, pencol, penrow, &modcol, &modrow );
return model_getTile( board->model, modcol, modrow, XP_TRUE,
- board->selPlayer, &tile, &ignore, &isPending,
- (XP_Bool*)NULL )
+ board->selPlayer, &tile, NULL, &isPending,
+ NULL )
&& isPending;
} /* holdsPendingTile */
@@ -3232,16 +3229,14 @@ boardCellChanged( void* p_board, XP_U16 turn, XP_U16 modelCol, XP_U16 modelRow,
XP_Bool added )
{
BoardCtxt* board = (BoardCtxt*)p_board;
- XP_Bool pending, found, ignoreBlank;
- Tile ignoreTile;
+ XP_Bool pending, found;
XP_U16 col, row;
flipIf( board, modelCol, modelRow, &col, &row );
/* for each player, check if the tile overwrites the cursor */
found = model_getTile( board->model, modelCol, modelRow, XP_TRUE, turn,
- &ignoreTile, &ignoreBlank, &pending,
- (XP_Bool*)NULL );
+ NULL, NULL, &pending, NULL );
XP_ASSERT( !added || found ); /* if added is true so must found be */
diff --git a/xwords4/common/dragdrpp.c b/xwords4/common/dragdrpp.c
index 92860bfc3..ec6d933d2 100644
--- a/xwords4/common/dragdrpp.c
+++ b/xwords4/common/dragdrpp.c
@@ -91,14 +91,13 @@ ddStartBoard( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
trayVisible = board->trayVisState == TRAY_REVEALED;
if ( trayVisible && holdsPendingTile( board, col, row ) ) {
XP_U16 modelc, modelr;
- XP_Bool ignore;
ds->dtype = DT_TILE;
flipIf( board, col, row, &modelc, &modelr );
found = model_getTile( board->model, modelc, modelr, XP_TRUE,
board->selPlayer, &ds->tile, &ds->isBlank,
- &ignore, &ignore );
+ NULL, NULL );
XP_ASSERT( found );
} else {
/* If we're not dragging a tile, we can either drag the board (scroll)
diff --git a/xwords4/common/engine.c b/xwords4/common/engine.c
index b9c6cf0ed..eb32eacad 100644
--- a/xwords4/common/engine.c
+++ b/xwords4/common/engine.c
@@ -732,7 +732,7 @@ localGetBoardTile( EngineCtxt* engine, XP_U16 col, XP_U16 row,
XP_Bool substBlank )
{
Tile result;
- XP_Bool isBlank, ignore;
+ XP_Bool isBlank;
if ( !engine->searchHorizontal ) {
XP_U16 tmp = col;
@@ -742,7 +742,7 @@ localGetBoardTile( EngineCtxt* engine, XP_U16 col, XP_U16 row,
if ( model_getTile( engine->model, col, row, XP_FALSE,
0, /* don't get pending, so turn doesn't matter */
- &result, &isBlank, &ignore, (XP_Bool*)NULL ) ) {
+ &result, &isBlank, NULL, NULL ) ) {
if ( isBlank && substBlank ) {
result = engine->blankTile;
}
diff --git a/xwords4/common/model.c b/xwords4/common/model.c
index 4b87f24fd..b1ade983c 100644
--- a/xwords4/common/model.c
+++ b/xwords4/common/model.c
@@ -327,10 +327,16 @@ model_getTile( const ModelCtxt* model, XP_U16 col, XP_U16 row,
if ( (cellTile & TILE_EMPTY_BIT) != 0 ) {
return XP_FALSE;
}
-
- *tileP = cellTile & TILE_VALUE_MASK;
- *isBlank = IS_BLANK(cellTile);
- *pendingP = pending;
+
+ if ( NULL != tileP ) {
+ *tileP = cellTile & TILE_VALUE_MASK;
+ }
+ if ( NULL != isBlank ) {
+ *isBlank = IS_BLANK(cellTile);
+ }
+ if ( NULL != pendingP ) {
+ *pendingP = pending;
+ }
if ( !!recentP ) {
*recentP = (cellTile & PREV_MOVE_BIT) != 0;
}
@@ -1007,12 +1013,11 @@ model_moveTrayToBoard( ModelCtxt* model, XP_S16 turn, XP_U16 col, XP_U16 row,
XP_Bool
model_redoPendingTiles( ModelCtxt* model, XP_S16 turn )
{
- XP_Bool changed = XP_FALSE;
+ XP_U16 actualCnt = 0;
PlayerCtxt* player = &model->players[turn];
XP_U16 nUndone = player->nUndone;
- changed = nUndone > 0;
- if ( changed ) {
+ if ( nUndone > 0 ) {
PendingTile pendingTiles[nUndone];
PendingTile* pt = pendingTiles;
@@ -1031,11 +1036,16 @@ model_redoPendingTiles( ModelCtxt* model, XP_S16 turn )
}
foundAt = model_trayContains( model, turn, tile );
XP_ASSERT( foundAt >= 0 );
- model_moveTrayToBoard( model, turn, pt->col, pt->row,
- foundAt, pt->tile & ~TILE_BLANK_BIT );
+
+ if ( !model_getTile( model, pt->col, pt->row, XP_FALSE, turn,
+ NULL, NULL, NULL, NULL ) ) {
+ model_moveTrayToBoard( model, turn, pt->col, pt->row,
+ foundAt, pt->tile & ~TILE_BLANK_BIT );
+ ++actualCnt;
+ }
}
}
- return changed;
+ return actualCnt > 0;
}
void
diff --git a/xwords4/common/mscore.c b/xwords4/common/mscore.c
index 917ff2631..e8b3279c4 100644
--- a/xwords4/common/mscore.c
+++ b/xwords4/common/mscore.c
@@ -317,11 +317,10 @@ static XP_Bool
modelIsEmptyAt( const ModelCtxt* model, XP_U16 col, XP_U16 row )
{
Tile tile;
- XP_Bool ignore;
XP_Bool found;
found = model_getTile( model, col, row, XP_FALSE, -1, &tile,
- &ignore, &ignore, (XP_Bool*)NULL );
+ NULL, NULL, NULL );
return !found;
} /* modelIsEmptyAt */
@@ -643,11 +642,10 @@ scoreWord( const ModelCtxt* model, MoveInfo* movei, /* new tiles */
++tiles;
--nTiles;
} else { /* placed on the board before this move */
- XP_Bool ignore;
tileMultiplier = 1;
(void)model_getTile( model, col, row, XP_FALSE, -1, &tile,
- &isBlank, &ignore, (XP_Bool*)NULL );
+ &isBlank, NULL, NULL );
XP_ASSERT( (tile & TILE_VALUE_MASK) == tile );
}