From ccafd673bfcda89a75f428e58dc06525e1b0a368 Mon Sep 17 00:00:00 2001 From: gotty Date: Fri, 19 Apr 2019 03:31:04 +0300 Subject: [PATCH] [LIB-9] Add functional for build image chess diagrams --- .../hedgecode/chess/img/AbstractImageLoader.java | 54 +++++++++++ .../org/hedgecode/chess/img/DiagramBuilder.java | 79 +++++++++++---- .../java/org/hedgecode/chess/img/ImageBuilder.java | 4 +- .../org/hedgecode/chess/img/ImageConstants.java | 41 ++++++++ .../org/hedgecode/chess/img/ImageException.java | 36 +++++++ .../java/org/hedgecode/chess/img/ImageFilter.java | 67 +++++++++++++ .../java/org/hedgecode/chess/img/ImageFormat.java | 17 ++++ .../java/org/hedgecode/chess/img/ImageLoader.java | 39 ++++++++ .../java/org/hedgecode/chess/img/board/Board.java | 75 +++++++++++++++ .../org/hedgecode/chess/img/board/BoardLoader.java | 106 +++++++++++++++++++++ .../org/hedgecode/chess/img/board/SquarePair.java | 66 +++++++++++++ .../org/hedgecode/chess/img/piece/PieceSet.java | 99 +++++++++++++++++++ .../hedgecode/chess/img/piece/PieceSetLoader.java | 94 ++++++++++++++++++ .../java/org/hedgecode/chess/position/Color.java | 32 ++++++- 14 files changed, 788 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java create mode 100644 src/main/java/org/hedgecode/chess/img/ImageConstants.java create mode 100644 src/main/java/org/hedgecode/chess/img/ImageException.java create mode 100644 src/main/java/org/hedgecode/chess/img/ImageFilter.java create mode 100644 src/main/java/org/hedgecode/chess/img/ImageLoader.java create mode 100644 src/main/java/org/hedgecode/chess/img/board/Board.java create mode 100644 src/main/java/org/hedgecode/chess/img/board/BoardLoader.java create mode 100644 src/main/java/org/hedgecode/chess/img/board/SquarePair.java create mode 100644 src/main/java/org/hedgecode/chess/img/piece/PieceSet.java create mode 100644 src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java diff --git a/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java b/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java new file mode 100644 index 0000000..4bed015 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-2019. 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.img; + +import java.io.File; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public abstract class AbstractImageLoader implements ImageLoader { + + protected static final File IMAGES_PATH = new File( + ImageLoader.class.getResource( + ImageConstants.RESOURCE_ROOT_DIR + ImageConstants.RESOURCE_IMAGES_DIR + ).getPath() + ); + + private Type loadType; + + public AbstractImageLoader() { + this.loadType = Type.STATELESS; + } + + protected abstract void clear(); + + @Override + public Type loadType() { + return loadType; + } + + protected void setLoadType(Type loadType) { + if (Type.STATELESS.equals(loadType)) { + clear(); + } + this.loadType = loadType; + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java b/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java index 17ff21a..c059361 100644 --- a/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java +++ b/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java @@ -16,13 +16,24 @@ package org.hedgecode.chess.img; +import java.awt.Graphics; import java.awt.Image; -import java.util.HashSet; -import java.util.Set; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; +import java.util.Map; import javax.imageio.ImageIO; +import org.hedgecode.chess.img.board.Board; +import org.hedgecode.chess.img.board.BoardLoader; +import org.hedgecode.chess.img.piece.PieceSet; +import org.hedgecode.chess.img.piece.PieceSetLoader; +import org.hedgecode.chess.position.ColorPiece; import org.hedgecode.chess.position.Position; +import org.hedgecode.chess.position.Positions; +import org.hedgecode.chess.position.Square; /** * @@ -33,28 +44,53 @@ public class DiagramBuilder implements ImageBuilder { private static ImageBuilder _instance = new DiagramBuilder(); + private BoardLoader boardLoader; + private PieceSetLoader pieceSetLoader; + private DiagramBuilder() { + boardLoader = new BoardLoader(); + pieceSetLoader = new PieceSetLoader(); } @Override public String build(Position position) { - - return ""; + return ""; // todo } @Override - public Image build(Position position, String type) { - // BufferedImage - // Image image = ImageIO.read(new URL(urlname)); - // Graphics.drawImage() - -/* - Image image = ImageIO.read(new File("f://image1.jpg")); - - ImageIO.write(image, "JPEG", new File("f://image2.jpg")); -*/ - - return null; + public RenderedImage build(Position position, String boardType, String pieceType) + throws ImageException + { + Map squares = position.getSquares(); + + Board board = boardLoader.load(boardType); + PieceSet pieces = pieceSetLoader.load(pieceType); + + if (board == null || pieces == null) { + throw new ImageException("Couldn't find image resources!"); // todo: locale + } + + int squareSize = board.squareSize(); + + BufferedImage diagram = board.render(); + Graphics diagramGraphics = diagram.getGraphics(); + for (int y = 0; y < Square.getSize(); ++y) { + for (int x = 0; x < Square.getSize(); ++x) { + Square square = Square.getSquare(x, Square.getSize() - (y + 1)); + ColorPiece colorPiece = squares.get(square); + if (colorPiece != null) { + diagramGraphics.drawImage( + pieces.get(colorPiece).getScaledInstance( + squareSize, squareSize, Image.SCALE_SMOOTH + ), + x * squareSize, + y * squareSize, + null + ); + } + } + } + return diagram; } public static ImageBuilder getInstance() { @@ -62,7 +98,15 @@ public class DiagramBuilder implements ImageBuilder { } - public static void main(String[] args) { + public static void main(String[] args) throws IOException, ImageException { + + ImageIO.write( + DiagramBuilder.getInstance().build(Positions.INITIAL.getPosition(), "test", "shade"), + ImageFormat.PNG.name(), + new File("chessboard" + "." + ImageFormat.PNG.getExt()) + ); + +/* String[] formatNames; Set set = new HashSet<>(); @@ -91,6 +135,7 @@ public class DiagramBuilder implements ImageBuilder { for (String formatName : formatNames) set.add(formatName.toLowerCase()); System.out.println("Supported write MIME types: " + set); +*/ } } diff --git a/src/main/java/org/hedgecode/chess/img/ImageBuilder.java b/src/main/java/org/hedgecode/chess/img/ImageBuilder.java index 45537d5..fd79aa0 100644 --- a/src/main/java/org/hedgecode/chess/img/ImageBuilder.java +++ b/src/main/java/org/hedgecode/chess/img/ImageBuilder.java @@ -16,7 +16,7 @@ package org.hedgecode.chess.img; -import java.awt.Image; +import java.awt.image.RenderedImage; import org.hedgecode.chess.position.Builder; import org.hedgecode.chess.position.Position; @@ -30,6 +30,6 @@ public interface ImageBuilder extends Builder { String build(Position position); - Image build(Position position, String type); + RenderedImage build(Position position, String boardType, String pieceType) throws ImageException; } diff --git a/src/main/java/org/hedgecode/chess/img/ImageConstants.java b/src/main/java/org/hedgecode/chess/img/ImageConstants.java new file mode 100644 index 0000000..f4b4d44 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/ImageConstants.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2019. 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.img; + +/** + * Store of image constants. + * + * @author Dmitry Samoshin aka gotty + */ +public final class ImageConstants { + + public static final String RESOURCE_ROOT_DIR = "/"; + + public static final String RESOURCE_IMAGES_DIR = "images"; + public static final String RESOURCE_SQUARES_DIR = "squares"; + public static final String RESOURCE_PIECES_DIR = "pieces"; + + public static final String DARK_SQUARE_FILENAME = "dark"; + public static final String LIGHT_SQUARE_FILENAME = "light"; + + private ImageConstants() { + throw new AssertionError( + "No org.hedgecode.chess.img.ImageConstants instances!" + ); + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/ImageException.java b/src/main/java/org/hedgecode/chess/img/ImageException.java new file mode 100644 index 0000000..4a24b80 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/ImageException.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2019. 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.img; + +/** + * Image working Exception. + * + * @author Dmitry Samoshin aka gotty + */ +public class ImageException extends Exception { + + private String message; + + public ImageException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/ImageFilter.java b/src/main/java/org/hedgecode/chess/img/ImageFilter.java new file mode 100644 index 0000000..27c238e --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/ImageFilter.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018-2019. 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.img; + +import java.io.File; +import java.io.FilenameFilter; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class ImageFilter implements FilenameFilter { + + private static final String[] IMAGES_EXTS = ImageFormat.getAllExts(); + + private String[] names; + + public ImageFilter() { + this.names = null; + } + + public ImageFilter(String[] names) { + this.names = names; + } + + @Override + public boolean accept(File dir, String name) { + return isImageName(name) && isImageExt(name); + } + + private boolean isImageName(String name) { + if (names != null) { + name = name.substring(0, name.lastIndexOf('.')); + for (String imageName : names) { + if (imageName.equalsIgnoreCase(name)) + return true; + } + return false; + } + return true; + } + + private boolean isImageExt(String ext) { + ext = ext.substring(ext.lastIndexOf('.') + 1); + for (String imageExt : IMAGES_EXTS) { + if (imageExt.equalsIgnoreCase(ext)) + return true; + } + return false; + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/ImageFormat.java b/src/main/java/org/hedgecode/chess/img/ImageFormat.java index 26954ab..e5122fd 100644 --- a/src/main/java/org/hedgecode/chess/img/ImageFormat.java +++ b/src/main/java/org/hedgecode/chess/img/ImageFormat.java @@ -16,6 +16,10 @@ package org.hedgecode.chess.img; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import javax.imageio.ImageIO; /** @@ -36,6 +40,8 @@ public enum ImageFormat { private boolean isRead; private boolean isWrite; + private static String[] allAvailableExts; + ImageFormat(String[] exts) { fortmatExts = exts; isRead = isExist( @@ -72,6 +78,17 @@ public enum ImageFormat { return null; } + public static String[] getAllExts() { + if (allAvailableExts == null) { + List listExts = new ArrayList<>(); + for (ImageFormat imageFormat : ImageFormat.values()) { + listExts.addAll(Arrays.asList(imageFormat.getExts())); + } + allAvailableExts = listExts.toArray(new String[listExts.size()]); + } + return allAvailableExts; + } + private static boolean isExist(String[] names, String... args) { for (String arg : args) { for (String name : names) { diff --git a/src/main/java/org/hedgecode/chess/img/ImageLoader.java b/src/main/java/org/hedgecode/chess/img/ImageLoader.java new file mode 100644 index 0000000..1eee4c2 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/ImageLoader.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-2019. 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.img; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface ImageLoader { + + enum Type { + + STATELESS, + STATEFUL + + } + + T load(String name) throws ImageException; + + void unload(String name); + + Type loadType(); + +} diff --git a/src/main/java/org/hedgecode/chess/img/board/Board.java b/src/main/java/org/hedgecode/chess/img/board/Board.java new file mode 100644 index 0000000..f251e13 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/board/Board.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018-2019. 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.img.board; + +import java.awt.Graphics; +import java.awt.image.BufferedImage; + +import org.hedgecode.chess.position.Square; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class Board { + + private SquarePair squares; + private int squareSize; + + Board(SquarePair squares) { + this.squares = squares; + int width = Math.max(squares.getDark().getWidth(), squares.getLight().getWidth()); + int height = Math.max(squares.getDark().getHeight(), squares.getLight().getHeight()); + this.squareSize = Math.max(width, height); + } + + public int squareSize() { + return squareSize; + } + + public int boardSize() { + return squareSize * Square.getSize(); + } + + public BufferedImage render() { + BufferedImage board = new BufferedImage( + squareSize * Square.getSize(), + squareSize * Square.getSize(), + BufferedImage.TYPE_INT_ARGB + ); + Graphics boardGraphics = board.getGraphics(); + for (int y = 0; y < Square.getSize(); ++y) { + for (int x = 0; x < Square.getSize(); ++x) { + boardGraphics.drawImage( + (x + y) % 2 == 0 + ? squares.getLight() + : squares.getDark(), + x * squareSize, + y * squareSize, + null + ); + } + } + return board; + } + + public static Board create(SquarePair squares) { + return new Board(squares); + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java b/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java new file mode 100644 index 0000000..4c2c18d --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018-2019. 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.img.board; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.imageio.ImageIO; + +import org.hedgecode.chess.img.AbstractImageLoader; +import org.hedgecode.chess.img.ImageConstants; +import org.hedgecode.chess.img.ImageException; +import org.hedgecode.chess.img.ImageFilter; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class BoardLoader extends AbstractImageLoader { + + private static final File SQUARES_PATH = new File(IMAGES_PATH, ImageConstants.RESOURCE_SQUARES_DIR); + + private static final String SQUARE_DARK = ImageConstants.DARK_SQUARE_FILENAME; + private static final String SQUARE_LIGHT = ImageConstants.LIGHT_SQUARE_FILENAME; + + private static final String[] SQUARE_NAMES = {SQUARE_DARK, SQUARE_LIGHT}; + + private Map squareSetMap = new HashMap<>(); + + @Override + public Board load(String name) throws ImageException { + Board board = null; + SquarePair squarePair = null; + if (Type.STATELESS.equals(loadType()) || !squareSetMap.containsKey(name)) { + File boardPath = new File(SQUARES_PATH, name); + if (boardPath.exists() && boardPath.isDirectory()) { + squarePair = loadSquares(name, boardPath); + } + if (squarePair != null) { + board = Board.create(squarePair); + if (Type.STATEFUL.equals(loadType())) { + squareSetMap.put(name, board); + } + } + } else { + board = squareSetMap.get(name); + } + return board; + } + + @Override + public void unload(String name) { + if (Type.STATEFUL.equals(loadType()) && squareSetMap.containsKey(name)) { + squareSetMap.remove(name); + } + } + + @Override + protected void clear() { + squareSetMap.clear(); + } + + private SquarePair loadSquares(String name, File boardPath) throws ImageException { + BufferedImage dark = null, light = null; + File[] images = boardPath.listFiles(new ImageFilter(SQUARE_NAMES)); + if (images != null) { + for (File image : images) { + if (image.isFile()) { + String filename = image.getName(); + try { + switch (filename.substring(0, filename.lastIndexOf('.'))) { + case SQUARE_DARK: + dark = ImageIO.read(image); + break; + case SQUARE_LIGHT: + light = ImageIO.read(image); + break; + } + } catch (IOException e) { + throw new ImageException(e.getMessage()); // todo: locale + } + } + } + } + return (dark != null && light != null) ? SquarePair.create(dark, light) : null; + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/board/SquarePair.java b/src/main/java/org/hedgecode/chess/img/board/SquarePair.java new file mode 100644 index 0000000..836d273 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/board/SquarePair.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018-2019. 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.img.board; + +import java.awt.image.BufferedImage; +import java.util.Objects; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class SquarePair { + + private final T dark; + private final T light; + + SquarePair(T dark, T light) { + this.dark = dark; + this.light = light; + } + + public T getDark() { + return dark; + } + + public T getLight() { + return light; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof SquarePair)) { + return false; + } + SquarePair that = (SquarePair) o; + + return Objects.equals(this.dark, that.dark) + && Objects.equals(this.light, that.light); + } + + @Override + public int hashCode() { + return (dark == null ? 0 : dark.hashCode()) + ^ (light == null ? 0 : light.hashCode()); + } + + public static SquarePair create(BufferedImage dark, BufferedImage light) { + return new SquarePair<>(dark, light); + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java b/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java new file mode 100644 index 0000000..342ba1a --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018-2019. 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.img.piece; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hedgecode.chess.position.Color; +import org.hedgecode.chess.position.ColorPiece; +import org.hedgecode.chess.position.Piece; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class PieceSet { + + private Map pieceSetMap = new HashMap<>(); + + private static String[] allPieceNames; + + PieceSet() { + } + + public void add(String name, BufferedImage image) { + if (name != null && name.length() == 2) { + name = name.toLowerCase(); + ColorPiece colorPiece = ColorPiece.getColorPiece( + Color.byLetter(name.charAt(0)), + Piece.byLetter(name.charAt(1)) + ); + if (colorPiece != null){ + add(colorPiece, image); + } + } + } + + public void add(ColorPiece colorPiece, BufferedImage image) { + if (pieceSetMap.containsKey(colorPiece)) { + pieceSetMap.replace(colorPiece, image); + } else { + pieceSetMap.put(colorPiece, image); + } + } + + public BufferedImage get(ColorPiece colorPiece) { + return pieceSetMap.get(colorPiece); + } + + public boolean isFull() { + for (ColorPiece colorPiece : ColorPiece.values()) { + if (!pieceSetMap.containsKey(colorPiece) + || (pieceSetMap.get(colorPiece) == null)) { + return false; + } + } + return true; + } + + public static String[] getAllPieceNames() { + if (allPieceNames == null) { + List listNames = new ArrayList<>(); + for (Color color : Color.values()) { + for (Piece piece : Piece.values()) { + listNames.add( + String.valueOf( + new char[] {color.letter(), piece.letter()} + ) + ); + } + } + allPieceNames = listNames.toArray(new String[listNames.size()]); + } + return allPieceNames; + } + + public static PieceSet create() { + return new PieceSet(); + } + +} diff --git a/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java b/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java new file mode 100644 index 0000000..f069ba9 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2018-2019. 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.img.piece; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.imageio.ImageIO; + +import org.hedgecode.chess.img.AbstractImageLoader; +import org.hedgecode.chess.img.ImageConstants; +import org.hedgecode.chess.img.ImageException; +import org.hedgecode.chess.img.ImageFilter; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class PieceSetLoader extends AbstractImageLoader { + + private static final File PIECES_PATH = new File(IMAGES_PATH, ImageConstants.RESOURCE_PIECES_DIR); + + private static final String[] PIECES_NAMES = PieceSet.getAllPieceNames(); + + private Map pieceSetMap = new HashMap<>(); + + @Override + public PieceSet load(String name) throws ImageException { + PieceSet pieceSet = null; + if (Type.STATELESS.equals(loadType()) || !pieceSetMap.containsKey(name)) { + File piecePath = new File(PIECES_PATH, name); + if (piecePath.exists() && piecePath.isDirectory()) { + pieceSet = loadPieces(piecePath); + } + if (Type.STATEFUL.equals(loadType()) && pieceSet != null) { + pieceSetMap.put(name, pieceSet); + } + } else { + pieceSet = pieceSetMap.get(name); + } + return pieceSet; + } + + @Override + public void unload(String name) { + if (Type.STATEFUL.equals(loadType()) && pieceSetMap.containsKey(name)) { + pieceSetMap.remove(name); + } + } + + @Override + protected void clear() { + pieceSetMap.clear(); + } + + private PieceSet loadPieces(File piecePath) throws ImageException { + PieceSet pieceSet = PieceSet.create(); + File[] images = piecePath.listFiles(new ImageFilter(PIECES_NAMES)); + if (images != null) { + for (File image : images) { + if (image.isFile()) { + String filename = image.getName(); + try { + pieceSet.add( + filename.substring(0, filename.lastIndexOf('.')), + ImageIO.read(image) + ); + } catch (IOException e) { + throw new ImageException(e.getMessage()); // todo: locale + } + } + } + } + return pieceSet.isFull() ? pieceSet : null; + } + +} diff --git a/src/main/java/org/hedgecode/chess/position/Color.java b/src/main/java/org/hedgecode/chess/position/Color.java index 742dc0d..79878d9 100644 --- a/src/main/java/org/hedgecode/chess/position/Color.java +++ b/src/main/java/org/hedgecode/chess/position/Color.java @@ -23,7 +23,35 @@ package org.hedgecode.chess.position; */ public enum Color { - WHITE, - BLACK + WHITE ('w'), + BLACK ('b'); + + private char letter; + + Color(char letter) { + this.letter = letter; + } + + public char letter() { + return letter; + } + + public static Color byLetter(char letter) { + for (Color color : Color.values()) { + if (color.letter() == letter) + return color; + } + return null; + } + + public static Color byLetter(String letter) { + if (letter == null || letter.length() != 1) + return null; + for (Color color : Color.values()) { + if (color.letter() == letter.charAt(0)) + return color; + } + return null; + } } -- 2.10.0