support sub7 trades on Android too

This commit is contained in:
Eric House 2024-02-18 08:16:41 -08:00
parent e9ab81c552
commit f716768a71
13 changed files with 69 additions and 19 deletions

View file

@ -115,6 +115,7 @@ public class GameConfigDelegate extends DelegateBase
R.id.lang_spinner, R.id.lang_spinner,
R.id.dict_spinner, R.id.dict_spinner,
R.id.hints_allowed, R.id.hints_allowed,
R.id.trade_sub_seven,
R.id.duplicate_check, R.id.duplicate_check,
R.id.pick_faceup, R.id.pick_faceup,
R.id.boardsize_spinner, R.id.boardsize_spinner,
@ -683,6 +684,7 @@ public class GameConfigDelegate extends DelegateBase
tweakTimerStuff(); tweakTimerStuff();
setChecked( R.id.hints_allowed, !m_gi.hintsNotAllowed ); setChecked( R.id.hints_allowed, !m_gi.hintsNotAllowed );
setChecked( R.id.trade_sub_seven, m_gi.tradeSub7 );
setChecked( R.id.pick_faceup, m_gi.allowPickTiles ); setChecked( R.id.pick_faceup, m_gi.allowPickTiles );
setBoardsizeSpinner(); setBoardsizeSpinner();
@ -1276,6 +1278,7 @@ public class GameConfigDelegate extends DelegateBase
m_gi.inDuplicateMode = getChecked( R.id.duplicate_check ); m_gi.inDuplicateMode = getChecked( R.id.duplicate_check );
m_gi.hintsNotAllowed = !getChecked( R.id.hints_allowed ); m_gi.hintsNotAllowed = !getChecked( R.id.hints_allowed );
m_gi.tradeSub7 = getChecked( R.id.trade_sub_seven );
m_gi.allowPickTiles = getChecked( R.id.pick_faceup ); m_gi.allowPickTiles = getChecked( R.id.pick_faceup );
m_gi.timerEnabled = getChecked( R.id.use_timer ); m_gi.timerEnabled = getChecked( R.id.use_timer );

View file

