Initial commit
This commit is contained in:
commit
f83c07c460
14 changed files with 470 additions and 0 deletions
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
7
.idea/encodings.xml
Normal file
7
.idea/encodings.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
14
.idea/misc.xml
Normal file
14
.idea/misc.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="graalvm-ce-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
124
.idea/uiDesigner.xml
Normal file
124
.idea/uiDesigner.xml
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
26
pom.xml
Normal file
26
pom.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>eu.m724</groupId>
|
||||
<artifactId>crossword-generator</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.jfree/org.jfree.svg -->
|
||||
<dependency>
|
||||
<groupId>org.jfree</groupId>
|
||||
<artifactId>org.jfree.svg</artifactId>
|
||||
<version>5.0.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
25
src/main/java/eu/m724/Crossword.java
Normal file
25
src/main/java/eu/m724/Crossword.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package eu.m724;
|
||||
|
||||
/**
|
||||
* Represents the crossword<br>
|
||||
* A tile is a single letter
|
||||
*
|
||||
* @param width Width (x) in tiles
|
||||
* @param height Height (y) in tiles
|
||||
* @param solution The solution
|
||||
* @param words Words of the crossword
|
||||
*/
|
||||
public record Crossword(
|
||||
int width, int height,
|
||||
String solution,
|
||||
PlacedWord[] words
|
||||
) {
|
||||
/**
|
||||
* Render as SVG
|
||||
*
|
||||
* @return SVG file content
|
||||
*/
|
||||
public String render() {
|
||||
return Renderer.render(this);
|
||||
}
|
||||
}
|
96
src/main/java/eu/m724/CrosswordBuilder.java
Normal file
96
src/main/java/eu/m724/CrosswordBuilder.java
Normal file
|
@ -0,0 +1,96 @@
|
|||
package eu.m724;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Easily builds {@link Crossword}s<br>
|
||||
* TODO bad javadoc
|
||||
*/
|
||||
public class CrosswordBuilder {
|
||||
private int width, height;
|
||||
private String solution;
|
||||
private Set<Word> words = new HashSet<>();
|
||||
private Set<PlacedWord> placedWords = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link CrosswordBuilder}
|
||||
*
|
||||
* @param width The width of the crossword
|
||||
* @param height The height of the crossword
|
||||
* @param solution The solution
|
||||
*/
|
||||
public CrosswordBuilder(int width, int height, String solution) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.solution = solution.toLowerCase();
|
||||
System.out.printf("Initialized builder of %dx%d with solution \"%s\"\n", width, height, solution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a word.
|
||||
*
|
||||
* @param word The word
|
||||
* @param hint the hint / clue
|
||||
* @return This exact {@link CrosswordBuilder}
|
||||
*/
|
||||
public CrosswordBuilder addWord(String word, String hint) {
|
||||
return addWord(new Word(word.toLowerCase(), hint));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a word.
|
||||
*
|
||||
* @param word The word
|
||||
* @return This exact {@link CrosswordBuilder}
|
||||
*/
|
||||
public CrosswordBuilder addWord(Word word) {
|
||||
this.words.add(word);
|
||||
System.out.println("Word added: " + word.word());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple words.
|
||||
*
|
||||
* @param words The words
|
||||
* @return This exact {@link CrosswordBuilder}
|
||||
*/
|
||||
public CrosswordBuilder addWords(Word... words) {
|
||||
this.words.addAll(Set.of(words));
|
||||
System.out.println("Multiple words added: " + String.join(", ", Arrays.stream(words).map(Word::word).toList()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CrosswordBuilder generate() {
|
||||
System.out.println("Generator invoked");
|
||||
placedWords = Generator.generate(width, height, solution, words.toArray(Word[]::new));
|
||||
System.out.println("Generator done");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link Crossword}
|
||||
*
|
||||
* @throws SizeMismatchException When not all words have been placed. Or too many, for some reason.
|
||||
* @return The {@link Crossword}
|
||||
*/
|
||||
public Crossword build() throws SizeMismatchException { // TODO maybe it should be unchecked
|
||||
System.out.println("Building");
|
||||
// TODO
|
||||
if (words.size() != placedWords.size()) {
|
||||
throw new SizeMismatchException("Words: %d, placed: %d".formatted(words.size(), placedWords.size()));
|
||||
}
|
||||
return new Crossword(width, height, solution, placedWords.toArray(PlacedWord[]::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* When not all words have been placed. Or too many, for some reason.
|
||||
*/
|
||||
public static class SizeMismatchException extends Exception {
|
||||
public SizeMismatchException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
45
src/main/java/eu/m724/Generator.java
Normal file
45
src/main/java/eu/m724/Generator.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package eu.m724;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class Generator {
|
||||
public static Set<PlacedWord> generate(int width, int height, String solution, Word[] words) {
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
Set<PlacedWord> placedWords = new HashSet<>(words.length);
|
||||
|
||||
System.out.printf("Generator running with %d words\n", words.length);
|
||||
|
||||
boolean vertical = random.nextBoolean();
|
||||
for (int i=0; i<words.length; i++) {
|
||||
Word word = words[i];
|
||||
placedWords.add(new PlacedWord(0, i, false, word));
|
||||
vertical = !vertical;
|
||||
}
|
||||
|
||||
return placedWords;
|
||||
}
|
||||
|
||||
private static PlacedWord getWordAt(int x, int y, Set<PlacedWord> placedWords) {
|
||||
for (PlacedWord placedWord : placedWords) {
|
||||
if (placedWord == null) continue;
|
||||
|
||||
if (placedWord.vertical()) {
|
||||
if (placedWord.x() == x) {
|
||||
if (y >= placedWord.y() && y <= placedWord.y() + placedWord.wordLength() - 1) {
|
||||
return placedWord;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (placedWord.y() == y) {
|
||||
if (x >= placedWord.x() && x <= placedWord.y() + placedWord.wordLength() - 1) {
|
||||
return placedWord;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
20
src/main/java/eu/m724/Main.java
Normal file
20
src/main/java/eu/m724/Main.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package eu.m724;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws CrosswordBuilder.SizeMismatchException {
|
||||
CrosswordBuilder builder = new CrosswordBuilder(20, 20, "ardour")
|
||||
.addWord("cat", "Furry feline pet")
|
||||
.addWord("sun", "Bright star in our sky")
|
||||
.addWord("book", "Bound pages with a story")
|
||||
.addWord("tree", "Woody plant with branches")
|
||||
.addWord("blue", "Color of a clear sky")
|
||||
.addWord("door", "Entrance to a room")
|
||||
.generate();
|
||||
|
||||
Crossword crossword = builder.build();
|
||||
|
||||
System.out.println(crossword.render());
|
||||
|
||||
System.out.println("Hello world!");
|
||||
}
|
||||
}
|
20
src/main/java/eu/m724/PlacedWord.java
Normal file
20
src/main/java/eu/m724/PlacedWord.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package eu.m724;
|
||||
|
||||
/**
|
||||
* Represents a placement of a word
|
||||
*
|
||||
* @param x x of the first letter
|
||||
* @param y y of the first letter
|
||||
* @param vertical is the word, from the first letter, downwards (true), or rightwards (false)
|
||||
* @param word the word
|
||||
*/
|
||||
public record PlacedWord(
|
||||
int x,
|
||||
int y,
|
||||
boolean vertical,
|
||||
Word word
|
||||
) {
|
||||
public int wordLength() {
|
||||
return word.word().length();
|
||||
}
|
||||
}
|
29
src/main/java/eu/m724/Renderer.java
Normal file
29
src/main/java/eu/m724/Renderer.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package eu.m724;
|
||||
|
||||
import org.jfree.svg.SVGGraphics2D;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class Renderer {
|
||||
public static String render(Crossword crossword) {
|
||||
SVGGraphics2D g2 = new SVGGraphics2D(crossword.width() * 10, crossword.height() * 10);
|
||||
g2.setPaint(Color.BLACK);
|
||||
|
||||
for (PlacedWord word : crossword.words()) {
|
||||
int x = word.x();
|
||||
int y = word.y();
|
||||
|
||||
if (word.vertical()) {
|
||||
for (int _y=y; _y<y+word.wordLength(); _y++) {
|
||||
g2.draw(new Rectangle(x * 10, _y * 10, 10, 10));
|
||||
}
|
||||
} else {
|
||||
for (int _x=x; _x<x+word.wordLength(); _x++) {
|
||||
g2.draw(new Rectangle(_x * 10, y * 10, 10, 10));
|
||||
}
|
||||
}
|
||||
}
|
||||
//g2.draw(new Rectangle(10, 10, 280, 180));
|
||||
return g2.getSVGDocument();
|
||||
}
|
||||
}
|
17
src/main/java/eu/m724/Word.java
Normal file
17
src/main/java/eu/m724/Word.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package eu.m724;
|
||||
|
||||
/**
|
||||
* Represents a word and a hint.<br>
|
||||
* The word should be lowercase. TODO make that not a requirement
|
||||
*
|
||||
* @param word the word
|
||||
* @param hint the hint / clue
|
||||
*/
|
||||
public record Word(
|
||||
String word,
|
||||
String hint
|
||||
) {
|
||||
public int length() {
|
||||
return word.length();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue