mirror of
https://github.com/fooflington/wordsearch.git
synced 2025-07-12 10:42:29 +00:00
Compare commits
10 Commits
master
...
more-modes
Author | SHA1 | Date | |
---|---|---|---|
6e2767e066 | |||
f7b05f3183 | |||
e44b5356ab | |||
f869de337f | |||
21c558950c | |||
7d313a6baf | |||
cce371ecb4 | |||
d8a0ed6f5a | |||
b02ef52f65 | |||
cc2c7eee29 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,3 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
._.DS_Store
|
._.DS_Store
|
||||||
*.class
|
*.class
|
||||||
wordsearch.war
|
|
||||||
wordsearch.jar
|
|
||||||
|
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2018 Matthew Slowe
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
34
Makefile
34
Makefile
@ -1,34 +0,0 @@
|
|||||||
JAVA = /usr/bin/java
|
|
||||||
LIBS = .:war/WEB-INF/lib/commons-lang.jar:war/WEB-INF/lib/sqlite-jdbc.jar
|
|
||||||
JAVAC = /usr/bin/javac
|
|
||||||
JFLAGS = -g -classpath $(LIBS)
|
|
||||||
|
|
||||||
SRCS = uk/org/mafoo/wordsearch/CouldNotPlaceWordException.java \
|
|
||||||
uk/org/mafoo/wordsearch/Bounds.java \
|
|
||||||
uk/org/mafoo/wordsearch/GridFactory.java \
|
|
||||||
uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java \
|
|
||||||
uk/org/mafoo/wordsearch/Direction.java
|
|
||||||
|
|
||||||
JSPS = $(wildcard war/*.jsp war/*.css war/WEB-INF/jspf/*.jspf)
|
|
||||||
|
|
||||||
OBJS = ${SRCS:.java=.class}
|
|
||||||
|
|
||||||
.SUFFIXES: .java .class
|
|
||||||
|
|
||||||
.PHONY: default clean
|
|
||||||
default: wordsearch.war
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJS) wordsearch.jar wordsearch.war
|
|
||||||
|
|
||||||
.java.class:
|
|
||||||
$(JAVAC) $(JFLAGS) $<
|
|
||||||
|
|
||||||
wordsearch.jar: $(OBJS)
|
|
||||||
jar cf $@ $(OBJS)
|
|
||||||
|
|
||||||
war/WEB-INF/lib/wordsearch.jar: wordsearch.jar
|
|
||||||
cp $< $@
|
|
||||||
|
|
||||||
wordsearch.war: war/WEB-INF/lib/wordsearch.jar $(JSPS)
|
|
||||||
jar -cvf $@ -C war .
|
|
11
README.md
11
README.md
@ -12,4 +12,15 @@ A simple ```Makefile``` is provided:
|
|||||||
$ make
|
$ make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Once built, you need to make a "war" file to deploy to your J2EE container (tested on Tomcat)
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd war && jar cfv ../wordsearch.war .
|
||||||
|
```
|
||||||
Then deploy your war file :-)
|
Then deploy your war file :-)
|
||||||
|
|
||||||
|
Alternatively you can test-run the engine...
|
||||||
|
```
|
||||||
|
$ make run <wordlist.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
91
counties.txt
Executable file
91
counties.txt
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
Aberdeenshire
|
||||||
|
Anglesey
|
||||||
|
Angus
|
||||||
|
Antrim
|
||||||
|
Argyll
|
||||||
|
Armagh
|
||||||
|
Ayrshire
|
||||||
|
Banffshire
|
||||||
|
Bedfordshire
|
||||||
|
Berkshire
|
||||||
|
Berwickshire
|
||||||
|
Brecknockshire
|
||||||
|
Buckinghamshire
|
||||||
|
Buteshire
|
||||||
|
Caernarfonshire
|
||||||
|
Caithness
|
||||||
|
Cambridgeshire
|
||||||
|
Cardiganshire
|
||||||
|
Carmarthenshire
|
||||||
|
Cheshire
|
||||||
|
Clackmannanshire
|
||||||
|
Cornwall
|
||||||
|
Cromartyshire
|
||||||
|
Cumberland
|
||||||
|
Denbighshire
|
||||||
|
Derbyshire
|
||||||
|
Devon
|
||||||
|
Dorset
|
||||||
|
Down
|
||||||
|
Dumbartonshire
|
||||||
|
Dumfriesshire
|
||||||
|
Durham
|
||||||
|
East Lothian
|
||||||
|
Essex
|
||||||
|
Fermanagh
|
||||||
|
Fife
|
||||||
|
Flintshire
|
||||||
|
Glamorgan
|
||||||
|
Gloucestershire
|
||||||
|
Hampshire
|
||||||
|
Herefordshire
|
||||||
|
Hertfordshire
|
||||||
|
Huntingdonshire
|
||||||
|
Invernessshire
|
||||||
|
Kent
|
||||||
|
Kincardineshire
|
||||||
|
Kirkcudbrightshire
|
||||||
|
Lanarkshire
|
||||||
|
Lancashire
|
||||||
|
Leicestershire
|
||||||
|
Lincolnshire
|
||||||
|
Londonderry
|
||||||
|
Merionethshire
|
||||||
|
Middlesex
|
||||||
|
Midlothian
|
||||||
|
Monmouthshire
|
||||||
|
Montgomeryshire
|
||||||
|
Morayshire
|
||||||
|
Nairnshire
|
||||||
|
Norfolk
|
||||||
|
Northamptonshire
|
||||||
|
Northumberland
|
||||||
|
Nottinghamshire
|
||||||
|
Orkney
|
||||||
|
Oxfordshire
|
||||||
|
Peeblesshire
|
||||||
|
Pembrokeshire
|
||||||
|
Perthshire
|
||||||
|
Radnorshire
|
||||||
|
Renfrewshire
|
||||||
|
Rossshire
|
||||||
|
Roxburghshire
|
||||||
|
Rutland
|
||||||
|
Selkirkshire
|
||||||
|
Shetland
|
||||||
|
Shropshire
|
||||||
|
Somerset
|
||||||
|
Staffordshire
|
||||||
|
Stirlingshire
|
||||||
|
Suffolk
|
||||||
|
Surrey
|
||||||
|
Sussex
|
||||||
|
Sutherland
|
||||||
|
Tyrone
|
||||||
|
Warwickshire
|
||||||
|
West Lothian
|
||||||
|
Westmorland
|
||||||
|
Wigtownshire
|
||||||
|
Wiltshire
|
||||||
|
Worcestershire
|
||||||
|
Yorkshire
|
@ -1 +0,0 @@
|
|||||||
CREATE TABLE grids (id integer primary key, ts timestamp default current_timestamp, remotehost varchar, input, size_x int, size_y int, simple tinyint, result varchar);
|
|
52
tags
Executable file
52
tags
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||||
|
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||||
|
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
||||||
|
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
||||||
|
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
||||||
|
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
|
||||||
|
Bounds uk/org/mafoo/wordsearch/Bounds.java /^ protected Bounds(int min_y, int max_y, int min_x, int max_x) {$/;" m class:Bounds
|
||||||
|
Bounds uk/org/mafoo/wordsearch/Bounds.java /^class Bounds {$/;" c
|
||||||
|
CouldNotPlaceWordException uk/org/mafoo/wordsearch/CouldNotPlaceWordException.java /^ protected CouldNotPlaceWordException() {$/;" m class:CouldNotPlaceWordException
|
||||||
|
CouldNotPlaceWordException uk/org/mafoo/wordsearch/CouldNotPlaceWordException.java /^class CouldNotPlaceWordException extends Exception {$/;" c
|
||||||
|
Direction uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" g
|
||||||
|
DistributedRandomNumberGenerator uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java /^ public DistributedRandomNumberGenerator() {$/;" m class:DistributedRandomNumberGenerator
|
||||||
|
DistributedRandomNumberGenerator uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java /^public class DistributedRandomNumberGenerator {$/;" c
|
||||||
|
E uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
GridFactory uk/org/mafoo/wordsearch/GridFactory.java /^public class GridFactory {$/;" c
|
||||||
|
MAX_TRIES uk/org/mafoo/wordsearch/GridFactory.java /^ static final int MAX_TRIES = 500;$/;" f class:GridFactory
|
||||||
|
N uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
NE uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
NW uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
S uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
SE uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
SW uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
W uk/org/mafoo/wordsearch/Direction.java /^enum Direction { N, NE, E, SE, S, SW, W, NW; };$/;" e enum:Direction file:
|
||||||
|
addNumber uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java /^ public void addNumber(int value, double distribution) {$/;" m class:DistributedRandomNumberGenerator
|
||||||
|
chars uk/org/mafoo/wordsearch/GridFactory.java /^ private static char[] chars = new char[] {$/;" f class:GridFactory file:
|
||||||
|
clone2d uk/org/mafoo/wordsearch/GridFactory.java /^ private static char[][] clone2d(char[][] source) {$/;" m class:GridFactory file:
|
||||||
|
directions uk/org/mafoo/wordsearch/GridFactory.java /^ private static Direction[] directions = new Direction[] { Direction.N, Direction.NE, Direction.E, Direction.SE, Direction.S, Direction.SW, Direction.W, Direction.NW };$/;" f class:GridFactory file:
|
||||||
|
distSum uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java /^ private double distSum;$/;" f class:DistributedRandomNumberGenerator file:
|
||||||
|
distribution uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java /^ private HashMap<Integer, Double> distribution;$/;" f class:DistributedRandomNumberGenerator file:
|
||||||
|
drng uk/org/mafoo/wordsearch/GridFactory.java /^ static DistributedRandomNumberGenerator drng = new DistributedRandomNumberGenerator();$/;" f class:GridFactory
|
||||||
|
dump2d uk/org/mafoo/wordsearch/GridFactory.java /^ private static void dump2d(char[][] g) {$/;" m class:GridFactory file:
|
||||||
|
getBounds uk/org/mafoo/wordsearch/GridFactory.java /^ private static Bounds getBounds(int height, int width, Direction direction, int length) {$/;" m class:GridFactory file:
|
||||||
|
getDirection uk/org/mafoo/wordsearch/GridFactory.java /^ private static Direction getDirection(boolean simple) {$/;" m class:GridFactory file:
|
||||||
|
getDistributedRandomNumber uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java /^ public int getDistributedRandomNumber() {$/;" m class:DistributedRandomNumberGenerator
|
||||||
|
getRandomChar uk/org/mafoo/wordsearch/GridFactory.java /^ private static char getRandomChar() {$/;" m class:GridFactory file:
|
||||||
|
main uk/org/mafoo/wordsearch/GridFactory.java /^ public static void main(String[] args) throws IOException {$/;" m class:GridFactory
|
||||||
|
makeGrid uk/org/mafoo/wordsearch/GridFactory.java /^ public static char[][] makeGrid(List<String> words, int height, int width) {$/;" m class:GridFactory
|
||||||
|
makeGrid uk/org/mafoo/wordsearch/GridFactory.java /^ public static char[][] makeGrid(List<String> words, int height, int width, boolean simple) {$/;" m class:GridFactory
|
||||||
|
max_x uk/org/mafoo/wordsearch/Bounds.java /^ int max_x;$/;" f class:Bounds
|
||||||
|
max_y uk/org/mafoo/wordsearch/Bounds.java /^ int max_y;$/;" f class:Bounds
|
||||||
|
min_x uk/org/mafoo/wordsearch/Bounds.java /^ int min_x;$/;" f class:Bounds
|
||||||
|
min_y uk/org/mafoo/wordsearch/Bounds.java /^ int min_y;$/;" f class:Bounds
|
||||||
|
move_x uk/org/mafoo/wordsearch/GridFactory.java /^ private static int move_x(int x, Direction d) {$/;" m class:GridFactory file:
|
||||||
|
move_y uk/org/mafoo/wordsearch/GridFactory.java /^ private static int move_y(int y, Direction d) {$/;" m class:GridFactory file:
|
||||||
|
placeWord uk/org/mafoo/wordsearch/GridFactory.java /^ private static char[][] placeWord(String word, char[][] grid, boolean simple) throws CouldNotPlaceWordException {$/;" m class:GridFactory file:
|
||||||
|
rnd uk/org/mafoo/wordsearch/GridFactory.java /^ static Random rnd = new Random();$/;" f class:GridFactory
|
||||||
|
toString uk/org/mafoo/wordsearch/Bounds.java /^ public String toString() {$/;" m class:Bounds
|
||||||
|
uk.org.mafoo.wordsearch uk/org/mafoo/wordsearch/Bounds.java /^package uk.org.mafoo.wordsearch;$/;" p
|
||||||
|
uk.org.mafoo.wordsearch uk/org/mafoo/wordsearch/CouldNotPlaceWordException.java /^package uk.org.mafoo.wordsearch;$/;" p
|
||||||
|
uk.org.mafoo.wordsearch uk/org/mafoo/wordsearch/Direction.java /^package uk.org.mafoo.wordsearch;$/;" p
|
||||||
|
uk.org.mafoo.wordsearch uk/org/mafoo/wordsearch/DistributedRandomNumberGenerator.java /^package uk.org.mafoo.wordsearch;$/;" p
|
||||||
|
uk.org.mafoo.wordsearch uk/org/mafoo/wordsearch/GridFactory.java /^package uk.org.mafoo.wordsearch;$/;" p
|
9
test.txt
9
test.txt
@ -1,9 +0,0 @@
|
|||||||
Kitchen
|
|
||||||
Lounge
|
|
||||||
Study
|
|
||||||
Ballroom
|
|
||||||
Conservatory
|
|
||||||
Billiard Room
|
|
||||||
Library
|
|
||||||
Hall
|
|
||||||
Dining Room
|
|
@ -6,7 +6,7 @@ import java.util.*;
|
|||||||
public class GridFactory {
|
public class GridFactory {
|
||||||
|
|
||||||
static Random rnd = new Random();
|
static Random rnd = new Random();
|
||||||
static final int MAX_TRIES = 5000;
|
static final int MAX_TRIES = 500;
|
||||||
|
|
||||||
/* https://www.math.cornell.edu/~mec/2003-2004/cryptography/subs/frequencies.html */
|
/* https://www.math.cornell.edu/~mec/2003-2004/cryptography/subs/frequencies.html */
|
||||||
static DistributedRandomNumberGenerator drng = new DistributedRandomNumberGenerator();
|
static DistributedRandomNumberGenerator drng = new DistributedRandomNumberGenerator();
|
||||||
@ -61,8 +61,8 @@ public class GridFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Direction[] directions = new Direction[] { Direction.N, Direction.NE, Direction.E, Direction.SE, Direction.S, Direction.SW, Direction.W, Direction.NW };
|
private static Direction[] directions = new Direction[] { Direction.N, Direction.NE, Direction.E, Direction.SE, Direction.S, Direction.SW, Direction.W, Direction.NW };
|
||||||
private static Direction getDirection(boolean simple) {
|
private static Direction getDirection(Modes mode) {
|
||||||
if(simple) {
|
if(mode == Modes.SIMPLE || mode == Modes.CROSSWORD) {
|
||||||
return rnd.nextBoolean() ? Direction.E : Direction.S;
|
return rnd.nextBoolean() ? Direction.E : Direction.S;
|
||||||
} else {
|
} else {
|
||||||
return directions[rnd.nextInt(directions.length-1)];
|
return directions[rnd.nextInt(directions.length-1)];
|
||||||
@ -158,10 +158,6 @@ public class GridFactory {
|
|||||||
return makeGrid(words, height, width, false, true);
|
return makeGrid(words, height, width, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char[][] makeGrid(List<String> words, int height, int width, boolean simple) {
|
|
||||||
return makeGrid(words, height, width, simple, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char[][] makeGrid(List<String> words, int height, int width, boolean simple, boolean fill) {
|
public static char[][] makeGrid(List<String> words, int height, int width, boolean simple, boolean fill) {
|
||||||
char[][] grid = new char[height][width];
|
char[][] grid = new char[height][width];
|
||||||
|
|
||||||
@ -170,7 +166,7 @@ public class GridFactory {
|
|||||||
int tries = 0;
|
int tries = 0;
|
||||||
while(true) {
|
while(true) {
|
||||||
try {
|
try {
|
||||||
grid = placeWord(word, grid, simple);
|
grid = placeWord(word, grid, mode);
|
||||||
break;
|
break;
|
||||||
} catch (CouldNotPlaceWordException e) {
|
} catch (CouldNotPlaceWordException e) {
|
||||||
if(tries > MAX_TRIES) {
|
if(tries > MAX_TRIES) {
|
||||||
@ -184,8 +180,8 @@ public class GridFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mode != Modes.CROSSWORD) {
|
||||||
// Fill rest of grid
|
// Fill rest of grid
|
||||||
if(fill) {
|
|
||||||
for (int y=0; y<height; y++) {
|
for (int y=0; y<height; y++) {
|
||||||
for (int x=0; x<width; x++) {
|
for (int x=0; x<width; x++) {
|
||||||
if (grid[y][x] == Character.UNASSIGNED)
|
if (grid[y][x] == Character.UNASSIGNED)
|
||||||
@ -198,8 +194,8 @@ public class GridFactory {
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static char[][] placeWord(String word, char[][] grid, boolean simple) throws CouldNotPlaceWordException {
|
private static char[][] placeWord(String word, char[][] grid, Modes mode) throws CouldNotPlaceWordException {
|
||||||
Direction direction = getDirection(simple);
|
Direction direction = getDirection(mode);
|
||||||
Bounds b = getBounds(grid.length, grid[0].length, direction, word.length());
|
Bounds b = getBounds(grid.length, grid[0].length, direction, word.length());
|
||||||
// System.out.println("[" + word + "] bounds: " + b);
|
// System.out.println("[" + word + "] bounds: " + b);
|
||||||
|
|
||||||
@ -209,6 +205,7 @@ public class GridFactory {
|
|||||||
// System.out.println("[" + word + "] Placing @ " + x + "," + y + " going " + direction);
|
// System.out.println("[" + word + "] Placing @ " + x + "," + y + " going " + direction);
|
||||||
char[][] tempgrid = clone2d(grid);
|
char[][] tempgrid = clone2d(grid);
|
||||||
for( char c : word.toUpperCase().toCharArray() ) {
|
for( char c : word.toUpperCase().toCharArray() ) {
|
||||||
|
|
||||||
if(!Character.isLetter(c)) continue;
|
if(!Character.isLetter(c)) continue;
|
||||||
if(grid[y][x] != Character.UNASSIGNED) {
|
if(grid[y][x] != Character.UNASSIGNED) {
|
||||||
if (grid[y][x] != c) {
|
if (grid[y][x] != c) {
|
||||||
|
7
uk/org/mafoo/wordsearch/Modes.java
Executable file
7
uk/org/mafoo/wordsearch/Modes.java
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
package uk.org.mafoo.wordsearch;
|
||||||
|
|
||||||
|
public enum Modes {
|
||||||
|
NORMAL,
|
||||||
|
SIMPLE,
|
||||||
|
CROSSWORD;
|
||||||
|
}
|
22
uk/org/mafoo/wordsearch/Store.java
Executable file
22
uk/org/mafoo/wordsearch/Store.java
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
package uk.org.mafoo.wordsearch;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
|
||||||
|
class Store {
|
||||||
|
|
||||||
|
Connection conn = null;
|
||||||
|
|
||||||
|
protected Store(String dbfile) {
|
||||||
|
try {
|
||||||
|
Class.forName("org.sqlite.JDBC");
|
||||||
|
conn = DriverManager.getConnection("jdbc:sqlite:" + dbfile);
|
||||||
|
} catch ( Exception e ) {
|
||||||
|
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected storeInstance()
|
||||||
|
|
||||||
|
}
|
28
uk/org/mafoo/wordsearch/f
Executable file
28
uk/org/mafoo/wordsearch/f
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
Letter Frequency
|
||||||
|
E 12.02
|
||||||
|
T 9.10
|
||||||
|
A 8.12
|
||||||
|
O 7.68
|
||||||
|
I 7.31
|
||||||
|
N 6.95
|
||||||
|
S 6.28
|
||||||
|
R 6.02
|
||||||
|
H 5.92
|
||||||
|
D 4.32
|
||||||
|
L 3.98
|
||||||
|
U 2.88
|
||||||
|
C 2.71
|
||||||
|
M 2.61
|
||||||
|
F 2.30
|
||||||
|
Y 2.11
|
||||||
|
W 2.09
|
||||||
|
G 2.03
|
||||||
|
P 1.82
|
||||||
|
B 1.49
|
||||||
|
V 1.11
|
||||||
|
K 0.69
|
||||||
|
X 0.17
|
||||||
|
Q 0.11
|
||||||
|
J 0.10
|
||||||
|
Z 0.07
|
||||||
|
|
19
war/WEB-INF/jspf/footer.jspf
Normal file → Executable file
19
war/WEB-INF/jspf/footer.jspf
Normal file → Executable file
@ -1,3 +1,16 @@
|
|||||||
<div id="footer">
|
<!-- Piwik -->
|
||||||
Generated at: https://bombadil.mafoo.org.uk/wordsearch/
|
<script type="text/javascript">
|
||||||
</div>
|
var _paq = _paq || [];
|
||||||
|
// tracker methods like "setCustomDimension" should be called before "trackPageView"
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {
|
||||||
|
var u="//mafoo.org.uk/piwik/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||||
|
_paq.push(['setSiteId', '3']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<noscript><p><img src="//mafoo.org.uk/piwik/piwik.php?idsite=3&rec=1" style="border:0;" alt="" /></p></noscript>
|
||||||
|
<!-- End Piwik Code -->
|
||||||
|
BIN
war/WEB-INF/lib/sqlite-3.20.0.jar
Executable file
BIN
war/WEB-INF/lib/sqlite-3.20.0.jar
Executable file
Binary file not shown.
BIN
war/WEB-INF/lib/wordsearch.jar
Executable file
BIN
war/WEB-INF/lib/wordsearch.jar
Executable file
Binary file not shown.
@ -10,20 +10,4 @@
|
|||||||
Wordsearch building app
|
Wordsearch building app
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<param-name>sqlite_db</param-name>
|
|
||||||
<param-value>/tmp/wordsearch.db</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<security-constraint>
|
|
||||||
<web-resource-collection>
|
|
||||||
<web-resource-name>dump</web-resource-name>
|
|
||||||
<url-pattern>/dump.jsp</url-pattern>
|
|
||||||
</web-resource-collection>
|
|
||||||
<auth-constraint>
|
|
||||||
<role-name>admin</role-name>
|
|
||||||
</auth-constraint>
|
|
||||||
</security-constraint>
|
|
||||||
|
|
||||||
|
|
||||||
</web-app>
|
</web-app>
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Wordsearch Builder: About</title>
|
<title>Wordsearch Builder: About</title>
|
||||||
<link rel="stylesheet" type="text/css" href="base.css" />
|
<link rel="stylesheet" type="text/css" href="base.css" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500&family=Roboto:wght@500&display=swap" rel="stylesheet">
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
18
war/base.css
18
war/base.css
@ -1,5 +1,5 @@
|
|||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
@ -14,16 +14,17 @@ table, th, td {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table#grid td {
|
table#grid td {
|
||||||
font-family: 'Fira Mono', monospace;
|
font-family: monospace;
|
||||||
font-size: 14pt;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
align-content: center;
|
width: 80%;
|
||||||
|
margin: 0 auto 60px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wordsearch {
|
#wordsearch {
|
||||||
float: left;
|
float: left;
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#words {
|
#words {
|
||||||
@ -34,11 +35,8 @@ table#grid td {
|
|||||||
#footer {
|
#footer {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
bottom:0;
|
bottom:0;
|
||||||
}
|
width:100%;
|
||||||
|
height:60px; /* Height of the footer */
|
||||||
textarea#textarea_words {
|
|
||||||
font-family: 'Fira Mono', monospace;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only print {
|
@media only print {
|
||||||
|
@ -3,21 +3,21 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Wordsearch builder</title>
|
<title>Wordsearch builder</title>
|
||||||
<link rel="stylesheet" type="text/css" href="base.css" />
|
<link rel="stylesheet" type="text/css" href="base.css" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500&family=Roboto:wght@500&display=swap" rel="stylesheet">
|
|
||||||
</head>
|
</head>
|
||||||
<%@ page import="uk.org.mafoo.wordsearch.*" %>
|
<%@ page import="uk.org.mafoo.wordsearch.*" %>
|
||||||
<%@ page import="java.util.*" %>
|
<%@ page import="java.util.*" %>
|
||||||
<%@ page import="org.apache.commons.lang.StringUtils" %>
|
<%@ page import="org.apache.commons.lang.StringUtils" %>
|
||||||
<%@ page import="org.apache.commons.lang.StringEscapeUtils" %>
|
<%@ page import="org.apache.commons.lang.StringEscapeUtils" %>
|
||||||
<%@ page import="java.sql.*" %>
|
|
||||||
<%@ page import="org.sqlite.*" %>
|
|
||||||
|
|
||||||
<%@ page errorPage="error.jsp" %>
|
<%@ page errorPage="error.jsp" %>
|
||||||
<%
|
<%
|
||||||
|
|
||||||
int height = Integer.parseInt(request.getParameter("height"));
|
int height = Integer.parseInt(request.getParameter("height"));
|
||||||
int width = Integer.parseInt(request.getParameter("width"));
|
int width = Integer.parseInt(request.getParameter("width"));
|
||||||
boolean simple = request.getParameter("simple") != null;
|
Modes mode = Modes.NORMAL;
|
||||||
|
if(request.getParameter("mode") != null) {
|
||||||
|
if(request.getParameter("mode").equals("SIMPLE")) mode = Modes.SIMPLE;
|
||||||
|
if(request.getParameter("mode").equals("CROSSWORD")) mode = Modes.CROSSWORD;
|
||||||
|
}
|
||||||
String name = StringEscapeUtils.escapeHtml(request.getParameter("name"));
|
String name = StringEscapeUtils.escapeHtml(request.getParameter("name"));
|
||||||
|
|
||||||
if (request.getParameter("words").length() > 2048) { throw new Exception("Input too large"); }
|
if (request.getParameter("words").length() > 2048) { throw new Exception("Input too large"); }
|
||||||
@ -25,55 +25,25 @@
|
|||||||
|
|
||||||
List<String> words = new ArrayList<String>();
|
List<String> words = new ArrayList<String>();
|
||||||
for ( String line : request.getParameter("words").split("\r\n")) {
|
for ( String line : request.getParameter("words").split("\r\n")) {
|
||||||
words.add(line.trim().toLowerCase());
|
words.add(line.trim());
|
||||||
}
|
}
|
||||||
Collections.sort(words);
|
Collections.sort(words);
|
||||||
|
|
||||||
Connection conn = DriverManager.getConnection(
|
char[][] grid = GridFactory.makeGrid(words, height, width, mode);
|
||||||
"jdbc:sqlite:" + getServletContext().getRealPath("/WEB-INF/files/database.sqlite"));
|
|
||||||
PreparedStatement stmt = conn.prepareStatement(
|
|
||||||
"INSERT INTO grids (remotehost, input, size_x, size_y, simple) VALUES (?, ?, ?, ?, ?)",
|
|
||||||
Statement.RETURN_GENERATED_KEYS);
|
|
||||||
// PreparedStatement getlastid = conn.prepareStatement("select last_insert_rowid();");
|
|
||||||
PreparedStatement stmt2 = conn.prepareStatement("UPDATE grids SET result=? WHERE id=?");
|
|
||||||
|
|
||||||
stmt.setString(1, request.getRemoteHost());
|
String csv = "";
|
||||||
stmt.setString(2, words.toString());
|
|
||||||
stmt.setInt(3, height);
|
|
||||||
stmt.setInt(4, width);
|
|
||||||
stmt.setBoolean(5, simple);
|
|
||||||
stmt.executeUpdate();
|
|
||||||
ResultSet record_id_rs = stmt.getGeneratedKeys();
|
|
||||||
int record_id = -1;
|
|
||||||
if(record_id_rs.next()){
|
|
||||||
record_id = record_id_rs.getInt(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually generate the grid
|
|
||||||
char[][] grid = GridFactory.makeGrid(words, height, width, simple);
|
|
||||||
|
|
||||||
StringBuilder _csv = new StringBuilder();
|
|
||||||
for (char[] cs : grid) {
|
|
||||||
for(char c : cs) {
|
|
||||||
_csv.append(c);
|
|
||||||
_csv.append(",");
|
|
||||||
}
|
|
||||||
_csv.append("\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
String csv = _csv.toString();
|
|
||||||
|
|
||||||
stmt2.setString(1, csv);
|
|
||||||
stmt2.setInt(2, record_id);
|
|
||||||
stmt2.executeUpdate();
|
|
||||||
conn.close();
|
|
||||||
%>
|
%>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1><%= name %></h1>
|
<h1><%= name %></h1>
|
||||||
<div class="noprint">
|
<div class="noprint">
|
||||||
[ <a href="index.jsp">Start again</a> | <a id='csvdownload' href="data:text/csv;base64,<%= Base64.getEncoder().encodeToString(csv.getBytes()) %>">Download CSV</a> ]
|
[ <a href="index.jsp">Start again</a> | <a id='csvdownload'>Download CSV</a> ]
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
var csv = '<%= csv %>';
|
||||||
|
var csvdownload = document.getElementById('csvdownload');
|
||||||
|
csvdownload.href='data:text/csv;base64,' + btoa(csv);
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
@ -85,7 +55,7 @@
|
|||||||
<% for(char c : row) {
|
<% for(char c : row) {
|
||||||
csv += "" + c + ',';
|
csv += "" + c + ',';
|
||||||
%>
|
%>
|
||||||
<td class="cell"><%= c %></td>
|
<td class="cell"><%= c != Character.UNASSIGNED ? c : " " %></td>
|
||||||
<% } %>
|
<% } %>
|
||||||
</tr>
|
</tr>
|
||||||
<%
|
<%
|
||||||
|
53
war/db.jsp
53
war/db.jsp
@ -1,53 +0,0 @@
|
|||||||
<%@ page contentType="text/html" %>
|
|
||||||
<%@ page import="java.sql.*" %>
|
|
||||||
<%@ page import="org.sqlite.*" %>
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Database dump</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Database stats</h1>
|
|
||||||
<%
|
|
||||||
Connection conn =
|
|
||||||
DriverManager.getConnection("jdbc:sqlite:" + getServletContext().getRealPath("/WEB-INF/files/database.sqlite"));
|
|
||||||
Statement stmt = conn.createStatement();
|
|
||||||
ResultSet rs = stmt.executeQuery("select * from sqlite_master where type='table' and name='grids';");
|
|
||||||
if(rs.next()) {
|
|
||||||
// we have a row and are probably ok
|
|
||||||
} else {
|
|
||||||
// Initialise the schema
|
|
||||||
PreparedStatement pstmt = conn.prepareStatement("CREATE TABLE grids (id integer primary key, ts timestamp default current_timestamp, remotehost varchar, input, size_x int, size_y int, simple tinyint, result varchar);");
|
|
||||||
pstmt.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
rs.close();
|
|
||||||
|
|
||||||
PreparedStatement ps_count = conn.prepareStatement("SELECT COUNT(*) FROM grids");
|
|
||||||
PreparedStatement ps_last = conn.prepareStatement("SELECT max(ts) FROM grids;");
|
|
||||||
|
|
||||||
ResultSet rs_count = ps_count.executeQuery();
|
|
||||||
ResultSet rs_last = ps_last.executeQuery();
|
|
||||||
int count = -1;
|
|
||||||
String last = "unknown";
|
|
||||||
if(rs_count.next()) {
|
|
||||||
count = rs_count.getInt(1);
|
|
||||||
}
|
|
||||||
if(rs_last.next()) {
|
|
||||||
last = rs_last.getString(1);
|
|
||||||
}
|
|
||||||
rs_count.close();
|
|
||||||
rs_last.close();
|
|
||||||
%>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Number of grids generated: <%= count %></li>
|
|
||||||
<li>Last grid generated at: <%= last %></li>
|
|
||||||
<li>Path to db: <pre><%= getServletContext().getRealPath("/WEB-INF/files/database.sqlite") %></pre></li>
|
|
||||||
</ul>
|
|
||||||
</body>
|
|
||||||
<%
|
|
||||||
conn.close();
|
|
||||||
%>
|
|
||||||
</html>
|
|
50
war/dump.jsp
50
war/dump.jsp
@ -1,50 +0,0 @@
|
|||||||
<%@ page contentType="text/html" %>
|
|
||||||
<%@ page import="java.sql.*" %>
|
|
||||||
<%@ page import="org.sqlite.*" %>
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Database dump</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table border="1">
|
|
||||||
<thead>
|
|
||||||
<th>id</th>
|
|
||||||
<th>timestamp</th>
|
|
||||||
<th>remotehost</th>
|
|
||||||
<th>input</th>
|
|
||||||
<th>size_x</th>
|
|
||||||
<th>size_y</th>
|
|
||||||
<th>simple</th>
|
|
||||||
<th>result</th>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<%
|
|
||||||
Connection conn =
|
|
||||||
DriverManager.getConnection("jdbc:sqlite:" + getServletContext().getInitParameter("sqlite_db"));
|
|
||||||
Statement stat = conn.createStatement();
|
|
||||||
|
|
||||||
ResultSet rs = stat.executeQuery("select * from grids;");
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
out.println("<tr>");
|
|
||||||
out.println("<td>" + rs.getString("id") + "</td>");
|
|
||||||
out.println("<td>" + rs.getString("ts") + "</td>");
|
|
||||||
out.println("<td>" + rs.getString("remotehost") + "</td>");
|
|
||||||
out.println("<td><pre>" + rs.getString("input") + "</pre></td>");
|
|
||||||
out.println("<td>" + rs.getInt("size_x") + "</td>");
|
|
||||||
out.println("<td>" + rs.getInt("size_y") + "</td>");
|
|
||||||
out.println("<td>" + rs.getInt("simple") + "</td>");
|
|
||||||
out.println("<td><pre>" + rs.getString("result") + "</pre></td>");
|
|
||||||
out.println("</tr>");
|
|
||||||
}
|
|
||||||
|
|
||||||
rs.close();
|
|
||||||
conn.close();
|
|
||||||
%>
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
22
war/env.jsp
22
war/env.jsp
@ -1,22 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head></head>
|
|
||||||
<body>
|
|
||||||
<h1>Environment</h1>
|
|
||||||
<ul>
|
|
||||||
<li>You are connecting from: <%= request.getRemoteHost() %> (<%= request.getRemoteAddr() %>)</li>
|
|
||||||
<li>If present your X-Forwarded-For header is: <%= request.getHeader("X-Forwarded-For") %></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Header dump</h2>
|
|
||||||
<pre>
|
|
||||||
<%
|
|
||||||
for (java.util.Enumeration<String> headers = request.getHeaderNames(); headers.hasMoreElements(); ) {
|
|
||||||
String h = headers.nextElement();
|
|
||||||
%>
|
|
||||||
<%= h %>=<%= request.getHeader(h) %>
|
|
||||||
<%
|
|
||||||
}
|
|
||||||
%>
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
@ -3,7 +3,6 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Wordsearch Builder</title>
|
<title>Wordsearch Builder</title>
|
||||||
<link rel="stylesheet" type="text/css" href="base.css" />
|
<link rel="stylesheet" type="text/css" href="base.css" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500&family=Roboto:wght@500&display=swap" rel="stylesheet">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Wordsearch Builder</h1>
|
<h1>Wordsearch Builder</h1>
|
||||||
@ -12,7 +11,7 @@
|
|||||||
<h2>Words</h2>
|
<h2>Words</h2>
|
||||||
<form action="build.jsp" method="post">
|
<form action="build.jsp" method="post">
|
||||||
Name: <input type="text" size="25" name="name" value="Wordsearch"><br />
|
Name: <input type="text" size="25" name="name" value="Wordsearch"><br />
|
||||||
<textarea id="textarea_words" name="words" rows="10">
|
<textarea name="words" rows="10">
|
||||||
Kitchen
|
Kitchen
|
||||||
Lounge
|
Lounge
|
||||||
Study
|
Study
|
||||||
@ -26,7 +25,9 @@ Dining Room
|
|||||||
<br />
|
<br />
|
||||||
<input type="number" name="height" min="3" max="50" value="15" />
|
<input type="number" name="height" min="3" max="50" value="15" />
|
||||||
<input type="number" name="width" min="3" max="50" value="15" />
|
<input type="number" name="width" min="3" max="50" value="15" />
|
||||||
<input type="checkbox" name="simple" value="yes">Simple [<span class="tooltip" title="In simple mode, words are only placed Left-to-Right or Top-to-Bottom">?</span>]</span>
|
<input type="radio" name="mode" value="NORMAL" checked />Normal
|
||||||
|
<input type="radio" name="mode" value="SIMPLE" />Simple[<span class="tooltip" title="In simple mode, words are only placed Left-to-Right or Top-to-Bottom">?</span>]
|
||||||
|
<input type="radio" name="mode" value="CROSSWORD" />Crossword
|
||||||
<input type="submit" value="Build!" />
|
<input type="submit" value="Build!" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
BIN
wordsearch.jar
Executable file
BIN
wordsearch.jar
Executable file
Binary file not shown.
BIN
wordsearch.war
Executable file
BIN
wordsearch.war
Executable file
Binary file not shown.
Reference in New Issue
Block a user