mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-17 19:22:18 +01:00
DroidFish: Implemented setting of engine UCI options.
This commit is contained in:
@@ -118,5 +118,9 @@
|
|||||||
<activity android:name=".activities.CPUWarning"
|
<activity android:name=".activities.CPUWarning"
|
||||||
android:label="@string/cpu_warning_title">
|
android:label="@string/cpu_warning_title">
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
<activity android:name=".activities.EditOptions"
|
||||||
|
android:label="@string/edit_options_title"
|
||||||
|
android:configChanges="orientation">
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
38
DroidFish/res/layout-land/editoptions.xml
Normal file
38
DroidFish/res/layout-land/editoptions.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:baselineAligned="false">
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/eo_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<Button
|
||||||
|
android:text="@android:string/ok"
|
||||||
|
android:id="@+id/eo_ok"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1">
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
android:text="@string/cancel"
|
||||||
|
android:id="@+id/eo_cancel"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1">
|
||||||
|
</Button>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
37
DroidFish/res/layout/editoptions.xml
Normal file
37
DroidFish/res/layout/editoptions.xml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/eo_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<Button
|
||||||
|
android:text="@android:string/ok"
|
||||||
|
android:id="@+id/eo_ok"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1">
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
android:text="@string/cancel"
|
||||||
|
android:id="@+id/eo_cancel"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1">
|
||||||
|
</Button>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
5
DroidFish/res/layout/uci_option_button.xml
Normal file
5
DroidFish/res/layout/uci_option_button.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<ToggleButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/eo_label"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</ToggleButton>
|
||||||
5
DroidFish/res/layout/uci_option_check.xml
Normal file
5
DroidFish/res/layout/uci_option_check.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/eo_value"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</CheckBox>
|
||||||
15
DroidFish/res/layout/uci_option_combo.xml
Normal file
15
DroidFish/res/layout/uci_option_combo.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/eo_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</TextView>
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/eo_value"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1">
|
||||||
|
</Spinner>
|
||||||
|
</LinearLayout>
|
||||||
16
DroidFish/res/layout/uci_option_spin.xml
Normal file
16
DroidFish/res/layout/uci_option_spin.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent" >
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/eo_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</TextView>
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/eo_value"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:inputType="numberSigned">
|
||||||
|
</EditText>
|
||||||
|
</LinearLayout>
|
||||||
16
DroidFish/res/layout/uci_option_string.xml
Normal file
16
DroidFish/res/layout/uci_option_string.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent" >
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/eo_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</TextView>
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/eo_value"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:inputType="text">
|
||||||
|
</EditText>
|
||||||
|
</LinearLayout>
|
||||||
@@ -169,6 +169,7 @@ you are not actively using the program.\
|
|||||||
<string name="load_scid_game_title">Load Scid Game</string>
|
<string name="load_scid_game_title">Load Scid Game</string>
|
||||||
<string name="load_fen_title">Load Position</string>
|
<string name="load_fen_title">Load Position</string>
|
||||||
<string name="cpu_warning_title">CPU Warning</string>
|
<string name="cpu_warning_title">CPU Warning</string>
|
||||||
|
<string name="edit_options_title">UCI Options</string>
|
||||||
<string name="failed_to_read_pgn_data">Failed to read PGN data</string>
|
<string name="failed_to_read_pgn_data">Failed to read PGN data</string>
|
||||||
<string name="variation">Var:</string>
|
<string name="variation">Var:</string>
|
||||||
<string name="add_analysis">Add Analysis</string>
|
<string name="add_analysis">Add Analysis</string>
|
||||||
@@ -201,6 +202,7 @@ you are not actively using the program.\
|
|||||||
<string name="stockfish_engine">Stockfish</string>
|
<string name="stockfish_engine">Stockfish</string>
|
||||||
<string name="cuckoochess_engine">CuckooChess</string>
|
<string name="cuckoochess_engine">CuckooChess</string>
|
||||||
<string name="select_engine">Select Engine</string>
|
<string name="select_engine">Select Engine</string>
|
||||||
|
<string name="set_engine_options">Set options</string>
|
||||||
<string name="configure_network_engine">Configure Network Engine</string>
|
<string name="configure_network_engine">Configure Network Engine</string>
|
||||||
<string name="create_network_engine">Create Network Engine</string>
|
<string name="create_network_engine">Create Network Engine</string>
|
||||||
<string name="delete_network_engine">Delete Network Engine?</string>
|
<string name="delete_network_engine">Delete Network Engine?</string>
|
||||||
|
|||||||
@@ -30,11 +30,13 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import org.petero.droidfish.ChessBoard.SquareDecoration;
|
import org.petero.droidfish.ChessBoard.SquareDecoration;
|
||||||
import org.petero.droidfish.activities.CPUWarning;
|
import org.petero.droidfish.activities.CPUWarning;
|
||||||
import org.petero.droidfish.activities.EditBoard;
|
import org.petero.droidfish.activities.EditBoard;
|
||||||
|
import org.petero.droidfish.activities.EditOptions;
|
||||||
import org.petero.droidfish.activities.EditPGNLoad;
|
import org.petero.droidfish.activities.EditPGNLoad;
|
||||||
import org.petero.droidfish.activities.EditPGNSave;
|
import org.petero.droidfish.activities.EditPGNSave;
|
||||||
import org.petero.droidfish.activities.LoadFEN;
|
import org.petero.droidfish.activities.LoadFEN;
|
||||||
@@ -42,6 +44,7 @@ import org.petero.droidfish.activities.LoadScid;
|
|||||||
import org.petero.droidfish.activities.Preferences;
|
import org.petero.droidfish.activities.Preferences;
|
||||||
import org.petero.droidfish.book.BookOptions;
|
import org.petero.droidfish.book.BookOptions;
|
||||||
import org.petero.droidfish.engine.EngineUtil;
|
import org.petero.droidfish.engine.EngineUtil;
|
||||||
|
import org.petero.droidfish.engine.UCIOptions;
|
||||||
import org.petero.droidfish.gamelogic.DroidChessController;
|
import org.petero.droidfish.gamelogic.DroidChessController;
|
||||||
import org.petero.droidfish.gamelogic.ChessParseError;
|
import org.petero.droidfish.gamelogic.ChessParseError;
|
||||||
import org.petero.droidfish.gamelogic.Move;
|
import org.petero.droidfish.gamelogic.Move;
|
||||||
@@ -155,7 +158,6 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||||||
// FIXME!!! Handle PGN non-file intents with more than one game.
|
// FIXME!!! Handle PGN non-file intents with more than one game.
|
||||||
// FIXME!!! Save position to fen/epd file
|
// FIXME!!! Save position to fen/epd file
|
||||||
|
|
||||||
// FIXME!!! Strength setting for external engines
|
|
||||||
// FIXME!!! Selection dialog for going into variation
|
// FIXME!!! Selection dialog for going into variation
|
||||||
// FIXME!!! Use two engines in engine/engine games
|
// FIXME!!! Use two engines in engine/engine games
|
||||||
|
|
||||||
@@ -1275,6 +1277,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||||||
static private final int RESULT_OI_PGN_LOAD = 6;
|
static private final int RESULT_OI_PGN_LOAD = 6;
|
||||||
static private final int RESULT_OI_FEN_LOAD = 7;
|
static private final int RESULT_OI_FEN_LOAD = 7;
|
||||||
static private final int RESULT_GET_FEN = 8;
|
static private final int RESULT_GET_FEN = 8;
|
||||||
|
static private final int RESULT_EDITOPTIONS = 9;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
@@ -1326,6 +1329,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||||||
showDialog(SELECT_BOOK_DIALOG);
|
showDialog(SELECT_BOOK_DIALOG);
|
||||||
return true;
|
return true;
|
||||||
case R.id.manage_engines:
|
case R.id.manage_engines:
|
||||||
|
removeDialog(MANAGE_ENGINES_DIALOG);
|
||||||
showDialog(MANAGE_ENGINES_DIALOG);
|
showDialog(MANAGE_ENGINES_DIALOG);
|
||||||
return true;
|
return true;
|
||||||
case R.id.set_color_theme:
|
case R.id.set_color_theme:
|
||||||
@@ -1429,6 +1433,14 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||||||
setFenHelper(fen);
|
setFenHelper(fen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RESULT_EDITOPTIONS:
|
||||||
|
if (resultCode == RESULT_OK) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String,String> uciOpts =
|
||||||
|
(Map<String,String>)data.getSerializableExtra("org.petero.droidfish.ucioptions");
|
||||||
|
ctrl.setEngineUCIOptions(uciOpts);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2726,20 +2738,48 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Dialog manageEnginesDialog() {
|
private final Dialog manageEnginesDialog() {
|
||||||
final CharSequence[] items = {
|
final int SELECT_ENGINE = 0;
|
||||||
getString(R.string.select_engine),
|
final int SET_ENGINE_OPTIONS = 1;
|
||||||
getString(R.string.configure_network_engine)
|
final int CONFIG_NET_ENGINE = 2;
|
||||||
};
|
List<CharSequence> lst = new ArrayList<CharSequence>();
|
||||||
|
List<Integer> actions = new ArrayList<Integer>();
|
||||||
|
lst.add(getString(R.string.select_engine)); actions.add(SELECT_ENGINE);
|
||||||
|
if (ctrl.computerIdle()) {
|
||||||
|
UCIOptions uciOpts = ctrl.getUCIOptions();
|
||||||
|
if (uciOpts != null) {
|
||||||
|
boolean visible = false;
|
||||||
|
for (String name : uciOpts.getOptionNames())
|
||||||
|
if (uciOpts.getOption(name).visible) {
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (visible) {
|
||||||
|
lst.add(getString(R.string.set_engine_options));
|
||||||
|
actions.add(SET_ENGINE_OPTIONS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lst.add(getString(R.string.configure_network_engine)); actions.add(CONFIG_NET_ENGINE);
|
||||||
|
final List<Integer> finalActions = actions;
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(R.string.option_manage_engines);
|
builder.setTitle(R.string.option_manage_engines);
|
||||||
builder.setItems(items, new DialogInterface.OnClickListener() {
|
builder.setItems(lst.toArray(new CharSequence[lst.size()]), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int item) {
|
public void onClick(DialogInterface dialog, int item) {
|
||||||
switch (item) {
|
switch (finalActions.get(item)) {
|
||||||
case 0:
|
case SELECT_ENGINE:
|
||||||
removeDialog(SELECT_ENGINE_DIALOG);
|
removeDialog(SELECT_ENGINE_DIALOG);
|
||||||
showDialog(SELECT_ENGINE_DIALOG);
|
showDialog(SELECT_ENGINE_DIALOG);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case SET_ENGINE_OPTIONS: {
|
||||||
|
Intent i = new Intent(DroidFish.this, EditOptions.class);
|
||||||
|
UCIOptions uciOpts = ctrl.getUCIOptions();
|
||||||
|
if (uciOpts != null) {
|
||||||
|
i.putExtra("org.petero.droidfish.ucioptions", uciOpts);
|
||||||
|
startActivityForResult(i, RESULT_EDITOPTIONS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONFIG_NET_ENGINE:
|
||||||
removeDialog(NETWORK_ENGINE_DIALOG);
|
removeDialog(NETWORK_ENGINE_DIALOG);
|
||||||
showDialog(NETWORK_ENGINE_DIALOG);
|
showDialog(NETWORK_ENGINE_DIALOG);
|
||||||
break;
|
break;
|
||||||
|
|||||||
247
DroidFish/src/org/petero/droidfish/activities/EditOptions.java
Normal file
247
DroidFish/src/org/petero/droidfish/activities/EditOptions.java
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
DroidFish - An Android chess program.
|
||||||
|
Copyright (C) 2014 Peter Österlund, peterosterlund2@gmail.com
|
||||||
|
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.petero.droidfish.activities;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.petero.droidfish.R;
|
||||||
|
import org.petero.droidfish.Util;
|
||||||
|
import org.petero.droidfish.engine.UCIOptions;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
/** Edit UCI options. */
|
||||||
|
public class EditOptions extends Activity {
|
||||||
|
private UCIOptions uciOpts = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
Util.setFullScreenMode(this, settings);
|
||||||
|
|
||||||
|
Intent i = getIntent();
|
||||||
|
uciOpts = (UCIOptions)i.getSerializableExtra("org.petero.droidfish.ucioptions");
|
||||||
|
if (uciOpts != null) {
|
||||||
|
initUI();
|
||||||
|
} else {
|
||||||
|
setResult(RESULT_CANCELED);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
super.onConfigurationChanged(newConfig);
|
||||||
|
initUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
|
sendBackResult();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CutPasteId")
|
||||||
|
private final void initUI() {
|
||||||
|
setContentView(R.layout.editoptions);
|
||||||
|
Util.overrideFonts(findViewById(android.R.id.content));
|
||||||
|
|
||||||
|
LinearLayout content = (LinearLayout)findViewById(R.id.eo_content);
|
||||||
|
Button okButton = (Button)findViewById(R.id.eo_ok);
|
||||||
|
Button cancelButton = (Button)findViewById(R.id.eo_cancel);
|
||||||
|
|
||||||
|
for (String name : uciOpts.getOptionNames()) {
|
||||||
|
UCIOptions.OptionBase o = uciOpts.getOption(name);
|
||||||
|
if (!o.visible)
|
||||||
|
continue;
|
||||||
|
switch (o.type) {
|
||||||
|
case CHECK: {
|
||||||
|
View v = View.inflate(this, R.layout.uci_option_check, null);
|
||||||
|
CheckBox checkBox = (CheckBox)v.findViewById(R.id.eo_value);
|
||||||
|
checkBox.setText(o.name);
|
||||||
|
final UCIOptions.CheckOption co = (UCIOptions.CheckOption)o;
|
||||||
|
checkBox.setChecked(co.value);
|
||||||
|
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
co.set(isChecked);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
content.addView(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPIN: {
|
||||||
|
View v = View.inflate(this, R.layout.uci_option_spin, null);
|
||||||
|
TextView label = (TextView)v.findViewById(R.id.eo_label);
|
||||||
|
EditText value = (EditText)v.findViewById(R.id.eo_value);
|
||||||
|
final UCIOptions.SpinOption so = (UCIOptions.SpinOption)o;
|
||||||
|
String labelText = String.format(Locale.US, "%s (%d\u2013%d)", so.name, so.minValue, so.maxValue);
|
||||||
|
label.setText(labelText);
|
||||||
|
value.setText(so.getStringValue());
|
||||||
|
if (so.minValue >= 0)
|
||||||
|
value.setInputType(android.text.InputType.TYPE_CLASS_NUMBER);
|
||||||
|
value.addTextChangedListener(new TextWatcher() {
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { }
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
try {
|
||||||
|
int newVal = Integer.parseInt(s.toString());
|
||||||
|
if (newVal < so.minValue)
|
||||||
|
so.set(so.minValue);
|
||||||
|
else if (newVal > so.maxValue)
|
||||||
|
so.set(so.maxValue);
|
||||||
|
else
|
||||||
|
so.set(newVal);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
content.addView(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COMBO: {
|
||||||
|
View v = View.inflate(this, R.layout.uci_option_combo, null);
|
||||||
|
TextView label = (TextView)v.findViewById(R.id.eo_label);
|
||||||
|
Spinner value = (Spinner)v.findViewById(R.id.eo_value);
|
||||||
|
label.setText(o.name);
|
||||||
|
final UCIOptions.ComboOption co = (UCIOptions.ComboOption)o;
|
||||||
|
ArrayAdapter<CharSequence> adapter =
|
||||||
|
new ArrayAdapter<CharSequence>(this, android.R.layout.simple_spinner_item,
|
||||||
|
co.allowedValues);
|
||||||
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
value.setAdapter(adapter);
|
||||||
|
value.setSelection(adapter.getPosition(co.value));
|
||||||
|
value.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> av, View view, int position, long id) {
|
||||||
|
if ((position >= 0) && (position < co.allowedValues.length))
|
||||||
|
co.set(co.allowedValues[position]);
|
||||||
|
}
|
||||||
|
public void onNothingSelected(AdapterView<?> arg0) { }
|
||||||
|
});
|
||||||
|
content.addView(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BUTTON: {
|
||||||
|
View v = View.inflate(this, R.layout.uci_option_button, null);
|
||||||
|
ToggleButton button = (ToggleButton)v.findViewById(R.id.eo_label);
|
||||||
|
final UCIOptions.ButtonOption bo = (UCIOptions.ButtonOption)o;
|
||||||
|
bo.trigger = false;
|
||||||
|
button.setText(o.name);
|
||||||
|
button.setTextOn(o.name);
|
||||||
|
button.setTextOff(o.name);
|
||||||
|
button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
bo.trigger = isChecked;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
content.addView(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STRING: {
|
||||||
|
View v = View.inflate(this, R.layout.uci_option_string, null);
|
||||||
|
TextView label = (TextView)v.findViewById(R.id.eo_label);
|
||||||
|
EditText value = (EditText)v.findViewById(R.id.eo_value);
|
||||||
|
label.setText(o.name + " ");
|
||||||
|
final UCIOptions.StringOption so = (UCIOptions.StringOption)o;
|
||||||
|
value.setText(so.value);
|
||||||
|
value.addTextChangedListener(new TextWatcher() {
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { }
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
so.set(s.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
content.addView(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
okButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
sendBackResult();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cancelButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
setResult(RESULT_CANCELED);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void sendBackResult() {
|
||||||
|
if (uciOpts != null) {
|
||||||
|
TreeMap<String, String> uciMap = new TreeMap<String,String>();
|
||||||
|
for (String name : uciOpts.getOptionNames()) {
|
||||||
|
UCIOptions.OptionBase o = uciOpts.getOption(name);
|
||||||
|
if (o != null) {
|
||||||
|
if (o instanceof UCIOptions.ButtonOption) {
|
||||||
|
UCIOptions.ButtonOption bo = (UCIOptions.ButtonOption)o;
|
||||||
|
if (bo.trigger)
|
||||||
|
uciMap.put(name, "");
|
||||||
|
} else {
|
||||||
|
uciMap.put(name, o.getStringValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Intent i = new Intent();
|
||||||
|
i.putExtra("org.petero.droidfish.ucioptions", uciMap);
|
||||||
|
setResult(RESULT_OK, i);
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
setResult(RESULT_CANCELED);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import java.io.FileReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.petero.droidfish.EngineOptions;
|
import org.petero.droidfish.EngineOptions;
|
||||||
@@ -266,6 +267,18 @@ public class DroidComputerPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true if computer player is in IDLE state. */
|
||||||
|
public final synchronized boolean computerIdle() {
|
||||||
|
return engineState.state == MainState.IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final synchronized UCIOptions getUCIOptions() {
|
||||||
|
UCIEngine uci = uciEngine;
|
||||||
|
if (uci == null)
|
||||||
|
return null;
|
||||||
|
return uci.getUCIOptions();
|
||||||
|
}
|
||||||
|
|
||||||
/** Return maximum number of PVs supported by engine. */
|
/** Return maximum number of PVs supported by engine. */
|
||||||
public final synchronized int getMaxPV() {
|
public final synchronized int getMaxPV() {
|
||||||
return maxPV;
|
return maxPV;
|
||||||
@@ -280,6 +293,14 @@ public class DroidComputerPlayer {
|
|||||||
engineOptions = options;
|
engineOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void setEngineUCIOptions(Map<String,String> uciOptions) {
|
||||||
|
if (engineState.state == MainState.IDLE) {
|
||||||
|
UCIEngine uci = uciEngine;
|
||||||
|
if (uci != null)
|
||||||
|
uci.setUCIOptions(uciOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Return all book moves, both as a formatted string and as a list of moves. */
|
/** Return all book moves, both as a formatted string and as a list of moves. */
|
||||||
public final Pair<String, ArrayList<Move>> getBookHints(Position pos, boolean localized) {
|
public final Pair<String, ArrayList<Move>> getBookHints(Position pos, boolean localized) {
|
||||||
return book.getAllBookMoves(pos, localized);
|
return book.getAllBookMoves(pos, localized);
|
||||||
@@ -744,24 +765,11 @@ public class DroidComputerPlayer {
|
|||||||
}
|
}
|
||||||
listener.notifyEngineName(engineName);
|
listener.notifyEngineName(engineName);
|
||||||
}
|
}
|
||||||
} else if (tokens.length > 2) {
|
} else if (tokens[0].equals("option")) {
|
||||||
String optName = tokens[2].toLowerCase(Locale.US);
|
UCIOptions.OptionBase o = uci.registerOption(tokens);
|
||||||
for (int i = 3; i < tokens.length; i++) {
|
if (o instanceof UCIOptions.SpinOption &&
|
||||||
if ("type".equals(tokens[i]))
|
o.name.toLowerCase(Locale.US).equals("multipv"))
|
||||||
break;
|
maxPV = Math.max(maxPV, ((UCIOptions.SpinOption)o).maxValue);
|
||||||
optName += " " + tokens[i].toLowerCase(Locale.US);
|
|
||||||
}
|
|
||||||
uci.registerOption(optName);
|
|
||||||
if (optName.equals("multipv")) {
|
|
||||||
try {
|
|
||||||
for (int i = 3; i < tokens.length; i++) {
|
|
||||||
if (tokens[i].equals("max") && (i+1 < tokens.length)) {
|
|
||||||
maxPV = Math.max(maxPV, Integer.parseInt(tokens[i+1]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException nfe) { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -43,11 +44,14 @@ public class InternalStockFish extends ExternalEngine {
|
|||||||
@Override
|
@Override
|
||||||
protected File getOptionsFile() {
|
protected File getOptionsFile() {
|
||||||
File extDir = Environment.getExternalStorageDirectory();
|
File extDir = Environment.getExternalStorageDirectory();
|
||||||
return new File(extDir, "uci/stockfish.ini");
|
return new File(extDir, "/DroidFish/uci/stockfish.ini");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean configurableOption(String name) {
|
protected boolean configurableOption(String name) {
|
||||||
|
name = name.toLowerCase(Locale.US);
|
||||||
|
if (!super.configurableOption(name))
|
||||||
|
return false;
|
||||||
if (name.equals("skill level"))
|
if (name.equals("skill level"))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package org.petero.droidfish.engine;
|
package org.petero.droidfish.engine;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.petero.droidfish.EngineOptions;
|
import org.petero.droidfish.EngineOptions;
|
||||||
|
|
||||||
public interface UCIEngine {
|
public interface UCIEngine {
|
||||||
@@ -37,6 +39,12 @@ public interface UCIEngine {
|
|||||||
/** Read UCI options from .ini file and send them to the engine. */
|
/** Read UCI options from .ini file and send them to the engine. */
|
||||||
public void applyIniFile();
|
public void applyIniFile();
|
||||||
|
|
||||||
|
/** Set engine UCI options. */
|
||||||
|
public void setUCIOptions(Map<String,String> uciOptions);
|
||||||
|
|
||||||
|
/** Get engine UCI options. */
|
||||||
|
public UCIOptions getUCIOptions();
|
||||||
|
|
||||||
/** Return true if engine options have correct values.
|
/** Return true if engine options have correct values.
|
||||||
* If false is returned, engine will be restarted. */
|
* If false is returned, engine will be restarted. */
|
||||||
public boolean optionsOk(EngineOptions engineOptions);
|
public boolean optionsOk(EngineOptions engineOptions);
|
||||||
@@ -66,14 +74,17 @@ public interface UCIEngine {
|
|||||||
/** Set an engine boolean option. */
|
/** Set an engine boolean option. */
|
||||||
public void setOption(String name, boolean value);
|
public void setOption(String name, boolean value);
|
||||||
|
|
||||||
/** Set an engine string option. */
|
/** Set an engine option. If the option is not a string option,
|
||||||
public void setOption(String name, String value);
|
* value is converted to the correct type.
|
||||||
|
* @return True if the option was changed. */
|
||||||
|
public boolean setOption(String name, String value);
|
||||||
|
|
||||||
/** Clear list of supported options. */
|
/** Clear list of supported options. */
|
||||||
public void clearOptions();
|
public void clearOptions();
|
||||||
|
|
||||||
/** Register an option as supported by the engine. */
|
/** Register an option as supported by the engine.
|
||||||
public void registerOption(String optName);
|
* @param tokens The UCI option line sent by the engine, split in words. */
|
||||||
|
public UCIOptions.OptionBase registerOption(String[] tokens);
|
||||||
|
|
||||||
/** Set number of search threads to use. */
|
/** Set number of search threads to use. */
|
||||||
public void setNThreads(int nThreads);
|
public void setNThreads(int nThreads);
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ package org.petero.droidfish.engine;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@@ -35,8 +35,7 @@ import android.content.Context;
|
|||||||
public abstract class UCIEngineBase implements UCIEngine {
|
public abstract class UCIEngineBase implements UCIEngine {
|
||||||
|
|
||||||
private boolean processAlive;
|
private boolean processAlive;
|
||||||
private HashSet<String> allOptions;
|
UCIOptions options;
|
||||||
private HashMap<String, String> currOptions;
|
|
||||||
protected boolean isUCI;
|
protected boolean isUCI;
|
||||||
|
|
||||||
public static UCIEngine getEngine(Context context, String engine,
|
public static UCIEngine getEngine(Context context, String engine,
|
||||||
@@ -55,8 +54,7 @@ public abstract class UCIEngineBase implements UCIEngine {
|
|||||||
|
|
||||||
protected UCIEngineBase() {
|
protected UCIEngineBase() {
|
||||||
processAlive = false;
|
processAlive = false;
|
||||||
allOptions = new HashSet<String>();
|
options = new UCIOptions();
|
||||||
currOptions = new HashMap<String, String>();
|
|
||||||
isUCI = false;
|
isUCI = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,22 +90,56 @@ public abstract class UCIEngineBase implements UCIEngine {
|
|||||||
if (ent.getKey() instanceof String && ent.getValue() instanceof String) {
|
if (ent.getKey() instanceof String && ent.getValue() instanceof String) {
|
||||||
String key = ((String)ent.getKey()).toLowerCase(Locale.US);
|
String key = ((String)ent.getKey()).toLowerCase(Locale.US);
|
||||||
String value = (String)ent.getValue();
|
String value = (String)ent.getValue();
|
||||||
if (key.startsWith("uci_") || key.equals("hash") || key.equals("ponder") ||
|
if (configurableOption(key))
|
||||||
key.equals("multipv") || key.equals("gaviotatbpath") ||
|
setOption(key, value);
|
||||||
key.equals("syzygypath") || key.equals("threads") || key.equals("cores"))
|
|
||||||
continue;
|
|
||||||
if (!configurableOption(key))
|
|
||||||
continue;
|
|
||||||
setOption(key, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void setUCIOptions(Map<String,String> uciOptions) {
|
||||||
|
boolean modified = false;
|
||||||
|
for (Map.Entry<String,String> ent : uciOptions.entrySet()) {
|
||||||
|
String key = ((String)ent.getKey()).toLowerCase(Locale.US);
|
||||||
|
String value = (String)ent.getValue();
|
||||||
|
if (configurableOption(key))
|
||||||
|
modified |= setOption(key, value);
|
||||||
|
}
|
||||||
|
if (modified) { // Save .ini file
|
||||||
|
Properties iniOptions = new Properties();
|
||||||
|
for (String name : options.getOptionNames()) {
|
||||||
|
UCIOptions.OptionBase o = options.getOption(name);
|
||||||
|
if (configurableOption(name) && o.modified())
|
||||||
|
iniOptions.put(o.name, o.getStringValue());
|
||||||
|
}
|
||||||
|
File optionsFile = getOptionsFile();
|
||||||
|
FileOutputStream os = null;
|
||||||
|
try {
|
||||||
|
os = new FileOutputStream(optionsFile);
|
||||||
|
iniOptions.store(os, null);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
} finally {
|
||||||
|
if (os != null)
|
||||||
|
try { os.close(); } catch (IOException ex) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final UCIOptions getUCIOptions() {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
/** Get engine UCI options file. */
|
/** Get engine UCI options file. */
|
||||||
protected abstract File getOptionsFile();
|
protected abstract File getOptionsFile();
|
||||||
|
|
||||||
/** Return true if the UCI option can be changed by the user. */
|
/** Return true if the UCI option can be changed by the user. */
|
||||||
protected boolean configurableOption(String name) {
|
protected boolean configurableOption(String name) {
|
||||||
|
name = name.toLowerCase(Locale.US);
|
||||||
|
if (name.startsWith("uci_") || name.equals("hash") || name.equals("ponder") ||
|
||||||
|
name.equals("multipv") || name.equals("gaviotatbpath") ||
|
||||||
|
name.equals("syzygypath") || name.equals("threads") || name.equals("cores"))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,47 +152,143 @@ public abstract class UCIEngineBase implements UCIEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearOptions() {
|
public final void clearOptions() {
|
||||||
allOptions.clear();
|
options.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerOption(String optName) {
|
public final UCIOptions.OptionBase registerOption(String[] tokens) {
|
||||||
allOptions.add(optName);
|
if (tokens.length < 5 || !tokens[1].equals("name"))
|
||||||
|
return null;
|
||||||
|
String name = tokens[2];
|
||||||
|
int i;
|
||||||
|
for (i = 3; i < tokens.length; i++) {
|
||||||
|
if ("type".equals(tokens[i]))
|
||||||
|
break;
|
||||||
|
name += " " + tokens[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= tokens.length - 1)
|
||||||
|
return null;
|
||||||
|
i++;
|
||||||
|
String type = tokens[i++];
|
||||||
|
|
||||||
|
String defVal = null;
|
||||||
|
String minVal = null;
|
||||||
|
String maxVal = null;
|
||||||
|
ArrayList<String> var = new ArrayList<String>();
|
||||||
|
try {
|
||||||
|
for (; i < tokens.length; i++) {
|
||||||
|
if (tokens[i].equals("default")) {
|
||||||
|
String stop = null;
|
||||||
|
if (type.equals("spin"))
|
||||||
|
stop = "min";
|
||||||
|
else if (type.equals("combo"))
|
||||||
|
stop = "var";
|
||||||
|
defVal = "";
|
||||||
|
while (i+1 < tokens.length && !tokens[i+1].equals(stop)) {
|
||||||
|
if (defVal.length() > 0)
|
||||||
|
defVal += " ";
|
||||||
|
defVal += tokens[i+1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else if (tokens[i].equals("min")) {
|
||||||
|
minVal = tokens[++i];
|
||||||
|
} else if (tokens[i].equals("max")) {
|
||||||
|
maxVal = tokens[++i];
|
||||||
|
} else if (tokens[i].equals("var")) {
|
||||||
|
String value = "";
|
||||||
|
while (i+1 < tokens.length && !tokens[i+1].equals("var")) {
|
||||||
|
if (value.length() > 0)
|
||||||
|
value += " ";
|
||||||
|
value += tokens[i+1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
var.add(value);
|
||||||
|
} else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UCIOptions.OptionBase option = null;
|
||||||
|
if (type.equals("check")) {
|
||||||
|
if (defVal != null) {
|
||||||
|
defVal = defVal.toLowerCase(Locale.US);
|
||||||
|
option = new UCIOptions.CheckOption(name, defVal.equals("true"));
|
||||||
|
}
|
||||||
|
} else if (type.equals("spin")) {
|
||||||
|
if (defVal != null && minVal != null && maxVal != null) {
|
||||||
|
try {
|
||||||
|
int defV = Integer.parseInt(defVal);
|
||||||
|
int minV = Integer.parseInt(minVal);
|
||||||
|
int maxV = Integer.parseInt(maxVal);
|
||||||
|
if (minV <= defV && defV <= maxV)
|
||||||
|
option = new UCIOptions.SpinOption(name, minV, maxV, defV);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type.equals("combo")) {
|
||||||
|
if (defVal != null && var.size() > 0) {
|
||||||
|
String[] allowed = var.toArray(new String[var.size()]);
|
||||||
|
for (String s : allowed)
|
||||||
|
if (s.equals(defVal)) {
|
||||||
|
option = new UCIOptions.ComboOption(name, allowed, defVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type.equals("button")) {
|
||||||
|
option = new UCIOptions.ButtonOption(name);
|
||||||
|
} else if (type.equals("string")) {
|
||||||
|
if (defVal != null)
|
||||||
|
option = new UCIOptions.StringOption(name, defVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option != null) {
|
||||||
|
if (!configurableOption(name))
|
||||||
|
option.visible = false;
|
||||||
|
options.addOption(option);
|
||||||
|
}
|
||||||
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true if engine has option optName. */
|
/** Return true if engine has option optName. */
|
||||||
protected boolean hasOption(String optName) {
|
protected final boolean hasOption(String optName) {
|
||||||
return allOptions.contains(optName);
|
return options.contains(optName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOption(String name, int value) {
|
public final void setOption(String name, int value) {
|
||||||
setOption(name, String.format(Locale.US, "%d", value));
|
setOption(name, String.format(Locale.US, "%d", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOption(String name, boolean value) {
|
public final void setOption(String name, boolean value) {
|
||||||
setOption(name, value ? "true" : "false");
|
setOption(name, value ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOption(String name, String value) {
|
public final boolean setOption(String name, String value) {
|
||||||
String lcName = name.toLowerCase(Locale.US);
|
if (!options.contains(name))
|
||||||
if (!allOptions.contains(lcName))
|
return false;
|
||||||
return;
|
UCIOptions.OptionBase o = options.getOption(name);
|
||||||
String currVal = currOptions.get(lcName);
|
if (o instanceof UCIOptions.ButtonOption) {
|
||||||
if (value.equals(currVal))
|
writeLineToEngine(String.format(Locale.US, "setoption name %s", name));
|
||||||
return;
|
} else if (o.setFromString(value)) {
|
||||||
writeLineToEngine(String.format(Locale.US, "setoption name %s value %s", name, value));
|
if (value.length() == 0)
|
||||||
currOptions.put(lcName, value);
|
value = "<empty>";
|
||||||
|
writeLineToEngine(String.format(Locale.US, "setoption name %s value %s", name, value));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNThreads(int nThreads) {
|
public final void setNThreads(int nThreads) {
|
||||||
if (allOptions.contains("threads"))
|
if (options.contains("Threads"))
|
||||||
setOption("Threads", nThreads);
|
setOption("Threads", nThreads);
|
||||||
else if (allOptions.contains("cores"))
|
else if (options.contains("Cores"))
|
||||||
setOption("Cores", nThreads);
|
setOption("Cores", nThreads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
228
DroidFish/src/org/petero/droidfish/engine/UCIOptions.java
Normal file
228
DroidFish/src/org/petero/droidfish/engine/UCIOptions.java
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
package org.petero.droidfish.engine;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
public class UCIOptions implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private ArrayList<String> names;
|
||||||
|
private Map<String, OptionBase> options;
|
||||||
|
|
||||||
|
public static enum Type {
|
||||||
|
CHECK,
|
||||||
|
SPIN,
|
||||||
|
COMBO,
|
||||||
|
BUTTON,
|
||||||
|
STRING
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class OptionBase implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public String name;
|
||||||
|
public Type type;
|
||||||
|
public boolean visible = true;
|
||||||
|
|
||||||
|
/** Return true if current value != default value. */
|
||||||
|
abstract public boolean modified();
|
||||||
|
|
||||||
|
/** Return current value as a string. */
|
||||||
|
abstract public String getStringValue();
|
||||||
|
|
||||||
|
/** Set option from string value. Return true if option was modified. */
|
||||||
|
public final boolean setFromString(String value) {
|
||||||
|
OptionBase o = this;
|
||||||
|
switch (o.type) {
|
||||||
|
case CHECK:
|
||||||
|
if (value.toLowerCase(Locale.US).equals("true"))
|
||||||
|
return ((CheckOption)o).set(true);
|
||||||
|
else if (value.toLowerCase(Locale.US).equals("false"))
|
||||||
|
return ((CheckOption)o).set(false);
|
||||||
|
return false;
|
||||||
|
case SPIN:
|
||||||
|
try {
|
||||||
|
int val = Integer.parseInt(value);
|
||||||
|
SpinOption so = (SpinOption)o;
|
||||||
|
return so.set(val);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case COMBO:
|
||||||
|
return ((ComboOption)o).set(value);
|
||||||
|
case BUTTON:
|
||||||
|
return false;
|
||||||
|
case STRING:
|
||||||
|
return ((StringOption)o).set(value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class CheckOption extends OptionBase {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public boolean value;
|
||||||
|
public boolean defaultValue;
|
||||||
|
CheckOption(String name, boolean def) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = Type.CHECK;
|
||||||
|
this.value = def;
|
||||||
|
this.defaultValue = def;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean modified() {
|
||||||
|
return value != defaultValue;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getStringValue() {
|
||||||
|
return value ? "true" : "false";
|
||||||
|
}
|
||||||
|
public boolean set(boolean value) {
|
||||||
|
if (this.value != value) {
|
||||||
|
this.value = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class SpinOption extends OptionBase {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public int minValue;
|
||||||
|
public int maxValue;
|
||||||
|
public int value;
|
||||||
|
public int defaultValue;
|
||||||
|
SpinOption(String name, int minV, int maxV, int def) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = Type.SPIN;
|
||||||
|
this.minValue = minV;
|
||||||
|
this.maxValue = maxV;
|
||||||
|
this.value = def;
|
||||||
|
this.defaultValue = def;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean modified() {
|
||||||
|
return value != defaultValue;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getStringValue() {
|
||||||
|
return String.format(Locale.US, "%d", value);
|
||||||
|
}
|
||||||
|
public boolean set(int value) {
|
||||||
|
if ((value >= minValue) && (value <= maxValue)) {
|
||||||
|
if (this.value != value) {
|
||||||
|
this.value = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ComboOption extends OptionBase {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public String[] allowedValues;
|
||||||
|
public String value;
|
||||||
|
public String defaultValue;
|
||||||
|
ComboOption(String name, String[] allowed, String def) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = Type.COMBO;
|
||||||
|
this.allowedValues = allowed;
|
||||||
|
this.value = def;
|
||||||
|
this.defaultValue = def;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean modified() {
|
||||||
|
return !value.equals(defaultValue);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getStringValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
public boolean set(String value) {
|
||||||
|
for (String allowed : allowedValues) {
|
||||||
|
if (allowed.toLowerCase(Locale.US).equals(value.toLowerCase(Locale.US))) {
|
||||||
|
if (!this.value.equals(allowed)) {
|
||||||
|
this.value = allowed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ButtonOption extends OptionBase {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public boolean trigger;
|
||||||
|
ButtonOption(String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = Type.BUTTON;
|
||||||
|
this.trigger = false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean modified() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getStringValue() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class StringOption extends OptionBase {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public String value;
|
||||||
|
public String defaultValue;
|
||||||
|
StringOption(String name, String def) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = Type.STRING;
|
||||||
|
this.value = def;
|
||||||
|
this.defaultValue = def;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean modified() {
|
||||||
|
return !value.equals(defaultValue);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getStringValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
public boolean set(String value) {
|
||||||
|
if (!this.value.equals(value)) {
|
||||||
|
this.value = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UCIOptions() {
|
||||||
|
names = new ArrayList<String>();
|
||||||
|
options = new TreeMap<String, OptionBase>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
options.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(String optName) {
|
||||||
|
return getOption(optName) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String[] getOptionNames() {
|
||||||
|
return names.toArray(new String[names.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final OptionBase getOption(String name) {
|
||||||
|
return options.get(name.toLowerCase(Locale.US));
|
||||||
|
}
|
||||||
|
|
||||||
|
final void addOption(OptionBase p) {
|
||||||
|
String name = p.name.toLowerCase(Locale.US);
|
||||||
|
names.add(name);
|
||||||
|
options.put(name, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,11 +78,14 @@ public class CuckooChessEngine extends UCIEngineBase {
|
|||||||
@Override
|
@Override
|
||||||
protected File getOptionsFile() {
|
protected File getOptionsFile() {
|
||||||
File extDir = Environment.getExternalStorageDirectory();
|
File extDir = Environment.getExternalStorageDirectory();
|
||||||
return new File(extDir, "uci/cuckoochess.ini");
|
return new File(extDir, "/DroidFish/uci/cuckoochess.ini");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean configurableOption(String name) {
|
protected boolean configurableOption(String name) {
|
||||||
|
name = name.toLowerCase(Locale.US);
|
||||||
|
if (!super.configurableOption(name))
|
||||||
|
return false;
|
||||||
if (name.equals("strength"))
|
if (name.equals("strength"))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import org.petero.droidfish.PGNOptions;
|
|||||||
import org.petero.droidfish.Util;
|
import org.petero.droidfish.Util;
|
||||||
import org.petero.droidfish.book.BookOptions;
|
import org.petero.droidfish.book.BookOptions;
|
||||||
import org.petero.droidfish.engine.DroidComputerPlayer;
|
import org.petero.droidfish.engine.DroidComputerPlayer;
|
||||||
|
import org.petero.droidfish.engine.UCIOptions;
|
||||||
import org.petero.droidfish.engine.DroidComputerPlayer.SearchRequest;
|
import org.petero.droidfish.engine.DroidComputerPlayer.SearchRequest;
|
||||||
import org.petero.droidfish.engine.DroidComputerPlayer.SearchType;
|
import org.petero.droidfish.engine.DroidComputerPlayer.SearchType;
|
||||||
import org.petero.droidfish.gamelogic.Game.GameState;
|
import org.petero.droidfish.gamelogic.Game.GameState;
|
||||||
@@ -153,6 +154,7 @@ public class DroidChessController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set engine options. */
|
||||||
public final synchronized void setEngineOptions(EngineOptions options, boolean restart) {
|
public final synchronized void setEngineOptions(EngineOptions options, boolean restart) {
|
||||||
if (!engineOptions.equals(options)) {
|
if (!engineOptions.equals(options)) {
|
||||||
engineOptions = options;
|
engineOptions = options;
|
||||||
@@ -184,6 +186,12 @@ public class DroidChessController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set engine UCI options. */
|
||||||
|
public final synchronized void setEngineUCIOptions(Map<String,String> uciOptions) {
|
||||||
|
if (computerPlayer != null)
|
||||||
|
computerPlayer.setEngineUCIOptions(uciOptions);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return current engine identifier. */
|
/** Return current engine identifier. */
|
||||||
public final synchronized String getEngine() {
|
public final synchronized String getEngine() {
|
||||||
return engine;
|
return engine;
|
||||||
@@ -287,6 +295,17 @@ public class DroidChessController {
|
|||||||
return (computerPlayer != null) && computerPlayer.computerBusy();
|
return (computerPlayer != null) && computerPlayer.computerBusy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true if computer player is in IDLE state. */
|
||||||
|
public final synchronized boolean computerIdle() {
|
||||||
|
return (computerPlayer != null) && computerPlayer.computerIdle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final synchronized UCIOptions getUCIOptions() {
|
||||||
|
if (!computerIdle() || computerPlayer == null)
|
||||||
|
return null;
|
||||||
|
return computerPlayer.getUCIOptions();
|
||||||
|
}
|
||||||
|
|
||||||
/** Make a move for a human player. */
|
/** Make a move for a human player. */
|
||||||
public final synchronized void makeHumanMove(Move m) {
|
public final synchronized void makeHumanMove(Move m) {
|
||||||
if (humansTurn()) {
|
if (humansTurn()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user