[LIB-9] Separate chesshog-uci module
[chesshog.git] / chesshog-uci / src / main / java / org / hedgecode / chess / uci / command / OptionParams.java
diff --git a/chesshog-uci/src/main/java/org/hedgecode/chess/uci/command/OptionParams.java b/chesshog-uci/src/main/java/org/hedgecode/chess/uci/command/OptionParams.java
new file mode 100644 (file)
index 0000000..cb677e3
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * 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);
+        }
+    }
+
+
+
+}