[LIB-9] Separate chesshog-format module
[chesshog.git] / chesshog-format / src / main / java / org / hedgecode / chess / tcd / TCD.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.tcd;
18
19 import java.nio.charset.Charset;
20 import java.nio.charset.StandardCharsets;
21
22 /**
23  * Tiny Chess Diagram (TCD) constants.
24  *
25  * @author Dmitry Samoshin aka gotty
26  */
27 public final class TCD {
28
29     public static final byte BYTE_MASK = 0b01000000;
30     public static final byte FRAME_MASK = 0b111;
31     public static final byte FRAME_LENGTH = 3;
32
33     public static final byte WHITE = 0b000;
34     public static final byte BLACK = 0b111;
35
36     public static final byte END = 0b111;
37
38     public static final byte PAWN   = 0b001;
39     public static final byte KNIGHT = 0b010;
40     public static final byte BISHOP = 0b011;
41     public static final byte ROOK   = 0b100;
42     public static final byte QUEEN  = 0b101;
43     public static final byte KING   = 0b110;
44
45     private static final byte SQUARE_A = 0b000, SQUARE_1 = SQUARE_A;
46     private static final byte SQUARE_B = 0b001, SQUARE_2 = SQUARE_B;
47     private static final byte SQUARE_C = 0b010, SQUARE_3 = SQUARE_C;
48     private static final byte SQUARE_D = 0b011, SQUARE_4 = SQUARE_D;
49     private static final byte SQUARE_E = 0b100, SQUARE_5 = SQUARE_E;
50     private static final byte SQUARE_F = 0b101, SQUARE_6 = SQUARE_F;
51     private static final byte SQUARE_G = 0b110, SQUARE_7 = SQUARE_G;
52     private static final byte SQUARE_H = 0b111, SQUARE_8 = SQUARE_H;
53
54     public static final byte SQUARE_SIZE = 8;
55
56     public static final byte[][] SQUARE = {
57             {SQUARE_A, SQUARE_1},
58             {SQUARE_B, SQUARE_2},
59             {SQUARE_C, SQUARE_3},
60             {SQUARE_D, SQUARE_4},
61             {SQUARE_E, SQUARE_5},
62             {SQUARE_F, SQUARE_6},
63             {SQUARE_G, SQUARE_7},
64             {SQUARE_H, SQUARE_8},
65     };
66
67     public static final byte MOVE = 0b001;
68
69     public static final byte CASTLE_WHITE = 0b000;
70     public static final byte CASTLE_BLACK = 0b111;
71
72     public static final byte CASTLE_NONE = 0b000;
73     public static final byte CASTLE_KING = 0b001;
74     public static final byte CASTLE_QUEEN = 0b010;
75     public static final byte CASTLE_BOTH = 0b011;
76
77     public static final byte[] CASTLE_OPTS = {CASTLE_NONE, CASTLE_KING, CASTLE_QUEEN, CASTLE_BOTH};
78
79     public static final byte EN_PASSANT = 0b100;
80
81     public static final byte HALFMOVE = 0b010;
82     public static final byte FULLMOVE = 0b011;
83
84     public static final byte MIN_BYTE = 0x40;
85     public static final byte MAX_BYTE = 0x7F;
86
87     private static final byte[] REPLACE_TO =
88             {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2D};
89     private static final byte[] REPLACE_FROM =
90             {0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F};
91
92     public static final Charset OUTPUT_CHARSET = StandardCharsets.US_ASCII;
93
94     private static boolean onlyDiagram = true;
95
96     private TCD() {
97     }
98
99     public static void setDiagram(boolean isDiagram) {
100         onlyDiagram = isDiagram;
101     }
102
103     public static boolean isDiagram() {
104         return onlyDiagram;
105     }
106
107     public static void replaceTo(byte[] bytes) {
108         for (int i = 0; i < bytes.length; ++i) {
109             int j = frameSearch(REPLACE_FROM, bytes[i]);
110             if (j >= 0)
111                 bytes[i] = REPLACE_TO[j];
112         }
113     }
114
115     public static void replaceFrom(byte[] bytes) {
116         for (int i = 0; i < bytes.length; ++i) {
117             int j = frameSearch(REPLACE_TO, bytes[i]);
118             if (j >= 0)
119                 bytes[i] = REPLACE_FROM[j];
120         }
121     }
122
123     public static boolean isValid(byte[] bytes) {
124         if (bytes.length < 1)
125             return false;
126         for (byte bite : bytes) {
127             if (bite < MIN_BYTE)
128                 return false;
129         }
130         return true;
131     }
132
133     public static boolean isColor(byte frame) {
134         return frame == WHITE || frame == BLACK;
135     }
136
137     public static boolean isNotColor(byte frame) {
138         return !isColor(frame);
139     }
140
141     public static boolean isWhiteBlack(byte first, byte second) {
142         return first == WHITE && second == BLACK;
143     }
144
145     public static boolean isBlackWhite(byte first, byte second) {
146         return isWhiteBlack(second, first);
147     }
148
149     public static boolean isNotCastle(byte frame) {
150         return frameSearch(CASTLE_OPTS, frame) < 0;
151     }
152
153     private static int frameSearch(byte[] bytes, byte frame) {
154         for (int i = 0; i < bytes.length; ++i)
155             if (bytes[i] == frame)
156                 return i;
157         return -1;
158     }
159
160 }