001package ball.game.scrabble;
002/*-
003 * ##########################################################################
004 * Game Applications and Utilities
005 * $Id: SQ.html 5431 2020-02-12 19:03:17Z ball $
006 * $HeadURL: svn+ssh://svn.hcf.dev/var/spool/scm/repository.svn/hcf-dev/blog/2019-07-08-fivethirtyeight-best-scrabble-string/src/main/resources/javadoc/src-html/ball/game/scrabble/SQ.html $
007 * %%
008 * Copyright (C) 2010 - 2020 Allen D. Ball
009 * %%
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 *
014 *      http://www.apache.org/licenses/LICENSE-2.0
015 *
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 * ##########################################################################
022 */
023import static java.util.Objects.requireNonNull;
024
025/**
026 * Scrabble {@link Board} square.
027 *
028 * {@bean.info}
029 *
030 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
031 * @version $Revision: 5431 $
032 */
033public class SQ {
034    private final int letterPremium;
035    private final int wordPremium;
036    private Tile tile = null;
037    private char letter = ' ';
038    private String string = null;
039
040    /**
041     * Sole public constructor.
042     */
043    public SQ() { this("."); }
044
045    /**
046     * Protected constructor to specify the {@link SQ} representation.
047     *
048     * @param   string          The {@link String} representation of this
049     *                          {@link SQ} if no {@link Tile} has been
050     *                          played.
051     */
052    protected SQ(String string) {
053        if (getClass().getAnnotation(LetterPremium.class) != null) {
054            letterPremium =
055                getClass().getAnnotation(LetterPremium.class).value();
056        } else {
057            letterPremium = 0;
058        }
059
060        if (getClass().getAnnotation(WordPremium.class) != null) {
061            wordPremium = getClass().getAnnotation(WordPremium.class).value();
062        } else {
063            wordPremium = 0;
064        }
065
066        this.string = requireNonNull(string, "string");
067    }
068
069    public boolean isPremium() {
070        return (letterPremium > 1 || wordPremium > 1);
071    }
072
073    /**
074     * @return  The letter premium value.
075     *
076     * @see LetterPremium
077     */
078    public int getLetterPremium() { return letterPremium; }
079
080    /**
081     * @return  The word premium value.
082     *
083     * @see WordPremium
084     */
085    public int getWordPremium() { return wordPremium; }
086
087    public boolean isEmpty() { return (tile == null); }
088
089    public void play(Tile tile) { play(tile, tile.getLetter()); }
090
091    public void play(Tile tile, char letter) {
092        if (isEmpty()) {
093            this.tile = tile;
094            this.letter = letter;
095        } else {
096            throw new IllegalStateException();
097        }
098
099        if (tile.isBlank()) {
100            string = String.valueOf(letter).toLowerCase();
101        } else {
102            string = tile.toString().toUpperCase();
103        }
104    }
105
106    @Override
107    public String toString() { return string; }
108}