--- /dev/null
+/*
+ * Copyright (c) 2018. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.uci.command;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Container class for values of UCI command "option".
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class OptionParams {
+
+ public static final String OPTION_NAME = "name";
+ public static final String OPTION_TYPE = "type";
+ public static final String OPTION_DEFAULT = "default";
+ public static final String OPTION_MIN = "min";
+ public static final String OPTION_MAX = "max";
+ public static final String OPTION_VAR = "var";
+
+ private static final String OPTION_PIPE = "|";
+ private static final String OPTION_EMPTY = "<empty>";
+
+ private static final Pattern OPTION_PATTERN =
+ Pattern.compile(
+ String.format("^\\s*%s(.*)%s\\s+(%s)(.*)$", OPTION_NAME, OPTION_TYPE, typeRegex())
+ );
+
+ private static final String PARAMS_REGEX = "%s\\s+([^\\s]+)\\s*";
+
+ private String name;
+ private OptionType type;
+
+ private String defValue;
+ private int minValue, maxValue;
+ private List<String> vars = new ArrayList<>();
+
+ private OptionParams(String name, String type, String params) {
+ this.name = name;
+ this.type = OptionType.get(type);
+ if (!params.isEmpty())
+ parseParams(params);
+ }
+
+ private void parseParams(String option) {
+ parseDefValue(option);
+ parseMinValue(option);
+ parseMaxValue(option);
+ parseVars(option);
+ }
+
+ private void parseDefValue(String option) {
+ Pattern pattern = Pattern.compile(
+ String.format(PARAMS_REGEX, OPTION_DEFAULT)
+ );
+ Matcher matcher = pattern.matcher(option);
+ if (matcher.find()) {
+ defValue = parseEmptyValue(matcher.group(1));
+ }
+ }
+
+ private void parseMinValue(String option) {
+ Pattern pattern = Pattern.compile(
+ String.format(PARAMS_REGEX, OPTION_MIN)
+ );
+ Matcher matcher = pattern.matcher(option);
+ if (matcher.find()) {
+ minValue = Integer.parseInt(
+ matcher.group(1)
+ );
+ }
+ }
+
+ private void parseMaxValue(String option) {
+ Pattern pattern = Pattern.compile(
+ String.format(PARAMS_REGEX, OPTION_MAX)
+ );
+ Matcher matcher = pattern.matcher(option);
+ if (matcher.find()) {
+ maxValue = Integer.parseInt(
+ matcher.group(1)
+ );
+ }
+ }
+
+ private void parseVars(String option) {
+ Pattern pattern = Pattern.compile(
+ String.format(PARAMS_REGEX, OPTION_VAR)
+ );
+ Matcher matcher = pattern.matcher(option);
+ vars.clear();
+ while (matcher.find()) {
+ vars.add(
+ parseEmptyValue(matcher.group(1))
+ );
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public OptionType getType() {
+ return type;
+ }
+
+ public String getDefValue() {
+ return defValue;
+ }
+
+ public int getMinValue() {
+ return minValue;
+ }
+
+ public int getMaxValue() {
+ return maxValue;
+ }
+
+ public List<String> getVars() {
+ return vars;
+ }
+
+ private String parseEmptyValue(String value) {
+ return OPTION_EMPTY.equals(value) ? "" : value;
+ }
+
+ private static String typeRegex() {
+ StringBuilder sb = new StringBuilder();
+ for (OptionType optionType : OptionType.values()) {
+ if (optionType.ordinal() > 0)
+ sb.append(OPTION_PIPE);
+ sb.append(optionType.type());
+ }
+ return sb.toString();
+ }
+
+ public static final class Factory {
+
+ public static OptionParams parse(String option) {
+ Matcher matcher = OPTION_PATTERN.matcher(option);
+ if (matcher.find()) {
+ return new OptionParams(
+ matcher.group(1).trim(),
+ matcher.group(2).trim(),
+ matcher.group(3).trim()
+ );
+ }
+ return null;
+ }
+
+ }
+
+
+ public static void main(String... args) throws Exception {
+ String[] strings = {"name Debug Log File type string default",
+ " name Contempt type spin default 21 min -100 max 100",
+ " name Analysis Contempt type combo default Both var Off var White var Black var Both",
+ "name Threads type spin default 1 min 1 max 512",
+ "name Hash type spin default 16 min 1 max 131072",
+ "name Clear Hash type button",
+ "name Ponder type check default false",
+ "name MultiPV type spin default 1 min 1 max 500",
+ "name Skill Level type spin default 20 min 0 max 20",
+ "name Move Overhead type spin default 30 min 0 max 5000",
+ "name Minimum Thinking Time type spin default 20 min 0 max 5000",
+ "name Slow Mover type spin default 84 min 10 max 1000",
+ "name nodestime type spin default 0 min 0 max 10000",
+ "name UCI_Chess960 type check default false",
+ "name UCI_AnalyseMode type check default false",
+ "name SyzygyPath type string default <empty>",
+ "name SyzygyProbeDepth type spin default 1 min 1 max 100",
+ "name Syzygy50MoveRule type check default true",
+ "name SyzygyProbeLimit type spin default 7 min 0 max 7"};
+
+ for (String string : strings) {
+ OptionParams optionParams = OptionParams.Factory.parse(string);
+ System.out.println(optionParams);
+ }
+ }
+
+
+
+}