Merge branch 'android_branch' of ssh://xwords.git.sourceforge.net/gitroot/xwords/xwords into android_branch

This commit is contained in:
Eric House 2011-01-13 14:57:24 -08:00
commit e7172fb4af
33 changed files with 456 additions and 311 deletions

View file

@ -26,6 +26,7 @@
> >
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" /> <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />

View file

@ -23,6 +23,7 @@ local_DEFINES += \
-DSCROLL_DRAG_THRESHHOLD=1 \ -DSCROLL_DRAG_THRESHHOLD=1 \
-DDROP_BITMAPS \ -DDROP_BITMAPS \
-DDISABLE_EMPTYTRAY_UNDO \ -DDISABLE_EMPTYTRAY_UNDO \
-DDISABLE_TILE_SEL \
-DNODE_CAN_4 \ -DNODE_CAN_4 \
-DRELAY_ROOM_DEFAULT=\"\"\ -DRELAY_ROOM_DEFAULT=\"\"\
-D__LITTLE_ENDIAN \ -D__LITTLE_ENDIAN \

View file

@ -47,7 +47,6 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
gi->boardSize = getInt( env, j_gi, "boardSize" ); gi->boardSize = getInt( env, j_gi, "boardSize" );
gi->gameID = getInt( env, j_gi, "gameID" ); gi->gameID = getInt( env, j_gi, "gameID" );
gi->dictLang = getInt( env, j_gi, "dictLang" ); gi->dictLang = getInt( env, j_gi, "dictLang" );
gi->robotSmartness = getInt( env, j_gi, "robotSmartness" );
gi->hintsNotAllowed = getBool( env, j_gi, "hintsNotAllowed" ); gi->hintsNotAllowed = getBool( env, j_gi, "hintsNotAllowed" );
gi->timerEnabled = getBool( env, j_gi, "timerEnabled" ); gi->timerEnabled = getBool( env, j_gi, "timerEnabled" );
gi->allowPickTiles = getBool( env, j_gi, "allowPickTiles" ); gi->allowPickTiles = getBool( env, j_gi, "allowPickTiles" );
@ -76,7 +75,7 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
jobject jlp = (*env)->GetObjectArrayElement( env, jplayers, ii ); jobject jlp = (*env)->GetObjectArrayElement( env, jplayers, ii );
XP_ASSERT( !!jlp ); XP_ASSERT( !!jlp );
lp->isRobot = getBool( env, jlp, "isRobot" ); lp->robotIQ = getInt( env, jlp, "robotIQ" );
lp->isLocal = getBool( env, jlp, "isLocal" ); lp->isLocal = getBool( env, jlp, "isLocal" );
getString( env, jlp, "name", buf, VSIZE(buf) ); getString( env, jlp, "name", buf, VSIZE(buf) );
@ -105,7 +104,6 @@ setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
setInt( env, jgi, "boardSize", gi->boardSize ); setInt( env, jgi, "boardSize", gi->boardSize );
setInt( env, jgi, "gameID", gi->gameID ); setInt( env, jgi, "gameID", gi->gameID );
setInt( env, jgi, "dictLang", gi->dictLang ); setInt( env, jgi, "dictLang", gi->dictLang );
setInt( env, jgi, "robotSmartness", gi->robotSmartness );
setBool( env, jgi, "hintsNotAllowed", gi->hintsNotAllowed ); setBool( env, jgi, "hintsNotAllowed", gi->hintsNotAllowed );
setBool( env, jgi, "timerEnabled", gi->timerEnabled ); setBool( env, jgi, "timerEnabled", gi->timerEnabled );
setBool( env, jgi, "allowPickTiles", gi->allowPickTiles ); setBool( env, jgi, "allowPickTiles", gi->allowPickTiles );
@ -127,7 +125,7 @@ setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
jobject jlp = (*env)->GetObjectArrayElement( env, jplayers, ii ); jobject jlp = (*env)->GetObjectArrayElement( env, jplayers, ii );
XP_ASSERT( !!jlp ); XP_ASSERT( !!jlp );
setBool( env, jlp, "isRobot", lp->isRobot ); setInt( env, jlp, "robotIQ", lp->robotIQ );
setBool( env, jlp, "isLocal", lp->isLocal ); setBool( env, jlp, "isLocal", lp->isLocal );
setString( env, jlp, "name", lp->name ); setString( env, jlp, "name", lp->name );
setString( env, jlp, "password", lp->password ); setString( env, jlp, "password", lp->password );

View file

@ -199,11 +199,13 @@
/> />
</LinearLayout> </LinearLayout>
<CheckBox android:id="@+id/smart_robot" <Spinner android:id="@+id/smart_robot"
android:layout_width="fill_parent" android:prompt="@string/robot_spinner_prompt"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:text="@string/smart_robot" android:layout_height="wrap_content"
/> android:drawSelectorOnTop="true"
android:entries="@array/robot_levels"
/>
<Spinner android:id="@+id/phonies_spinner" <Spinner android:id="@+id/phonies_spinner"
android:prompt="@string/phonies_spinner_prompt" android:prompt="@string/phonies_spinner_prompt"

View file

@ -73,6 +73,12 @@
<item>@string/phonies_disallow</item> <item>@string/phonies_disallow</item>
</string-array> </string-array>
<string-array name="robot_levels">
<item>@string/robot_smartest</item>
<item>@string/robot_smarter</item>
<item>@string/robot_smart</item>
</string-array>
<string-array name="connect_frequencies"> <string-array name="connect_frequencies">
<item>@string/connect_thirty_seconds</item> <item>@string/connect_thirty_seconds</item>
<item>@string/connect_five_mins</item> <item>@string/connect_five_mins</item>

View file

@ -177,8 +177,6 @@
<string name="settings_label">Other settings</string> <string name="settings_label">Other settings</string>
<string name="minutes_label">Minutes per player</string> <string name="minutes_label">Minutes per player</string>
<string name="smart_robot">Smart robot</string>
<string name="download_dicts">Download more...</string> <string name="download_dicts">Download more...</string>
<string name="confirm_save_title">Confirm save</string> <string name="confirm_save_title">Confirm save</string>
@ -230,6 +228,11 @@
<string name="phonies_ignore">Ignore phonies</string> <string name="phonies_ignore">Ignore phonies</string>
<string name="phonies_warn">Warn if phonies</string> <string name="phonies_warn">Warn if phonies</string>
<string name="phonies_disallow">Disallow phonies</string> <string name="phonies_disallow">Disallow phonies</string>
<string name="robot_spinner_prompt">How smart is the robot player?</string>
<string name="robot_smart">Smart robot</string>
<string name="robot_smarter">Smarter robot</string>
<string name="robot_smartest">Smartest robot</string>
<string name="menu_prefs">Settings</string> <string name="menu_prefs">Settings</string>
<string name="gamel_menu_dicts">Dictionaries</string> <string name="gamel_menu_dicts">Dictionaries</string>
<string name="menu_revert_all">Restore all</string> <string name="menu_revert_all">Restore all</string>
@ -257,7 +260,8 @@
<string name="default_dict">Game dictionary</string> <string name="default_dict">Game dictionary</string>
<string name="default_phonies">Handle phonies</string> <string name="default_phonies">Handle phonies</string>
<string name="phonies_spinner_prompt">Handle phonies (words not in dictionary)</string> <string name="phonies_spinner_prompt">How to handle \"phonies\"
(words not in dictionary)</string>
<string name="board_size">Board size</string> <string name="board_size">Board size</string>
<string name="default_timerenabled">Use game timer</string> <string name="default_timerenabled">Use game timer</string>

View file

