lots of changes, still needing cleanup and a bit of debugging, to

simplify game settings dialog and remove role: a game is now
standalone or not.  Games will be matched on the relay (or over BT, I
assume) based on how many players they provide vs. need -- and other
settings like dictionary
This commit is contained in:
Andy2 2010-08-31 05:43:41 -07:00
parent adf9c28e0d
commit 9367251b33
4 changed files with 250 additions and 370 deletions

View file

@ -25,43 +25,17 @@
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView style="@style/config_separator"
android:text="@string/role_label"
<CheckBox android:id="@+id/game_not_networked"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/all_players_here"
/>
<Spinner android:id="@+id/role_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:entries="@array/role_names"
android:prompt="@string/role_prompt"
/>
<TextView style="@style/config_separator"
android:id="@+id/connection_label"
android:text="@string/connection_label"
/>
<Spinner android:id="@+id/connect_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:visibility="gone"
android:prompt="@string/connect_prompt"
/>
<Button android:id="@+id/configure_role"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:text="@string/configure_role"
/>
<TextView style="@style/config_separator"
android:id="@+id/players_label"
/>
<!-- players -->
<TextView style="@style/config_separator"
android:id="@+id/players_label"
/>
<LinearLayout android:id="@+id/player_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"

View file

@ -20,7 +20,7 @@
<string name="button_new_game">Add game</string>
<string name="list_item_play">Play game</string>
<string name="list_item_config">Game settings</string>
<string name="list_item_config">Game settings...</string>
<string name="list_item_hide">Hide</string>
<string name="list_item_delete">Delete</string>
<string name="list_item_copy">Copy</string>
@ -140,15 +140,15 @@
<string name="str_server_dict_wins">Conflict between Host and Guest dictionaries; Host wins.</string>
<string name="str_reg_server_sans_remote">At least one player must be marked \"Remote\" for a game started as Host.</string>
<string name="remote_label">Guest player</string>
<string name="remote_label">Off-device player</string>
<string name="robot_label">Robot player</string>
<string name="robot_name">(robot)</string>
<string name="guest_name">(guest player)</string>
<string name="guest_name">(Off-device player)</string>
<string name="password_label">Password</string>
<string name="player_edit_title">Player</string>
<string name="players_label_standalone">Players</string>
<string name="players_label_host">Players -- local and expected</string>
<string name="players_label_host">Players (%d local, %d off-device)</string>
<string name="players_label_guest">Players -- local only</string>
<string name="button_add_player">Add player</string>
<string name="button_juggle_players">Shuffle players</string>
@ -212,11 +212,7 @@
<string name="show_bonussum_summary">Include text like "2W" on
empty bonus squares</string>
<string name="role_standalone">Standalone</string>
<string name="role_host">Host</string>
<string name="role_guest">Guest</string>
<string name="role_prompt">Standalone if all players are on this
device; otherwise Host a game or be a Guest.</string>
<string name="all_players_here">All players live on this device</string>
<string name="room_edit_hint_host">As host, you name the room you
and your guests will use. You must connect before any guests to
@ -315,14 +311,18 @@
<string name="ids_endnow">Are you sure you want to end the game now?</string>
<string name="force_title">Remote player[s]</string>
<string name="force_expl">As the Host, check the one or more
remote player[s] that will come from Guest device[s].</string>
<string name="force_title">Off-device player[s]</string>
<string name="force_expl">In a multi-device game there must be at
least one player from and another not from this device. Please
check off-device players.</string>
<string name="added_player">Player added to meet two-player
minimum for multi-device games.</string>
<string name="forced_consistent">Adjusted off-device player count.</string>
<string name="vs">vs.</string>
<string name="dictionary">Dictionary:</string>
<string name="summary_fmt_listening">%s listening</string>
<string name="summary_fmt_relay">%s via Relay, room \"%s\"</string>
<string name="summary_fmt_relay">Connecting via Relay, room \"%s\"</string>
<string name="summary_fmt_sms">%s via SMS, dialing %s</string>
<string name="gameOver">Game over</string>
<string name="movesf">%d moves played</string>
@ -375,5 +375,4 @@
<string name="connect_daily">Once every day</string>
<string name="connect_never">Never connect</string>
</resources>

