add option to have robot words reversed

With reject-phonies set this will trigger the reject path.
Also init CommonPrefs in jni land since its makePhonyPct, left unitialized,
causes the robot to deliberately reverse every turn, firing an assertion that the
robot's moves are legal.
This commit is contained in:
Eric House 2020-04-21 20:55:48 -07:00
parent 410bc00d2e
commit 9d04b97ec8
10 changed files with 43 additions and 4 deletions

View file

@ -1026,7 +1026,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
}
globals->dctx = dctx;
globals->xportProcs = makeXportProcs( MPPARM(mpool) ti, j_procs );
CommonPrefs cp;
CommonPrefs cp = {0};
loadCommonPrefs( env, &cp, j_cp );
game_makeNewGame( MPPARM(mpool) &state->game, gi, globals->util, dctx, &cp,

View file

@ -237,6 +237,7 @@ typedef struct CommonPrefs {
#ifdef XWFEATURE_CROSSHAIRS
XP_Bool hideCrosshairs; /* applies to all games */
#endif
XP_U16 makePhonyPct;
} CommonPrefs;
typedef struct _PlayerDicts {

View file

@ -1253,6 +1253,20 @@ juggleMoveIfDebug( MoveInfo* move )
}
}
}
/* Reverse the *letters on* the tiles */
void
reverseTiles( MoveInfo* move )
{
MoveInfoTile* start = &move->tiles[0];
MoveInfoTile* end = start + move->nTiles - 1;
while ( start < end ) {
Tile tmp = start->tile;
start->tile = end->tile;
end->tile = tmp;
--end; ++start;
}
}
#endif
void

View file

