/* * 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 = ""; 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 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 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 ", "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); } } }