mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-07 20:46:17 +01:00
fix assertion around out-of-order tile assignment
Got a crash opening games where tile pick was on and first player was a robot. Cause: non-robot player's tiles were being assigned before the robot's, and the move stack didn't like the out-of-order assignments. Now we assign tiles in order as before, but pause each time we find a non-robot that needs to pick its own.
This commit is contained in:
parent
6e5973c55b
commit
1cd863b877
2 changed files with 25 additions and 32 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
|
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
|
||||||
/*
|
/*
|
||||||
* Copyright 2000-2015 by Eric House (xwords@eehouse.org). All rights
|
* Copyright 2000 - 2017 by Eric House (xwords@eehouse.org). All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -2573,7 +2573,7 @@ setContains( const TrayTileSet* tiles, Tile tile )
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void
|
static void
|
||||||
assertDiffTurn( ModelCtxt* model, XP_U16 XP_UNUSED(turn),
|
assertDiffTurn( ModelCtxt* model, XP_U16 XP_UNUSED(turn),
|
||||||
const StackEntry* entry, void* closure)
|
const StackEntry* entry, void* closure )
|
||||||
{
|
{
|
||||||
if ( 1 < model->nPlayers ) {
|
if ( 1 < model->nPlayers ) {
|
||||||
DiffTurnState* state = (DiffTurnState*)closure;
|
DiffTurnState* state = (DiffTurnState*)closure;
|
||||||
|
|
|
@ -132,7 +132,7 @@ struct ServerCtxt {
|
||||||
#define NPASSES_OK(s) model_recentPassCountOk((s)->vol.model)
|
#define NPASSES_OK(s) model_recentPassCountOk((s)->vol.model)
|
||||||
|
|
||||||
/******************************* prototypes *******************************/
|
/******************************* prototypes *******************************/
|
||||||
static void assignTilesToAll( ServerCtxt* server );
|
static XP_Bool assignTilesToAll( ServerCtxt* server );
|
||||||
static void makePoolOnce( ServerCtxt* server );
|
static void makePoolOnce( ServerCtxt* server );
|
||||||
|
|
||||||
static void resetEngines( ServerCtxt* server );
|
static void resetEngines( ServerCtxt* server );
|
||||||
|
@ -777,7 +777,7 @@ handleRegistrationMsg( ServerCtxt* server, XWStreamCtxt* stream )
|
||||||
XP_ASSERT( ii == playersInMsg ); /* otherwise malformed */
|
XP_ASSERT( ii == playersInMsg ); /* otherwise malformed */
|
||||||
setStreamVersion( server );
|
setStreamVersion( server );
|
||||||
checkResizeBoard( server );
|
checkResizeBoard( server );
|
||||||
assignTilesToAll( server );
|
(void)assignTilesToAll( server );
|
||||||
SETSTATE( server, XWSTATE_RECEIVED_ALL_REG );
|
SETSTATE( server, XWSTATE_RECEIVED_ALL_REG );
|
||||||
}
|
}
|
||||||
informMissing( server );
|
informMissing( server );
|
||||||
|
@ -1057,6 +1057,8 @@ void
|
||||||
server_tilesPicked( ServerCtxt* server, XP_U16 player,
|
server_tilesPicked( ServerCtxt* server, XP_U16 player,
|
||||||
const TrayTileSet* newTilesP )
|
const TrayTileSet* newTilesP )
|
||||||
{
|
{
|
||||||
|
XP_ASSERT( 0 == model_getNumTilesInTray( server->vol.model, player ) );
|
||||||
|
|
||||||
TrayTileSet newTiles = *newTilesP;
|
TrayTileSet newTiles = *newTilesP;
|
||||||
pool_removeTiles( server->pool, &newTiles );
|
pool_removeTiles( server->pool, &newTiles );
|
||||||
|
|
||||||
|
@ -1089,28 +1091,6 @@ informNeedPickTiles( ServerCtxt* server, XP_Bool initial, XP_U16 turn,
|
||||||
nToPick, nFaces, faces, counts );
|
nToPick, nFaces, faces, counts );
|
||||||
}
|
}
|
||||||
|
|
||||||
static XP_Bool
|
|
||||||
askedForTiles( ServerCtxt* server )
|
|
||||||
{
|
|
||||||
XP_Bool asked = XP_FALSE;
|
|
||||||
CurGameInfo* gi = server->vol.gi;
|
|
||||||
if ( gi->serverRole == SERVER_STANDALONE && gi->allowPickTiles ) {
|
|
||||||
XP_U16 nPlayers = gi->nPlayers;
|
|
||||||
ModelCtxt* model = server->vol.model;
|
|
||||||
makePoolOnce( server );
|
|
||||||
for ( XP_U16 turn = 0; !asked && turn < nPlayers; ++turn ) {
|
|
||||||
LocalPlayer* player = &gi->players[turn];
|
|
||||||
XP_U16 nTiles = model_getNumTilesInTray( model, turn );
|
|
||||||
if ( nTiles == 0 && !LP_IS_ROBOT(player) ) {
|
|
||||||
informNeedPickTiles( server, XP_TRUE, turn, MAX_TRAY_TILES );
|
|
||||||
asked = XP_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG_RETURNF( "%s", boolToStr(asked));
|
|
||||||
return asked;
|
|
||||||
}
|
|
||||||
|
|
||||||
XP_Bool
|
XP_Bool
|
||||||
server_do( ServerCtxt* server )
|
server_do( ServerCtxt* server )
|
||||||
{
|
{
|
||||||
|
@ -1126,8 +1106,7 @@ server_do( ServerCtxt* server )
|
||||||
case XWSTATE_BEGIN:
|
case XWSTATE_BEGIN:
|
||||||
if ( server->nv.pendingRegistrations == 0 ) { /* all players on
|
if ( server->nv.pendingRegistrations == 0 ) { /* all players on
|
||||||
device */
|
device */
|
||||||
if ( !askedForTiles( server ) ) {
|
if ( assignTilesToAll( server ) ) {
|
||||||
assignTilesToAll( server );
|
|
||||||
SETSTATE( server, XWSTATE_INTURN );
|
SETSTATE( server, XWSTATE_INTURN );
|
||||||
setTurn( server, 0 );
|
setTurn( server, 0 );
|
||||||
moreToDo = XP_TRUE;
|
moreToDo = XP_TRUE;
|
||||||
|
@ -1941,15 +1920,17 @@ makePoolOnce( ServerCtxt* server )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static XP_Bool
|
||||||
assignTilesToAll( ServerCtxt* server )
|
assignTilesToAll( ServerCtxt* server )
|
||||||
{
|
{
|
||||||
|
XP_Bool allDone = XP_TRUE;
|
||||||
XP_U16 numAssigned;
|
XP_U16 numAssigned;
|
||||||
XP_U16 ii;
|
XP_U16 ii;
|
||||||
ModelCtxt* model = server->vol.model;
|
ModelCtxt* model = server->vol.model;
|
||||||
XP_U16 nPlayers = server->vol.gi->nPlayers;
|
CurGameInfo* gi = server->vol.gi;
|
||||||
|
XP_U16 nPlayers = gi->nPlayers;
|
||||||
|
|
||||||
XP_ASSERT( server->vol.gi->serverRole != SERVER_ISCLIENT );
|
XP_ASSERT( gi->serverRole != SERVER_ISCLIENT );
|
||||||
makePoolOnce( server );
|
makePoolOnce( server );
|
||||||
|
|
||||||
XP_STATUSF( "assignTilesToAll" );
|
XP_STATUSF( "assignTilesToAll" );
|
||||||
|
@ -1960,15 +1941,27 @@ assignTilesToAll( ServerCtxt* server )
|
||||||
if ( numAssigned > MAX_TRAY_TILES ) {
|
if ( numAssigned > MAX_TRAY_TILES ) {
|
||||||
numAssigned = MAX_TRAY_TILES;
|
numAssigned = MAX_TRAY_TILES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Loop through all the players. If picking tiles is on, stop for each
|
||||||
|
local player that doesn't have tiles yet. Return TRUE if we get all the
|
||||||
|
way through without doing that. */
|
||||||
|
|
||||||
|
XP_Bool pickingTiles = gi->serverRole == SERVER_STANDALONE
|
||||||
|
&& gi->allowPickTiles;
|
||||||
for ( ii = 0; ii < nPlayers; ++ii ) {
|
for ( ii = 0; ii < nPlayers; ++ii ) {
|
||||||
if ( 0 == model_getNumTilesInTray( model, ii ) ) {
|
if ( 0 == model_getNumTilesInTray( model, ii ) ) {
|
||||||
|
if ( pickingTiles && !LP_IS_ROBOT(&gi->players[ii]) ) {
|
||||||
|
informNeedPickTiles( server, XP_TRUE, ii, MAX_TRAY_TILES );
|
||||||
|
allDone = XP_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
TrayTileSet newTiles = {0};
|
TrayTileSet newTiles = {0};
|
||||||
fetchTiles( server, ii, numAssigned, NULL, &newTiles );
|
fetchTiles( server, ii, numAssigned, NULL, &newTiles );
|
||||||
model_assignPlayerTiles( model, ii, &newTiles );
|
model_assignPlayerTiles( model, ii, &newTiles );
|
||||||
}
|
}
|
||||||
sortTilesIf( server, ii );
|
sortTilesIf( server, ii );
|
||||||
}
|
}
|
||||||
|
return allDone;
|
||||||
} /* assignTilesToAll */
|
} /* assignTilesToAll */
|
||||||
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
|
|
Loading…
Add table
Reference in a new issue