[LIB-9] Separate chesshog-uci module
[chesshog.git] / chesshog-uci / src / main / java / org / hedgecode / chess / uci / command / OptionParams.java
1 /*
2  * Copyright (c) 2018. Developed by Hedgecode.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.hedgecode.chess.uci.command;
18
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 /**
25  * Container class for values of UCI command "option".
26  *
27  * @author Dmitry Samoshin aka gotty
28  */
29 public final class OptionParams {
30
31     public static final String OPTION_NAME = "name";
32     public static final String OPTION_TYPE = "type";
33     public static final String OPTION_DEFAULT = "default";
34     public static final String OPTION_MIN = "min";
35     public static final String OPTION_MAX = "max";
36     public static final String OPTION_VAR = "var";
37
38     private static final String OPTION_PIPE = "|";
39     private static final String OPTION_EMPTY = "<empty>";
40
41     private static final Pattern OPTION_PATTERN =
42             Pattern.compile(
43                     String.format("^\\s*%s(.*)%s\\s+(%s)(.*)$", OPTION_NAME, OPTION_TYPE, typeRegex())
44             );
45
46     private static final String PARAMS_REGEX = "%s\\s+([^\\s]+)\\s*";
47
48     private String name;
49     private OptionType type;
50
51     private String defValue;
52     private int minValue, maxValue;
53     private List<String> vars = new ArrayList<>();
54
55     private OptionParams(String name, String type, String params) {
56         this.name = name;
57         this.type = OptionType.get(type);
58         if (!params.isEmpty())
59             parseParams(params);
60     }
61
62     private void parseParams(String option) {
63         parseDefValue(option);
64         parseMinValue(option);
65         parseMaxValue(option);
66         parseVars(option);
67     }
68
69     private void parseDefValue(String option) {
70         Pattern pattern = Pattern.compile(
71                 String.format(PARAMS_REGEX, OPTION_DEFAULT)
72         );
73         Matcher matcher = pattern.matcher(option);
74         if (matcher.find()) {
75             defValue = parseEmptyValue(matcher.group(1));
76         }
77     }
78
79     private void parseMinValue(String option) {
80         Pattern pattern = Pattern.compile(
81                 String.format(PARAMS_REGEX, OPTION_MIN)
82         );
83         Matcher matcher = pattern.matcher(option);
84         if (matcher.find()) {
85             minValue = Integer.parseInt(
86                     matcher.group(1)
87             );
88         }
89     }
90
91     private void parseMaxValue(String option) {
92         Pattern pattern = Pattern.compile(
93                 String.format(PARAMS_REGEX, OPTION_MAX)
94         );
95         Matcher matcher = pattern.matcher(option);
96         if (matcher.find()) {
97             maxValue = Integer.parseInt(
98                     matcher.group(1)
99             );
100         }
101     }
102
103     private void parseVars(String option) {
104         Pattern pattern = Pattern.compile(
105                 String.format(PARAMS_REGEX, OPTION_VAR)
106         );
107         Matcher matcher = pattern.matcher(option);
108         vars.clear();
109         while (matcher.find()) {
110             vars.add(
111                     parseEmptyValue(matcher.group(1))
112             );
113         }
114     }
115
116     public String getName() {
117         return name;
118     }
119
120     public OptionType getType() {
121         return type;
122     }
123
124     public String getDefValue() {
125         return defValue;
126     }
127
128     public int getMinValue() {
129         return minValue;
130     }
131
132     public int getMaxValue() {
133         return maxValue;
134     }
135
136     public List<String> getVars() {
137         return vars;
138     }
139
140     private String parseEmptyValue(String value) {
141         return OPTION_EMPTY.equals(value) ? "" : value;
142     }
143
144     private static String typeRegex() {
145         StringBuilder sb = new StringBuilder();
146         for (OptionType optionType : OptionType.values()) {
147             if (optionType.ordinal() > 0)
148                 sb.append(OPTION_PIPE);
149             sb.append(optionType.type());
150         }
151         return sb.toString();
152     }
153
154     public static final class Factory {
155
156         public static OptionParams parse(String option) {
157             Matcher matcher = OPTION_PATTERN.matcher(option);
158             if (matcher.find()) {
159                 return new OptionParams(
160                         matcher.group(1).trim(),
161                         matcher.group(2).trim(),
162                         matcher.group(3).trim()
163                 );
164             }
165             return null;
166         }
167
168     }
169
170
171     public static void main(String... args) throws Exception {
172         String[] strings = {"name Debug Log File type string default",
173                 " name Contempt type spin default 21 min -100 max 100",
174                 "   name Analysis Contempt type combo default Both var Off var White var Black var Both",
175                 "name Threads type spin default 1 min 1 max 512",
176                 "name Hash type spin default 16 min 1 max 131072",
177                 "name Clear Hash type button",
178                 "name Ponder type check default false",
179                 "name MultiPV type spin default 1 min 1 max 500",
180                 "name Skill Level type spin default 20 min 0 max 20",
181                 "name Move Overhead type spin default 30 min 0 max 5000",
182                 "name Minimum Thinking Time type spin default 20 min 0 max 5000",
183                 "name Slow Mover type spin default 84 min 10 max 1000",
184                 "name nodestime type spin default 0 min 0 max 10000",
185                 "name UCI_Chess960 type check default false",
186                 "name UCI_AnalyseMode type check default false",
187                 "name SyzygyPath type string default <empty>",
188                 "name SyzygyProbeDepth type spin default 1 min 1 max 100",
189                 "name Syzygy50MoveRule type check default true",
190                 "name SyzygyProbeLimit type spin default 7 min 0 max 7"};
191
192         for (String string : strings) {
193             OptionParams optionParams = OptionParams.Factory.parse(string);
194             System.out.println(optionParams);
195         }
196     }
197
198
199
200 }