[LIB-9] Separate chesshog-format module
[chesshog.git] / chesshog-format / src / main / java / org / hedgecode / chess / fen / FENBuilder.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.fen;
18
19 import java.util.Map;
20
21 import org.hedgecode.chess.Parsers;
22 import org.hedgecode.chess.position.Builder;
23 import org.hedgecode.chess.position.Color;
24 import org.hedgecode.chess.position.ColorPiece;
25 import org.hedgecode.chess.position.ParseException;
26 import org.hedgecode.chess.position.Position;
27 import org.hedgecode.chess.position.Square;
28
29 /**
30  * Forsyth–Edwards Notation (FEN) builder.
31  *
32  * @author Dmitry Samoshin aka gotty
33  */
34 public final class FENBuilder implements Builder {
35
36     private static Builder _instance = new FENBuilder();
37
38     private FENBuilder() {
39     }
40
41     @Override
42     public String build(Position position) {
43         return _build(
44                 position
45         );
46     }
47
48     private String _build(Position position) {
49         StringBuilder sb = new StringBuilder();
50         sb.append(
51                 _buildPosition(position)
52         ).append(
53                 FEN.FIELDS_SEP
54         ).append(
55                 FEN.getColor(
56                         position.getMove()
57                 )
58         ).append(
59                 FEN.FIELDS_SEP
60         ).append(
61                 FEN.getCastle(
62                         position.getCastle(Color.WHITE),
63                         position.getCastle(Color.BLACK)
64                 )
65         ).append(
66                 FEN.FIELDS_SEP
67         ).append(
68                 FEN.getEnPassant(
69                         position.getEnPassant()
70                 )
71         ).append(
72                 FEN.FIELDS_SEP
73         ).append(
74                 position.getHalfMove()
75         ).append(
76                 FEN.FIELDS_SEP
77         ).append(
78                 position.getFullMove()
79         );
80         return sb.toString();
81     }
82
83     private String _buildPosition(Position position) {
84         StringBuilder sb = new StringBuilder();
85         Map<Square, ColorPiece> squares = position.getSquares();
86         for (int i = Square.getSize() - 1; i >= 0; --i) {
87             int empty = 0;
88             for (int j = 0; j < Square.getSize(); ++j) {
89                 Square square = Square.getSquare(j, i);
90                 ColorPiece piece = squares.get(square);
91                 if (piece != null) {
92                     if (empty > 0)
93                         sb.append(empty);
94                     sb.append(
95                             FEN.getFenPiece(piece)
96                     );
97                     empty = 0;
98                 } else {
99                     ++empty;
100                 }
101             }
102             if (empty > 0)
103                 sb.append(empty);
104             if (i > 0)
105                 sb.append(FEN.LINE_SEP);
106         }
107         return sb.toString();
108     }
109
110     public static Builder getInstance() {
111         return _instance;
112     }
113
114
115     public static void main(String[] args) throws ParseException {
116
117         Position position = Parsers.FEN.parser().parse(
118                 "r7/7p/8/8/8/8/PPPPPP2/1N1Q2NR w KQkq a3 1 20"
119         );
120         System.out.println(
121                 getInstance().build(position)
122         );
123
124     }
125
126 }