mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
New feature, meant for testing relay, makes robot skip random number
of seconds within specified range before making a move. Working only on gtk so far, and will probably never be used other than on linux clients.
This commit is contained in:
parent
854b3d9349
commit
184a154c52
6 changed files with 153 additions and 9 deletions
|
@ -104,6 +104,9 @@ typedef enum {
|
|||
TIMER_TIMERTICK,
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
TIMER_COMMS,
|
||||
#endif
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
TIMER_SLOWROBOT,
|
||||
#endif
|
||||
NUM_TIMERS_PLUS_ONE /* must be last */
|
||||
} XWTimerReason;
|
||||
|
@ -124,6 +127,9 @@ typedef struct CommonPrefs {
|
|||
XP_Bool showRobotScores; /* applies to all games */
|
||||
XP_Bool hideTileValues;
|
||||
XP_Bool reserved2; /* get to 32-bit for ARM... */
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
XP_U16 robotThinkMin, robotThinkMax;
|
||||
#endif
|
||||
} CommonPrefs;
|
||||
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
|
|
|
@ -92,6 +92,10 @@ typedef struct ServerNonvolatiles {
|
|||
XP_U8 pendingRegistrations;
|
||||
XP_Bool showRobotScores;
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
XP_U16 robotThinkMin, robotThinkMax; /* not saved (yet) */
|
||||
#endif
|
||||
|
||||
RemoteAddress addresses[MAX_NUM_PLAYERS];
|
||||
} ServerNonvolatiles;
|
||||
|
||||
|
@ -108,9 +112,18 @@ struct ServerCtxt {
|
|||
|
||||
ServerPlayer players[MAX_NUM_PLAYERS];
|
||||
XP_Bool serverDoing;
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
XP_Bool robotWaiting;
|
||||
#endif
|
||||
MPSLOT
|
||||
};
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
# define ROBOTWAITING(s) (s)->robotWaiting
|
||||
#else
|
||||
# define ROBOTWAITING(s) XP_FALSE
|
||||
#endif
|
||||
|
||||
|
||||
#define NPASSES_OK(s) model_recentPassCountOk((s)->vol.model)
|
||||
|
||||
|
@ -123,7 +136,7 @@ static void doEndGame( ServerCtxt* server );
|
|||
static void endGameInternal( ServerCtxt* server, GameEndReason why );
|
||||
static void badWordMoveUndoAndTellUser( ServerCtxt* server,
|
||||
BadWordInfo* bwi );
|
||||
static XP_Bool tileCountsOk( ServerCtxt* server );
|
||||
static XP_Bool tileCountsOk( const ServerCtxt* server );
|
||||
static void setTurn( ServerCtxt* server, XP_S16 turn );
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
|
@ -404,10 +417,31 @@ server_destroy( ServerCtxt* server )
|
|||
XP_FREE( server->mpool, server );
|
||||
} /* server_destroy */
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
static int
|
||||
figureSleepTime( const ServerCtxt* server )
|
||||
{
|
||||
int result = 0;
|
||||
XP_U16 min = server->nv.robotThinkMin;
|
||||
XP_U16 max = server->nv.robotThinkMax;
|
||||
if ( min < max ) {
|
||||
int diff = max - min + 1;
|
||||
result = XP_RANDOM() % diff;
|
||||
}
|
||||
result += min;
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
server_prefsChanged( ServerCtxt* server, CommonPrefs* cp )
|
||||
{
|
||||
server->nv.showRobotScores = cp->showRobotScores;
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
server->nv.robotThinkMin = cp->robotThinkMin;
|
||||
server->nv.robotThinkMax = cp->robotThinkMax;
|
||||
#endif
|
||||
} /* server_prefsChanged */
|
||||
|
||||
XP_S16
|
||||
|
@ -701,18 +735,55 @@ makeRobotMove( ServerCtxt* server )
|
|||
return result; /* always return TRUE after robot move? */
|
||||
} /* makeRobotMove */
|
||||
|
||||
static XP_Bool
|
||||
robotMovePending( ServerCtxt* server )
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
static XP_Bool
|
||||
wakeRobotProc( void* closure, XWTimerReason why )
|
||||
{
|
||||
XP_ASSERT( TIMER_SLOWROBOT == why );
|
||||
ServerCtxt* server = (ServerCtxt*)closure;
|
||||
XP_ASSERT( ROBOTWAITING(server) );
|
||||
server->robotWaiting = XP_FALSE;
|
||||
util_requestTime( server->vol.util );
|
||||
return XP_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static XP_Bool
|
||||
robotMovePending( const ServerCtxt* server )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
XP_S16 turn = server->nv.currentTurn;
|
||||
if ( turn >= 0 && tileCountsOk(server) && NPASSES_OK(server) ) {
|
||||
CurGameInfo* gi = server->vol.gi;
|
||||
LocalPlayer* player = &gi->players[turn];
|
||||
return IS_ROBOT(player) && IS_LOCAL(player);
|
||||
result = IS_ROBOT(player) && IS_LOCAL(player);
|
||||
}
|
||||
return XP_FALSE;
|
||||
return result;
|
||||
} /* robotMovePending */
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
static XP_Bool
|
||||
postponeRobotMove( ServerCtxt* server )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
XP_ASSERT( robotMovePending(server) );
|
||||
|
||||
if ( !ROBOTWAITING(server) ) {
|
||||
XP_U16 sleepTime = figureSleepTime(server);
|
||||
if ( 0 != sleepTime ) {
|
||||
server->robotWaiting = XP_TRUE;
|
||||
util_setTimer( server->vol.util, TIMER_SLOWROBOT, sleepTime,
|
||||
wakeRobotProc, server );
|
||||
result = XP_TRUE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
# define POSTPONEROBOTMOVE(s) postponeRobotMove(s)
|
||||
#else
|
||||
# define POSTPONEROBOTMOVE(s) XP_FALSE
|
||||
#endif
|
||||
|
||||
static void
|
||||
showPrevScore( ServerCtxt* server )
|
||||
{
|
||||
|
@ -822,10 +893,11 @@ server_do( ServerCtxt* server )
|
|||
moreToDo = XP_TRUE; /* either process turn or end game... */
|
||||
break;
|
||||
case XWSTATE_INTURN:
|
||||
if ( robotMovePending( server ) ) {
|
||||
if ( robotMovePending( server ) && !ROBOTWAITING(server) ) {
|
||||
result = makeRobotMove( server );
|
||||
/* if robot was interrupted, we need to schedule again */
|
||||
moreToDo = !result || robotMovePending( server );
|
||||
moreToDo = !result ||
|
||||
(robotMovePending( server ) && !POSTPONEROBOTMOVE(server));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1587,7 +1659,7 @@ nextTurn( ServerCtxt* server, XP_S16 nxtTurn )
|
|||
XP_ASSERT( server->nv.gameState != XWSTATE_GAMEOVER );
|
||||
callTurnChangeListener( server );
|
||||
|
||||
if ( robotMovePending(server) ) {
|
||||
if ( robotMovePending(server) && !POSTPONEROBOTMOVE(server) ) {
|
||||
moreToDo = XP_TRUE;
|
||||
}
|
||||
|
||||
|
@ -2100,7 +2172,7 @@ server_endGame( ServerCtxt* server )
|
|||
/* If game is about to end because one player's out of tiles, we don't want to
|
||||
* keep trying to move */
|
||||
static XP_Bool
|
||||
tileCountsOk( ServerCtxt* server )
|
||||
tileCountsOk( const ServerCtxt* server )
|
||||
{
|
||||
XP_Bool maybeOver = 0 == pool_getNTilesLeft( server->pool );
|
||||
if ( maybeOver ) {
|
||||
|
|
|
@ -92,6 +92,9 @@ DEFINES += ${BLUETOOTH}
|
|||
DEFINES += -DXWFEATURE_RELAY
|
||||
DEFINES += -DXWFEATURE_SMS
|
||||
|
||||
# Robot can be made to think, to simulate for relay mostly
|
||||
DEFINES += -DXWFEATURE_SLOW_ROBOT
|
||||
|
||||
# Support device-to-device connection via UDP, e.g. using wifi on a
|
||||
# LAN or where the host/server isn't behind a firewall.
|
||||
# DEFINES += -DXWFEATURE_IP_DIRECT
|
||||
|
|
|
@ -1250,6 +1250,18 @@ comms_timer_func( gpointer data )
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
static gint
|
||||
slowrob_timer_func( gpointer data )
|
||||
{
|
||||
GtkAppGlobals* globals = (GtkAppGlobals*)data;
|
||||
|
||||
linuxFireTimer( &globals->cGlobals, TIMER_SLOWROBOT );
|
||||
|
||||
return (gint)0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
||||
XP_U16 XP_UNUSED_STANDALONE(when),
|
||||
|
@ -1276,6 +1288,10 @@ gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
|||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
} else if ( why == TIMER_COMMS ) {
|
||||
newSrc = g_timeout_add( 1000 * when, comms_timer_func, globals );
|
||||
#endif
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
} else if ( why == TIMER_SLOWROBOT ) {
|
||||
newSrc = g_timeout_add( 1000 * when, slowrob_timer_func, globals );
|
||||
#endif
|
||||
} else {
|
||||
XP_ASSERT( 0 );
|
||||
|
@ -1866,6 +1882,10 @@ gtkmain( LaunchParams* params, int argc, char *argv[] )
|
|||
globals.cp.showBoardArrow = XP_TRUE;
|
||||
globals.cp.hideTileValues = params->hideValues;
|
||||
globals.cp.showRobotScores = params->showRobotScores;
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
globals.cp.robotThinkMin = params->robotThinkMin;
|
||||
globals.cp.robotThinkMax = params->robotThinkMax;
|
||||
#endif
|
||||
|
||||
setupGtkUtilCallbacks( &globals, params->util );
|
||||
|
||||
|
|
|
@ -215,6 +215,10 @@ usage( char* appName, char* msg )
|
|||
"\t -d xwd_file # provides tile counts & values\n"
|
||||
"\t\t # list each player as local or remote\n"
|
||||
"\t [-N]* # remote client (listen for connection)\n"
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
"\t [-z min:max] # robot sleeps random min<=seconds<=max \n"
|
||||
#endif
|
||||
"\t # before turn \n"
|
||||
#ifdef XWFEATURE_RELAY
|
||||
"\t [-p relay_port] # relay is at this port\n"
|
||||
"\t [-a relay_addr] # use relay (via port spec'd above)\n"
|
||||
|
@ -649,6 +653,29 @@ nameToBtAddr( const char* name, bdaddr_t* ba )
|
|||
} /* nameToBtAddr */
|
||||
#endif
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
static bool
|
||||
parsePair( const char* optarg, XP_U16* min, XP_U16* max )
|
||||
{
|
||||
bool success = false;
|
||||
char* colon = strstr( optarg, ":" );
|
||||
if ( !colon ) {
|
||||
fprintf( stderr, ": not found in argument\n" );
|
||||
} else {
|
||||
int intmin, intmax;
|
||||
if ( 2 == sscanf( optarg, "%d:%d", &intmin, &intmax ) ) {
|
||||
if ( intmin <= intmin ) {
|
||||
success = true;
|
||||
*min = intmin;
|
||||
*max = intmax;
|
||||
fprintf( stderr, "min: %d; max: %d\n", *min, *max );
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main( int argc, char** argv )
|
||||
{
|
||||
|
@ -741,6 +768,9 @@ main( int argc, char** argv )
|
|||
"h:I"
|
||||
#endif
|
||||
"kKf:ln:Nsd:e:r:b:q:w:Sit:UmvcVP"
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
"z:"
|
||||
#endif
|
||||
#ifdef XWFEATURE_SMS
|
||||
"M:"
|
||||
#endif
|
||||
|
@ -889,6 +919,15 @@ main( int argc, char** argv )
|
|||
case 'v':
|
||||
mainParams.verticalScore = XP_TRUE;
|
||||
break;
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
case 'z':
|
||||
if ( !parsePair( optarg, &mainParams.robotThinkMin,
|
||||
&mainParams.robotThinkMax ) ) {
|
||||
usage(argv[0], "bad param to -z" );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined PLATFORM_GTK && defined PLATFORM_NCURSES
|
||||
case 'g':
|
||||
useCurses = XP_FALSE;
|
||||
|
|
|
@ -67,6 +67,10 @@ typedef struct LaunchParams {
|
|||
XP_Bool allowHintRect;
|
||||
#endif
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
XP_U16 robotThinkMin, robotThinkMax;
|
||||
#endif
|
||||
|
||||
DeviceRole serverRole;
|
||||
|
||||
CommsConnType conType;
|
||||
|
|
Loading…
Reference in a new issue