001package ball.game.crossword; 002/*- 003 * ########################################################################## 004 * Game Applications and Utilities 005 * $Id: Cell.java 5285 2020-02-05 04:23:21Z ball $ 006 * $HeadURL: svn+ssh://svn.hcf.dev/var/spool/scm/repository.svn/ball-game/trunk/src/main/java/ball/game/crossword/Cell.java $ 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 java.util.List; 024import java.util.stream.Collectors; 025 026import static java.lang.Character.isDigit; 027import static java.lang.Character.isLetter; 028import static java.lang.Character.isLowerCase; 029import static java.lang.Character.toLowerCase; 030import static java.lang.Character.toUpperCase; 031 032/** 033 * Crossword {@link Puzzle} {@link Cell}. 034 * 035 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball} 036 * @version $Revision: 5285 $ 037 */ 038public class Cell implements Cloneable { 039 private static final Block BLOCK = new Block(); 040 041 private final Boolean special; 042 private Character solution = null; 043 044 private Cell(boolean special) { this.special = special; } 045 046 private Cell(boolean special, Character solution) { 047 this(special); 048 049 setSolution(solution); 050 } 051 052 public boolean isBlock() { return false; } 053 054 public boolean isSpecial() { return special; } 055 056 public boolean isSolved() { return solution != null; } 057 058 public Character getSolution() { return solution; } 059 public void setSolution(Character solution) { this.solution = solution; } 060 061 @Override 062 public Cell clone() throws CloneNotSupportedException { 063 return (Cell) super.clone(); 064 } 065 066 @Override 067 public String toString() { 068 char representation = '.'; 069 070 if (isSolved()) { 071 representation = getSolution(); 072 073 if (isSpecial()) { 074 representation = toLowerCase(representation); 075 } else { 076 representation = toUpperCase(representation); 077 } 078 } 079 080 return String.valueOf(representation); 081 } 082 083 /** 084 * Factory method to produce a {@link Cell}. 085 * 086 * @param character The {@code char} representing the 087 * {@link Cell}. 088 * 089 * @return The new {@link Cell}. 090 */ 091 public static Cell getInstance(char character) { 092 Cell cell = null; 093 094 switch (character) { 095 case '.': 096 cell = new Cell(false); 097 break; 098 099 case '#': 100 cell = BLOCK; 101 break; 102 103 default: 104 if (isLetter(character)) { 105 cell = 106 new Cell(isLowerCase(character), toUpperCase(character)); 107 } else if (isDigit(character)) { 108 cell = new Cell(false, character); 109 } else { 110 throw new IllegalArgumentException(String.valueOf(character)); 111 } 112 break; 113 } 114 115 return cell; 116 } 117 118 public static List<Cell> getRowFrom(String line) { 119 return (line.chars() 120 .mapToObj(c -> getInstance((char) c)) 121 .collect(Collectors.toList())); 122 } 123 124 private static class Block extends Cell { 125 private Block() { super(false); } 126 127 @Override 128 public boolean isBlock() { return true; } 129 130 @Override 131 public boolean isSolved() { return true; } 132 133 @Override 134 public void setSolution(Character solution) { 135 throw new IllegalStateException(); 136 } 137 138 @Override 139 public String toString() { return "#"; } 140 } 141}