@ -57,7 +57,7 @@ extern "C" {
#define MAX_NUM_BLANKS 4
/* Used by scoring code and engine as fast representation of moves. */
typedef struct MoveInfoTile {
typedef struct _MoveInfoTile {
XP_U8 varCoord; /* 5 bits ok (0-16 for 17x17 board) */
Tile tile; /* 6 bits will do */
} MoveInfoTile;
@ -237,6 +237,7 @@ void model_makeTurnFromMoveInfo( ModelCtxt* model, XP_U16 playerNum,
#ifdef DEBUG
void juggleMoveIfDebug( MoveInfo* move );
void reverseTiles( MoveInfo* move );
void model_dumpSelf( const ModelCtxt* model, const XP_UCHAR* msg );
#else
# define juggleMoveIfDebug(newMove)

View file

@ -106,6 +106,7 @@ typedef struct ServerNonvolatiles {
XP_U16 robotThinkMin, robotThinkMax; /* not saved (yet) */
XP_U16 robotTradePct;
#endif
XP_U16 makePhonyPct;
RemoteAddress addresses[MAX_NUM_PLAYERS];
XWStreamCtxt* prevMoveStream; /* save it to print later */
@ -630,6 +631,7 @@ server_prefsChanged( ServerCtxt* server, const CommonPrefs* cp )
server->nv.robotThinkMax = cp->robotThinkMax;
server->nv.robotTradePct = cp->robotTradePct;
#endif
server->nv.makePhonyPct = cp->makePhonyPct;
} /* server_prefsChanged */
XP_S16
@ -1374,6 +1376,11 @@ makeRobotMove( ServerCtxt* server )
/* if canMove is false, this is a fake move, a pass */
if ( canMove || NPASSES_OK(server) ) {
#ifdef DEBUG
if ( server->nv.makePhonyPct > XP_RANDOM() % 100 ) {
reverseTiles( &newMove );
}
#endif
juggleMoveIfDebug( &newMove );
model_makeTurnFromMoveInfo( model, turn, &newMove );
XP_LOGFF( "robot making %d tile move for player %d", newMove.nTiles, turn );

View file

@ -591,6 +591,7 @@ initNoDraw( CursesBoardState* cbState, sqlite3_int64 rowid,
cGlobals->cp.robotThinkMax = params->robotThinkMax;
cGlobals->cp.robotTradePct = params->robotTradePct;
#endif
cGlobals->cp.makePhonyPct = params->makePhonyPct;
if ( linuxOpenGame( cGlobals, &result->procs, returnAddr ) ) {
result = ref( result );

View file

@ -2372,6 +2372,7 @@ initGlobalsNoDraw( GtkGameGlobals* globals, LaunchParams* params,
cGlobals->cp.robotThinkMax = params->robotThinkMax;
cGlobals->cp.robotTradePct = params->robotTradePct;
#endif
cGlobals->cp.makePhonyPct = params->makePhonyPct;
#ifdef XWFEATURE_CROSSHAIRS
cGlobals->cp.hideCrosshairs = params->hideCrosshairs;
#endif

View file

@ -896,6 +896,7 @@ typedef enum {
,CMD_SLOWROBOT
,CMD_TRADEPCT
#endif
,CMD_MAKE_PHONY_PCT
#ifdef USE_GLIBLOOP /* just because hard to implement otherwise */
,CMD_UNDOPCT
#endif
@ -1030,6 +1031,8 @@ static CmdInfoRec CmdInfoRecs[] = {
,{ CMD_SLOWROBOT, true, "slow-robot", "make robot slower to test network" }
,{ CMD_TRADEPCT, true, "trade-pct", "what pct of the time should robot trade" }
#endif
,{ CMD_MAKE_PHONY_PCT, true, "make-phony-pct",
"what pct of the time should robot play a bad word" }
#ifdef USE_GLIBLOOP
,{ CMD_UNDOPCT, true, "undo-pct",
"each second, what are the odds of doing an undo" }
@ -2944,6 +2947,13 @@ main( int argc, char** argv )
usage(argv[0], "must be 0 <= n <= 100" );
}
break;
case CMD_MAKE_PHONY_PCT:
mainParams.makePhonyPct = atoi( optarg );
if ( mainParams.makePhonyPct < 0 || mainParams.makePhonyPct > 100 ) {
usage(argv[0], "must be 0 <= n <= 100" );
}
break;
#endif
#ifdef USE_GLIBLOOP

View file

@ -129,6 +129,7 @@ typedef struct LaunchParams {
XP_U16 robotThinkMin, robotThinkMax;
XP_U16 robotTradePct;
#endif
XP_U16 makePhonyPct;
XP_Bool commsDisableds[COMMS_CONN_NTYPES][2];
DeviceRole serverRole;

View file

@ -422,6 +422,8 @@ def build_cmds(args):
# make one in three games public
usePublic = args.ADD_RELAY and random.randint(0, 3) == 0
useDupeMode = random.randint(0, 100) < args.DUP_PCT
if args.PHONIES == -1: phonies = GAME % 3
else: phonies = args.PHONIES
DEV = 0
for NLOCALS in LOCALS:
DEV += 1
@ -480,11 +482,10 @@ def build_cmds(args):
if DEV == 1 or usePublic: PARAMS += ['--force-game']
if DEV == 1:
if args.PHONIES == -1: phonies = GAME % 3
else: phonies = args.PHONIES
PARAMS += ['--server', '--phonies', phonies ]
else:
PARAMS += ['--force-channel', DEV - 1]
if args.PHONY_PCT and phonies == 2: PARAMS += [ '--make-phony-pct', args.PHONY_PCT ]
if useDupeMode: PARAMS += ['--duplicate-mode']
if usePublic: PARAMS += ['--make-public', '--join-public']
@ -702,6 +703,8 @@ def mkParser():
help = 'send all packet twice')
parser.add_argument('--phonies', dest = 'PHONIES', default = -1, type = int,
help = '0 (ignore), 1 (warn)) or 2 (lose turn); default is pick at random')
parser.add_argument('--make-phony-pct', dest = 'PHONY_PCT', default = 0, type = int,
help = 'how often a robot should play a phony (only applies when --phonies==2')
parser.add_argument('--use-gtk', dest = 'USE_GTK', default = False, action = 'store_true',
help = 'run games using gtk instead of ncurses')