View file

@ -48,6 +48,7 @@ import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ListAdapter;
import android.widget.Toast;
import android.database.DataSetObserver;
import junit.framework.Assert;
@ -58,22 +59,24 @@ public class GameConfig extends Activity implements View.OnClickListener,
XWListItem.DeleteCallback {
private static final int PLAYER_EDIT = 1;
private static final int ROLE_EDIT_RELAY = 2;
private static final int ROLE_EDIT_SMS = 3;
private static final int ROLE_EDIT_BT = 4;
// private static final int ROLE_EDIT_RELAY = 2;
// private static final int ROLE_EDIT_SMS = 3;
// private static final int ROLE_EDIT_BT = 4;
private static final int FORCE_REMOTE = 5;
private static final int CONFIRM_CHANGE = 6;
private CheckBox m_notNetworkedGameCheckbx;
private boolean m_notNetworkedGame;
private Button m_addPlayerButton;
private Button m_jugglePlayersButton;
private Button m_configureButton;
// private Button m_configureButton;
private String m_path;
private CurGameInfo m_gi;
private CurGameInfo m_giOrig;
private int m_whichPlayer;
private Dialog m_curDialog;
private Spinner m_roleSpinner;
private Spinner m_connectSpinner;
// private Spinner m_roleSpinner;
// private Spinner m_connectSpinner;
private Spinner m_phoniesSpinner;
private Spinner m_dictSpinner;
private String[] m_dictItems;
@ -141,23 +144,23 @@ public class GameConfig extends Activity implements View.OnClickListener,
.setNegativeButton( R.string.button_cancel, null )
.create();
break;
case ROLE_EDIT_RELAY:
case ROLE_EDIT_SMS:
case ROLE_EDIT_BT:
dialog = new AlertDialog.Builder( this )
.setTitle(titleForDlg(id))
.setView( LayoutInflater.from(this)
.inflate( layoutForDlg(id), null ))
.setPositiveButton( R.string.button_ok,
new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
getRoleSettings();
}
})
.setNegativeButton( R.string.button_cancel, null )
.create();
break;
// case ROLE_EDIT_RELAY:
// case ROLE_EDIT_SMS:
// case ROLE_EDIT_BT:
// dialog = new AlertDialog.Builder( this )
// .setTitle(titleForDlg(id))
// .setView( LayoutInflater.from(this)
// .inflate( layoutForDlg(id), null ))
// .setPositiveButton( R.string.button_ok,
// new DialogInterface.OnClickListener() {
// public void onClick( DialogInterface dlg,
// int whichButton ) {
// getRoleSettings();
// }
// })
// .setNegativeButton( R.string.button_cancel, null )
// .create();
// break;
case FORCE_REMOTE:
dialog = new AlertDialog.Builder( this )
@ -171,16 +174,25 @@ public class GameConfig extends Activity implements View.OnClickListener,
loadPlayers();
}
})
.setNegativeButton( R.string.button_cancel, null )
.setNegativeButton( R.string.button_cancel,
new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
m_notNetworkedGameCheckbx
.setChecked( true );
m_notNetworkedGame = true;
loadPlayers();
}
})
.create();
dialog.setOnDismissListener( new DialogInterface.OnDismissListener() {
@Override
public void onDismiss( DialogInterface di )
{
if ( m_gi.remoteCount() == 0 ) {
// force one to remote -- or make it
// standalone???
m_gi.players[0].isLocal = false;
if ( m_gi.forceRemoteConsistent() ) {
Toast.makeText( GameConfig.this,
R.string.forced_consistent,
Toast.LENGTH_SHORT).show();
loadPlayers();
}
}
@ -220,12 +232,12 @@ public class GameConfig extends Activity implements View.OnClickListener,
case PLAYER_EDIT:
setPlayerSettings();
break;
case ROLE_EDIT_RELAY:
case ROLE_EDIT_SMS:
case ROLE_EDIT_BT:
setRoleHints( id, dialog );
setRoleSettings();
break;
// case ROLE_EDIT_RELAY:
// case ROLE_EDIT_SMS:
// case ROLE_EDIT_BT:
// setRoleHints( id, dialog );
// setRoleSettings();
// break;
case FORCE_REMOTE:
ListView listview = (ListView)dialog.findViewById( R.id.players );
listview.setAdapter( new RemoteChoices() );
@ -237,8 +249,7 @@ public class GameConfig extends Activity implements View.OnClickListener,
private void setPlayerSettings()
{
// Hide remote option if in standalone mode...
boolean isServer = DeviceRole.SERVER_ISSERVER == curRole();
boolean isServer = !m_notNetworkedGame;
LocalPlayer lp = m_gi.players[m_whichPlayer];
Utils.setText( m_curDialog, R.id.player_name_edit, lp.name );
Utils.setText( m_curDialog, R.id.password_edit, lp.password );
@ -276,70 +287,6 @@ public class GameConfig extends Activity implements View.OnClickListener,
Utils.setChecked( m_curDialog, R.id.remote_check, ! lp.isLocal );
}
private void setRoleHints( int id, Dialog dialog )
{
int[] guestHints = null;
int[] hostHints = null;
switch( id ) {
case ROLE_EDIT_RELAY:
// Can these be in an array in a resource?
guestHints = new int[] { R.id.room_edit_hint_guest };
hostHints = new int[] { R.id.room_edit_hint_host };
break;
case ROLE_EDIT_SMS:
case ROLE_EDIT_BT:
}
DeviceRole role = m_gi.serverRole;
if ( null != guestHints ) {
for ( int hintID : guestHints ) {
View view = dialog.findViewById( hintID );
view.setVisibility( DeviceRole.SERVER_ISCLIENT == role ?
View.VISIBLE : View.GONE );
}
}
if ( null != hostHints ) {
for ( int hintID : hostHints ) {
View view = dialog.findViewById( hintID );
view.setVisibility( DeviceRole.SERVER_ISSERVER == role ?
View.VISIBLE : View.GONE );
}
}
}
private void setRoleSettings()
{
switch( m_types[m_connectSpinner.getSelectedItemPosition()] ) {
case COMMS_CONN_RELAY:
Utils.setText( m_curDialog, R.id.room_edit, m_car.ip_relay_invite );
break;
case COMMS_CONN_SMS:
Utils.setText( m_curDialog, R.id.sms_phone_edit, m_car.sms_phone );
Utils.logf( "set phone: " + m_car.sms_phone );
Utils.setInt( m_curDialog, R.id.sms_port_edit, m_car.sms_port );
break;
case COMMS_CONN_BT:
}
}
private void getRoleSettings()
{
m_car.conType = m_types[ m_connectSpinner.getSelectedItemPosition() ];
switch ( m_car.conType ) {
case COMMS_CONN_RELAY:
m_car.ip_relay_invite = Utils.getText( m_curDialog, R.id.room_edit );
break;
case COMMS_CONN_SMS:
m_car.sms_phone = Utils.getText( m_curDialog, R.id.sms_phone_edit );
Utils.logf( "grabbed phone: " + m_car.sms_phone );
m_car.sms_port = (short)Utils.getInt( m_curDialog,
R.id.sms_port_edit );
break;
case COMMS_CONN_BT:
break;
}
}
private void getPlayerSettings()
{
LocalPlayer lp = m_gi.players[m_whichPlayer];
@ -394,37 +341,45 @@ public class GameConfig extends Activity implements View.OnClickListener,
setContentView(R.layout.game_config);
m_notNetworkedGameCheckbx =
(CheckBox)findViewById(R.id.game_not_networked);
m_notNetworkedGameCheckbx.setOnClickListener( this );
// m_notNetworkedGameCheckbx.setChecked( true );
// m_notNetworkedGame = true;
m_addPlayerButton = (Button)findViewById(R.id.add_player);
m_addPlayerButton.setOnClickListener( this );
m_jugglePlayersButton = (Button)findViewById(R.id.juggle_players);
m_jugglePlayersButton.setOnClickListener( this );
m_configureButton = (Button)findViewById(R.id.configure_role);
m_configureButton.setOnClickListener( this );
// m_configureButton = (Button)findViewById(R.id.configure_role);
// m_configureButton.setOnClickListener( this );
m_playerLayout = (LinearLayout)findViewById( R.id.player_list );
m_notNetworkedGame = DeviceRole.SERVER_STANDALONE == m_gi.serverRole;
m_notNetworkedGameCheckbx.setChecked( m_notNetworkedGame );
loadPlayers();
m_dictSpinner = (Spinner)findViewById( R.id.dict_spinner );
configDictSpinner();
m_roleSpinner = (Spinner)findViewById( R.id.role_spinner );
m_roleSpinner.setSelection( m_gi.serverRole.ordinal() );
m_roleSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position,
long id ) {
m_gi.setServerRole( DeviceRole.values()[position] );
adjustVisibility();
loadPlayers();
}
// m_roleSpinner = (Spinner)findViewById( R.id.role_spinner );
// m_roleSpinner.setSelection( m_gi.serverRole.ordinal() );
// m_roleSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
// @Override
// public void onItemSelected(AdapterView<?> parentView,
// View selectedItemView, int position,
// long id ) {
// m_gi.setServerRole( DeviceRole.values()[position] );
// adjustVisibility();
// loadPlayers();
// }
@Override
public void onNothingSelected(AdapterView<?> parentView) {
}
});
// @Override
// public void onNothingSelected(AdapterView<?> parentView) {
// }
// });
configConnectSpinner();
// configConnectSpinner();
m_phoniesSpinner = (Spinner)findViewById( R.id.phonies_spinner );
m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() );
@ -447,7 +402,7 @@ public class GameConfig extends Activity implements View.OnClickListener,
Utils.setChecked( this, R.id.smart_robot, 0 < m_gi.robotSmartness );
adjustVisibility();
// adjustVisibility();
String fmt = getString( R.string.title_game_configf );
setTitle( String.format( fmt, GameUtils.gameName( this, m_path ) ) );
@ -472,19 +427,33 @@ public class GameConfig extends Activity implements View.OnClickListener,
} else if ( m_jugglePlayersButton == view ) {
m_gi.juggle();
loadPlayers();
} else if ( m_configureButton == view ) {
int position = m_connectSpinner.getSelectedItemPosition();
switch ( m_types[ position ] ) {
case COMMS_CONN_RELAY:
showDialog( ROLE_EDIT_RELAY );
break;
case COMMS_CONN_SMS:
showDialog( ROLE_EDIT_SMS );
break;
case COMMS_CONN_BT:
showDialog( ROLE_EDIT_BT );
break;
} else if ( m_notNetworkedGameCheckbx == view ) {
if ( m_gi.nPlayers < 2 ) {
Assert.assertTrue( m_gi.nPlayers == 1 );
m_gi.addPlayer();
Toast.makeText( this, R.string.added_player,
Toast.LENGTH_SHORT).show();
}
m_notNetworkedGame = m_notNetworkedGameCheckbx.isChecked();
m_gi.setServerRole( m_notNetworkedGame
? DeviceRole.SERVER_STANDALONE
: DeviceRole.SERVER_ISSERVER );
loadPlayers();
// } else if ( m_configureButton == view ) {
// int position = m_connectSpinner.getSelectedItemPosition();
// switch ( m_types[ position ] ) {
// case COMMS_CONN_RELAY:
// showDialog( ROLE_EDIT_RELAY );
// break;
// case COMMS_CONN_SMS:
// showDialog( ROLE_EDIT_SMS );
// break;
// case COMMS_CONN_BT:
// showDialog( ROLE_EDIT_BT );
// break;
// }
} else {
Utils.logf( "unknown v: " + view.toString() );
}
@ -522,6 +491,9 @@ public class GameConfig extends Activity implements View.OnClickListener,
m_playerLayout.removeAllViews();
String[] names = m_gi.visibleNames( this );
// only enable delete if one will remain (or two if networked)
boolean canDelete = names.length > 2
|| (m_notNetworkedGame && names.length > 1);
LayoutInflater factory = LayoutInflater.from(this);
for ( int ii = 0; ii < names.length; ++ii ) {
@ -530,8 +502,7 @@ public class GameConfig extends Activity implements View.OnClickListener,
view.setPosition( ii );
view.setText( names[ii] );
view.setGravity( Gravity.CENTER );
// only enable delete if one will remain
if ( 1 < names.length ) {
if ( canDelete ) {
view.setDeleteCallback( this );
}
@ -556,10 +527,12 @@ public class GameConfig extends Activity implements View.OnClickListener,
.setVisibility( names.length <= 1 ?
View.GONE : View.VISIBLE );
if ( DeviceRole.SERVER_ISSERVER == m_gi.serverRole
&& 0 == m_gi.remoteCount() ) {
if ( ! m_notNetworkedGame
&& ((0 == m_gi.remoteCount() )
|| (m_gi.nPlayers == m_gi.remoteCount()) ) ) {
showDialog( FORCE_REMOTE );
}
adjustPlayersLabel();
} // loadPlayers
private int listAvailableDicts( String curDict )
@ -618,68 +591,54 @@ public class GameConfig extends Activity implements View.OnClickListener,
});
}
private void configConnectSpinner()
// private void configConnectSpinner()
// {
// m_connectSpinner = (Spinner)findViewById( R.id.connect_spinner );
// m_connStrings = makeXportStrings();
// ArrayAdapter<String> adapter =
// new ArrayAdapter<String>( this,
// android.R.layout.simple_spinner_item,
// m_connStrings );
// adapter.setDropDownViewResource( android.R.layout
// .simple_spinner_dropdown_item );
// m_connectSpinner.setAdapter( adapter );
// m_connectSpinner.setSelection( connTypeToPos( m_car.conType ) );
// AdapterView.OnItemSelectedListener
// lstnr = new AdapterView.OnItemSelectedListener() {
// @Override
// public void onItemSelected(AdapterView<?> parentView,
// View selectedItemView,
// int position,
// long id )
// {
// String fmt = getString( R.string.configure_rolef );
// m_configureButton
// .setText( String.format( fmt,
// m_connStrings[position] ));
// }
// @Override
// public void onNothingSelected(AdapterView<?> parentView)
// {
// }
// };
// m_connectSpinner.setOnItemSelectedListener( lstnr );
// } // configConnectSpinner
private void adjustPlayersLabel()
{
m_connectSpinner = (Spinner)findViewById( R.id.connect_spinner );
m_connStrings = makeXportStrings();
ArrayAdapter<String> adapter =
new ArrayAdapter<String>( this,
android.R.layout.simple_spinner_item,
m_connStrings );
adapter.setDropDownViewResource( android.R.layout
.simple_spinner_dropdown_item );
m_connectSpinner.setAdapter( adapter );
m_connectSpinner.setSelection( connTypeToPos( m_car.conType ) );
AdapterView.OnItemSelectedListener
lstnr = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView,
int position,
long id )
{
String fmt = getString( R.string.configure_rolef );
m_configureButton
.setText( String.format( fmt,
m_connStrings[position] ));
}
@Override
public void onNothingSelected(AdapterView<?> parentView)
{
}
};
m_connectSpinner.setOnItemSelectedListener( lstnr );
} // configConnectSpinner
private void adjustVisibility()
{
// compiler insists these be initialized, so set 'em for
// SERVER_STANDALONE
int vis = View.GONE;
int labelId = R.string.players_label_standalone;
switch ( curRole() ) {
case SERVER_ISSERVER:
vis = View.VISIBLE;
labelId = R.string.players_label_host;
break;
case SERVER_ISCLIENT:
vis = View.VISIBLE;
labelId = R.string.players_label_guest;
break;
Utils.logf( "adjustPlayersLabel()" );
String label;
if ( m_notNetworkedGame ) {
label = getString( R.string.players_label_standalone );
} else {
String fmt = getString( R.string.players_label_host );
int remoteCount = m_gi.remoteCount();
label = String.format( fmt, m_gi.nPlayers - remoteCount,
remoteCount );
}
int[] ids = { R.id.connection_label,
R.id.connect_spinner,
R.id.configure_role };
for ( int id : ids ) {
findViewById( id ).setVisibility( vis );
}
((TextView)findViewById( R.id.players_label )).
setText( getString(labelId) );
((TextView)findViewById( R.id.players_label )).setText( label );
}
private int connTypeToPos( CommsAddrRec.CommsConnType typ )
@ -698,12 +657,12 @@ public class GameConfig extends Activity implements View.OnClickListener,
private int layoutForDlg( int id )
{
switch( id ) {
case ROLE_EDIT_RELAY:
return R.layout.role_edit_relay;
case ROLE_EDIT_SMS:
return R.layout.role_edit_sms;
case ROLE_EDIT_BT:
return R.layout.role_edit_bt;
// case ROLE_EDIT_RELAY:
// return R.layout.role_edit_relay;
// case ROLE_EDIT_SMS:
// return R.layout.role_edit_sms;
// case ROLE_EDIT_BT:
// return R.layout.role_edit_bt;
case FORCE_REMOTE:
return R.layout.force_remote;
}
@ -714,12 +673,12 @@ public class GameConfig extends Activity implements View.OnClickListener,
private int titleForDlg( int id )
{
switch( id ) {
case ROLE_EDIT_RELAY:
return R.string.tab_relay;
case ROLE_EDIT_SMS:
return R.string.tab_sms;
case ROLE_EDIT_BT:
return R.string.tab_bluetooth;
// case ROLE_EDIT_RELAY:
// return R.string.tab_relay;
// case ROLE_EDIT_SMS:
// return R.string.tab_sms;
// case ROLE_EDIT_BT:
// return R.string.tab_bluetooth;
}
Assert.fail();
return -1;
@ -746,12 +705,6 @@ public class GameConfig extends Activity implements View.OnClickListener,
return strings.toArray( new String[strings.size()] );
}
private DeviceRole curRole()
{
int position = m_roleSpinner.getSelectedItemPosition();
return DeviceRole.values()[position];
}
private void saveChanges()
{
m_gi.hintsNotAllowed = !Utils.getChecked( this, R.id.hints_allowed );
@ -766,8 +719,12 @@ public class GameConfig extends Activity implements View.OnClickListener,
m_gi.fixup();
position = m_connectSpinner.getSelectedItemPosition();
m_car.conType = m_types[ position ];
// position = m_connectSpinner.getSelectedItemPosition();
// m_car.conType = m_types[ position ];
m_car.conType = m_notNetworkedGame
? CommsAddrRec.CommsConnType.COMMS_CONN_NONE
: CommsAddrRec.CommsConnType.COMMS_CONN_RELAY;
}
private void applyChanges( boolean forceNew )

View file

@ -51,8 +51,8 @@ public class CurGameInfo {
public XWPhoniesChoice phoniesAction;
public boolean confirmBTConnect; /* only used for BT */
private int[] m_visiblePlayers;
private int m_nVisiblePlayers;
// private int[] m_visiblePlayers;
// private int m_nVisiblePlayers;
private boolean m_inProgress;
public CurGameInfo( Context context ) {
@ -77,8 +77,6 @@ public class CurGameInfo {
for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
players[ii] = new LocalPlayer( context, ii );
}
figureVisible();
}
public CurGameInfo( CurGameInfo src )
@ -102,25 +100,21 @@ public class CurGameInfo {
for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
players[ii] = new LocalPlayer( src.players[ii] );
}
figureVisible();
}
public void setServerRole( DeviceRole newRole )
{
serverRole = newRole;
figureVisible();
if ( m_nVisiblePlayers == 0 ) { // must always be one visible player
Assert.assertTrue( nPlayers > 0 );
if ( nPlayers == 0 ) { // must always be one visible player
Assert.assertFalse( players[0].isLocal );
players[0].isLocal = true;
figureVisible();
}
}
public void setInProgress( boolean inProgress )
{
m_inProgress = inProgress;
figureVisible();
}
/** return true if any of the changes made would invalide a game
@ -156,16 +150,31 @@ public class CurGameInfo {
public int remoteCount()
{
figureVisible();
int count = 0;
for ( int ii = 0; ii < m_nVisiblePlayers; ++ii ) {
if ( !players[m_visiblePlayers[ii]].isLocal ) {
for ( int ii = 0; ii < nPlayers; ++ii ) {
if ( !players[ii].isLocal ) {
++count;
}
}
Utils.logf( "remoteCount()=>%d", count );
return count;
}
public boolean forceRemoteConsistent()
{
boolean consistent = serverRole == DeviceRole.SERVER_STANDALONE;
if ( !consistent ) {
if ( remoteCount() == 0 ) {
players[0].isLocal = false;
} else if ( remoteCount() == nPlayers ) {
players[0].isLocal = true;
} else {
consistent = true; // nothing changed
}
}
return !consistent;
}
/**
* fixup: if we're pretending some players don't exist, move them
* up and make externally (i.e. in the jni world) visible fields
@ -173,34 +182,34 @@ public class CurGameInfo {
*/
public void fixup()
{
if ( m_nVisiblePlayers < nPlayers ) {
Assert.assertTrue( serverRole == DeviceRole.SERVER_ISCLIENT );
// if ( m_nVisiblePlayers < nPlayers ) {
// Assert.assertTrue( serverRole == DeviceRole.SERVER_ISCLIENT );
for ( int ii = 0; ii < m_nVisiblePlayers; ++ii ) {
Assert.assertTrue( m_visiblePlayers[ii] >= ii );
if ( m_visiblePlayers[ii] != ii ) {
LocalPlayer tmp = players[ii];
players[ii] = players[m_visiblePlayers[ii]];
players[m_visiblePlayers[ii]] = tmp;
m_visiblePlayers[ii] = ii;
}
}
// for ( int ii = 0; ii < nPlayers; ++ii ) {
// // Assert.assertTrue( m_visiblePlayers[ii] >= ii );
// if ( m_visiblePlayers[ii] != ii ) {
// LocalPlayer tmp = players[ii];
// players[ii] = players[m_visiblePlayers[ii]];
// players[m_visiblePlayers[ii]] = tmp;
// m_visiblePlayers[ii] = ii;
// }
// }
nPlayers = m_nVisiblePlayers;
}
// nPlayers = m_nVisiblePlayers;
// }
if ( !m_inProgress && serverRole != DeviceRole.SERVER_ISSERVER ) {
for ( int ii = 0; ii < nPlayers; ++ii ) {
players[ii].isLocal = true;
}
}
// if ( !m_inProgress && serverRole != DeviceRole.SERVER_ISSERVER ) {
// for ( int ii = 0; ii < nPlayers; ++ii ) {
// players[ii].isLocal = true;
// }
// }
}
public String[] visibleNames( Context context )
{
String[] names = new String[m_nVisiblePlayers];
for ( int ii = 0; ii < m_nVisiblePlayers; ++ii ) {
LocalPlayer lp = players[m_visiblePlayers[ii]];
String[] names = new String[nPlayers];
for ( int ii = 0; ii < nPlayers; ++ii ) {
LocalPlayer lp = players[ii];
if ( lp.isLocal || serverRole == DeviceRole.SERVER_STANDALONE ) {
names[ii] = lp.name;
if ( lp.isRobot ) {
@ -237,41 +246,13 @@ public class CurGameInfo {
public String summarizeRole( Context context, GameSummary summary )
{
String result = null;
if ( null != summary ) {
DeviceRole role = serverRole;
if ( role != DeviceRole.SERVER_STANDALONE ) {
if ( null != summary.conType ) {
boolean isHost = role == DeviceRole.SERVER_ISSERVER;
boolean justListening = false;
int roleID = isHost ? R.string.role_host : R.string.role_guest;
String via;
int summaryID;
switch ( summary.conType ) {
case COMMS_CONN_RELAY:
via = summary.roomName;
summaryID = R.string.summary_fmt_relay;
break;
case COMMS_CONN_SMS:
via = summary.smsPhone;
summaryID = R.string.summary_fmt_sms;
justListening = isHost;
break;
default:
summaryID = 0;
via = null;
Assert.fail();
}
String fmt = context.getString( justListening?
R.string.summary_fmt_listening
: summaryID );
String roleStr = context.getString( roleID );
if ( justListening ) {
result = String.format( fmt, roleStr );
} else {
result = String.format( fmt, roleStr, via );
}
}
}
if ( null != summary
&& null != summary.conType
&& serverRole != DeviceRole.SERVER_STANDALONE ) {
Assert.assertTrue( CommsAddrRec.CommsConnType.COMMS_CONN_RELAY
== summary.conType );
String fmt = context.getString( R.string.summary_fmt_relay );
result = String.format( fmt, summary.roomName );
}
return result;
}
@ -296,23 +277,11 @@ public class CurGameInfo {
public boolean addPlayer()
{
boolean added = false;
boolean added = nPlayers < MAX_NUM_PLAYERS;
// We can add either by adding a player, if nPlayers <
// MAX_NUM_PLAYERS, or by making an unusable player usable.
if ( nPlayers < MAX_NUM_PLAYERS ) {
++nPlayers;
added = true;
} else if ( serverRole == DeviceRole.SERVER_ISCLIENT ) {
for ( int ii = 0; ii < players.length; ++ii ) {
if ( !players[ii].isLocal ) {
players[ii].isLocal = true;
added = true;
break;
}
}
}
if ( added ) {
figureVisible();
++nPlayers;
}
return added;
}
@ -335,56 +304,37 @@ public class CurGameInfo {
public boolean delete( int which )
{
boolean canDelete = m_nVisiblePlayers > 1;
boolean canDelete = nPlayers > 0;
if ( canDelete ) {
which = m_visiblePlayers[which]; // translate
LocalPlayer tmp = players[which];
for ( int ii = which; ii < nPlayers - 1; ++ii ) {
moveDown( ii );
}
--nPlayers;
players[nPlayers] = tmp;
figureVisible();
}
return canDelete;
}
public boolean juggle()
{
boolean canJuggle = m_nVisiblePlayers > 1;
boolean canJuggle = nPlayers > 1;
if ( canJuggle ) {
// for each element, exchange with randomly chocsen from
// range <= to self.
Random rgen = new Random();
for ( int ii = m_nVisiblePlayers - 1; ii > 0; --ii ) {
for ( int ii = nPlayers - 1; ii > 0; --ii ) {
// Contrary to docs, nextInt() comes back negative!
int rand = Math.abs(rgen.nextInt());
int indx = rand % (ii+1);
if ( indx != ii ) {
LocalPlayer tmp = players[m_visiblePlayers[ii]];
players[m_visiblePlayers[ii]]
= players[m_visiblePlayers[indx]];
players[m_visiblePlayers[indx]] = tmp;
LocalPlayer tmp = players[ii];
players[ii] = players[indx];
players[indx] = tmp;
}
}
}
return canJuggle;
}
private void figureVisible()
{
if ( null == m_visiblePlayers ) {
m_visiblePlayers = new int[MAX_NUM_PLAYERS];
}
m_nVisiblePlayers = 0;
for ( int ii = 0; ii < nPlayers; ++ii ) {
if ( m_inProgress
|| serverRole != DeviceRole.SERVER_ISCLIENT
|| players[ii].isLocal ) {
m_visiblePlayers[m_nVisiblePlayers++] = ii;
}
}
}
}