@ -30,14 +30,7 @@ import java.net.InetSocketAddress;
import java.util.Vector; import java.util.Vector;
import java.util.Iterator; import java.util.Iterator;
import junit.framework.Assert; import junit.framework.Assert;
import android.telephony.SmsManager;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
@ -46,7 +39,8 @@ import org.eehouse.android.xw4.jni.*;
import org.eehouse.android.xw4.jni.JNIThread.*; import org.eehouse.android.xw4.jni.JNIThread.*;
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole; import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
public class CommsTransport implements TransportProcs { public class CommsTransport implements TransportProcs,
NetStateCache.StateChangedIf {
public static final int DIALOG = 0; public static final int DIALOG = 0;
public static final int DIALOG_RETRY = 1; public static final int DIALOG_RETRY = 1;
@ -84,8 +78,6 @@ public class CommsTransport implements TransportProcs {
private ByteBuffer m_bytesIn; private ByteBuffer m_bytesIn;
private Context m_context; private Context m_context;
private BroadcastReceiver m_receiver;
private boolean m_netAvail = true;
// assembling inbound packet // assembling inbound packet
private byte[] m_packetIn; private byte[] m_packetIn;
@ -100,7 +92,7 @@ public class CommsTransport implements TransportProcs {
m_buffersOut = new Vector<ByteBuffer>(); m_buffersOut = new Vector<ByteBuffer>();
m_bytesIn = ByteBuffer.allocate( 2048 ); m_bytesIn = ByteBuffer.allocate( 2048 );
buildNetAvailReceiver(); NetStateCache.register( context, this );
} }
public class CommsThread extends Thread { public class CommsThread extends Thread {
@ -238,9 +230,15 @@ public class CommsTransport implements TransportProcs {
public void waitToStop() public void waitToStop()
{ {
waitToStopImpl(); waitToStopImpl();
if ( null != m_receiver ) { NetStateCache.unregister( m_context, this );
m_context.unregisterReceiver( m_receiver ); }
m_receiver = null;
// NetStateCache.StateChangedIf interface
public void netAvail( boolean nowAvailable )
{
if ( !nowAvailable ) {
waitToStopImpl();
m_jniThread.handle( JNICmd.CMD_TRANSFAIL );
} }
} }
@ -332,39 +330,6 @@ public class CommsTransport implements TransportProcs {
} }
} }
private class CommsBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive( Context context, Intent intent )
{
if ( intent.getAction().
equals( ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo ni = (NetworkInfo)intent.
getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
boolean netAvail = NetworkInfo.State.CONNECTED == ni.getState();
boolean netAvailDet = NetworkInfo.DetailedState.CONNECTED ==
ni.getDetailedState();
Utils.logf( "CommsTransport::onReceive: netAvail=%s;netAvailDet=%s",
netAvail?"true":"false", netAvailDet?"true":"false" );
m_netAvail = netAvail;
if ( !netAvail ) {
waitToStopImpl();
m_jniThread.handle( JNICmd.CMD_TRANSFAIL );
}
}
}
}
private void buildNetAvailReceiver()
{
m_receiver = new CommsBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction( ConnectivityManager.CONNECTIVITY_ACTION );
Intent intent = m_context.registerReceiver( m_receiver, filter );
}
private void waitToStopImpl() private void waitToStopImpl()
{ {
m_done = true; // this is in a race! m_done = true; // this is in a race!
@ -398,7 +363,7 @@ public class CommsTransport implements TransportProcs {
switch ( m_addr.conType ) { switch ( m_addr.conType ) {
case COMMS_CONN_RELAY: case COMMS_CONN_RELAY:
if ( m_netAvail ) { if ( NetStateCache.netAvail( m_context ) ) {
putOut( buf ); // add to queue putOut( buf ); // add to queue
if ( null == m_thread ) { if ( null == m_thread ) {
m_thread = new CommsThread(); m_thread = new CommsThread();

View file

@ -91,6 +91,7 @@ public class GameConfig extends XWActivity
// private Spinner m_connectSpinner; // private Spinner m_connectSpinner;
private Spinner m_phoniesSpinner; private Spinner m_phoniesSpinner;
private Spinner m_dictSpinner; private Spinner m_dictSpinner;
private Spinner m_smartnessSpinner;
private String[] m_dictItems; private String[] m_dictItems;
private String[] m_dicts; private String[] m_dicts;
private int m_browsePosition; private int m_browsePosition;
@ -330,7 +331,7 @@ public class GameConfig extends XWActivity
}; };
check.setOnCheckedChangeListener( lstnr ); check.setOnCheckedChangeListener( lstnr );
Utils.setChecked( m_curDialog, R.id.robot_check, lp.isRobot ); Utils.setChecked( m_curDialog, R.id.robot_check, lp.isRobot() );
Utils.setChecked( m_curDialog, R.id.remote_check, ! lp.isLocal ); Utils.setChecked( m_curDialog, R.id.remote_check, ! lp.isLocal );
} }
@ -340,7 +341,7 @@ public class GameConfig extends XWActivity
lp.name = Utils.getText( m_curDialog, R.id.player_name_edit ); lp.name = Utils.getText( m_curDialog, R.id.player_name_edit );
lp.password = Utils.getText( m_curDialog, R.id.password_edit ); lp.password = Utils.getText( m_curDialog, R.id.password_edit );
lp.isRobot = Utils.getChecked( m_curDialog, R.id.robot_check ); lp.setIsRobot( Utils.getChecked( m_curDialog, R.id.robot_check ) );
lp.isLocal = !Utils.getChecked( m_curDialog, R.id.remote_check ); lp.isLocal = !Utils.getChecked( m_curDialog, R.id.remote_check );
} }
@ -443,6 +444,9 @@ public class GameConfig extends XWActivity
m_phoniesSpinner = (Spinner)findViewById( R.id.phonies_spinner ); m_phoniesSpinner = (Spinner)findViewById( R.id.phonies_spinner );
m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() ); m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() );
m_smartnessSpinner = (Spinner)findViewById( R.id.smart_robot );
setSmartnessSpinner();
Utils.setChecked( this, R.id.hints_allowed, !m_gi.hintsNotAllowed ); Utils.setChecked( this, R.id.hints_allowed, !m_gi.hintsNotAllowed );
Utils.setInt( this, R.id.timer_minutes_edit, Utils.setInt( this, R.id.timer_minutes_edit,
m_gi.gameSeconds/60/m_gi.nPlayers ); m_gi.gameSeconds/60/m_gi.nPlayers );
@ -459,8 +463,6 @@ public class GameConfig extends XWActivity
check.setOnCheckedChangeListener( lstnr ); check.setOnCheckedChangeListener( lstnr );
Utils.setChecked( this, R.id.use_timer, m_gi.timerEnabled ); Utils.setChecked( this, R.id.use_timer, m_gi.timerEnabled );
Utils.setChecked( this, R.id.smart_robot, 0 < m_gi.robotSmartness );
String fmt = getString( m_notNetworkedGame ? String fmt = getString( m_notNetworkedGame ?
R.string.title_game_configf R.string.title_game_configf
: R.string.title_gamenet_configf ); : R.string.title_gamenet_configf );
@ -665,6 +667,28 @@ public class GameConfig extends XWActivity
}); });
} }
private void setSmartnessSpinner()
{
int setting = -1;
switch ( m_gi.getRobotSmartness() ) {
case 1:
setting = 0;
break;
case 50:
setting = 1;
break;
case 99:
case 100:
setting = 2;
break;
default:
Utils.logf( "setSmartnessSpinner got %d from getRobotSmartness()",
m_gi.getRobotSmartness() );
Assert.fail();
}
m_smartnessSpinner.setSelection( setting );
}
// private void configConnectSpinner() // private void configConnectSpinner()
// { // {
// m_connectSpinner = (Spinner)findViewById( R.id.connect_spinner ); // m_connectSpinner = (Spinner)findViewById( R.id.connect_spinner );
@ -831,12 +855,13 @@ public class GameConfig extends XWActivity
m_gi.timerEnabled = Utils.getChecked( this, R.id.use_timer ); m_gi.timerEnabled = Utils.getChecked( this, R.id.use_timer );
m_gi.gameSeconds = 60 * m_gi.nPlayers * m_gi.gameSeconds = 60 * m_gi.nPlayers *
Utils.getInt( this, R.id.timer_minutes_edit ); Utils.getInt( this, R.id.timer_minutes_edit );
m_gi.robotSmartness
= Utils.getChecked( this, R.id.smart_robot ) ? 1 : 0;
int position = m_phoniesSpinner.getSelectedItemPosition(); int position = m_phoniesSpinner.getSelectedItemPosition();
m_gi.phoniesAction = CurGameInfo.XWPhoniesChoice.values()[position]; m_gi.phoniesAction = CurGameInfo.XWPhoniesChoice.values()[position];
position = m_smartnessSpinner.getSelectedItemPosition();
m_gi.setRobotSmartness(position * 49 + 1);
if ( !m_notNetworkedGame ) { if ( !m_notNetworkedGame ) {
m_car.ip_relay_seeksPublicRoom = m_joinPublicCheck.isChecked(); m_car.ip_relay_seeksPublicRoom = m_joinPublicCheck.isChecked();
Utils.logf( "ip_relay_seeksPublicRoom: %s", Utils.logf( "ip_relay_seeksPublicRoom: %s",

View file

@ -0,0 +1,129 @@
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
/*
* Copyright 2010 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.NetworkInfo;
import android.net.ConnectivityManager;
import java.util.HashSet;
import java.util.Iterator;
import junit.framework.Assert;
public class NetStateCache {
public interface StateChangedIf {
public void netAvail( boolean nowAvailable );
}
private static Boolean s_haveReceiver = new Boolean( false );
private static HashSet<StateChangedIf> s_ifs;
private static boolean s_netAvail = false;
private static CommsBroadcastReceiver s_receiver;
public static void register( Context context, StateChangedIf proc )
{
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.add( proc );
}
}
public static void unregister( Context context, StateChangedIf proc )
{
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.remove( proc );
}
}
public static boolean netAvail( Context context )
{
initIfNot( context );
return s_netAvail;
}
private static void initIfNot( Context context )
{
synchronized( s_haveReceiver ) {
if ( !s_haveReceiver ) {
// First figure out the current net state. Note that
// this doesn't seem to work on the emulator.
ConnectivityManager connMgr = (ConnectivityManager)
context.getSystemService( Context.CONNECTIVITY_SERVICE );
NetworkInfo ni = connMgr.getActiveNetworkInfo();
s_netAvail = null != ni &&
NetworkInfo.State.CONNECTED == ni.getState();
s_receiver = new CommsBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction( ConnectivityManager.CONNECTIVITY_ACTION );
Intent intent = context.registerReceiver( s_receiver, filter );
s_ifs = new HashSet<StateChangedIf>();
s_haveReceiver = true;
}
}
}
private static class CommsBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive( Context context, Intent intent )
{
if ( intent.getAction().
equals( ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo ni = (NetworkInfo)intent.
getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
Utils.logf( "CommsTransport::onReceive: %s",
ni.getState().toString() );
boolean netAvail;
switch ( ni.getState() ) {
case CONNECTED:
netAvail = true;
break;
case DISCONNECTED:
netAvail = false;
break;
default:
// ignore everything else
netAvail = s_netAvail;
break;
}
if ( s_netAvail != netAvail ) {
Iterator<StateChangedIf> iter = s_ifs.iterator();
while ( iter.hasNext() ) {
StateChangedIf proc = iter.next();
proc.netAvail( netAvail );
}
s_netAvail = netAvail;
}
}
}
} // class CommsBroadcastReceiver
}

View file

@ -49,13 +49,13 @@ public class CurGameInfo {
public boolean timerEnabled; public boolean timerEnabled;
public boolean allowPickTiles; public boolean allowPickTiles;
public boolean allowHintRect; public boolean allowHintRect;
public int robotSmartness;
public XWPhoniesChoice phoniesAction; public XWPhoniesChoice phoniesAction;
public boolean confirmBTConnect; /* only used for BT */ public boolean confirmBTConnect; /* only used for BT */
// private int[] m_visiblePlayers; // private int[] m_visiblePlayers;
// private int m_nVisiblePlayers; // private int m_nVisiblePlayers;
private boolean m_inProgress; private boolean m_inProgress;
private int m_smartness;
public CurGameInfo( Context context ) public CurGameInfo( Context context )
{ {
@ -79,7 +79,7 @@ public class CurGameInfo {
timerEnabled = CommonPrefs.getDefaultTimerEnabled( context ); timerEnabled = CommonPrefs.getDefaultTimerEnabled( context );
allowPickTiles = false; allowPickTiles = false;
allowHintRect = false; allowHintRect = false;
robotSmartness = 1; m_smartness = 0; // needs to be set from players
// Always create MAX_NUM_PLAYERS so jni code doesn't ever have // Always create MAX_NUM_PLAYERS so jni code doesn't ever have
// to cons up a LocalPlayer instance. // to cons up a LocalPlayer instance.
@ -90,7 +90,7 @@ public class CurGameInfo {
if ( isNetworked ) { if ( isNetworked ) {
players[1].isLocal = false; players[1].isLocal = false;
} else { } else {
players[0].isRobot = true; players[0].setRobotSmartness( 1 );
} }
} }
@ -110,7 +110,6 @@ public class CurGameInfo {
timerEnabled = src.timerEnabled; timerEnabled = src.timerEnabled;
allowPickTiles = src.allowPickTiles; allowPickTiles = src.allowPickTiles;
allowHintRect = src.allowHintRect; allowHintRect = src.allowHintRect;
robotSmartness = src.robotSmartness;
int ii; int ii;
for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) { for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
@ -133,6 +132,30 @@ public class CurGameInfo {
m_inProgress = inProgress; m_inProgress = inProgress;
} }
public int getRobotSmartness()
{
if ( m_smartness == 0 ) {
m_smartness = 1; // default if no robots
for ( int ii = 0; ii < nPlayers; ++ii ) {
if ( players[ii].isRobot() ) {
m_smartness = players[ii].robotIQ;
break; // should all be the same
}
}
}
return m_smartness;
}
public void setRobotSmartness( int smartness )
{
m_smartness = smartness;
for ( int ii = 0; ii < nPlayers; ++ii ) {
if ( players[ii].isRobot() ) {
players[ii].robotIQ = smartness;
}
}
}
/** return true if any of the changes made would invalide a game /** return true if any of the changes made would invalide a game
* in progress, i.e. require that it be restarted with the new * in progress, i.e. require that it be restarted with the new
* params. E.g. changing a player to a robot is harmless for a * params. E.g. changing a player to a robot is harmless for a
@ -152,7 +175,7 @@ public class CurGameInfo {
for ( int ii = 0; ii < nPlayers; ++ii ) { for ( int ii = 0; ii < nPlayers; ++ii ) {
LocalPlayer me = players[ii]; LocalPlayer me = players[ii];
LocalPlayer him = other.players[ii]; LocalPlayer him = other.players[ii];
matter = me.isRobot != him.isRobot matter = me.isRobot() != him.isRobot()
|| me.isLocal != him.isLocal || me.isLocal != him.isLocal
|| !me.name.equals( him.name ); || !me.name.equals( him.name );
if ( matter ) { if ( matter ) {
@ -198,7 +221,7 @@ public class CurGameInfo {
LocalPlayer lp = players[ii]; LocalPlayer lp = players[ii];
if ( lp.isLocal || serverRole == DeviceRole.SERVER_STANDALONE ) { if ( lp.isLocal || serverRole == DeviceRole.SERVER_STANDALONE ) {
names[ii] = lp.name; names[ii] = lp.name;
if ( lp.isRobot ) { if ( lp.isRobot() ) {
names[ii] += " " + context.getString( R.string.robot_name ); names[ii] += " " + context.getString( R.string.robot_name );
} }
} else { } else {

View file

@ -22,18 +22,19 @@ package org.eehouse.android.xw4.jni;
import android.content.Context; import android.content.Context;
import org.eehouse.android.xw4.R; import org.eehouse.android.xw4.R;
import junit.framework.Assert;
public class LocalPlayer { public class LocalPlayer {
public String name; public String name;
public String password; public String password;
public int secondsUsed; public int secondsUsed;
public boolean isRobot; public int robotIQ;
public boolean isLocal; public boolean isLocal;
public LocalPlayer( Context context, int num ) public LocalPlayer( Context context, int num )
{ {
isLocal = true; isLocal = true;
isRobot = false; robotIQ = 0; // human
String fmt = context.getString( R.string.playerf ); String fmt = context.getString( R.string.playerf );
name = String.format( fmt, num + 1 ); name = String.format( fmt, num + 1 );
password = ""; password = "";
@ -42,7 +43,7 @@ public class LocalPlayer {
public LocalPlayer( final LocalPlayer src ) public LocalPlayer( final LocalPlayer src )
{ {
isLocal = src.isLocal; isLocal = src.isLocal;
isRobot = src.isRobot; robotIQ = src.robotIQ;
if ( null != src.name ) { if ( null != src.name ) {
name = new String(src.name); name = new String(src.name);
} }
@ -51,5 +52,21 @@ public class LocalPlayer {
} }
secondsUsed = src.secondsUsed; secondsUsed = src.secondsUsed;
} }
public boolean isRobot()
{
return robotIQ > 0;
}
public void setIsRobot( boolean isRobot )
{
robotIQ = isRobot ? 1 : 0;
}
public void setRobotSmartness( int iq )
{
Assert.assertTrue( iq > 0 );
robotIQ = iq;
}
} }

View file

@ -564,7 +564,7 @@ board_canHint( const BoardCtxt* board )
&& 0 < model_getNumTilesTotal( board->model, board->selPlayer ); && 0 < model_getNumTilesTotal( board->model, board->selPlayer );
if ( canHint ) { if ( canHint ) {
LocalPlayer* lp = &board->gi->players[board->selPlayer]; LocalPlayer* lp = &board->gi->players[board->selPlayer];
canHint = lp->isLocal && !lp->isRobot; canHint = lp->isLocal && !LP_IS_ROBOT(lp);
} }
return canHint; return canHint;
} }
@ -1412,7 +1412,7 @@ chooseBestSelPlayer( BoardCtxt* board )
for ( i = 0; i < nPlayers; ++i ) { for ( i = 0; i < nPlayers; ++i ) {
LocalPlayer* lp = &board->gi->players[curTurn]; LocalPlayer* lp = &board->gi->players[curTurn];
if ( !lp->isRobot && lp->isLocal ) { if ( !LP_IS_ROBOT(lp) && lp->isLocal ) {
return curTurn; return curTurn;
} }
curTurn = (curTurn + 1) % nPlayers; curTurn = (curTurn + 1) % nPlayers;
@ -1707,7 +1707,7 @@ board_requestHint( BoardCtxt* board,
#ifdef XWFEATURE_SEARCHLIMIT #ifdef XWFEATURE_SEARCHLIMIT
lp, useTileLimits, lp, useTileLimits,
#endif #endif
NO_SCORE_LIMIT, 0, /* 0: not a robot */
&canMove, &newMove ); &canMove, &newMove );
board_popTimerSave( board ); board_popTimerSave( board );
@ -2160,7 +2160,7 @@ askRevealTray( BoardCtxt* board )
} else if ( !lp->isLocal ) { } else if ( !lp->isLocal ) {
util_userError( board->util, ERR_NO_PEEK_REMOTE_TILES ); util_userError( board->util, ERR_NO_PEEK_REMOTE_TILES );
#endif #endif
} else if ( lp->isRobot ) { } else if ( LP_IS_ROBOT(lp) ) {
if ( reversed ) { if ( reversed ) {
util_userError( board->util, ERR_NO_PEEK_ROBOT_TILES ); util_userError( board->util, ERR_NO_PEEK_ROBOT_TILES );
} else { } else {
@ -2286,6 +2286,7 @@ board_handlePenMove( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
return result; return result;
} /* board_handlePenMove */ } /* board_handlePenMove */
#ifndef DISABLE_TILE_SEL
/* Called when user taps on the board and a tray tile's selected. /* Called when user taps on the board and a tray tile's selected.
*/ */
static XP_Bool static XP_Bool
@ -2320,6 +2321,7 @@ moveSelTileToBoardXY( BoardCtxt* board, XP_U16 col, XP_U16 row )
return result; return result;
} /* moveSelTileToBoardXY */ } /* moveSelTileToBoardXY */
#endif
XP_Bool XP_Bool
cellOccupied( const BoardCtxt* board, XP_U16 col, XP_U16 row, cellOccupied( const BoardCtxt* board, XP_U16 col, XP_U16 row,
@ -2412,7 +2414,10 @@ tryReplaceTile( BoardCtxt* board, XP_U16 pencol, XP_U16 penrow )
static XP_Bool static XP_Bool
handleActionInCell( BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Bool isPen ) handleActionInCell( BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Bool isPen )
{ {
return moveSelTileToBoardXY( board, col, row ) return XP_FALSE
#ifndef DISABLE_TILE_SEL
|| moveSelTileToBoardXY( board, col, row )
#endif
|| tryMoveArrow( board, col, row ) || tryMoveArrow( board, col, row )
|| (!isPen && tryReplaceTile( board, col, row )) || (!isPen && tryReplaceTile( board, col, row ))
; ;

View file

@ -90,14 +90,14 @@ struct EngineCtxt {
XP_Bool usePrev; XP_Bool usePrev;
XP_Bool searchInProgress; XP_Bool searchInProgress;
XP_Bool searchHorizontal; XP_Bool searchHorizontal;
XP_Bool isRobot;
XP_Bool isFirstMove; XP_Bool isFirstMove;
XP_U16 numRows, numCols; XP_U16 numRows, numCols;
XP_U16 curRow; XP_U16 curRow;
XP_U16 blankCount; XP_U16 blankCount;
XP_U16 targetScore; XP_U16 nMovesToSave;
XP_U16 star_row; XP_U16 star_row;
XP_Bool returnNOW; XP_Bool returnNOW;
XP_Bool isRobot;
MoveIterationData miData; MoveIterationData miData;
XP_S16 blankValues[MAX_TRAY_TILES]; XP_S16 blankValues[MAX_TRAY_TILES];
@ -202,7 +202,7 @@ engine_getScoreCache( EngineCtxt* engine, XP_U16 row )
* turn it into a separate code module later. * turn it into a separate code module later.
****************************************************************************/ ****************************************************************************/
EngineCtxt* EngineCtxt*
engine_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isRobot ) engine_make( MPFORMAL XW_UtilCtxt* util )
{ {
EngineCtxt* result = (EngineCtxt*)XP_MALLOC( mpool, sizeof(*result) ); EngineCtxt* result = (EngineCtxt*)XP_MALLOC( mpool, sizeof(*result) );
XP_MEMSET( result, 0, sizeof(*result) ); XP_MEMSET( result, 0, sizeof(*result) );
@ -211,8 +211,6 @@ engine_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isRobot )
result->util = util; result->util = util;
result->isRobot = isRobot;
engine_reset( result ); engine_reset( result );
return result; return result;
@ -230,9 +228,9 @@ engine_writeToStream( EngineCtxt* XP_UNUSED(ctxt),
EngineCtxt* EngineCtxt*
engine_makeFromStream( MPFORMAL XWStreamCtxt* XP_UNUSED_DBG(stream), engine_makeFromStream( MPFORMAL XWStreamCtxt* XP_UNUSED_DBG(stream),
XW_UtilCtxt* util, XP_Bool isRobot ) XW_UtilCtxt* util )
{ {
EngineCtxt* engine = engine_make( MPPARM(mpool) util, isRobot ); EngineCtxt* engine = engine_make( MPPARM(mpool) util );
/* All the engine's data seems to be used only in the process of finding a /* All the engine's data seems to be used only in the process of finding a
move. So if we're willing to have the set of moves found lost across move. So if we're willing to have the set of moves found lost across
@ -306,7 +304,7 @@ print_savedMoves( const EngineCtxt* engine, const char* label )
int ii; int ii;
int pos = 0; int pos = 0;
char buf[(NUM_SAVED_ENGINE_MOVES*10) + 3] = {0}; char buf[(NUM_SAVED_ENGINE_MOVES*10) + 3] = {0};
for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES; ++ii ) { for ( ii = 0; ii < engine->nMovesToSave; ++ii ) {
if ( 0 < engine->miData.savedMoves[ii].score ) { if ( 0 < engine->miData.savedMoves[ii].score ) {
pos += XP_SNPRINTF( &buf[pos], VSIZE(buf)-pos, "[%d]: %d; ", pos += XP_SNPRINTF( &buf[pos], VSIZE(buf)-pos, "[%d]: %d; ",
ii, engine->miData.savedMoves[ii].score ); ii, engine->miData.savedMoves[ii].score );
@ -322,8 +320,9 @@ static XP_Bool
chooseMove( EngineCtxt* engine, PossibleMove** move ) chooseMove( EngineCtxt* engine, PossibleMove** move )
{ {
XP_U16 ii; XP_U16 ii;
PossibleMove* chosen; PossibleMove* chosen = NULL;
XP_Bool result; XP_Bool result;
XP_Bool done;
print_savedMoves( engine, "unsorted moves" ); print_savedMoves( engine, "unsorted moves" );
@ -331,31 +330,38 @@ chooseMove( EngineCtxt* engine, PossibleMove** move )
get picked up first. Don't sort if we're working for a robot; we've get picked up first. Don't sort if we're working for a robot; we've
only been saving the single best move anyway. At least not until we only been saving the single best move anyway. At least not until we
start applying other criteria than score to moves. */ start applying other criteria than score to moves. */
if ( engine->isRobot ) {
chosen = &engine->miData.savedMoves[0]; done = !move_cache_empty( engine );
} else { while ( !done ) { /* while so can break */
XP_Bool done = !move_cache_empty( engine ); done = XP_TRUE;
while ( !done ) { /* while so can break */ PossibleMove* cur = engine->miData.savedMoves;
done = XP_TRUE; for ( ii = 0; ii < engine->nMovesToSave-1; ++ii ) {
PossibleMove* cur = engine->miData.savedMoves; PossibleMove* next = cur + 1;
for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES-1; ++ii ) { if ( CMPMOVES( cur, next ) > 0 ) {
PossibleMove* next = cur + 1; PossibleMove tmp;
if ( CMPMOVES( cur, next ) > 0 ) { XP_MEMCPY( &tmp, cur, sizeof(tmp) );
PossibleMove tmp; XP_MEMCPY( cur, next, sizeof(*cur) );
XP_MEMCPY( &tmp, cur, sizeof(tmp) ); XP_MEMCPY( next, &tmp, sizeof(*next) );
XP_MEMCPY( cur, next, sizeof(*cur) ); done = XP_FALSE;
XP_MEMCPY( next, &tmp, sizeof(*next) );
done = XP_FALSE;
}
cur = next;
}
if ( done ) {
init_move_cache( engine );
print_savedMoves( engine, "sorted moves" );
} }
cur = next;
} }
/* now pick the one we're supposed to return */ if ( done ) {
if ( !engine->isRobot ) {
init_move_cache( engine );
}
print_savedMoves( engine, "sorted moves" );
}
}
/* now pick the one we're supposed to return */
if ( engine->isRobot ) {
XP_ASSERT( engine->miData.nInMoveCache <= NUM_SAVED_ENGINE_MOVES );
XP_ASSERT( engine->miData.nInMoveCache <= engine->nMovesToSave );
/* PENDING not nInMoveCache-1 below?? */
chosen = &engine->miData.savedMoves[engine->miData.nInMoveCache];
} else {
chosen = next_from_cache( engine ); chosen = next_from_cache( engine );
} }
@ -366,10 +372,35 @@ chooseMove( EngineCtxt* engine, PossibleMove** move )
if ( !result ) { if ( !result ) {
engine_reset( engine ); engine_reset( engine );
} }
LOG_RETURNF( "%d", result ); LOG_RETURNF( "%s", result?"true":"false" );
return result; return result;
} /* chooseMove */ } /* chooseMove */
/* Robot smartness is a number between 0 and 100, inclusive. 0 means a human
* player who may want to iterate, so save all moves. If a robot player, we
* want a random move within a range proportional to the 1-100 range, so we
* figure out now what we'll be picking, save only that many moves and take
* the worst of 'em in chooseMove().
*/
static void
normalizeIQ( EngineCtxt* engine, XP_U16 iq )
{
engine->isRobot = 0 < iq;
if ( 0 == iq ) { /* human */
engine->nMovesToSave = NUM_SAVED_ENGINE_MOVES; /* save 'em all */
} else if ( 1 == iq ) { /* smartest robot */
engine->nMovesToSave = 1;
} else {
XP_U16 count = NUM_SAVED_ENGINE_MOVES * iq / 100;
engine->nMovesToSave = 1;
if ( count > 0 ) {
engine->nMovesToSave += XP_RANDOM() % count;
}
}
XP_LOGF( "%s: set nMovesToSave=%d (iq=%d; NUM_SAVED_ENGINE_MOVES=%d)",
__func__, engine->nMovesToSave, iq, NUM_SAVED_ENGINE_MOVES );
}
/* Return of XP_TRUE means that we ran to completion. XP_FALSE means we were /* Return of XP_TRUE means that we ran to completion. XP_FALSE means we were
* interrupted. Whether an actual move was found is indicated by what's * interrupted. Whether an actual move was found is indicated by what's
* filled in in *newMove. * filled in in *newMove.
@ -382,8 +413,7 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
const BdHintLimits* searchLimits, const BdHintLimits* searchLimits,
XP_Bool useTileLimits, XP_Bool useTileLimits,
#endif #endif
XP_U16 targetScore, XP_Bool* canMoveP, XP_U16 robotIQ, XP_Bool* canMoveP, MoveInfo* newMove )
MoveInfo* newMove )
{ {
XP_Bool result = XP_TRUE; XP_Bool result = XP_TRUE;
XP_U16 star_row; XP_U16 star_row;
@ -442,7 +472,7 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
util_engineStarting( engine->util, util_engineStarting( engine->util,
engine->rack[engine->blankTile] ); engine->rack[engine->blankTile] );
engine->targetScore = targetScore; normalizeIQ( engine, robotIQ );
if ( move_cache_empty( engine ) ) { if ( move_cache_empty( engine ) ) {
set_search_limits( engine ); set_search_limits( engine );
@ -1141,7 +1171,9 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
XP_Bool usePrev = engine->usePrev; XP_Bool usePrev = engine->usePrev;
XP_Bool foundEmpty = XP_FALSE; XP_Bool foundEmpty = XP_FALSE;
if ( !engine->isRobot ) { /* robot doesn't ask for next hint.... */ if ( 1 == engine->nMovesToSave ) { /* only saving one */
mostest = 0;
} else {
mostest = -1; mostest = -1;
/* we're not interested if we've seen this */ /* we're not interested if we've seen this */
cmpVal = CMPMOVES( posmove, &engine->miData.lastSeenMove ); cmpVal = CMPMOVES( posmove, &engine->miData.lastSeenMove );
@ -1154,7 +1186,7 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
} else { } else {
XP_S16 ii; XP_S16 ii;
/* terminate i at 1 because mostest starts at 0 */ /* terminate i at 1 because mostest starts at 0 */
for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES; ++ii ) { for ( ii = 0; ii < engine->nMovesToSave; ++ii ) {
/* Find the mostest value move and overwrite it. Note that /* Find the mostest value move and overwrite it. Note that
there might not be one, as all may have the same or higher there might not be one, as all may have the same or higher
scores and those that have the same score may compare scores and those that have the same score may compare
@ -1222,7 +1254,7 @@ set_search_limits( EngineCtxt* engine )
move as the limit; otherwise the lowest */ move as the limit; otherwise the lowest */
if ( 0 < engine->miData.nInMoveCache ) { if ( 0 < engine->miData.nInMoveCache ) {
XP_U16 srcIndx = engine->usePrev XP_U16 srcIndx = engine->usePrev
? NUM_SAVED_ENGINE_MOVES-1 : engine->miData.bottom; ? engine->nMovesToSave-1 : engine->miData.bottom;
XP_MEMCPY( &engine->miData.lastSeenMove, XP_MEMCPY( &engine->miData.lastSeenMove,
&engine->miData.savedMoves[srcIndx], &engine->miData.savedMoves[srcIndx],
sizeof(engine->miData.lastSeenMove) ); sizeof(engine->miData.lastSeenMove) );
@ -1238,9 +1270,11 @@ set_search_limits( EngineCtxt* engine )
static void static void
init_move_cache( EngineCtxt* engine ) init_move_cache( EngineCtxt* engine )
{ {
XP_U16 nInMoveCache = NUM_SAVED_ENGINE_MOVES; XP_U16 nInMoveCache = engine->nMovesToSave;
XP_U16 ii; XP_U16 ii;
XP_ASSERT( engine->nMovesToSave == NUM_SAVED_ENGINE_MOVES );
for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES; ++ii ) { for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES; ++ii ) {
if ( 0 == engine->miData.savedMoves[ii].score ) { if ( 0 == engine->miData.savedMoves[ii].score ) {
--nInMoveCache; --nInMoveCache;
@ -1306,9 +1340,7 @@ scoreQualifies( EngineCtxt* engine, XP_U16 score )
XP_Bool qualifies = XP_FALSE; XP_Bool qualifies = XP_FALSE;
XP_Bool usePrev = engine->usePrev; XP_Bool usePrev = engine->usePrev;
if ( score > engine->targetScore ) { if ( usePrev && score < engine->miData.lastSeenMove.score ) {
/* drop it */
} else if ( usePrev && score < engine->miData.lastSeenMove.score ) {
/* drop it */ /* drop it */
} else if ( !usePrev && score > engine->miData.lastSeenMove.score } else if ( !usePrev && score > engine->miData.lastSeenMove.score
/* || (score < engine->miData.lowestSavedScore) */ ) { /* || (score < engine->miData.lowestSavedScore) */ ) {
@ -1322,7 +1354,7 @@ scoreQualifies( EngineCtxt* engine, XP_U16 score )
NUM_SAVED_ENGINE_MOVES moves in here* and doing a quick test on NUM_SAVED_ENGINE_MOVES moves in here* and doing a quick test on
that. Or better, keeping the list in sorted order. */ that. Or better, keeping the list in sorted order. */
for ( ii = 0, savedMoves = engine->miData.savedMoves; for ( ii = 0, savedMoves = engine->miData.savedMoves;
ii < NUM_SAVED_ENGINE_MOVES; ++ii, ++savedMoves ) { ii < engine->nMovesToSave; ++ii, ++savedMoves ) {
if ( savedMoves->score == 0 ) { /* empty slot */ if ( savedMoves->score == 0 ) { /* empty slot */
qualifies = XP_TRUE; qualifies = XP_TRUE;
} else if ( usePrev && score <= savedMoves->score ) { } else if ( usePrev && score <= savedMoves->score ) {
@ -1332,9 +1364,6 @@ scoreQualifies( EngineCtxt* engine, XP_U16 score )
qualifies = XP_TRUE; qualifies = XP_TRUE;
break; break;
} }
if ( engine->isRobot ) { /* we look at only one for robot */
break;
}
} }
} }
//XP_LOGF( "%s(%d)->%d", __func__, score, qualifies ); //XP_LOGF( "%s(%d)->%d", __func__, score, qualifies );

View file

@ -38,17 +38,16 @@ typedef struct BdHintLimits {
XP_U16 engine_getScoreCache( EngineCtxt* engine, XP_U16 row ); XP_U16 engine_getScoreCache( EngineCtxt* engine, XP_U16 row );
EngineCtxt* engine_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isRobot ); EngineCtxt* engine_make( MPFORMAL XW_UtilCtxt* util );
void engine_writeToStream( EngineCtxt* ctxt, XWStreamCtxt* stream ); void engine_writeToStream( EngineCtxt* ctxt, XWStreamCtxt* stream );
EngineCtxt* engine_makeFromStream( MPFORMAL XWStreamCtxt* stream, EngineCtxt* engine_makeFromStream( MPFORMAL XWStreamCtxt* stream,
XW_UtilCtxt* util, XP_Bool isRobot ); XW_UtilCtxt* util );
void engine_init( EngineCtxt* ctxt ); void engine_init( EngineCtxt* ctxt );
void engine_reset( EngineCtxt* ctxt ); void engine_reset( EngineCtxt* ctxt );
void engine_destroy( EngineCtxt* ctxt ); void engine_destroy( EngineCtxt* ctxt );
#define NO_SCORE_LIMIT 10000 /* for targetScore */
XP_Bool engine_findMove( EngineCtxt* ctxt, const ModelCtxt* model, XP_Bool engine_findMove( EngineCtxt* ctxt, const ModelCtxt* model,
const DictionaryCtxt* dict, const Tile* tiles, const DictionaryCtxt* dict, const Tile* tiles,
XP_U16 nTiles, XP_Bool usePrev, XP_U16 nTiles, XP_Bool usePrev,
@ -56,8 +55,7 @@ XP_Bool engine_findMove( EngineCtxt* ctxt, const ModelCtxt* model,
const BdHintLimits* boardLimits, const BdHintLimits* boardLimits,
XP_Bool useTileLimits, XP_Bool useTileLimits,
#endif #endif
XP_U16 targetScore, XP_Bool* canMove, XP_U16 robotIQ, XP_Bool* canMove, MoveInfo* result );
MoveInfo* result );
XP_Bool engine_check( DictionaryCtxt* dict, Tile* buf, XP_U16 buflen ); XP_Bool engine_check( DictionaryCtxt* dict, Tile* buf, XP_U16 buflen );
#ifdef CPLUS #ifdef CPLUS

View file

@ -297,7 +297,6 @@ gi_initPlayerInfo( MPFORMAL CurGameInfo* gi, const XP_UCHAR* nameTemplate )
gi->serverRole = SERVER_STANDALONE; gi->serverRole = SERVER_STANDALONE;
gi->nPlayers = 2; gi->nPlayers = 2;
gi->boardSize = 15; gi->boardSize = 15;
gi->robotSmartness = SMART_ROBOT;
gi->gameSeconds = 25 * 60; /* 25 minute game is common? */ gi->gameSeconds = 25 * 60; /* 25 minute game is common? */
gi->confirmBTConnect = XP_TRUE; gi->confirmBTConnect = XP_TRUE;
@ -312,7 +311,7 @@ gi_initPlayerInfo( MPFORMAL CurGameInfo* gi, const XP_UCHAR* nameTemplate )
fp->name = copyString( mpool, buf ); fp->name = copyString( mpool, buf );
} }
fp->isRobot = (i == 0); /* one robot */ fp->robotIQ = (i == 0) ? 1 : 0; /* one robot */
fp->isLocal = XP_TRUE; fp->isLocal = XP_TRUE;
fp->secondsUsed = 0; fp->secondsUsed = 0;
} }
@ -367,7 +366,6 @@ gi_copy( MPFORMAL CurGameInfo* destGI, const CurGameInfo* srcGI )
destGI->hintsNotAllowed = srcGI->hintsNotAllowed; destGI->hintsNotAllowed = srcGI->hintsNotAllowed;
destGI->timerEnabled = srcGI->timerEnabled; destGI->timerEnabled = srcGI->timerEnabled;
destGI->robotSmartness = (XP_U8)srcGI->robotSmartness;
destGI->phoniesAction = srcGI->phoniesAction; destGI->phoniesAction = srcGI->phoniesAction;
destGI->allowPickTiles = srcGI->allowPickTiles; destGI->allowPickTiles = srcGI->allowPickTiles;
@ -378,7 +376,7 @@ gi_copy( MPFORMAL CurGameInfo* destGI, const CurGameInfo* srcGI )
replaceStringIfDifferent( mpool, &destPl->password, replaceStringIfDifferent( mpool, &destPl->password,
srcPl->password ); srcPl->password );
destPl->secondsUsed = srcPl->secondsUsed; destPl->secondsUsed = srcPl->secondsUsed;
destPl->isRobot = srcPl->isRobot; destPl->robotIQ = srcPl->robotIQ;
destPl->isLocal = srcPl->isLocal; destPl->isLocal = srcPl->isLocal;
} }
} /* gi_copy */ } /* gi_copy */
@ -391,7 +389,7 @@ gi_countLocalPlayers( const CurGameInfo* gi, XP_Bool humanOnly )
const LocalPlayer* lp = gi->players; const LocalPlayer* lp = gi->players;
while ( nPlayers-- ) { while ( nPlayers-- ) {
if ( lp->isLocal ) { if ( lp->isLocal ) {
if ( humanOnly && lp->isRobot ) { if ( humanOnly && LP_IS_ROBOT(lp) ) {
// skip // skip
} else { } else {
++count; ++count;
@ -420,7 +418,9 @@ gi_readFromStream( MPFORMAL XWStreamCtxt* stream, CurGameInfo* gi )
gi->boardSize = (XP_U8)stream_getBits( stream, 4 ); gi->boardSize = (XP_U8)stream_getBits( stream, 4 );
gi->serverRole = (DeviceRole)stream_getBits( stream, 2 ); gi->serverRole = (DeviceRole)stream_getBits( stream, 2 );
gi->hintsNotAllowed = stream_getBits( stream, 1 ); gi->hintsNotAllowed = stream_getBits( stream, 1 );
gi->robotSmartness = (XP_U8)stream_getBits( stream, 2 ); if ( strVersion < STREAM_VERS_ROBOTIQ ) {
(void)stream_getBits( stream, 2 );
}
gi->phoniesAction = (XWPhoniesChoice)stream_getBits( stream, 2 ); gi->phoniesAction = (XWPhoniesChoice)stream_getBits( stream, 2 );
gi->timerEnabled = stream_getBits( stream, 1 ); gi->timerEnabled = stream_getBits( stream, 1 );
@ -459,7 +459,9 @@ gi_readFromStream( MPFORMAL XWStreamCtxt* stream, CurGameInfo* gi )
} }
pl->secondsUsed = stream_getU16( stream ); pl->secondsUsed = stream_getU16( stream );
pl->isRobot = stream_getBits( stream, 1 ); pl->robotIQ = ( strVersion < STREAM_VERS_ROBOTIQ )
? (XP_U8)stream_getBits( stream, 1 )
: stream_getU8( stream );
pl->isLocal = stream_getBits( stream, 1 ); pl->isLocal = stream_getBits( stream, 1 );
} }
} /* gi_readFromStream */ } /* gi_readFromStream */
@ -476,7 +478,6 @@ gi_writeToStream( XWStreamCtxt* stream, const CurGameInfo* gi )
stream_putBits( stream, 4, gi->boardSize ); stream_putBits( stream, 4, gi->boardSize );
stream_putBits( stream, 2, gi->serverRole ); stream_putBits( stream, 2, gi->serverRole );
stream_putBits( stream, 1, gi->hintsNotAllowed ); stream_putBits( stream, 1, gi->hintsNotAllowed );
stream_putBits( stream, 2, gi->robotSmartness );
stream_putBits( stream, 2, gi->phoniesAction ); stream_putBits( stream, 2, gi->phoniesAction );
stream_putBits( stream, 1, gi->timerEnabled ); stream_putBits( stream, 1, gi->timerEnabled );
stream_putBits( stream, 1, gi->allowPickTiles ); stream_putBits( stream, 1, gi->allowPickTiles );
@ -491,7 +492,7 @@ gi_writeToStream( XWStreamCtxt* stream, const CurGameInfo* gi )
stringToStream( stream, pl->name ); stringToStream( stream, pl->name );
stringToStream( stream, pl->password ); stringToStream( stream, pl->password );
stream_putU16( stream, pl->secondsUsed ); stream_putU16( stream, pl->secondsUsed );
stream_putBits( stream, 1, pl->isRobot ); stream_putU8( stream, pl->robotIQ );
stream_putBits( stream, 1, pl->isLocal ); stream_putBits( stream, 1, pl->isLocal );
} }
} /* gi_writeToStream */ } /* gi_writeToStream */

View file

@ -31,6 +31,7 @@
extern "C" { extern "C" {
#endif #endif
#define STREAM_VERS_ROBOTIQ 0x0E /* robots have different smarts */
#define STREAM_VERS_DICTLANG 0x0D /* save dict lang code in CurGameInfo */ #define STREAM_VERS_DICTLANG 0x0D /* save dict lang code in CurGameInfo */
#define STREAM_VERS_NUNDONE 0x0C /* save undone tile in model */ #define STREAM_VERS_NUNDONE 0x0C /* save undone tile in model */
#define STREAM_VERS_GAMESECONDS 0x0B /* save gameSeconds whether or not #define STREAM_VERS_GAMESECONDS 0x0B /* save gameSeconds whether or not
@ -48,16 +49,20 @@ extern "C" {
#define STREAM_VERS_41B4 0x02 #define STREAM_VERS_41B4 0x02
#define STREAM_VERS_405 0x01 #define STREAM_VERS_405 0x01
#define CUR_STREAM_VERS STREAM_VERS_DICTLANG #define CUR_STREAM_VERS STREAM_VERS_ROBOTIQ
typedef struct LocalPlayer { typedef struct LocalPlayer {
XP_UCHAR* name; XP_UCHAR* name;
XP_UCHAR* password; XP_UCHAR* password;
XP_U16 secondsUsed; XP_U16 secondsUsed;
XP_Bool isRobot;
XP_Bool isLocal; XP_Bool isLocal;
XP_U8 robotIQ; /* 0 means not a robot; 1-100 means how
dumb is it with 1 meaning very smart */
} LocalPlayer; } LocalPlayer;
#define LP_IS_ROBOT(lp) ((lp)->robotIQ != 0)
#define LP_IS_LOCAL(lp) ((lp)->isLocal)
#define DUMB_ROBOT 0 #define DUMB_ROBOT 0
#define SMART_ROBOT 1 #define SMART_ROBOT 1
@ -75,7 +80,6 @@ typedef struct CurGameInfo {
XP_Bool timerEnabled; XP_Bool timerEnabled;
XP_Bool allowPickTiles; XP_Bool allowPickTiles;
XP_Bool allowHintRect; XP_Bool allowHintRect;
XP_U8 robotSmartness;
XWPhoniesChoice phoniesAction; XWPhoniesChoice phoniesAction;
XP_Bool confirmBTConnect; /* only used for BT */ XP_Bool confirmBTConnect; /* only used for BT */
} CurGameInfo; } CurGameInfo;

View file

@ -198,7 +198,7 @@ cpToLP( NGValue value, const void* cbClosure )
strAddr = &lp->password; strAddr = &lp->password;
break; break;
case NG_COL_ROBOT: case NG_COL_ROBOT:
lp->isRobot = value.ng_bool; lp->robotIQ = value.ng_bool ? 1 : 0;
break; break;
} }
@ -591,7 +591,7 @@ loadPlayer( NewGameCtx* ngc, XP_U16 player, const LocalPlayer* lp )
value.ng_cp = lp->password; value.ng_cp = lp->password;
(*ngc->setColProc)(closure, player, NG_COL_PASSWD, value ); (*ngc->setColProc)(closure, player, NG_COL_PASSWD, value );
value.ng_bool = lp->isRobot; value.ng_bool = LP_IS_ROBOT(lp);
(*ngc->setColProc)(closure, player, NG_COL_ROBOT, value ); (*ngc->setColProc)(closure, player, NG_COL_ROBOT, value );
} }

View file

@ -161,7 +161,7 @@ drawScoreBoard( BoardCtxt* board )
dp->dsi.name = emptyStringIfNull(lp->name); dp->dsi.name = emptyStringIfNull(lp->name);
dp->dsi.selected = board->trayVisState != TRAY_HIDDEN dp->dsi.selected = board->trayVisState != TRAY_HIDDEN
&& ii==selPlayer; && ii==selPlayer;
dp->dsi.isRobot = lp->isRobot; dp->dsi.isRobot = LP_IS_ROBOT(lp);
dp->dsi.isRemote = !lp->isLocal; dp->dsi.isRemote = !lp->isLocal;
dp->dsi.nTilesLeft = (nTilesInPool > 0)? -1: dp->dsi.nTilesLeft = (nTilesInPool > 0)? -1:
model_getNumTilesTotal( model, ii ); model_getNumTilesTotal( model, ii );

View file

@ -45,9 +45,6 @@ extern "C" {
#define LOCAL_ADDR NULL #define LOCAL_ADDR NULL
#define IS_ROBOT(p) ((p)->isRobot)
#define IS_LOCAL(p) ((p)->isLocal)
enum { enum {
END_REASON_USER_REQUEST, END_REASON_USER_REQUEST,
END_REASON_OUT_OF_TILES, END_REASON_OUT_OF_TILES,
@ -309,7 +306,6 @@ server_makeFromStream( MPFORMAL XWStreamCtxt* stream, ModelCtxt* model,
{ {
ServerCtxt* server; ServerCtxt* server;
short i; short i;
CurGameInfo* gi = util->gameInfo;
server = server_make( MPPARM(mpool) model, comms, util ); server = server_make( MPPARM(mpool) model, comms, util );
getNV( stream, &server->nv, nPlayers ); getNV( stream, &server->nv, nPlayers );
@ -324,10 +320,8 @@ server_makeFromStream( MPFORMAL XWStreamCtxt* stream, ModelCtxt* model,
player->deviceIndex = stream_getU8( stream ); player->deviceIndex = stream_getU8( stream );
if ( stream_getU8( stream ) != 0 ) { if ( stream_getU8( stream ) != 0 ) {
LocalPlayer* lp = &gi->players[i];
player->engine = engine_makeFromStream( MPPARM(mpool) player->engine = engine_makeFromStream( MPPARM(mpool)
stream, util, stream, util );
lp->isRobot );
} }
} }
@ -504,7 +498,7 @@ server_initClientConnection( ServerCtxt* server, XWStreamCtxt* stream )
continue; continue;
} }
stream_putBits( stream, 1, lp->isRobot ); /* better not to send this */ stream_putBits( stream, 1, LP_IS_ROBOT(lp) ); /* better not to send this */
/* The first nPlayers players are the ones we'll use. The local flag /* The first nPlayers players are the ones we'll use. The local flag
doesn't matter when for SERVER_ISCLIENT. */ doesn't matter when for SERVER_ISCLIENT. */
@ -635,43 +629,6 @@ robotTradeTiles( ServerCtxt* server, MoveInfo* newMove )
} /* robotTradeTiles */ } /* robotTradeTiles */
#endif #endif
#define FUDGE_RANGE 10
#define MINIMUM_SCORE 5
static XP_U16
figureTargetScore( ServerCtxt* server, XP_U16 turn )
{
XP_S16 result = 1000;
XP_S16 highScore = 0;
ModelCtxt* model = server->vol.model;
XP_U16 nPlayers = server->vol.gi->nPlayers;
XP_U16 i;
XP_ASSERT( IS_ROBOT(&server->vol.gi->players[turn]) );
if ( 1 /* server->nHumanPlayers > 0 */ ) {
result = 0;
/* find the highest score anybody but the current player has */
for ( i = 0; i < nPlayers; ++i ) {
if ( i != turn ) {
XP_S16 score = model_getPlayerScore( model, i );
XP_ASSERT( score >= 0 );
if ( highScore < score ) {
highScore = score;
}
}
}
result = (XP_S16)(highScore - model_getPlayerScore( model, turn )
+ (FUDGE_RANGE-(XP_RANDOM() % (FUDGE_RANGE*2))));
if ( result < 0 ) {
result = MINIMUM_SCORE;
}
}
return result;
} /* figureTargetScore */
static XWStreamCtxt* static XWStreamCtxt*
mkServerStream( ServerCtxt* server ) mkServerStream( ServerCtxt* server )
{ {
@ -697,7 +654,6 @@ makeRobotMove( ServerCtxt* server )
XP_Bool timerEnabled = gi->timerEnabled; XP_Bool timerEnabled = gi->timerEnabled;
XP_Bool canMove; XP_Bool canMove;
XP_U32 time = 0L; /* stupid compiler.... */ XP_U32 time = 0L; /* stupid compiler.... */
XP_U16 targetScore = NO_SCORE_LIMIT;
XW_UtilCtxt* util = server->vol.util; XW_UtilCtxt* util = server->vol.util;
if ( timerEnabled ) { if ( timerEnabled ) {
@ -715,10 +671,6 @@ makeRobotMove( ServerCtxt* server )
tileSet = model_getPlayerTiles( model, turn ); tileSet = model_getPlayerTiles( model, turn );
if ( gi->robotSmartness == DUMB_ROBOT ) {
targetScore = figureTargetScore( server, turn );
}
XP_ASSERT( !!server_getEngineFor( server, turn ) ); XP_ASSERT( !!server_getEngineFor( server, turn ) );
searchComplete = engine_findMove( server_getEngineFor( server, turn ), searchComplete = engine_findMove( server_getEngineFor( server, turn ),
model, model_getDictionary( model ), model, model_getDictionary( model ),
@ -726,7 +678,8 @@ makeRobotMove( ServerCtxt* server )
#ifdef XWFEATURE_SEARCHLIMIT #ifdef XWFEATURE_SEARCHLIMIT
NULL, XP_FALSE, NULL, XP_FALSE,
#endif #endif
targetScore, &canMove, &newMove ); server->vol.gi->players[turn].robotIQ,
&canMove, &newMove );
if ( searchComplete ) { if ( searchComplete ) {
const XP_UCHAR* str; const XP_UCHAR* str;
XWStreamCtxt* stream = NULL; XWStreamCtxt* stream = NULL;
@ -806,7 +759,7 @@ robotMovePending( const ServerCtxt* server )
if ( turn >= 0 && tileCountsOk(server) && NPASSES_OK(server) ) { if ( turn >= 0 && tileCountsOk(server) && NPASSES_OK(server) ) {
CurGameInfo* gi = server->vol.gi; CurGameInfo* gi = server->vol.gi;
LocalPlayer* player = &gi->players[turn]; LocalPlayer* player = &gi->players[turn];
result = IS_ROBOT(player) && IS_LOCAL(player); result = LP_IS_ROBOT(player) && LP_IS_LOCAL(player);
} }
return result; return result;
} /* robotMovePending */ } /* robotMovePending */
@ -852,8 +805,8 @@ showPrevScore( ServerCtxt* server )
prevTurn = (server->nv.currentTurn + nPlayers - 1) % nPlayers; prevTurn = (server->nv.currentTurn + nPlayers - 1) % nPlayers;
lp = &gi->players[prevTurn]; lp = &gi->players[prevTurn];
wasRobot = lp->isRobot; wasRobot = LP_IS_ROBOT(lp);
wasLocal = lp->isLocal; wasLocal = LP_IS_LOCAL(lp);
if ( wasLocal ) { if ( wasLocal ) {
XP_ASSERT( wasRobot ); XP_ASSERT( wasRobot );
@ -1023,7 +976,7 @@ registerRemotePlayer( ServerCtxt* server, XWStreamCtxt* stream )
lp = findFirstPending( server, &player ); lp = findFirstPending( server, &player );
/* get data from stream */ /* get data from stream */
lp->isRobot = stream_getBits( stream, 1 ); lp->robotIQ = 1 == stream_getBits( stream, 1 )? 1 : 0;
nameLen = stream_getBits( stream, NAME_LEN_NBITS ); nameLen = stream_getBits( stream, NAME_LEN_NBITS );
name = (XP_UCHAR*)XP_MALLOC( server->mpool, nameLen + 1 ); name = (XP_UCHAR*)XP_MALLOC( server->mpool, nameLen + 1 );
stream_getBytes( stream, name, nameLen ); stream_getBytes( stream, name, nameLen );
@ -1060,8 +1013,8 @@ clearLocalRobots( ServerCtxt* server )
for ( i = 0; i < nPlayers; ++i ) { for ( i = 0; i < nPlayers; ++i ) {
LocalPlayer* player = &gi->players[i]; LocalPlayer* player = &gi->players[i];
if ( IS_LOCAL( player ) ) { if ( LP_IS_LOCAL( player ) ) {
player->isRobot = XP_FALSE; player->robotIQ = 0;
} }
} }
} /* clearLocalRobots */ } /* clearLocalRobots */
@ -1409,8 +1362,7 @@ server_getEngineFor( ServerCtxt* server, XP_U16 playerNum )
engine = player->engine; engine = player->engine;
if ( !engine && server->vol.gi->players[playerNum].isLocal ) { if ( !engine && server->vol.gi->players[playerNum].isLocal ) {
engine = engine_make( MPPARM(server->mpool) engine = engine_make( MPPARM(server->mpool)
server->vol.util, server->vol.util );
server->vol.gi->players[playerNum].isRobot );
player->engine = engine; player->engine = engine;
} }
@ -1542,7 +1494,7 @@ fetchTiles( ServerCtxt* server, XP_U16 playerNum, XP_U16 nToFetch,
XP_ASSERT( !!pool ); XP_ASSERT( !!pool );
#ifdef FEATURE_TRAY_EDIT #ifdef FEATURE_TRAY_EDIT
ask = server->vol.gi->allowPickTiles ask = server->vol.gi->allowPickTiles
&& !server->vol.gi->players[playerNum].isRobot; && !LP_IS_ROBOT(&server->vol.gi->players[playerNum]);
#else #else
ask = XP_FALSE; ask = XP_FALSE;
#endif #endif
@ -2060,7 +2012,7 @@ server_commitMove( ServerCtxt* server )
XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT; XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT;
#ifdef DEBUG #ifdef DEBUG
if ( IS_ROBOT( &gi->players[turn] ) ) { if ( LP_IS_ROBOT( &gi->players[turn] ) ) {
XP_ASSERT( model_checkMoveLegal( model, turn, (XWStreamCtxt*)NULL, XP_ASSERT( model_checkMoveLegal( model, turn, (XWStreamCtxt*)NULL,
(WordNotifierInfo*)NULL ) ); (WordNotifierInfo*)NULL ) );
} }
@ -2388,7 +2340,7 @@ server_handleUndo( ServerCtxt* server )
++nUndone; ++nUndone;
XP_ASSERT( moveNum >= 0 ); XP_ASSERT( moveNum >= 0 );
lastUndone = moveNum; lastUndone = moveNum;
if ( !IS_ROBOT(&gi->players[lastTurnUndone]) ) { if ( !LP_IS_ROBOT(&gi->players[lastTurnUndone]) ) {
break; break;
} }
} }

View file

@ -372,7 +372,6 @@ static XP_Bool
handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider ) handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider )
{ {
XP_Bool result = XP_FALSE; XP_Bool result = XP_FALSE;
const XP_U16 selPlayer = board->selPlayer;
PerTurnInfo* pti = board->selInfo; PerTurnInfo* pti = board->selInfo;
if ( onDivider ) { if ( onDivider ) {
@ -387,6 +386,7 @@ handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider )
} }
} else if ( index >= 0 ) { } else if ( index >= 0 ) {
result = moveTileToArrowLoc( board, (XP_U8)index ); result = moveTileToArrowLoc( board, (XP_U8)index );
#ifndef DISABLE_TILE_SEL
if ( !result ) { if ( !result ) {
TileBit newBits = 1 << index; TileBit newBits = 1 << index;
XP_U8 selBits = pti->traySelBits; XP_U8 selBits = pti->traySelBits;
@ -398,7 +398,7 @@ handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider )
pti->traySelBits = NO_TILES; pti->traySelBits = NO_TILES;
} else if ( selBits != 0 ) { } else if ( selBits != 0 ) {
XP_U16 selIndex = indexForBits( selBits ); XP_U16 selIndex = indexForBits( selBits );
model_moveTileOnTray( board->model, selPlayer, model_moveTileOnTray( board->model, board->selPlayer,
selIndex, index ); selIndex, index );
pti->traySelBits = NO_TILES; pti->traySelBits = NO_TILES;
} else { } else {
@ -410,6 +410,7 @@ handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider )
pti->dividerSelected = XP_FALSE; pti->dividerSelected = XP_FALSE;
result = XP_TRUE; result = XP_TRUE;
} }
#endif
} else if ( index == -(MAX_TRAY_TILES) ) { /* pending score tile */ } else if ( index == -(MAX_TRAY_TILES) ) { /* pending score tile */
result = board_commitTurn( board ); result = board_commitTurn( board );
#ifndef DISABLE_EMPTYTRAY_UNDO #ifndef DISABLE_EMPTYTRAY_UNDO

View file

@ -1,4 +1,4 @@
# -*-mode: Makefile; compile-command: "make -f Makefile.BasEnglish"; -*- # -*-mode: Makefile; -*-
# Copyright 2002-2010 by Eric House (xwords@eehouse.org). All rights # Copyright 2002-2010 by Eric House (xwords@eehouse.org). All rights
# reserved. # reserved.
# #
@ -27,11 +27,8 @@ TARGET_TYPE ?= WINCE
include ../Makefile.langcommon include ../Makefile.langcommon
# Empty dict # Empty dict
$(XWLANG)Main.dict: $(XWLANG)Main.dict.gz:
> $@ echo -n "" | gzip -c > $@
$(XWLANG)Main.dict.gz: $(XWLANG)Main.dict
gzip -c $< > $@
# Everything but creating of the Main.dict file is inherited from the # Everything but creating of the Main.dict file is inherited from the
# "parent" Makefile.langcommon in the parent directory. # "parent" Makefile.langcommon in the parent directory.

View file

@ -1,4 +1,4 @@
# -*- mode: makefile -*- # -*- coding: utf-8; -*-
# Copyright 2002-2007 by Eric House (xwords@eehouse.org). All rights reserved. # Copyright 2002-2007 by Eric House (xwords@eehouse.org). All rights reserved.
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
@ -15,21 +15,23 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
XWLANG=Russian XWLANG = Russian
LANGCODE=ru_RU LANGCODE = ru_RU
ENC = UTF-8
DICT2DAWGARGS = -r DICT2DAWGARGS = -r
TARGET_TYPE ?= WINCE TARGET_TYPE ?= WINCE
include ../Makefile.langcommon include ../Makefile.langcommon
SOURCEDICT ?= $(XWDICTPATH)/$(XWLANG)/RU5000.txt.gz SOURCEDICT ?= $(XWDICTPATH)/Russian/RU5000.txt.gz
$(XWLANG)Main.dict.gz: $(SOURCEDICT) Makefile $(XWLANG)Main.dict.gz: $(SOURCEDICT) Makefile
zcat $< | tr -d '\r' | \ zcat $< | tr -d '\r' | \
tr [àáâãäåæçèéêëìíîïğñòóôõö÷øùÚûüışÿ] [ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞß] | \ iconv -f ISO_8859-2 -t utf8 | \
gzip -c > $@ sed 's,.,\U\0,g' | \
grep '^[ŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢß]*$$' | \
gzip -c > $@
# Everything but creating of the Main.dict file is inherited from the # Everything but creating of the Main.dict file is inherited from the
# "parent" Makefile.langcommon in the parent directory. # "parent" Makefile.langcommon in the parent directory.

View file

@ -1,3 +1,4 @@
# -*- mode: conf; coding: utf-8; -*-
# Copyright 2002,2007 by Eric House (xwords@eehouse.org). All rights # Copyright 2002,2007 by Eric House (xwords@eehouse.org). All rights
# reserved. # reserved.
# #
@ -21,56 +22,54 @@ CHARSET:windows-1251
# deal with DOS files # deal with DOS files
LANGFILTER: tr -d '\r' LANGFILTER: tr -d '\r'
# uppercase all # uppercase all
LANGFILTER: | tr [àáâãäåæçèéêëìíîïðñòóôõö÷øùÚûüýþÿ] [ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß] LANGFILTER: | tr [ŕáâăäĺćçčéęëěíîďđńňóôőö÷řůÚűüýţ˙] [ŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢß]
# LANGFILTER: | tr -s '\n' '\000' # LANGFILTER: | tr -s '\n' '\000'
# note: don't turn off sorting! Can't do it with GNU 'sort' without # note: don't turn off sorting! Can't do it with GNU 'sort' without
# setting LANG # setting LANG
D2DARGS: -r -term 10 D2DARGS: -r -term 10
LANGINFO: <p>Russian wordlists must be in the Windows-1251 LANGINFO: <p>Russian wordlists must be in utf-8: codepage. Lower-case
LANGINFO: codepage. Lower-case letters are converted to upper case and LANGINFO: letters are converted to upper case and any words that
LANGINFO: any words that contain letters not listed below are LANGINFO: contain letters not listed below are removed.</p>
LANGINFO: removed.</p>
# High bit means "official". Next 7 bits are an enum where # High bit means "official". Next 7 bits are an enum where
# Russian==0x0F. Low byte is padding. # Russian==0x0F. Low byte is padding.
XLOC_HEADER:0x8F00 XLOC_HEADER:0x8F00
<BEGIN_TILES> <BEGIN_TILES>
8 1 'À' 8 1 'Ŕ'
2 3 'Á' 2 3 'Á'
4 1 'Â' 4 1 'Â'
2 3 'Ã' 2 3 'Ă'
2 2 'Ä' 2 2 'Ä'
7 1 'Å' 7 1 'Ĺ'
1 4 'Æ' 1 4 'Ć'
1 3 'Ç' 1 3 'Ç'
7 1 'È' 7 1 'Č'
1 2 'É' 1 2 'É'
4 2 'Ê' 4 2 'Ę'
4 2 'Ë' 4 2 'Ë'
2 3 'Ì' 2 3 'Ě'
4 1 'Í' 4 1 'Í'
9 1 'Î' 9 1 'Î'
4 2 'Ï' 4 2 'Ď'
5 1 'Ð' 5 1 'Đ'
5 1 'Ñ' 5 1 'Ń'
7 1 'Ò' 7 1 'Ň'
4 2 'Ó' 4 2 'Ó'
1 5 'Ô' 1 5 'Ô'
1 4 'Õ' 1 4 'Ő'
1 4 'Ö' 1 4 'Ö'
1 3 '×' 1 3 '×'
1 4 'Ø' 1 4 'Ř'
1 5 'Ù' 1 5 'Ů'
1 10 'Ú' 1 10 'Ú'
2 2 'Û' 2 2 'Ű'
4 1 'Ü' 4 1 'Ü'
1 8 'Ý' 1 8 'Ý'
1 5 'Þ' 1 5 'Ţ'
2 2 'ß' 2 2 'ß'
2 0 {"_"} 2 0 {"_"}
<END_TILES> <END_TILES>
# should ignore all after the <END_TILES> above # should ignore all after the <END_TILES> above

View file

@ -10,12 +10,12 @@ usage() {
do_lang() { do_lang() {
LANG=$1 LANG=$1
echo "<tr><td>$LANG</td></tr>" echo "<tr><td><a name=\"$LANG\">$LANG</a></td></tr>"
cd $LANG cd $LANG
for DICT in $(ls *.xwd); do for DICT in $(ls *.xwd); do
echo "<tr>" echo "<tr>"
echo "<td><a href=\"./$LANG/$DICT\">${DICT#.xwd}</a></td>" echo "<td>&nbsp;&nbsp;<a href=\"./$LANG/$DICT\">${DICT%.xwd}</a></td>"
SIZE=$(ls -l $DICT | awk '{print $5}') SIZE=$(ls -l $DICT | awk '{print $5}')
echo "<td>${SIZE}</td>" echo "<td>${SIZE}</td>"
HEXCOUNT=$(hd $DICT | head -n 1 | awk '{print $6 $7 $8 $9}' | tr [a-f] [A-F]) HEXCOUNT=$(hd $DICT | head -n 1 | awk '{print $6 $7 $8 $9}' | tr [a-f] [A-F])
@ -41,14 +41,21 @@ done
echo "<html><body>" echo "<html><body>"
echo "<p>Download dictionaries for:"
for DIR in $DIRS; do
echo " <a href=\"#$DIR\">$DIR</a>"
done
echo ".</p>"
echo "<table>" echo "<table>"
echo "<tr><th>File</th><th>Size</th><th>Wordcount</th></tr>" echo "<tr><th>File</th><th>Size</th><th>Wordcount</th></tr>"
for DIR in $DIRS; do for DIR in $DIRS; do
do_lang $DIR do_lang $DIR
done done
echo "</table>" echo "</table>"
echo "</body></html>"
echo "</body></html>"
cd $WD cd $WD

View file

@ -75,7 +75,7 @@ endif
include ../common/config.mk include ../common/config.mk
DEFINES += -DPLATFORM_LINUX -DKEY_SUPPORT -DKEYBOARD_NAV -DNODE_CAN_4 \ DEFINES += -DPLATFORM_LINUX -DKEY_SUPPORT -DKEYBOARD_NAV -DNODE_CAN_4 \
-DSCROLL_DRAG_THRESHHOLD=1 -DSCROLL_DRAG_THRESHHOLD=1 -DNUM_SAVED_ENGINE_MOVES=32
# DEFINES += -DSTUBBED_DICT # DEFINES += -DSTUBBED_DICT
ifdef DO_GTK ifdef DO_GTK
DEFINES += -DXWFEATURE_SEARCHLIMIT DEFINES += -DXWFEATURE_SEARCHLIMIT

View file

@ -22,6 +22,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#undef GDK_DISABLE_DEPRECATED
#include <gdk/gdkdrawable.h> #include <gdk/gdkdrawable.h>
#include "gtkmain.h" #include "gtkmain.h"

View file

@ -195,7 +195,6 @@ typedef enum {
,CMD_PRINTHISORY ,CMD_PRINTHISORY
,CMD_SKIPWARNINGS ,CMD_SKIPWARNINGS
,CMD_LOCALPWD ,CMD_LOCALPWD
,CMD_ROBOTSANDBAGS /* dumb robot */
,CMD_DUPPACKETS ,CMD_DUPPACKETS
,CMD_NOHINTS ,CMD_NOHINTS
,CMD_PICKTILESFACEUP ,CMD_PICKTILESFACEUP
@ -203,6 +202,7 @@ typedef enum {
,CMD_REMOTEPLAYER ,CMD_REMOTEPLAYER
,CMD_PORT ,CMD_PORT
,CMD_ROBOTNAME ,CMD_ROBOTNAME
,CMD_LOCALSMARTS
,CMD_SORTNEW ,CMD_SORTNEW
,CMD_ISSERVER ,CMD_ISSERVER
,CMD_SLEEPONANCHOR ,CMD_SLEEPONANCHOR
@ -262,14 +262,14 @@ static CmdInfoRec CmdInfoRecs[] = {
,{ CMD_PRINTHISORY, false, "print-history", "print history on game over" } ,{ CMD_PRINTHISORY, false, "print-history", "print history on game over" }
,{ CMD_SKIPWARNINGS, false, "skip-warnings", "no modals on phonies" } ,{ CMD_SKIPWARNINGS, false, "skip-warnings", "no modals on phonies" }
,{ CMD_LOCALPWD, true, "password", "password for user (in sequence)" } ,{ CMD_LOCALPWD, true, "password", "password for user (in sequence)" }
,{ CMD_ROBOTSANDBAGS, false, "dumb-robot", "robot keeps score close" }
,{ CMD_DUPPACKETS, false, "dup-packets", "send two of each to test dropping" } ,{ CMD_DUPPACKETS, false, "dup-packets", "send two of each to test dropping" }
,{ CMD_NOHINTS, false, "no-hints", "disallow hints" } ,{ CMD_NOHINTS, false, "no-hints", "disallow hints" }
,{ CMD_PICKTILESFACEUP, false, "pick-face-up", "allow to pick tiles" } ,{ CMD_PICKTILESFACEUP, false, "pick-face-up", "allow to pick tiles" }
,{ CMD_PLAYERNAME, true, "name", "name of local, non-robot player" } ,{ CMD_PLAYERNAME, true, "name", "name of local, non-robot player" }
,{ CMD_REMOTEPLAYER, false, "remote-player", "add an expected player" } ,{ CMD_REMOTEPLAYER, false, "remote-player", "add an expected player" }
,{ CMD_PORT, true, "port", "port to connect to on host" } ,{ CMD_PORT, true, "port", "port to connect to on host" }
,{ CMD_ROBOTNAME, true, "robot-name", "name of local, robot player" } ,{ CMD_ROBOTNAME, true, "robot", "name of local, robot player" }
,{ CMD_LOCALSMARTS, true, "robot-iq", "smarts for robot (in sequence)" }
,{ CMD_SORTNEW, false, "sort-tiles", "sort tiles each time assigned" } ,{ CMD_SORTNEW, false, "sort-tiles", "sort tiles each time assigned" }
,{ CMD_ISSERVER, false, "server", "this device acting as host" } ,{ CMD_ISSERVER, false, "server", "this device acting as host" }
,{ CMD_SLEEPONANCHOR, false, "sleep-on-anchor", "slow down hint progress" } ,{ CMD_SLEEPONANCHOR, false, "sleep-on-anchor", "slow down hint progress" }
@ -298,7 +298,7 @@ static CmdInfoRec CmdInfoRecs[] = {
,{ CMD_BTADDR, true, "btaddr", "bluetooth address of host" } ,{ CMD_BTADDR, true, "btaddr", "bluetooth address of host" }
#endif #endif
#ifdef XWFEATURE_SLOW_ROBOT #ifdef XWFEATURE_SLOW_ROBOT
,{ CMD_SLOWROBOT, true, "slow-robot", "make robot slower" } ,{ CMD_SLOWROBOT, true, "slow-robot", "make robot slower to test network" }
#endif #endif
#if defined PLATFORM_GTK && defined PLATFORM_NCURSES #if defined PLATFORM_GTK && defined PLATFORM_NCURSES
,{ CMD_GTK, false, "gtk", "use GTK for display" } ,{ CMD_GTK, false, "gtk", "use GTK for display" }
@ -335,7 +335,7 @@ usage( char* appName, char* msg )
fprintf( stderr, "usage: %s \n", appName ); fprintf( stderr, "usage: %s \n", appName );
for ( ii = 0; ii < VSIZE(CmdInfoRecs); ++ii ) { for ( ii = 0; ii < VSIZE(CmdInfoRecs); ++ii ) {
const CmdInfoRec* rec = &CmdInfoRecs[ii]; const CmdInfoRec* rec = &CmdInfoRecs[ii];
fprintf( stderr, " --%s %s # %s\n", rec->param, fprintf( stderr, " --%s %-20s # %s\n", rec->param,
rec->hasArg? "<param>" : "", rec->hint ); rec->hasArg? "<param>" : "", rec->hint );
} }
fprintf( stderr, "\n(revision: %s)\n", SVN_REV); fprintf( stderr, "\n(revision: %s)\n", SVN_REV);
@ -862,7 +862,6 @@ main( int argc, char** argv )
mainParams.printHistory = XP_FALSE; mainParams.printHistory = XP_FALSE;
mainParams.undoWhenDone = XP_FALSE; mainParams.undoWhenDone = XP_FALSE;
mainParams.gi.timerEnabled = XP_FALSE; mainParams.gi.timerEnabled = XP_FALSE;
mainParams.gi.robotSmartness = SMART_ROBOT;
mainParams.gi.dictLang = -1; mainParams.gi.dictLang = -1;
mainParams.noHeartbeat = XP_FALSE; mainParams.noHeartbeat = XP_FALSE;
mainParams.nHidden = 0; mainParams.nHidden = 0;
@ -937,6 +936,11 @@ main( int argc, char** argv )
mainParams.gi.players[mainParams.nLocalPlayers-1].password mainParams.gi.players[mainParams.nLocalPlayers-1].password
= (XP_UCHAR*)optarg; = (XP_UCHAR*)optarg;
break; break;
case CMD_LOCALSMARTS:
index = mainParams.gi.nPlayers - 1;
XP_ASSERT( LP_IS_ROBOT( &mainParams.gi.players[index] ) );
mainParams.gi.players[index].robotIQ = atoi(optarg);
break;
#ifdef XWFEATURE_SMS #ifdef XWFEATURE_SMS
case CMD_SMSNUMBER: /* SMS phone number */ case CMD_SMSNUMBER: /* SMS phone number */
XP_ASSERT( COMMS_CONN_NONE == conType ); XP_ASSERT( COMMS_CONN_NONE == conType );
@ -944,9 +948,6 @@ main( int argc, char** argv )
conType = COMMS_CONN_SMS; conType = COMMS_CONN_SMS;
break; break;
#endif #endif
case CMD_ROBOTSANDBAGS: /* dumb robot */
mainParams.gi.robotSmartness = DUMB_ROBOT;
break;
case CMD_DUPPACKETS: case CMD_DUPPACKETS:
mainParams.duplicatePackets = XP_TRUE; mainParams.duplicatePackets = XP_TRUE;
break; break;
@ -959,7 +960,7 @@ main( int argc, char** argv )
case CMD_PLAYERNAME: case CMD_PLAYERNAME:
index = mainParams.gi.nPlayers++; index = mainParams.gi.nPlayers++;
++mainParams.nLocalPlayers; ++mainParams.nLocalPlayers;
mainParams.gi.players[index].isRobot = XP_FALSE; mainParams.gi.players[index].robotIQ = 0; /* means human */
mainParams.gi.players[index].isLocal = XP_TRUE; mainParams.gi.players[index].isLocal = XP_TRUE;
mainParams.gi.players[index].name = mainParams.gi.players[index].name =
copyString( mainParams.util->mpool, (XP_UCHAR*)optarg); copyString( mainParams.util->mpool, (XP_UCHAR*)optarg);
@ -977,7 +978,7 @@ main( int argc, char** argv )
++robotCount; ++robotCount;
index = mainParams.gi.nPlayers++; index = mainParams.gi.nPlayers++;
++mainParams.nLocalPlayers; ++mainParams.nLocalPlayers;
mainParams.gi.players[index].isRobot = XP_TRUE; mainParams.gi.players[index].robotIQ = 1; /* real smart by default */
mainParams.gi.players[index].isLocal = XP_TRUE; mainParams.gi.players[index].isLocal = XP_TRUE;
mainParams.gi.players[index].name = mainParams.gi.players[index].name =
copyString( mainParams.util->mpool, (XP_UCHAR*)optarg); copyString( mainParams.util->mpool, (XP_UCHAR*)optarg);

View file

@ -35,6 +35,7 @@ declare -A CMDS
declare -A FILES declare -A FILES
declare -A LOGS declare -A LOGS
PLAT_PARMS=""
if [ $USE_GTK = FALSE ]; then if [ $USE_GTK = FALSE ]; then
PLAT_PARMS="--curses --close-stdin" PLAT_PARMS="--curses --close-stdin"
fi fi
@ -91,7 +92,8 @@ build_cmds() {
NDEVS=$(($RANDOM%3+2)) NDEVS=$(($RANDOM%3+2))
DICT=${DICTS_ARR[$((GAME%${#DICTS_ARR[*]}))]} DICT=${DICTS_ARR[$((GAME%${#DICTS_ARR[*]}))]}
# make one in three games public # make one in three games public
[ $((RANDOM%3)) -eq 0 ] && PUBLIC="--make-public --join-public" || PUBLIC="" PUBLIC=""
[ $((RANDOM%3)) -eq 0 ] && PUBLIC="--make-public --join-public"
OTHERS="" OTHERS=""
for II in $(seq 2 $NDEVS); do for II in $(seq 2 $NDEVS); do
@ -102,8 +104,10 @@ build_cmds() {
FILE="${LOGDIR}/GAME_${GAME}_${DEV}.xwg" FILE="${LOGDIR}/GAME_${GAME}_${DEV}.xwg"
LOG=${LOGDIR}/${GAME}_${DEV}_LOG.txt LOG=${LOGDIR}/${GAME}_${DEV}_LOG.txt
touch $LOG # so greps won't show errors touch $LOG # so greps won't show errors
CMD="./obj_linux_memdbg/xwords --room $ROOM --robot-name ${NAMES[$DEV]} $OTHERS" CMD="./obj_linux_memdbg/xwords --room $ROOM"
CMD="$CMD --dict $DICT --port $PORT --host $HOST --file $FILE --slow-robot 1:3 $PLAT_PARMS" CMD="$CMD --robot ${NAMES[$DEV]} --robot-iq=$((1 + (RANDOM%100))) "
CMD="$CMD $OTHERS --dict=$DICT --port=$PORT --host=$HOST "
CMD="$CMD --file=$FILE --slow-robot 1:3 $PLAT_PARMS"
CMD="$CMD $PUBLIC" CMD="$CMD $PUBLIC"
CMDS[$COUNTER]=$CMD CMDS[$COUNTER]=$CMD
FILES[$COUNTER]=$FILE FILES[$COUNTER]=$FILE

View file

@ -86,7 +86,6 @@ CookieRef::ReInit( const char* cookie, const char* connName, CookieID id,
m_cookie = cookie==NULL?"":cookie; m_cookie = cookie==NULL?"":cookie;
m_connName = connName==NULL?"":connName; m_connName = connName==NULL?"":connName;
m_cookieID = id; m_cookieID = id;
m_totalSent = 0;
m_curState = XWS_INITED; m_curState = XWS_INITED;
m_nPlayersSought = nPlayers; m_nPlayersSought = nPlayers;
m_nPlayersHere = nAlreadyHere; m_nPlayersHere = nAlreadyHere;
@ -132,9 +131,7 @@ CookieRef::~CookieRef()
printSeeds(__func__); printSeeds(__func__);
logf( XW_LOGINFO, logf( XW_LOGINFO, "CookieRef for %d being deleted", m_cookieID );
"CookieRef for %d being deleted; sent %d bytes over lifetime",
m_cookieID, m_totalSent );
} /* ~CookieRef */ } /* ~CookieRef */
void void
@ -729,7 +726,7 @@ CookieRef::send_with_length( int socket, unsigned char* buf, int bufLen,
{ {
bool failed = false; bool failed = false;
if ( send_with_length_unsafe( socket, buf, bufLen ) ) { if ( send_with_length_unsafe( socket, buf, bufLen ) ) {
RecordSent( bufLen, socket ); DBMgr::Get()->RecordSent( ConnName(), HostForSocket(socket), bufLen );
} else { } else {
failed = true; failed = true;
} }
@ -1006,13 +1003,6 @@ CookieRef::send_msg( int socket, HostID id, XWRelayMsg msg, XWREASON why,
send_with_length( socket, buf, len, cascade ); send_with_length( socket, buf, len, cascade );
} /* send_msg */ } /* send_msg */
void
CookieRef::RecordSent( int nBytes, int socket ) {
m_totalSent += nBytes;
DBMgr::Get()->RecordSent( ConnName(), HostForSocket(socket), nBytes );
}
void void
CookieRef::notifyOthers( int socket, XWRelayMsg msg, XWREASON why ) CookieRef::notifyOthers( int socket, XWRelayMsg msg, XWREASON why )
{ {
@ -1311,9 +1301,6 @@ CookieRef::_PrintCookieInfo( string& out )
snprintf( buf, sizeof(buf), "id=%d\n", GetCookieID() ); snprintf( buf, sizeof(buf), "id=%d\n", GetCookieID() );
out += buf; out += buf;
snprintf( buf, sizeof(buf), "Bytes sent=%d\n", m_totalSent );
out += buf;
snprintf( buf, sizeof(buf), "Total players=%d\n", m_nPlayersSought ); snprintf( buf, sizeof(buf), "Total players=%d\n", m_nPlayersSought );
out += buf; out += buf;
snprintf( buf, sizeof(buf), "Players here=%d\n", m_nPlayersHere ); snprintf( buf, sizeof(buf), "Players here=%d\n", m_nPlayersHere );

View file

@ -81,7 +81,6 @@ class CookieRef {
/* Within this cookie, remember that this hostID and socket go together. /* Within this cookie, remember that this hostID and socket go together.
If the hostID is HOST_ID_SERVER, it's the server. */ If the hostID is HOST_ID_SERVER, it's the server. */
CookieID GetCookieID() { return m_cookieID; } CookieID GetCookieID() { return m_cookieID; }
int GetTotalSent() { return m_totalSent; }
int GetPlayersSought() { return m_nPlayersSought; } int GetPlayersSought() { return m_nPlayersSought; }
int GetPlayersHere() { return m_nPlayersHere; } int GetPlayersHere() { return m_nPlayersHere; }
@ -181,7 +180,6 @@ class CookieRef {
bool cascade ); bool cascade );
void send_msg( int socket, HostID id, XWRelayMsg msg, XWREASON why, void send_msg( int socket, HostID id, XWRelayMsg msg, XWREASON why,
bool cascade ); bool cascade );
void RecordSent( int nBytes, int socket );
void pushConnectEvent( int socket, int nPlayersH, int nPlayersS, void pushConnectEvent( int socket, int nPlayersH, int nPlayersS,
int seed ); int seed );
void pushReconnectEvent( int socket, HostID srcID, void pushReconnectEvent( int socket, HostID srcID,
@ -258,7 +256,6 @@ class CookieRef {
string m_cookie; /* cookie used for initial connections */ string m_cookie; /* cookie used for initial connections */
string m_connName; /* globally unique name */ string m_connName; /* globally unique name */
CookieID m_cookieID; /* Unique among current games on this server */ CookieID m_cookieID; /* Unique among current games on this server */
int m_totalSent;
/* Guard the event queue. Only one thread at a time can post to the /* Guard the event queue. Only one thread at a time can post to the
queue, but once in a thread can post new events while processing queue, but once in a thread can post new events while processing

View file

@ -174,7 +174,6 @@ CRefMgr::GetStats( CrefMgrInfo& mgrInfo )
info.m_connName = cref->ConnName(); info.m_connName = cref->ConnName();
info.m_cookieID = cref->GetCookieID(); info.m_cookieID = cref->GetCookieID();
info.m_curState = cref->CurState(); info.m_curState = cref->CurState();
info.m_totalSent = cref->GetTotalSent();
info.m_nPlayersSought = cref->GetPlayersSought(); info.m_nPlayersSought = cref->GetPlayersSought();
info.m_nPlayersHere = cref->GetPlayersHere(); info.m_nPlayersHere = cref->GetPlayersHere();
info.m_startTime = cref->GetStarttime(); info.m_startTime = cref->GetStarttime();

View file

@ -50,7 +50,6 @@ class CrefInfo {
string m_cookie; string m_cookie;
string m_connName; string m_connName;
CookieID m_cookieID; CookieID m_cookieID;
int m_totalSent;
int m_nPlayersSought; int m_nPlayersSought;
int m_nPlayersHere; int m_nPlayersHere;
XW_RELAY_STATE m_curState; XW_RELAY_STATE m_curState;
@ -329,14 +328,6 @@ class SafeCref {
} }
} }
int GetTotalSent() {
if ( IsValid() ) {
return m_cref->GetTotalSent();
} else {
return -1; /* so don't crash.... */
}
}
int GetPlayersTotal() { int GetPlayersTotal() {
if ( IsValid() ) { if ( IsValid() ) {
return m_cref->GetPlayersSought(); return m_cref->GetPlayersSought();

View file

@ -152,7 +152,6 @@ printCrefs( FILE* fil, const CrefMgrInfo* info, bool isLocal )
"<td>%s</td>" /* conn name */ "<td>%s</td>" /* conn name */
"<td>%d</td>" /* cookie id */ "<td>%d</td>" /* cookie id */
"<td>%s</td>" /* conntime */ "<td>%s</td>" /* conntime */
"<td>%d</td>" /* total sent */
"<td>%d</td>" /* players */ "<td>%d</td>" /* players */
"<td>%d</td>" /* players here */ "<td>%d</td>" /* players here */
"<td>%s</td>" /* State */ "<td>%s</td>" /* State */
@ -164,7 +163,6 @@ printCrefs( FILE* fil, const CrefMgrInfo* info, bool isLocal )
crefInfo->m_connName.c_str(), crefInfo->m_connName.c_str(),
crefInfo->m_cookieID, crefInfo->m_cookieID,
conntime, conntime,
crefInfo->m_totalSent,
crefInfo->m_nPlayersSought, crefInfo->m_nPlayersHere, crefInfo->m_nPlayersSought, crefInfo->m_nPlayersHere,
stateString( crefInfo->m_curState ), stateString( crefInfo->m_curState ),
crefInfo->m_hostsIds.c_str(), crefInfo->m_hostsIds.c_str(),