93d7ffacc1d4aed525fdf86793074477a69548be
[chesshog.git] / src / main / java / org / hedgecode / chess / wiki / WikiParser.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.wiki;
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 import org.hedgecode.chess.position.ParseException;
25 import org.hedgecode.chess.position.Parser;
26 import org.hedgecode.chess.position.Position;
27 import org.hedgecode.chess.position.Positions;
28 import org.hedgecode.chess.position.Square;
29
30 /**
31  * Wikipedia chess diagram parser.
32  *
33  * @author Dmitry Samoshin aka gotty
34  */
35 public final class WikiParser implements Parser {
36
37     private static final String LINE_REGEX = "\\r?\\n";
38     private static final String SQUARE_REGEX = String.format("[%s]", Wiki.SEPARATOR);
39
40     private static final Pattern PATTERN =
41             Pattern.compile(
42                     String.format("^([%s][^%s]*){%d}$", Wiki.SEPARATOR, Wiki.SEPARATOR, Square.getSize())
43             );
44
45     private static Parser _instance = new WikiParser();
46
47     private WikiParser() {
48     }
49
50     @Override
51     public Position parse(String string) throws ParseException {
52         return _parse(
53                 string.split(LINE_REGEX)
54         );
55     }
56
57     private Position _parse(String[] strings) throws ParseException {
58         List<String> lines = new ArrayList<>();
59         for (String line : strings) {
60             Matcher matcher = PATTERN.matcher(line);
61             if (matcher.find()) {
62                 lines.add(
63                         matcher.group(0)
64                 );
65             }
66         }
67         if (lines.size() != Square.getSize())
68             throw new ParseException("parse.wiki.incorrect.board");
69         Position position = Positions.EMPTY.getPosition();
70         _parsePieces(
71                 lines.toArray(
72                         new String[lines.size()]
73                 ),
74                 position
75         );
76         return position;
77     }
78
79     private void _parsePieces(String[] lines, Position position) throws ParseException {
80         for (int i = 0; i < lines.length; ++i) {
81             int line = lines.length - i;
82             String[] pieces = lines[i].split(SQUARE_REGEX, -1);
83             if (pieces.length != Square.getSize() + 1)
84                 throw new ParseException("parse.wiki.incorrect.board");
85             for (int j = 1; j < pieces.length; ++j) {
86                 position.setPiece(
87                         Wiki.getColorPiece(pieces[j]),
88                         Square.getSquare(j - 1, line - 1)
89                 );
90             }
91         }
92     }
93
94     public static Parser getInstance() {
95         return _instance;
96     }
97
98
99     public static void main(String[] args) throws ParseException {
100         Position position = getInstance().parse(
101                 "{{Шахматная диаграмма\n" +
102                         "|\n" +
103                         "|\n" +
104                         "|rd|nd|bd|qd|kd|bd|nd|rd\n" +
105                         "|pd|pd|  |pd|pd|pd|pd|pd\n" +
106                         "|  |  |  |  |  |  |  |\n" +
107                         "|  |  |  |  |  |  |  |\n" +
108                         "|  |  |  |pd|pl|  |  |\r\n" +
109                         "|  |  |pl|  |  |  |  |\n" +
110                         "|pl|pl|  |  |  |pl|pl|pl\n" +
111                         "|rl|nl|bl|ql|kl|bl|nl|rl\n" +
112                         "| }}"
113         );
114         System.out.println(position);
115     }
116
117 }