001package ball.game.scrabble;
002/*-
003 * ##########################################################################
004 * Game Applications and Utilities
005 * %%
006 * Copyright (C) 2010 - 2022 Allen D. Ball
007 * %%
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *      http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 * ##########################################################################
020 */
021import ball.util.CoordinateMap;
022import java.util.ArrayList;
023import java.util.List;
024import java.util.ResourceBundle;
025import java.util.TreeMap;
026
027import static java.util.Collections.copy;
028
029/**
030 * Scrabble {@link Board}.
031 *
032 * {@include Board.properties}
033 *
034 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
035 */
036public class Board extends CoordinateMap<SQ> {
037    private static final long serialVersionUID = -399826193477575690L;
038
039    private static final ResourceBundleMap MAP = new ResourceBundleMap(Board.class);
040
041    /**
042     * Sole public constructor.
043     */
044    public Board() { this(MAP); }
045
046    private Board(ResourceBundleMap map) {
047        super(map.size(), map.size());
048
049        copy(asList(), squares(map));
050    }
051
052    private static List<? extends SQ> squares(ResourceBundleMap map) {
053        ArrayList<SQ> list = null;
054
055        try {
056            var n = map.size();
057
058            list = new ArrayList<SQ>(n * n);
059
060            var pkg = SQ.class.getPackage().getName();
061
062            for (String value : map.values()) {
063                var names = value.split("[\\p{Space}]+", n);
064
065                for (int i = 0; i < n; i += 1) {
066                    var name = pkg + "." + names[i];
067
068                    try {
069                        list.add((SQ) Class.forName(name).getDeclaredConstructor().newInstance());
070                    } catch (Exception exception) {
071                        list.add(new SQ());
072                    }
073                }
074            }
075        } catch (Exception exception) {
076            throw new ExceptionInInitializerError(exception);
077        }
078
079        return list;
080    }
081
082    private static class ResourceBundleMap extends TreeMap<String,String> {
083        private static final long serialVersionUID = 5871194943402587641L;
084
085        public ResourceBundleMap(Class<? extends Board> type) {
086            super();
087
088            ResourceBundle bundle = ResourceBundle.getBundle(type.getName());
089
090            for (String key : bundle.keySet()) {
091                put(key, bundle.getString(key).trim());
092            }
093        }
094    }
095}