@ -303,6 +303,11 @@ public class CommonPrefs extends XWPrefs {
return getPrefsBoolean( context, key, true ); return getPrefsBoolean( context, key, true );
} }
public static boolean getSub7TradeAllowed( Context context )
{
return getPrefsBoolean( context, R.string.key_init_tradeSub7, false );
}
public static boolean getDefaultDupMode( Context context ) public static boolean getDefaultDupMode( Context context )
{ {
return getPrefsBoolean( context, R.string.key_init_dupmodeon, false ); return getPrefsBoolean( context, R.string.key_init_dupmodeon, false );

View file

@ -54,6 +54,7 @@ public class CurGameInfo implements Serializable {
private static final String ALLOW_PICK = "ALLOW_PICK"; private static final String ALLOW_PICK = "ALLOW_PICK";
private static final String PHONIES = "PHONIES"; private static final String PHONIES = "PHONIES";
private static final String DUP = "DUP"; private static final String DUP = "DUP";
private static final String SUB7 = "SUB7";
public enum XWPhoniesChoice { PHONIES_IGNORE, PHONIES_WARN, PHONIES_DISALLOW, PHONIES_BLOCK, }; public enum XWPhoniesChoice { PHONIES_IGNORE, PHONIES_WARN, PHONIES_DISALLOW, PHONIES_BLOCK, };
public enum DeviceRole { SERVER_STANDALONE, SERVER_ISSERVER, SERVER_ISCLIENT }; public enum DeviceRole { SERVER_STANDALONE, SERVER_ISSERVER, SERVER_ISCLIENT };
@ -71,6 +72,7 @@ public class CurGameInfo implements Serializable {
public DeviceRole serverRole; public DeviceRole serverRole;
public boolean inDuplicateMode; public boolean inDuplicateMode;
public boolean tradeSub7;
public boolean hintsNotAllowed; public boolean hintsNotAllowed;
public boolean timerEnabled; public boolean timerEnabled;
public boolean allowPickTiles; public boolean allowPickTiles;
@ -102,6 +104,7 @@ public class CurGameInfo implements Serializable {
: DeviceRole.SERVER_STANDALONE; : DeviceRole.SERVER_STANDALONE;
hintsNotAllowed = !CommonPrefs.getDefaultHintsAllowed( context, hintsNotAllowed = !CommonPrefs.getDefaultHintsAllowed( context,
isNetworked ); isNetworked );
tradeSub7 = CommonPrefs.getSub7TradeAllowed( context );
phoniesAction = CommonPrefs.getDefaultPhonies( context ); phoniesAction = CommonPrefs.getDefaultPhonies( context );
timerEnabled = CommonPrefs.getDefaultTimerEnabled( context ); timerEnabled = CommonPrefs.getDefaultTimerEnabled( context );
allowPickTiles = false; allowPickTiles = false;
@ -156,6 +159,7 @@ public class CurGameInfo implements Serializable {
isoCodeStr = src.isoCodeStr; isoCodeStr = src.isoCodeStr;
hintsNotAllowed = src.hintsNotAllowed; hintsNotAllowed = src.hintsNotAllowed;
inDuplicateMode = src.inDuplicateMode; inDuplicateMode = src.inDuplicateMode;
tradeSub7 = src.tradeSub7;
phoniesAction = src.phoniesAction; phoniesAction = src.phoniesAction;
timerEnabled = src.timerEnabled; timerEnabled = src.timerEnabled;
allowPickTiles = src.allowPickTiles; allowPickTiles = src.allowPickTiles;
@ -211,6 +215,7 @@ public class CurGameInfo implements Serializable {
.put( BINGO_MIN, bingoMin ) .put( BINGO_MIN, bingoMin )
.put( NO_HINTS, hintsNotAllowed ) .put( NO_HINTS, hintsNotAllowed )
.put( DUP, inDuplicateMode ) .put( DUP, inDuplicateMode )
.put( SUB7, tradeSub7 )
.put( TIMER, timerEnabled ) .put( TIMER, timerEnabled )
.put( ALLOW_PICK, allowPickTiles ) .put( ALLOW_PICK, allowPickTiles )
.put( PHONIES, phoniesAction.ordinal() ) .put( PHONIES, phoniesAction.ordinal() )
@ -233,6 +238,7 @@ public class CurGameInfo implements Serializable {
bingoMin = obj.optInt( BINGO_MIN, bingoMin ); bingoMin = obj.optInt( BINGO_MIN, bingoMin );
hintsNotAllowed = obj.optBoolean( NO_HINTS, hintsNotAllowed ); hintsNotAllowed = obj.optBoolean( NO_HINTS, hintsNotAllowed );
inDuplicateMode = obj.optBoolean( DUP, inDuplicateMode ); inDuplicateMode = obj.optBoolean( DUP, inDuplicateMode );
tradeSub7 = obj.optBoolean( SUB7, tradeSub7 );
timerEnabled = obj.optBoolean( TIMER, timerEnabled ); timerEnabled = obj.optBoolean( TIMER, timerEnabled );
allowPickTiles = obj.optBoolean( ALLOW_PICK, allowPickTiles ); allowPickTiles = obj.optBoolean( ALLOW_PICK, allowPickTiles );
int tmp = obj.optInt( PHONIES, phoniesAction.ordinal() ); int tmp = obj.optInt( PHONIES, phoniesAction.ordinal() );
@ -331,6 +337,7 @@ public class CurGameInfo implements Serializable {
|| bingoMin != other.bingoMin || bingoMin != other.bingoMin
|| hintsNotAllowed != other.hintsNotAllowed || hintsNotAllowed != other.hintsNotAllowed
|| inDuplicateMode != other.inDuplicateMode || inDuplicateMode != other.inDuplicateMode
|| tradeSub7 != other.tradeSub7
|| allowPickTiles != other.allowPickTiles || allowPickTiles != other.allowPickTiles
|| phoniesAction != other.phoniesAction; || phoniesAction != other.phoniesAction;
@ -367,6 +374,7 @@ public class CurGameInfo implements Serializable {
&& forceChannel == other.forceChannel && forceChannel == other.forceChannel
&& hintsNotAllowed == other.hintsNotAllowed && hintsNotAllowed == other.hintsNotAllowed
&& inDuplicateMode == other.inDuplicateMode && inDuplicateMode == other.inDuplicateMode
&& tradeSub7 == other.tradeSub7
&& timerEnabled == other.timerEnabled && timerEnabled == other.timerEnabled
&& allowPickTiles == other.allowPickTiles && allowPickTiles == other.allowPickTiles
&& allowHintRect == other.allowHintRect && allowHintRect == other.allowHintRect

View file

@ -142,7 +142,6 @@
<CheckBox android:id="@+id/use_timer" <CheckBox android:id="@+id/use_timer"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
/> />
<LinearLayout android:id="@+id/timer_set" <LinearLayout android:id="@+id/timer_set"
@ -177,6 +176,11 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hints_allowed" android:text="@string/hints_allowed"
/> />
<CheckBox android:id="@+id/trade_sub_seven"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/sub_seven_allowed"
/>
<org.eehouse.android.xw4.LabeledSpinner <org.eehouse.android.xw4.LabeledSpinner
android:id="@+id/smart_robot" android:id="@+id/smart_robot"
@ -190,6 +194,7 @@
android:entries="@array/robot_levels" android:entries="@array/robot_levels"
/> />
</org.eehouse.android.xw4.LabeledSpinner> </org.eehouse.android.xw4.LabeledSpinner>
<org.eehouse.android.xw4.LabeledSpinner <org.eehouse.android.xw4.LabeledSpinner
style="@style/config_spinner_container" style="@style/config_spinner_container"
android:id="@+id/phonies_spinner" android:id="@+id/phonies_spinner"

View file

@ -70,6 +70,7 @@
<string name="key_logging_on">key_logging_on</string> <string name="key_logging_on">key_logging_on</string>
<string name="key_show_sms">key_show_sms</string> <string name="key_show_sms">key_show_sms</string>
<string name="key_init_hintsallowed">key_init_hintsallowed</string> <string name="key_init_hintsallowed">key_init_hintsallowed</string>
<string name="key_init_tradeSub7">key_init_tradeSub7</string>
<string name="key_init_dupmodeon">key_init_dupmodeon</string> <string name="key_init_dupmodeon">key_init_dupmodeon</string>
<string name="key_unhide_dupmode">key_unhide_dupmode</string> <!--temporary--> <string name="key_unhide_dupmode">key_unhide_dupmode</string> <!--temporary-->
<string name="key_init_nethintsallowed">key_init_nethintsallowed</string> <string name="key_init_nethintsallowed">key_init_nethintsallowed</string>

View file

@ -13,4 +13,8 @@
<!-- Debug-only: menu to remove quashed marking from a game (in case <!-- Debug-only: menu to remove quashed marking from a game (in case
the quashing was accidental) --> the quashing was accidental) -->
<string name="menu_unquash">Unquash</string> <string name="menu_unquash">Unquash</string>
<string name="sub_seven_allowed">Allow trades below seven tiles left</string>
<string name="sub_seven_allowed_sum">Common in Spanish play, this
lets you trade tiles when as few as 1 are left in the pool.</string>
</resources> </resources>

View file

@ -41,6 +41,12 @@
android:defaultValue="true" android:defaultValue="true"
/> />
<CheckBoxPreference android:key="@string/key_init_tradeSub7"
android:title="@string/sub_seven_allowed"
android:summary="@string/sub_seven_allowed_sum"
android:defaultValue="false"
/>
<CheckBoxPreference android:key="@string/key_init_dupmodeon" <CheckBoxPreference android:key="@string/key_init_dupmodeon"
android:title="@string/offerdupmode_title" android:title="@string/offerdupmode_title"
android:summary="@string/offerdupmode_sum" android:summary="@string/offerdupmode_sum"

View file

@ -443,6 +443,7 @@ static const SetInfo gi_bools[] = {
,ARR_MEMBER( CurGameInfo, allowPickTiles ) ,ARR_MEMBER( CurGameInfo, allowPickTiles )
,ARR_MEMBER( CurGameInfo, allowHintRect ) ,ARR_MEMBER( CurGameInfo, allowHintRect )
,ARR_MEMBER( CurGameInfo, inDuplicateMode ) ,ARR_MEMBER( CurGameInfo, inDuplicateMode )
,ARR_MEMBER( CurGameInfo, tradeSub7 )
}; };
static const SetInfo pl_ints[] = { static const SetInfo pl_ints[] = {

View file

@ -635,7 +635,7 @@ gi_copy( MPFORMAL CurGameInfo* destGI, const CurGameInfo* srcGI )
destGI->inDuplicateMode = srcGI->inDuplicateMode; destGI->inDuplicateMode = srcGI->inDuplicateMode;
XP_LOGFF( "copied forceChannel: %d; inDuplicateMode: %d", XP_LOGFF( "copied forceChannel: %d; inDuplicateMode: %d",
destGI->forceChannel, destGI->inDuplicateMode ); destGI->forceChannel, destGI->inDuplicateMode );
destGI->tradeSubSeven = srcGI->tradeSubSeven; destGI->tradeSub7 = srcGI->tradeSub7;
const LocalPlayer* srcPl; const LocalPlayer* srcPl;
LocalPlayer* destPl; LocalPlayer* destPl;
@ -726,7 +726,7 @@ gi_equal( const CurGameInfo* gi1, const CurGameInfo* gi2 )
equal = strEq( gi1->isoCodeStr, gi2->isoCodeStr ); equal = strEq( gi1->isoCodeStr, gi2->isoCodeStr );
break; break;
case 17: case 17:
equal = gi1->tradeSubSeven == gi2->tradeSubSeven; equal = gi1->tradeSub7 == gi2->tradeSub7;
break; break;
case 18: case 18:
for ( int jj = 0; equal && jj < gi1->nPlayers; ++jj ) { for ( int jj = 0; equal && jj < gi1->nPlayers; ++jj ) {
@ -869,7 +869,7 @@ gi_readFromStream( MPFORMAL XWStreamCtxt* stream, CurGameInfo* gi )
gi->inDuplicateMode = strVersion >= STREAM_VERS_DUPLICATE gi->inDuplicateMode = strVersion >= STREAM_VERS_DUPLICATE
? stream_getBits( stream, 1 ) ? stream_getBits( stream, 1 )
: XP_FALSE; : XP_FALSE;
gi->tradeSubSeven = strVersion >= STREAM_VERS_SUBSEVEN gi->tradeSub7 = strVersion >= STREAM_VERS_SUBSEVEN
? stream_getBits( stream, 1 ) ? stream_getBits( stream, 1 )
: XP_FALSE; : XP_FALSE;
if ( strVersion >= STREAM_VERS_41B4 ) { if ( strVersion >= STREAM_VERS_41B4 ) {
@ -962,7 +962,7 @@ gi_writeToStream( XWStreamCtxt* stream, const CurGameInfo* gi )
stream_putBits( stream, 1, gi->timerEnabled ); stream_putBits( stream, 1, gi->timerEnabled );
stream_putBits( stream, 1, gi->inDuplicateMode ); stream_putBits( stream, 1, gi->inDuplicateMode );
if ( strVersion >= STREAM_VERS_SUBSEVEN ) { if ( strVersion >= STREAM_VERS_SUBSEVEN ) {
stream_putBits( stream, 1, gi->tradeSubSeven ); stream_putBits( stream, 1, gi->tradeSub7 );
} }
stream_putBits( stream, 1, gi->allowPickTiles ); stream_putBits( stream, 1, gi->allowPickTiles );
stream_putBits( stream, 1, gi->allowHintRect ); stream_putBits( stream, 1, gi->allowHintRect );
@ -1066,7 +1066,7 @@ game_logGI( const CurGameInfo* gi, const char* msg, const char* func, int line )
XP_LOGF( " serverRole: %d", gi->serverRole ); XP_LOGF( " serverRole: %d", gi->serverRole );
XP_LOGF( " dictName: %s", gi->dictName ); XP_LOGF( " dictName: %s", gi->dictName );
XP_LOGF( " isoCode: %s", gi->isoCodeStr ); XP_LOGF( " isoCode: %s", gi->isoCodeStr );
XP_LOGF( " tradeSubSeven: %s", boolToStr(gi->tradeSubSeven) ); XP_LOGF( " tradeSub7: %s", boolToStr(gi->tradeSub7) );
} }
} }
#endif #endif

View file

@ -61,12 +61,12 @@ typedef struct CurGameInfo {
XP_Bool allowPickTiles; XP_Bool allowPickTiles;
XP_Bool allowHintRect; XP_Bool allowHintRect;
XP_Bool inDuplicateMode; XP_Bool inDuplicateMode;
XP_Bool tradeSubSeven; XP_Bool tradeSub7;
XWPhoniesChoice phoniesAction; XWPhoniesChoice phoniesAction;
XP_Bool confirmBTConnect; /* only used for BT */ XP_Bool confirmBTConnect; /* only used for BT */
} CurGameInfo; } CurGameInfo;
#define MIN_TRADE_TILES(GI) ((GI)->tradeSubSeven ? 1 : (GI)->traySize) #define MIN_TRADE_TILES(GI) ((GI)->tradeSub7 ? 1 : (GI)->traySize)
#ifdef DEBUG #ifdef DEBUG
# define LOGGI( gip, msg ) game_logGI( (gip), (msg), __func__, __LINE__ ) # define LOGGI( gip, msg ) game_logGI( (gip), (msg), __func__, __LINE__ )

View file

@ -151,7 +151,7 @@ newg_load( NewGameCtx* ngc, XWEnv xwe, const CurGameInfo* gi )
value.ng_bool = ngc->duplicateEnabled; value.ng_bool = ngc->duplicateEnabled;
(*ngc->setAttrProc)( closure, NG_ATTR_DUPLICATE, value ); (*ngc->setAttrProc)( closure, NG_ATTR_DUPLICATE, value );
ngc->sub7Enabled = gi->tradeSubSeven; ngc->sub7Enabled = gi->tradeSub7;
value.ng_bool = ngc->sub7Enabled; value.ng_bool = ngc->sub7Enabled;
(*ngc->setAttrProc)( closure, NG_ATTR_SUB7, value ); (*ngc->setAttrProc)( closure, NG_ATTR_SUB7, value );
@ -234,7 +234,7 @@ newg_store( NewGameCtx* ngc, XWEnv xwe, CurGameInfo* gi, XP_Bool warn )
gi->timerEnabled = gi->gameSeconds > 0; gi->timerEnabled = gi->gameSeconds > 0;
gi->inDuplicateMode = ngc->duplicateEnabled; gi->inDuplicateMode = ngc->duplicateEnabled;
gi->tradeSubSeven = ngc->sub7Enabled; gi->tradeSub7 = ngc->sub7Enabled;
gi->gameSeconds = ngc->timerSeconds; gi->gameSeconds = ngc->timerSeconds;
gi->timerEnabled = gi->gameSeconds > 0; gi->timerEnabled = gi->gameSeconds > 0;

View file

@ -1139,6 +1139,7 @@ callDupTimerListener( const ServerCtxt* server, XWEnv xwe, XP_S32 oldVal, XP_S32
static void static void
setStreamVersion( ServerCtxt* server ) setStreamVersion( ServerCtxt* server )
{ {
XP_ASSERT( amHost( server ) );
XP_U8 streamVersion = CUR_STREAM_VERS; XP_U8 streamVersion = CUR_STREAM_VERS;
for ( XP_U16 devIndex = 1; devIndex < server->nv.nDevices; ++devIndex ) { for ( XP_U16 devIndex = 1; devIndex < server->nv.nDevices; ++devIndex ) {
XP_U8 devVersion = server->nv.addresses[devIndex].streamVersion; XP_U8 devVersion = server->nv.addresses[devIndex].streamVersion;
@ -1149,14 +1150,29 @@ setStreamVersion( ServerCtxt* server )
SRVR_LOGFFV( "setting streamVersion: 0x%x", streamVersion ); SRVR_LOGFFV( "setting streamVersion: 0x%x", streamVersion );
server->nv.streamVersion = streamVersion; server->nv.streamVersion = streamVersion;
/* If we're downgrading stream to accomodate an older guest, we need to
re-write gi in that version in case there are newer features the game
can't support, e.g. allowing to trade with less than a full tray left
in the pool. */
if ( CUR_STREAM_VERS != streamVersion ) {
CurGameInfo* gi = server->vol.gi; CurGameInfo* gi = server->vol.gi;
if ( STREAM_VERS_NINETILES > streamVersion ) { XP_U16 oldTraySize = gi->traySize;
if ( 7 < gi->traySize ) { XP_U16 oldBingoMin = gi->bingoMin;
SRVR_LOGFF( "reducing tray size from %d to 7", gi->traySize );
gi->traySize = gi->bingoMin = 7; XWStreamCtxt* tmp = mkServerStream( server, streamVersion );
} gi_writeToStream( tmp, gi );
gi_disposePlayerInfo( MPPARM(server->mpool) gi );
gi_readFromStream( MPPARM(server->mpool) tmp, gi );
stream_destroy( tmp );
/* If downgrading forced tray size change, model needs to know. BUT:
the guest would have to be >two years old now for this to happen. */
if ( oldTraySize != gi->traySize || oldBingoMin != gi->bingoMin ) {
XP_ASSERT( 7 == gi->traySize && 7 == gi->bingoMin );
if ( 7 == gi->traySize && 7 == gi->bingoMin ) {
model_forceStack7Tiles( server->vol.model ); model_forceStack7Tiles( server->vol.model );
} }
}
}
} }
static void static void
@ -1221,8 +1237,9 @@ handleRegistrationMsg( ServerCtxt* server, XWEnv xwe, XWStreamCtxt* stream )
if ( 0 < stream_getSize(stream) ) { if ( 0 < stream_getSize(stream) ) {
XP_U8 streamVersion = stream_getU8( stream ); XP_U8 streamVersion = stream_getU8( stream );
if ( streamVersion >= STREAM_VERS_BIGBOARD ) { if ( streamVersion >= STREAM_VERS_BIGBOARD ) {
SRVR_LOGFF( "upping device %d streamVersion to 0x%x", SRVR_LOGFF( "setting addresses[%d] streamVersion to 0x%x "
clientIndex, streamVersion ); "(CUR_STREAM_VERS is 0x%x)",
clientIndex, streamVersion, CUR_STREAM_VERS );
server->nv.addresses[clientIndex].streamVersion = streamVersion; server->nv.addresses[clientIndex].streamVersion = streamVersion;
} }
} }

View file

@ -1522,7 +1522,7 @@ makeGameFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
} }
tmp = cJSON_GetObjectItem( args, "allowSub7" ); tmp = cJSON_GetObjectItem( args, "allowSub7" );
gi.tradeSubSeven = !!tmp && cJSON_IsTrue( tmp ); gi.tradeSub7 = !!tmp && cJSON_IsTrue( tmp );
tmp = cJSON_GetObjectItem( args, "isSolo" ); tmp = cJSON_GetObjectItem( args, "isSolo" );
XP_ASSERT( !!tmp ); XP_ASSERT( !!tmp );