diff --git a/output_path/test/src/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/TestBoard b/output_path/test/src/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/TestBoard
new file mode 100644
index 000000000..a41ad749c
--- /dev/null
+++ b/output_path/test/src/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/TestBoard
@@ -0,0 +1,19 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
diff --git a/output_path/test/src/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion b/output_path/test/src/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion
new file mode 100644
index 000000000..49dae4aa6
--- /dev/null
+++ b/output_path/test/src/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion
@@ -0,0 +1,19 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
diff --git a/output_path/test/src/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/a b/output_path/test/src/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/a
new file mode 100644
index 000000000..e69de29bb
diff --git a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 1 b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 1
new file mode 100644
index 000000000..42ccf371b
--- /dev/null
+++ b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 1
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 2 b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 2
new file mode 100644
index 000000000..d73caa5d2
--- /dev/null
+++ b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 2
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 3 b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 3
new file mode 100644
index 000000000..99ec9769b
--- /dev/null
+++ b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 3
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 1 b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 1
new file mode 100644
index 000000000..d203617c8
--- /dev/null
+++ b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 1
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 2 b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 2
new file mode 100644
index 000000000..db56f04f3
--- /dev/null
+++ b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 2
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 3 b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 3
new file mode 100644
index 000000000..11940a6eb
--- /dev/null
+++ b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 3
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/10x10 Binary Very Hard/10x10 Binary Very Hard 1 b/puzzles files/binary/10x10 Binary Very Hard/10x10 Binary Very Hard 1
new file mode 100644
index 000000000..828a450cf
--- /dev/null
+++ b/puzzles files/binary/10x10 Binary Very Hard/10x10 Binary Very Hard 1
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 1 b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 1
new file mode 100644
index 000000000..7b22ffc10
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 1
@@ -0,0 +1,22 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
\ No newline at end of file
diff --git a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 2 b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 2
new file mode 100644
index 000000000..ea8ef93b0
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 2
@@ -0,0 +1,21 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 3 b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 3
new file mode 100644
index 000000000..0f0ff745e
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 3
@@ -0,0 +1,25 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 4 b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 4
new file mode 100644
index 000000000..da76d067b
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 4
@@ -0,0 +1,28 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 5 b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 5
new file mode 100644
index 000000000..a1ea13988
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 5
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 1 b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 1
new file mode 100644
index 000000000..5f7f72a8a
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 1
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 2 b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 2
new file mode 100644
index 000000000..a4ed30c31
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 2
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 3 b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 3
new file mode 100644
index 000000000..fc0e413c1
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 3
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 1 b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 1
new file mode 100644
index 000000000..a5ab8a2dc
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 1
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 2 b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 2
new file mode 100644
index 000000000..4be5fdaad
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 2
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 3 b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 3
new file mode 100644
index 000000000..eba370cab
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 3
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 1 b/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 1
new file mode 100644
index 000000000..faa68fa5e
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 1
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 2 b/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 2
new file mode 100644
index 000000000..3c707bdaa
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 2
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 3 b/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 3
new file mode 100644
index 000000000..217a032d8
--- /dev/null
+++ b/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 3
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 1 b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 1
new file mode 100644
index 000000000..befd674f9
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 1
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 2 b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 2
new file mode 100644
index 000000000..724426c26
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 2
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 3 b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 3
new file mode 100644
index 000000000..92a96c72b
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 3
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 1 b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 1
new file mode 100644
index 000000000..34eaf8388
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 1
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 2 b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 2
new file mode 100644
index 000000000..9ef23277e
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 2
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 3 b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 3
new file mode 100644
index 000000000..287ff6f68
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 3
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 1 b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 1
new file mode 100644
index 000000000..47dae23dc
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 1
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 2 b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 2
new file mode 100644
index 000000000..ae4cb8bb0
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 2
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 3 b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 3
new file mode 100644
index 000000000..2f951ecc4
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 3
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 1 b/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 1
new file mode 100644
index 000000000..9c875523b
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 1
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 2 b/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 2
new file mode 100644
index 000000000..14f2e4ad2
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 2
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 3 b/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 3
new file mode 100644
index 000000000..ad319a4b7
--- /dev/null
+++ b/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 3
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/puzzles files/light-color-theme.txt b/puzzles files/light-color-theme.txt
new file mode 100644
index 000000000..5c45bc71b
--- /dev/null
+++ b/puzzles files/light-color-theme.txt
@@ -0,0 +1,99 @@
+correct: BLUE
+incorrect: RED
+error: RED_700
+info: GRAY_900
+ui-movement: GRAY_300
+password-field-background: LIGHT_BLUE_400
+password-field-unfocused-background: GRAY_200
+progress-bar-background: GRAY_200
+progress-bar-foreground: LIGHT_BLUE_400
+text-field-background: LIGHT_BLUE_400
+text-field-unfocused-background: GRAY_200
+light-line-border: GRAY_200
+thick-line-border: GRAY_200
+data-selection-background: GRAY
+element-view: BLACK
+button-highlight: GRAY_300
+button-background: GRAY_200
+button-foreground: BLACK
+checkbox-background: WHITE
+checkbox-foreground: BLACK
+combobox-background: WHITE
+combobox-foreground: BLACK
+combobox-button-background: GRAY_300
+combobox-selection-background: WHITE
+combobox-selection-foreground: BLACK
+combobox-selected-in-drop-down-background: GRAY_200
+label-background: WHITE
+label-foreground: BLACK
+menu-background: LIGHT_BLUE_100
+menu-foreground: BLACK
+menu-selection-background: GRAY_200
+menu-selection-foreground: BLACK
+menu-disabled-foreground: #000
+menu-bar-background: WHITE
+menu-bar-foreground: BLACK
+menu-item-disabled-foreground: #000
+menu-item-selection-background: GRAY_200
+menu-item-selection-foreground: BLACK
+menu-item-background: WHITE
+menu-item-foreground: BLACK
+option-pane-background: WHITE
+panel-background-color: WHITE
+popup-menu-background: WHITE
+popup-menu-foreground: BLACK
+radio-button-background: WHITE
+radio-button-foreground: BLACK
+spinner-background: WHITE
+spinner-foreground: BLACK
+spinner-arrow-button-background: GRAY_200
+scroll-bar-track: GRAY_200
+scroll-bar-thumb: GRAY_300
+scroll-bar-thumb-dark-shadow: GRAY_300
+scroll-bar-thumb-highlight: GRAY_300
+scroll-bar-thumb-shadow: GRAY_300
+scroll-bar-arrow-button-background: GRAY_300
+scroll-pane-background: WHITE
+slider-background: WHITE
+slider-foreground: GRAY_700
+slider-track-color: BLACK
+split-pane-background: WHITE
+tabbed-pane-background: WHITE
+tabbed-pane-foreground: BLACK
+tabbed-pane-highlight: GRAY_200
+tabbed-pane-border-highlight: GRAY_300
+table-selection-background: GRAY_100
+table-selection-foreground: BLACK
+table-background: WHITE
+table-grid-color: GRAY_200
+table-header-background: GRAY_200
+text-area-background: GRAY_200
+text-area-foreground: BLACK
+toggle-button-background: WHITE
+toggle-button-foreground: BLACK
+tool-bar-background: WHITE
+tool-bar-foreground: BLACK
+tool-bar-docking-background: LIGHT_GREEN_A100
+tool-bar-floating-background: GRAY_200
+tree-selection-foreground: BLACK
+tree-foreground: BLACK
+tree-selection-background: GRAY_200
+tree-background: WHITE
+radio-button-menu-item-foreground: BLACK
+radio-button-menu-item-selection-foreground: BLACK
+radio-button-menu-item-selection-background: GRAY_200
+checkbox-menu-item-selection-background: GRAY_200
+checkbox-menu-item-foreground: BLACK
+checkbox-menu-item-selection-foreground: BLACK
+text-pane-background: GRAY_50
+text-pane-selection-background: LIGHT_BLUE_200
+text-pane-inactive-foreground: GRAY_500
+editor-pane-background: GRAY_50
+editor-pane-selection-background: LIGHT_BLUE_200
+editor-pane-inactive-foreground: GRAY_500
+separator-background: GRAY_300
+separator-foreground: GRAY_300
+tool-tip-background: GRAY_500
+tool-tip-foreground: GRAY_50
+color-chooser-background: WHITE
+color-chooser-foreground: BLACK
diff --git a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml
deleted file mode 100644
index b86e16ff2..000000000
--- a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
-
-
-
-
- |
-
-
-
-
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal1.xml b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal1.xml
deleted file mode 100644
index 110dd9abe..000000000
--- a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal1.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal2.xml b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal2.xml
deleted file mode 100644
index 49efeba59..000000000
--- a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal2.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml
deleted file mode 100644
index 855943612..000000000
--- a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml
deleted file mode 100644
index c1d7770f6..000000000
--- a/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml
deleted file mode 100644
index cab0a0a5e..000000000
--- a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
-
-
-
-
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml
deleted file mode 100644
index 70b81e376..000000000
--- a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml
deleted file mode 100644
index c541ece06..000000000
--- a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml
deleted file mode 100644
index 02dd5d6c0..000000000
--- a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml
deleted file mode 100644
index 0df84ef62..000000000
--- a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml
deleted file mode 100644
index 725c91d7f..000000000
--- a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/app/Config.java b/src/main/java/edu/rpi/legup/app/Config.java
index 3d212a597..b04ef9b88 100644
--- a/src/main/java/edu/rpi/legup/app/Config.java
+++ b/src/main/java/edu/rpi/legup/app/Config.java
@@ -96,6 +96,11 @@ public static String convertDisplayNameToClassName(String displayName) {
return className;
}
+ /**
+ * Gets a list of all available puzzle display names
+ *
+ * @return a List of puzzle display names as Strings
+ */
public List getPuzzleNames() {
List names = new LinkedList();
for (String puzzle : this.getPuzzleClassNames()) {
diff --git a/src/main/java/edu/rpi/legup/app/GameBoardFacade.java b/src/main/java/edu/rpi/legup/app/GameBoardFacade.java
index 12f6b73d0..c6f92e5b5 100644
--- a/src/main/java/edu/rpi/legup/app/GameBoardFacade.java
+++ b/src/main/java/edu/rpi/legup/app/GameBoardFacade.java
@@ -89,6 +89,11 @@ public void initializeUI() {
});
}
+ /**
+ * Sets the current puzzle in the game board
+ *
+ * @param puzzle the Puzzle to set
+ */
public void setPuzzle(Puzzle puzzle) {
this.puzzle = puzzle;
this.puzzleSolver.setPuzzleView(puzzle);
@@ -113,11 +118,21 @@ public static void setupConfig() {
GameBoardFacade.getInstance().setConfig(config);
}
+ /**
+ * Sets the current puzzle editor with the given puzzle
+ *
+ * @param puzzle the Puzzle to set in the editor
+ */
public void setPuzzleEditor(Puzzle puzzle) {
this.puzzle = puzzle;
this.puzzleEditor.setPuzzleView(puzzle);
}
+ /**
+ * Sets the configuration object for the GameBoardFacade
+ *
+ * @param config config the Config object to set
+ */
public void setConfig(Config config) {
this.config = config;
}
@@ -176,7 +191,7 @@ public boolean validateTextInput(String game, String[] statements) throws Runtim
}
/**
- * Loads an empty puzzle
+ * Loads an empty puzzle with the specified dimensions
*
* @param game name of the puzzle
* @param rows the number of rows on the board
@@ -187,10 +202,10 @@ public void loadPuzzle(String game, int rows, int columns) throws RuntimeExcepti
String qualifiedClassName = config.getPuzzleClassForName(game);
LOGGER.debug("Loading " + qualifiedClassName);
- try {
- Class> c = Class.forName(qualifiedClassName);
- Constructor> cons = c.getConstructor();
- Puzzle puzzle = (Puzzle) cons.newInstance();
+ try {
+ Class> c = Class.forName(qualifiedClassName);
+ Constructor> cons = c.getConstructor();
+ Puzzle puzzle = (Puzzle) cons.newInstance();
PuzzleImporter importer = puzzle.getImporter();
if (importer == null) {
@@ -225,6 +240,12 @@ public void loadPuzzle(String game, int rows, int columns) throws RuntimeExcepti
}
}
+ /**
+ * Loads an empty puzzle with the specified input
+ *
+ * @param game name of the puzzle
+ * @param statements an array of statements to load the puzzle with
+ */
public void loadPuzzle(String game, String[] statements) {
String qualifiedClassName = config.getPuzzleClassForName(game);
LOGGER.debug("Loading " + qualifiedClassName);
@@ -267,7 +288,7 @@ public void loadPuzzle(String game, String[] statements) {
}
/**
- * Loads a puzzle file
+ * Loads a puzzle file from the specified file
*
* @param fileName file name of the board file
* @throws InvalidFileFormatException if the file format is invalid or if the file cannot be
diff --git a/src/main/java/edu/rpi/legup/app/InvalidConfigException.java b/src/main/java/edu/rpi/legup/app/InvalidConfigException.java
index 2526b3776..cad80b5ce 100644
--- a/src/main/java/edu/rpi/legup/app/InvalidConfigException.java
+++ b/src/main/java/edu/rpi/legup/app/InvalidConfigException.java
@@ -5,6 +5,11 @@
* errors
*/
public class InvalidConfigException extends Exception {
+ /**
+ * Constructs a new InvalidConfigException with the specified detail message
+ *
+ * @param message the detail message
+ */
public InvalidConfigException(String message) {
super(message);
}
diff --git a/src/main/java/edu/rpi/legup/app/LegupPreferences.java b/src/main/java/edu/rpi/legup/app/LegupPreferences.java
index 0bca27b49..3d17233bd 100644
--- a/src/main/java/edu/rpi/legup/app/LegupPreferences.java
+++ b/src/main/java/edu/rpi/legup/app/LegupPreferences.java
@@ -81,7 +81,7 @@ public class LegupPreferences {
* Gets the legup preferences singleton instance This method ensures that only one instance of
* LegupPreferences exists
*
- * @return legup preferences
+ * @return the singleton instance of LegupPreferences
*/
public static LegupPreferences getInstance() {
if (instance == null) {
@@ -100,23 +100,30 @@ private LegupPreferences() {}
* Gets the user preference by the string key
*
* @param key key name of the preference
- * @return value of the preference
+ * @return value of the preference or {@code null} if the preference does not exist
*/
public String getUserPref(String key) {
return preferencesMap.get(key);
}
/**
- * Gets the user preference by the string key, value pair
+ * Sets the user preference for the specified key to the provided value
*
- * @param key key name of the preference
- * @param value value of the preference
+ * @param key key to set for the preference
+ * @param value value to set for the preference
*/
public void setUserPref(String key, String value) {
preferences.put(key, value);
preferencesMap.put(key, value);
}
+ /**
+ * Retrieves the user preference associated with the specified key as a boolean
+ *
+ * @param key the key for the preference to retrieve
+ * @return the boolean value of the preference
+ * @throws RuntimeException if the preference value cannot be interpreted as a boolean
+ */
public boolean getUserPrefAsBool(String key) {
if (preferencesMap.get(key).equalsIgnoreCase(Boolean.toString(true))) {
return true;
@@ -129,10 +136,20 @@ public boolean getUserPrefAsBool(String key) {
}
}
+ /**
+ * Gets the saved path
+ *
+ * @return the saved path as a String
+ */
public String getSavedPath() {
return SAVED_PATH;
}
+ /**
+ * Sets the saved path to the specified value
+ *
+ * @param path the new saved path
+ */
public void setSavedPath(String path) {
SAVED_PATH = path;
}
diff --git a/src/main/java/edu/rpi/legup/controller/Controller.java b/src/main/java/edu/rpi/legup/controller/Controller.java
index 4910e24d9..823bac716 100644
--- a/src/main/java/edu/rpi/legup/controller/Controller.java
+++ b/src/main/java/edu/rpi/legup/controller/Controller.java
@@ -24,6 +24,11 @@ public Controller() {
pan = false;
}
+ /**
+ * Sets the ScrollView instance that this controller manages
+ *
+ * @param viewer The ScrollView instance to be set
+ */
public void setViewer(ScrollView viewer) {
this.viewer = viewer;
}
diff --git a/src/main/java/edu/rpi/legup/controller/EditorElementController.java b/src/main/java/edu/rpi/legup/controller/EditorElementController.java
index 9922ccaed..050f5bd65 100644
--- a/src/main/java/edu/rpi/legup/controller/EditorElementController.java
+++ b/src/main/java/edu/rpi/legup/controller/EditorElementController.java
@@ -25,19 +25,33 @@ public EditorElementController() {
prevButton = null;
}
+ /**
+ * Sets the ElementController instance for this controller
+ *
+ * @param elementController the ElementController instance to be set
+ */
public void setElementController(ElementController elementController) {
this.elementController = elementController;
}
+ /**
+ * Handles the event when a button associated with an Element is pressed
+ *
+ * @param element the Element associated with the button that was pressed
+ */
public void buttonPressed(Element element) {
// TODO: implement what happens when element is pressed
- System.out.printf("%s button pressed!\n", element.getElementName());
if (elementController != null) {
elementController.setSelectedElement(element);
}
}
+ /**
+ * Handles action events triggered by buttons
+ *
+ * @param e the event to be processed
+ */
@Override
public void actionPerformed(ActionEvent e) {
lastSource = e.getSource();
diff --git a/src/main/java/edu/rpi/legup/controller/ElementController.java b/src/main/java/edu/rpi/legup/controller/ElementController.java
index 5840650e1..436b078b9 100644
--- a/src/main/java/edu/rpi/legup/controller/ElementController.java
+++ b/src/main/java/edu/rpi/legup/controller/ElementController.java
@@ -26,13 +26,17 @@
import java.awt.*;
import java.awt.event.*;
+/**
+ * The ElementController class manages UI interactions related to elements in a {@link BoardView}.
+ * It handles mouse events, key events, and actions related to element selection and manipulation
+ */
public class ElementController
implements MouseListener, MouseMotionListener, ActionListener, KeyListener {
protected BoardView boardView;
private Element selectedElement;
/**
- * ElementController Constructor controller to handles ui events associated interacting with a
+ * ElementController Constructor controller to handle ui events associated interacting with a
* {@link BoardView}
*/
public ElementController() {
@@ -86,6 +90,7 @@ public void mouseReleased(MouseEvent e) {
if (boardView == null) {
boardView = getInstance().getLegupUI().getEditorBoardView();
}
+
Board board = boardView.getBoard();
ElementView elementView = boardView.getElement(e.getPoint());
TreeViewSelection selection = null;
@@ -137,17 +142,8 @@ public void mouseReleased(MouseEvent e) {
if (this.boardView.getBoard() instanceof TreeTentBoard) {
scaledPoint.setLocation(scaledPoint.getX() - 1, scaledPoint.getY() - 1);
}
- System.out.printf(
- "selected Element is NOT null, attempting to change board at (%d, %d)\n",
- scaledPoint.x, scaledPoint.y);
- // System.out.println("Before: " + b.getCell(scaledPoint.x,
- // scaledPoint.y).getData());
+
b.setCell(scaledPoint.x, scaledPoint.y, this.selectedElement, e);
- // System.out.println("After: " + b.getCell(scaledPoint.x,
- // scaledPoint.y).getData());
- // } else {
- // System.out.println("selected Element is null!");
- // }
boardView.repaint();
}
diff --git a/src/main/java/edu/rpi/legup/history/CommandError.java b/src/main/java/edu/rpi/legup/history/CommandError.java
index f848485eb..78027f6ab 100644
--- a/src/main/java/edu/rpi/legup/history/CommandError.java
+++ b/src/main/java/edu/rpi/legup/history/CommandError.java
@@ -25,10 +25,20 @@ public enum CommandError {
private String value;
+ /**
+ * Constructs a CommandError with the specified error message
+ *
+ * @param value The error message associated with the command error
+ */
CommandError(String value) {
this.value = value;
}
+ /**
+ * Returns the error message associated with this CommandError
+ *
+ * @return The error message
+ */
@Override
public String toString() {
return value;
diff --git a/src/main/java/edu/rpi/legup/history/CommandState.java b/src/main/java/edu/rpi/legup/history/CommandState.java
index 90e44b70c..b72f15480 100644
--- a/src/main/java/edu/rpi/legup/history/CommandState.java
+++ b/src/main/java/edu/rpi/legup/history/CommandState.java
@@ -12,10 +12,20 @@ public enum CommandState {
private String value;
+ /**
+ * Constructs a CommandState with the specified state name
+ *
+ * @param value The name associated with the command state
+ */
CommandState(String value) {
this.value = value;
}
+ /**
+ * Returns the name associated with this CommandState
+ *
+ * @return The state name
+ */
@Override
public String toString() {
return value;
diff --git a/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java b/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java
index f56437400..bfd9cd7f5 100644
--- a/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java
+++ b/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java
@@ -32,6 +32,9 @@ public void executeCommand() {
Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
List selectedViews = selection.getSelectedViews();
+ if (selectedViews.isEmpty()) {
+ return;
+ }
TreeElementView firstSelectedView = selectedViews.get(0);
TreeElementView newSelectedView;
@@ -48,6 +51,7 @@ public void executeCommand() {
}
for (TreeElementView selectedView : selectedViews) {
+ System.out.println("DELETED");
TreeElement element = selectedView.getTreeElement();
tree.removeTreeElement(element);
puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(element));
diff --git a/src/main/java/edu/rpi/legup/history/EditDataCommand.java b/src/main/java/edu/rpi/legup/history/EditDataCommand.java
index a06a26854..0d51cc717 100644
--- a/src/main/java/edu/rpi/legup/history/EditDataCommand.java
+++ b/src/main/java/edu/rpi/legup/history/EditDataCommand.java
@@ -9,6 +9,7 @@
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.ui.boardview.BoardView;
import edu.rpi.legup.ui.boardview.ElementView;
+import edu.rpi.legup.ui.lookandfeel.materialdesign.MaterialColors;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
import java.awt.*;
import java.awt.event.MouseEvent;
@@ -33,7 +34,7 @@ public class EditDataCommand extends PuzzleCommand {
* EditDataCommand Constructor create a puzzle command for editing a board
*
* @param elementView currently selected puzzle puzzleElement view that is being edited
- * @param selection currently selected tree puzzleElement views that is being edited
+ * @param selection currently selected tree puzzleElement views that are being edited
* @param event mouse event
*/
public EditDataCommand(ElementView elementView, TreeViewSelection selection, MouseEvent event) {
@@ -61,16 +62,13 @@ public void executeCommand() {
if (treeElement.getType() == TreeElementType.NODE) {
TreeNode treeNode = (TreeNode) treeElement;
-
if (treeNode.getChildren().isEmpty()) {
if (transition == null) {
transition = tree.addNewTransition(treeNode);
}
puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(transition));
}
-
board = transition.getBoard();
-
puzzleElement = board.getPuzzleElement(selectedPuzzleElement);
savePuzzleElement = puzzleElement.copy();
} else {
@@ -80,7 +78,6 @@ public void executeCommand() {
}
Board prevBoard = transition.getParents().get(0).getBoard();
-
boardView.getElementController().changeCell(event, puzzleElement);
if (prevBoard.getPuzzleElement(selectedPuzzleElement).equalsData(puzzleElement)) {
@@ -109,28 +106,33 @@ public void executeCommand() {
public String getErrorString() {
List selectedViews = selection.getSelectedViews();
if (selectedViews.size() != 1) {
+ flashTreeViewRed();
return CommandError.ONE_SELECTED_VIEW.toString();
}
TreeElementView selectedView = selection.getFirstSelection();
Board board = selectedView.getTreeElement().getBoard();
PuzzleElement selectedPuzzleElement = elementView.getPuzzleElement();
if (selectedView.getType() == TreeElementType.NODE) {
-
TreeNodeView nodeView = (TreeNodeView) selectedView;
if (!nodeView.getChildrenViews().isEmpty()) {
+ flashTreeViewRed();
return CommandError.UNMODIFIABLE_BOARD.toString();
- } else {
- if (!board.getPuzzleElement(selectedPuzzleElement).isModifiable()) {
- return CommandError.UNMODIFIABLE_DATA.toString();
- }
+ } else if (!board.getPuzzleElement(selectedPuzzleElement).isModifiable()) {
+ flashTreeViewRed();
+ return CommandError.UNMODIFIABLE_DATA.toString();
}
} else {
TreeTransitionView transitionView = (TreeTransitionView) selectedView;
if (!transitionView.getTreeElement().getBoard().isModifiable()) {
+ flashTreeViewRed();
return CommandError.UNMODIFIABLE_BOARD.toString();
} else {
if (!board.getPuzzleElement(selectedPuzzleElement).isModifiable()) {
+ flashTreeViewRed();
return CommandError.UNMODIFIABLE_DATA.toString();
+ } else if (!board.getPuzzleElement(selectedPuzzleElement).isModifiableCaseRule()) {
+ flashTreeViewRed();
+ return CommandError.UNMODIFIABLE_DATA_CASE_RULE.toString();
}
}
}
diff --git a/src/main/java/edu/rpi/legup/history/History.java b/src/main/java/edu/rpi/legup/history/History.java
index 091d381ac..9eaeb3e75 100644
--- a/src/main/java/edu/rpi/legup/history/History.java
+++ b/src/main/java/edu/rpi/legup/history/History.java
@@ -48,7 +48,10 @@ public void pushChange(ICommand command) {
}
}
- /** Undoes an action */
+ /**
+ * Undoes the last action by calling the undo method of the command at the current index.
+ * Updates the current index and notifies listeners.
+ */
public void undo() {
synchronized (lock) {
if (curIndex > -1) {
@@ -63,7 +66,10 @@ public void undo() {
}
}
- /** Redoes an action */
+ /**
+ * Redoes the next action by calling the redo method of the command at the current index.
+ * Updates the current index and notifies listeners.
+ */
public void redo() {
synchronized (lock) {
if (curIndex < history.size() - 1) {
diff --git a/src/main/java/edu/rpi/legup/history/IHistoryListener.java b/src/main/java/edu/rpi/legup/history/IHistoryListener.java
index 344d8ede7..a752cd53a 100644
--- a/src/main/java/edu/rpi/legup/history/IHistoryListener.java
+++ b/src/main/java/edu/rpi/legup/history/IHistoryListener.java
@@ -6,15 +6,16 @@
* as pushing, undoing, redoing commands, and clearing the history.
*/
public interface IHistoryListener {
+
/**
- * Called when a action is pushed onto the edu.rpi.legup.history stack
+ * Called when a command is pushed onto the history stack.
*
- * @param command action to push onto the stack
+ * @param command the command that was pushed onto the stack
*/
void onPushChange(ICommand command);
/**
- * Called when an action is undone
+ * Called when a command is undone.
*
* @param isBottom true if there are no more actions to undo, false otherwise
* @param isTop true if there are no more changes to redo, false otherwise
@@ -22,7 +23,7 @@ public interface IHistoryListener {
void onUndo(boolean isBottom, boolean isTop);
/**
- * Called when an action is redone
+ * Called when a command is redone.
*
* @param isBottom true if there are no more actions to undo, false otherwise
* @param isTop true if there are no more changes to redo, false otherwise
diff --git a/src/main/java/edu/rpi/legup/history/IHistorySubject.java b/src/main/java/edu/rpi/legup/history/IHistorySubject.java
index 5c10e9b25..b526c7cf3 100644
--- a/src/main/java/edu/rpi/legup/history/IHistorySubject.java
+++ b/src/main/java/edu/rpi/legup/history/IHistorySubject.java
@@ -8,10 +8,11 @@
* listeners.
*/
public interface IHistorySubject {
+
/**
- * Adds a history listener
+ * Adds a history listener to receive updates about changes in the command history.
*
- * @param listener listener to add
+ * @param listener the listener to add
*/
void addHistoryListener(IHistoryListener listener);
@@ -19,12 +20,12 @@ public interface IHistorySubject {
* Removes a history listener, so it no longer receives updates about changes in the command
* history.
*
- * @param listener listener to remove
+ * @param listener the listener to remove
*/
void removeHistoryListener(IHistoryListener listener);
/**
- * Notifies listeners
+ * Notifies all registered listeners about a change in the command history.
*
* @param algorithm a Consumer function that takes an IHistoryListener and performs some action
* with it
diff --git a/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java b/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java
index 692c572d7..0e1ba1b0d 100644
--- a/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java
+++ b/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java
@@ -6,6 +6,13 @@
*/
public class InvalidCommandStateTransition extends RuntimeException {
+ /**
+ * Constructs a new InvalidCommandStateTransition exception with a detailed message
+ *
+ * @param puzzleCommand the PuzzleCommand involved in the invalid transition
+ * @param from the state from which the transition was attempted
+ * @param to the state to which the transition was attempted
+ */
public InvalidCommandStateTransition(
PuzzleCommand puzzleCommand, CommandState from, CommandState to) {
super(
diff --git a/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java b/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java
index b0daee986..49bf378ee 100644
--- a/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java
+++ b/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java
@@ -18,6 +18,7 @@
* ICommand interface.
*/
public class ValidateDirectRuleCommand extends PuzzleCommand {
+ private static final Logger LOGGER = LogManager.getLogger(History.class.getName());
private TreeViewSelection selection;
private Map oldRules;
@@ -49,14 +50,15 @@ public void executeCommand() {
for (TreeElementView selectedView : selectedViews) {
TreeElement element = selectedView.getTreeElement();
TreeTransitionView transitionView;
+
if (element.getType() == TreeElementType.NODE) {
TreeNodeView nodeView = (TreeNodeView) selectedView;
transitionView = nodeView.getChildrenViews().get(0);
} else {
transitionView = (TreeTransitionView) selectedView;
}
- TreeTransition transition = transitionView.getTreeElement();
+ TreeTransition transition = transitionView.getTreeElement();
oldRules.put(transition, transition.getRule());
transition.setRule(newRule);
@@ -73,17 +75,41 @@ public void executeCommand() {
final TreeNode finalNode = childNode;
puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(finalNode));
}
- newSelection.addToSelection(treeView.getElementView(childNode));
+
+ TreeElementView childView = treeView.getElementView(childNode);
+ if (childView == null) {
+ LOGGER.error("Child view is null for child node: " + childNode);
+ continue;
+ }
+ newSelection.addToSelection(childView);
}
+
TreeElementView firstSelectedView = selection.getFirstSelection();
+
final TreeElement finalTreeElement;
if (firstSelectedView.getType() == TreeElementType.NODE) {
TreeNodeView nodeView = (TreeNodeView) firstSelectedView;
+ if (nodeView.getChildrenViews().isEmpty()) {
+ LOGGER.error("NodeView has no children views");
+ return;
+ }
finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement();
} else {
TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
+ TreeNodeView childView = transitionView.getChildView();
+ if (childView == null) {
+ LOGGER.error("Child view is null for transition view: " + transitionView);
+ TreeNode childNode = transitionView.getTreeElement().getChildNode();
+ childView = (TreeNodeView) treeView.getElementView(childNode);
+ transitionView.setChildView(childView);
+ }
+ TreeTransition transition = transitionView.getTreeElement();
+ if (transition.getParents().get(0).getChildren().isEmpty()) {
+ transition.getParents().get(0).addChild(transition);
+ }
finalTreeElement = transitionView.getChildView().getTreeElement();
}
+
puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
}
@@ -133,6 +159,7 @@ public void undoCommand() {
transitionView = (TreeTransitionView) selectedView;
}
TreeTransition transition = transitionView.getTreeElement();
+
transition.setRule(oldRules.get(transition));
if (addNode.get(transition) != null) {
diff --git a/src/main/java/edu/rpi/legup/model/Puzzle.java b/src/main/java/edu/rpi/legup/model/Puzzle.java
index 1e3d0b3fe..da8f76ddd 100644
--- a/src/main/java/edu/rpi/legup/model/Puzzle.java
+++ b/src/main/java/edu/rpi/legup/model/Puzzle.java
@@ -58,7 +58,6 @@ public abstract class Puzzle implements IBoardSubject, ITreeSubject {
protected List contradictionRules;
protected List caseRules;
protected List placeableElements;
- protected List nonPlaceableElements;
/** Puzzle Constructor - creates a new Puzzle */
public Puzzle() {
@@ -70,7 +69,6 @@ public Puzzle() {
this.caseRules = new ArrayList<>();
this.placeableElements = new ArrayList<>();
- this.nonPlaceableElements = new ArrayList<>();
registerRules();
registerPuzzleElements();
@@ -109,9 +107,6 @@ private void registerPuzzleElements() {
case PLACEABLE:
this.addPlaceableElement((PlaceableElement) element);
break;
- case NONPLACEABLE:
- this.addNonPlaceableElement((NonPlaceableElement) element);
- break;
default:
break;
}
@@ -122,14 +117,6 @@ private void registerPuzzleElements() {
}
}
}
-
- // } catch (IOException | ClassNotFoundException | NoSuchMethodException |
- // InstantiationException | IllegalAccessException |
- // InvocationTargetException
- // e) {
- // LOGGER.error("Unable to find rules for " +
- // this.getClass().getSimpleName(), e);
- // }
} catch (Exception e) {
LOGGER.error("Unable to find elements for " + this.getClass().getSimpleName(), e);
}
@@ -185,14 +172,6 @@ private void registerRules() {
}
}
}
-
- // } catch (IOException | ClassNotFoundException | NoSuchMethodException |
- // InstantiationException | IllegalAccessException |
- // InvocationTargetException
- // e) {
- // LOGGER.error("Unable to find rules for " +
- // this.getClass().getSimpleName(), e);
- // }
} catch (Exception e) {
LOGGER.error("Unable to find rules for " + this.getClass().getSimpleName(), e);
}
@@ -221,10 +200,10 @@ public boolean isValidDimensions(int rows, int columns) {
}
/**
- * Checks if the given array of statements is valid text input for the given puzzle
+ * Checks if the provided text input is valid for the puzzle.
*
- * @param statements
- * @return
+ * @param statements array of statements to check
+ * @return true if input is valid, false otherwise
*/
public boolean isValidTextInput(String[] statements) {
return statements.length > 0;
@@ -356,14 +335,15 @@ public List getDirectRules() {
return directRules;
}
+ /**
+ * Gets the list of placeable elements.
+ *
+ * @return list of PlaceableElement instances
+ */
public List getPlaceableElements() {
return placeableElements;
}
- public List getNonPlaceableElements() {
- return nonPlaceableElements;
- }
-
/**
* Sets the list of direct rules
*
@@ -382,14 +362,15 @@ public void addDirectRule(DirectRule rule) {
directRules.add(rule);
}
+ /**
+ * Adds a placeable element to this puzzle.
+ *
+ * @param element PlaceableElement to add
+ */
public void addPlaceableElement(PlaceableElement element) {
placeableElements.add(element);
}
- public void addNonPlaceableElement(NonPlaceableElement element) {
- nonPlaceableElements.add(element);
- }
-
/**
* Remove a basic rule from this Puzzle
*
@@ -605,7 +586,7 @@ public void setFactory(ElementFactory factory) {
* Adds a board listener to the list of listeners. This allows the puzzle to notify the listener
* about changes to the board.
*
- * @param listener listener to add
+ * @param listener The IBoardListener to be added to the list of listeners.
*/
@Override
public void addBoardListener(IBoardListener listener) {
@@ -616,7 +597,7 @@ public void addBoardListener(IBoardListener listener) {
* Removes a board listener from the list of listeners. This prevents the puzzle from notifying
* the listener about future changes to the board.
*
- * @param listener listener to remove
+ * @param listener The IBoardListener to be removed from the list of listeners.
*/
@Override
public void removeBoardListener(IBoardListener listener) {
@@ -639,7 +620,7 @@ public void notifyBoardListeners(Consumer super IBoardListener> algorithm) {
* Adds a tree listener to the list of listeners. This allows the puzzle to notify the listener
* about changes to the tree.
*
- * @param listener listener to add
+ * @param listener The ITreeListener to be added to the list of listeners.
*/
@Override
public void addTreeListener(ITreeListener listener) {
@@ -650,7 +631,7 @@ public void addTreeListener(ITreeListener listener) {
* Removes a tree listener from the list of listeners. This prevents the puzzle from notifying
* the listener about future changes to the tree.
*
- * @param listener listener to remove
+ * @param listener The ITreeListener to be removed from the list of listeners.
*/
@Override
public void removeTreeListener(ITreeListener listener) {
@@ -673,7 +654,7 @@ public void notifyTreeListeners(Consumer super ITreeListener> algorithm) {
* Checks if the puzzle is valid. The implementation of this method can vary based on the
* specific criteria for puzzle validity.
*
- * @return if the puzzle is valid
+ * @return true if the puzzle is valid, false otherwise.
*/
public boolean checkValidity() {
return true;
diff --git a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
index 848e3169a..9d16d94e9 100644
--- a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
+++ b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
@@ -69,10 +69,10 @@ public void initializePuzzle(String[] statements)
}
/**
- * Initializes the puzzle attributes
+ * Initializes the puzzle attributes from the XML document node
*
- * @param node xml document node
- * @throws InvalidFileFormatException if file is invalid
+ * @param node the XML document node representing the puzzle
+ * @throws InvalidFileFormatException if the file format is invalid
*/
public void initializePuzzle(Node node) throws InvalidFileFormatException {
if (node.getNodeName().equalsIgnoreCase("puzzle")) {
@@ -125,19 +125,19 @@ public void initializePuzzle(Node node) throws InvalidFileFormatException {
}
/**
- * Creates the board for building
+ * Initializes the board with the specified number of rows and columns.
*
- * @param rows number of rows on the puzzle
- * @param columns number of columns on the puzzle
- * @throws RuntimeException if board can not be created
+ * @param rows the number of rows on the puzzle
+ * @param columns the number of columns on the puzzle
+ * @throws RuntimeException if the board cannot be created with the provided dimensions
*/
public abstract void initializeBoard(int rows, int columns);
/**
- * Creates an empty board for building
+ * Initializes the board from the XML document node.
*
- * @param node xml document node
- * @throws InvalidFileFormatException if file is invalid
+ * @param node the XML document node representing the board
+ * @throws InvalidFileFormatException if the file format is invalid
*/
public abstract void initializeBoard(Node node) throws InvalidFileFormatException;
@@ -454,7 +454,7 @@ protected void createDefaultTree() {
}
/**
- * Gets the result of building the Puzzle
+ * Gets the result of building the Puzzle object.
*
* @return puzzle
*/
diff --git a/src/main/java/edu/rpi/legup/model/elements/Element.java b/src/main/java/edu/rpi/legup/model/elements/Element.java
index 6f100c27d..ed47f6523 100644
--- a/src/main/java/edu/rpi/legup/model/elements/Element.java
+++ b/src/main/java/edu/rpi/legup/model/elements/Element.java
@@ -21,6 +21,14 @@ public abstract class Element {
private final String INVALID_USE_MESSAGE;
+ /**
+ * Constructs an Element with the specified ID, name, description, and image name
+ *
+ * @param elementID Unique identifier for the element
+ * @param elementName Name of the element
+ * @param description Description of the element
+ * @param imageName File name of the image associated with the element
+ */
public Element(String elementID, String elementName, String description, String imageName) {
this.elementID = elementID;
this.elementName = elementName;
@@ -55,30 +63,65 @@ private void loadImage() {
}
}
+ /**
+ * Gets the name of the element
+ *
+ * @return The name of the element
+ */
public String getElementName() {
return elementName;
}
+ /**
+ * Sets the name of the element
+ *
+ * @param elementName The new name for the element
+ */
public void setElementName(String elementName) {
this.elementName = elementName;
}
+ /**
+ * Gets the unique identifier of the element
+ *
+ * @return The ID of the element
+ */
public String getElementID() {
return elementID;
}
+ /**
+ * Gets the description of the element
+ *
+ * @return The description of the element
+ */
public String getDescription() {
return description;
}
+ /**
+ * Gets the image icon associated with the element
+ *
+ * @return The ImageIcon for the element
+ */
public ImageIcon getImageIcon() {
return image;
}
+ /**
+ * Gets the type of the element
+ *
+ * @return The ElementType of the element
+ */
public ElementType getElementType() {
return elementType;
}
+ /**
+ * Gets the message for invalid use of the rule
+ *
+ * @return The invalid use message
+ */
public String getInvalidUseOfRuleMessage() {
return this.INVALID_USE_MESSAGE;
}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/Board.java b/src/main/java/edu/rpi/legup/model/gameboard/Board.java
index f1fd27ad2..9e7d93441 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/Board.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/Board.java
@@ -35,21 +35,24 @@ public Board(int size) {
}
/**
- * Gets a specific {@link PuzzleElement} on this board.
+ * Gets a specific {@link PuzzleElement} from the board.
*
- * @param puzzleElement equivalent puzzleElement
- * @return equivalent puzzleElement on this board
+ * @param puzzleElement the puzzle element to retrieve
+ * @return the puzzle element at the corresponding index, or null if not found
*/
public PuzzleElement getPuzzleElement(PuzzleElement puzzleElement) {
+ if (puzzleElement == null) {
+ return null;
+ }
int index = puzzleElement.getIndex();
return index < puzzleElements.size() ? puzzleElements.get(index) : null;
}
/**
- * Sets a specific {@link PuzzleElement} on the board.
+ * Sets a specific {@link PuzzleElement} on the board
*
* @param index index of the puzzleElement
- * @param puzzleElement new puzzleElement at the index
+ * @param puzzleElement the puzzleElement to set at the index
*/
public void setPuzzleElement(int index, PuzzleElement puzzleElement) {
if (index < puzzleElements.size()) {
@@ -58,7 +61,7 @@ public void setPuzzleElement(int index, PuzzleElement puzzleElement) {
}
/**
- * Gets the number of elements on the board.
+ * Gets the number of elements on the board
*
* @return number of elements on the board
*/
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java b/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java
index 55484a2fc..07cc2947d 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java
@@ -14,40 +14,88 @@ public class CaseBoard extends Board {
protected CaseRule caseRule;
protected Set pickablePuzzleElements;
+ /**
+ * Constructs a CaseBoard with a base board and a case rule.
+ *
+ * @param baseBoard the base board to use for this CaseBoard
+ * @param caseRule the case rule applied to this CaseBoard
+ */
public CaseBoard(Board baseBoard, CaseRule caseRule) {
this.baseBoard = baseBoard;
this.caseRule = caseRule;
this.pickablePuzzleElements = new HashSet<>();
}
+ /**
+ * Adds a puzzle element to the set of pickable elements.
+ *
+ * @param puzzleElement the puzzle element to add
+ */
public void addPickableElement(PuzzleElement puzzleElement) {
pickablePuzzleElements.add(puzzleElement);
}
+ /**
+ * Removes a puzzle element from the set of pickable elements.
+ *
+ * @param puzzleElement the puzzle element to remove
+ */
public void removePickableElement(PuzzleElement puzzleElement) {
pickablePuzzleElements.remove(puzzleElement);
}
+ /**
+ * Checks if a puzzle element is pickable based on the mouse event.
+ *
+ * @param puzzleElement the puzzle element to check
+ * @param e the mouse event
+ * @return true if the puzzle element is pickable, false otherwise
+ */
public boolean isPickable(PuzzleElement puzzleElement, MouseEvent e) {
return pickablePuzzleElements.contains(baseBoard.getPuzzleElement(puzzleElement));
}
+ /**
+ * Retrieves the base board for this CaseBoard.
+ *
+ * @return the base board
+ */
public Board getBaseBoard() {
return baseBoard;
}
+ /**
+ * Sets the base board for this CaseBoard.
+ *
+ * @param baseBoard the new base board
+ */
public void setBaseBoard(Board baseBoard) {
this.baseBoard = baseBoard;
}
+ /**
+ * Retrieves the case rule for this CaseBoard.
+ *
+ * @return the case rule
+ */
public CaseRule getCaseRule() {
return caseRule;
}
+ /**
+ * Sets the case rule for this CaseBoard.
+ *
+ * @param caseRule the new case rule
+ */
public void setCaseRule(CaseRule caseRule) {
this.caseRule = caseRule;
}
+ /**
+ * Gets the count of pickable puzzle elements.
+ *
+ * @return the number of pickable elements
+ */
public int getCount() {
return pickablePuzzleElements.size();
}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java b/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java
index bfc785bdd..131feb122 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java
@@ -5,6 +5,9 @@
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+/**
+ * ElementFactory is an abstract class for importing and exporting {@link PuzzleElement} instances.
+ */
public abstract class ElementFactory {
/**
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java b/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java
index 9593690ce..7338132f8 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java
@@ -6,6 +6,11 @@
import java.awt.*;
import java.awt.event.MouseEvent;
+/**
+ * GridBoard represents a grid-based board where each cell can be manipulated based on its
+ * coordinates. The board supports operations such as getting and setting cells, and provides
+ * dimensions of the grid. It also supports deep copying of the board.
+ */
public class GridBoard extends Board {
protected Dimension dimension;
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java b/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java
index a4e2343b2..79027d9d1 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java
@@ -30,7 +30,7 @@ public void addCell(T cell) {
/**
* Removes the cell from the region
*
- * @param cell cell to be remove from the region
+ * @param cell cell to be removed from the region
*/
public void removeCell(T cell) {
regionCells.remove(cell);
@@ -53,9 +53,4 @@ public List getCells() {
public int getSize() {
return regionCells.size();
}
-
- /*
- public void colorRegion(){}
- */
-
}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java b/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java
index 7664c7aa0..eca6f3be4 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java
@@ -15,6 +15,7 @@ public abstract class PuzzleElement {
protected T data;
protected boolean isModifiable;
protected boolean isModified;
+ protected boolean isModifiableCaseRule;
protected boolean isGiven;
protected boolean isValid;
protected int casesDepended;
@@ -24,6 +25,7 @@ public PuzzleElement() {
this.index = -1;
this.data = null;
this.isModifiable = true;
+ this.isModifiableCaseRule = true;
this.isModified = false;
this.isGiven = false;
this.isValid = true;
@@ -80,6 +82,24 @@ public void setModifiable(boolean isModifiable) {
this.isModifiable = isModifiable;
}
+ /**
+ * Gets whether this puzzle element is modifiable as a result of a case rule.
+ *
+ * @return true if this puzzle element is modifiable, false otherwise
+ */
+ public boolean isModifiableCaseRule() {
+ return isModifiableCaseRule;
+ }
+
+ /**
+ * Sets whether this puzzle element is modifiable as a result of a case rule.
+ *
+ * @param isModifiableCaseRule true if this puzzle element is modifiable, false otherwise
+ */
+ public void setModifiableCaseRule(boolean isModifiableCaseRule) {
+ this.isModifiableCaseRule = isModifiableCaseRule;
+ }
+
/**
* Gets whether the puzzle element has been modified.
*
diff --git a/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java b/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java
index 7f5122a3d..7ba886fd4 100644
--- a/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java
+++ b/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java
@@ -17,7 +17,7 @@ public interface IBoardListener {
void onTreeElementChanged(TreeElement treeElement);
/**
- * Called when the a case board has been added to the view.
+ * Called when a case board has been added to the view.
*
* @param caseBoard case board to be added
*/
diff --git a/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java b/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java
index 2f9a3ff9b..6cdcd7dc2 100644
--- a/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java
+++ b/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java
@@ -22,7 +22,7 @@ public interface IBoardSubject {
void removeBoardListener(IBoardListener listener);
/**
- * Notifies all of the listeners using the specified algorithm.
+ * Notifies all the listeners using the specified algorithm.
*
* @param algorithm algorithm used to notify the listeners
*/
diff --git a/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java b/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java
index 6bb44296f..f7c033529 100644
--- a/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java
+++ b/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java
@@ -8,7 +8,7 @@
*/
public interface ITreeSubject {
/**
- * Adds a board listener.
+ * Adds a tree listener.
*
* @param listener listener to add
*/
@@ -22,7 +22,7 @@ public interface ITreeSubject {
void removeTreeListener(ITreeListener listener);
/**
- * Notifies all of the listeners using the specified algorithm.
+ * Notifies all the tree listeners using the specified algorithm.
*
* @param algorithm algorithm used to notify the listeners
*/
diff --git a/src/main/java/edu/rpi/legup/model/rules/MergeRule.java b/src/main/java/edu/rpi/legup/model/rules/MergeRule.java
index e7e3fd277..86c63fb7c 100644
--- a/src/main/java/edu/rpi/legup/model/rules/MergeRule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/MergeRule.java
@@ -27,7 +27,7 @@ public MergeRule() {
/**
* Checks whether the transition logically follows from the parent node using this rule. This
- * method is the one that should overridden in child classes
+ * method is the one that should have overridden in child classes
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
diff --git a/src/main/java/edu/rpi/legup/model/rules/Rule.java b/src/main/java/edu/rpi/legup/model/rules/Rule.java
index 6f5b1fd5c..edcab550b 100644
--- a/src/main/java/edu/rpi/legup/model/rules/Rule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/Rule.java
@@ -164,6 +164,11 @@ public RuleType getRuleType() {
return ruleType;
}
+ /**
+ * Gets the message indicating an invalid use of the rule.
+ *
+ * @return the invalid use message
+ */
public String getInvalidUseOfRuleMessage() {
return this.INVALID_USE_MESSAGE;
}
diff --git a/src/main/java/edu/rpi/legup/model/tree/Tree.java b/src/main/java/edu/rpi/legup/model/tree/Tree.java
index 2f74ca3af..545976fd1 100644
--- a/src/main/java/edu/rpi/legup/model/tree/Tree.java
+++ b/src/main/java/edu/rpi/legup/model/tree/Tree.java
@@ -1,5 +1,6 @@
package edu.rpi.legup.model.tree;
+import edu.rpi.legup.controller.TreeController;
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.ui.proofeditorui.treeview.TreeView;
import java.util.ArrayList;
@@ -29,6 +30,12 @@ public Tree() {
this.rootNode = null;
}
+ /**
+ * Adds a new transition to the specified node.
+ *
+ * @param treeNode the node to add a transition to
+ * @return the created transition
+ */
public TreeTransition addNewTransition(TreeNode treeNode) {
TreeTransition transition = new TreeTransition(treeNode, treeNode.getBoard().copy());
treeNode.addChild(transition);
@@ -36,13 +43,12 @@ public TreeTransition addNewTransition(TreeNode treeNode) {
return transition;
}
- public TreeNode addNode(TreeTransition transition) {
- TreeNode treeNode = new TreeNode(transition.getBoard().copy());
- transition.setChildNode(treeNode);
- treeNode.setParent(transition);
- return treeNode;
- }
-
+ /**
+ * Adds a tree element (node or transition) to the tree.
+ *
+ * @param element the tree element to add
+ * @return the added tree element
+ */
public TreeElement addTreeElement(TreeElement element) {
if (element.getType() == TreeElementType.NODE) {
TreeNode treeNode = (TreeNode) element;
@@ -51,30 +57,55 @@ public TreeElement addTreeElement(TreeElement element) {
} else {
TreeTransition transition = (TreeTransition) element;
Board copyBoard = transition.board.copy();
- copyBoard.setModifiable(false);
+ copyBoard.setModifiable(true);
return addTreeElement(transition, new TreeNode(copyBoard));
}
}
+ /**
+ * Adds a tree node and its associated transition to the tree.
+ *
+ * @param treeNode the tree node to add
+ * @param transition the transition to associate with the node
+ * @return the added transition
+ */
public TreeElement addTreeElement(TreeNode treeNode, TreeTransition transition) {
treeNode.addChild(transition);
treeNode.getChildren().forEach(TreeTransition::reverify);
return transition;
}
+ /**
+ * Adds a transition and its associated tree node to the tree.
+ *
+ * @param transition the transition to add
+ * @param treeNode the tree node to associate with the transition
+ * @return the added tree node
+ */
public TreeElement addTreeElement(TreeTransition transition, TreeNode treeNode) {
transition.setChildNode(treeNode);
treeNode.setParent(transition);
return treeNode;
}
+ /**
+ * Removes a tree element (node or transition) from the tree.
+ *
+ * @param element the tree element to remove
+ */
public void removeTreeElement(TreeElement element) {
if (element.getType() == TreeElementType.NODE) {
TreeNode node = (TreeNode) element;
+
+ node.getParent().removeChild(node);
node.getParent().setChildNode(null);
} else {
TreeTransition transition = (TreeTransition) element;
+
transition.getParents().forEach(n -> n.removeChild(transition));
+ TreeController treeController = new TreeController();
+ TreeView treeView = new TreeView(treeController);
+ treeView.removeTreeTransition(transition);
transition.getParents().get(0).getChildren().forEach(TreeTransition::reverify);
}
}
@@ -101,10 +132,10 @@ public Set getLeafTreeElements() {
}
/**
- * Gets a Set of TreeNodes that are leaf nodes from the sub tree rooted at the specified node
+ * Gets a Set of TreeNodes that are leaf nodes from the subtree rooted at the specified node
*
* @param node node that is input
- * @return Set of TreeNodes that are leaf nodes from the sub tree
+ * @return Set of TreeNodes that are leaf nodes from the subtree
*/
public Set getLeafTreeElements(TreeNode node) {
Set leafs = new HashSet<>();
diff --git a/src/main/java/edu/rpi/legup/model/tree/TreeElement.java b/src/main/java/edu/rpi/legup/model/tree/TreeElement.java
index e668a5c8f..8c865b89b 100644
--- a/src/main/java/edu/rpi/legup/model/tree/TreeElement.java
+++ b/src/main/java/edu/rpi/legup/model/tree/TreeElement.java
@@ -28,7 +28,7 @@ public TreeElement(TreeElementType type) {
public abstract boolean isContradictoryBranch();
/**
- * Recursively determines if the sub-tree rooted at this tree puzzleElement is valid by checking
+ * Recursively determines if the subtree rooted at this tree puzzleElement is valid by checking
* whether this tree puzzleElement and all descendants of this tree puzzleElement is justified
* and justified correctly
*
diff --git a/src/main/java/edu/rpi/legup/model/tree/TreeNode.java b/src/main/java/edu/rpi/legup/model/tree/TreeNode.java
index 2fe5ffcd2..d4095afa5 100644
--- a/src/main/java/edu/rpi/legup/model/tree/TreeNode.java
+++ b/src/main/java/edu/rpi/legup/model/tree/TreeNode.java
@@ -61,9 +61,9 @@ public boolean isValidBranch() {
}
/**
- * Gets all of the ancestors of this node
+ * Gets a list of the ancestors of this node
*
- * @return list of all of the ancestors for this node
+ * @return list of all the ancestors for this node
*/
public List getAncestors() {
List ancestors = new ArrayList<>();
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java b/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java
index d304dbb24..7b70a43a1 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java
@@ -36,18 +36,12 @@ public Board generatePuzzle(int difficulty) {
return null;
}
- // /**
- // * Determines if the given dimensions are valid for Binary
- // *
- // * @param rows the number of rows
- // * @param columns the number of columns
- // * @return true if the given dimensions are valid for Binary, false otherwise
- // */
- // @Override
- // public boolean isValidDimensions(int rows, int columns){
- // return rows >= 2 && rows % 2 == 0 && columns >= 2 && columns % 2 == 0;
- // }
-
+ /**
+ * Determines if the current board is a valid state
+ *
+ * @param board board to check for validity
+ * @return true if board is valid, false otherwise
+ */
@Override
public boolean isBoardComplete(Board board) {
BinaryBoard binaryBoard = (BinaryBoard) board;
@@ -66,6 +60,11 @@ public boolean isBoardComplete(Board board) {
return true;
}
+ /**
+ * Callback for when the board puzzleElement changes
+ *
+ * @param board the board that has changed
+ */
@Override
public void onBoardChange(Board board) {}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java
index 9a3d0f083..d5d65ed26 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java
@@ -19,6 +19,13 @@ public BinaryBoard(int size) {
this.size = size;
}
+ /**
+ * Gets the cell at the (x,y) position
+ *
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @return BinaryCell cell at (x,y)
+ */
@Override
public BinaryCell getCell(int x, int y) {
if (y * dimension.width + x >= puzzleElements.size()
@@ -31,6 +38,12 @@ public BinaryCell getCell(int x, int y) {
return (BinaryCell) super.getCell(x, y);
}
+ /**
+ * Get all the binary cells in a row
+ *
+ * @param rowNum row number
+ * @return set of all binary cells in specified rowNum
+ */
public Set getRowCells(int rowNum) {
Set row = new HashSet<>();
for (int i = 0; i < size; i++) {
@@ -91,7 +104,6 @@ public ArrayList getColTypes(int colNum) {
*/
@Override
public BinaryBoard copy() {
- System.out.println("BinaryBoard copy()");
BinaryBoard copy = new BinaryBoard(dimension.width, dimension.height);
for (int x = 0; x < this.dimension.width; x++) {
for (int y = 0; y < this.dimension.height; y++) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java
index e7be09b8d..0edb8444e 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java
@@ -1,14 +1,26 @@
package edu.rpi.legup.puzzle.binary;
+import edu.rpi.legup.model.elements.Element;
import edu.rpi.legup.model.gameboard.GridCell;
import java.awt.Point;
import java.awt.event.MouseEvent;
public class BinaryCell extends GridCell {
- public BinaryCell(int valueInt, Point location) {
- super(valueInt, location);
+ /**
+ * BinaryCell Constructor - creates a BinaryCell from the specified value and location
+ *
+ * @param value value of the BinaryCell
+ * @param location position of the BinaryCell
+ */
+ public BinaryCell(int value, Point location) {
+ super(value, location);
}
+ /**
+ * Gets the type of this BinaryCell
+ *
+ * @return type of BinaryCell
+ */
public BinaryType getType() {
switch (data) {
case 0:
@@ -25,6 +37,11 @@ public BinaryType getType() {
return null;
}
+ /**
+ * Performs a deep copy on the BinaryCell
+ *
+ * @return a new copy of the BinaryCell that is independent of this one
+ */
@Override
public BinaryCell copy() {
BinaryCell copy = new BinaryCell(data, (Point) location.clone());
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java
index 890c26656..a819177d6 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java
@@ -10,7 +10,14 @@
import org.w3c.dom.Node;
public class BinaryCellFactory extends ElementFactory {
-
+ /**
+ * Creates a puzzleElement based on the xml document Node and adds it to the board
+ *
+ * @param node node that represents the puzzleElement
+ * @param board board to add the newly created cell
+ * @return newly created cell from the xml document Node
+ * @throws InvalidFileFormatException if file is invalid
+ */
public BinaryCell importCell(Node node, Board board) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("cell")) {
@@ -45,6 +52,13 @@ public BinaryCell importCell(Node node, Board board) throws InvalidFileFormatExc
}
}
+ /**
+ * Creates a xml document puzzleElement from a cell for exporting
+ *
+ * @param document xml document
+ * @param puzzleElement PuzzleElement cell
+ * @return xml PuzzleElement
+ */
public org.w3c.dom.Element exportCell(Document document, PuzzleElement puzzleElement) {
org.w3c.dom.Element cellElement = document.createElement("cell");
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java
index f2a735c4d..5ec6669a0 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java
@@ -39,13 +39,13 @@ public void changeCell(MouseEvent e, PuzzleElement data) {
}
} else {
if (e.getButton() == MouseEvent.BUTTON3) {
- if (cell.getData() == 0) {
+ if (cell.getData() == 2) {
data.setData(1);
} else {
if (cell.getData() == 1) {
- data.setData(2);
- } else {
data.setData(0);
+ } else {
+ data.setData(2);
}
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java
index b523a74a9..74a761e89 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java
@@ -7,6 +7,8 @@ public class BinaryElementView extends GridElementView {
private static final Font FONT = new Font("TimesRoman", Font.BOLD, 17);
private static final Color FONT_COLOR = Color.BLACK;
+ private static final Color GIVEN_COLOR = Color.LIGHT_GRAY;
+ private static final Color ELEMENT_COLOR = Color.WHITE;
public BinaryElementView(BinaryCell cell) {
super(cell);
@@ -51,95 +53,35 @@ public void drawElement(Graphics2D graphics2D) {
private void drawCell(Graphics2D graphics2D, Color bgColor) {
BinaryCell cell = (BinaryCell) puzzleElement;
BinaryType type = cell.getType();
- if (type == BinaryType.ZERO) {
+
+ if (type == BinaryType.ZERO || type == BinaryType.ONE) {
graphics2D.setStroke(new BasicStroke(1));
- graphics2D.setColor(Color.LIGHT_GRAY);
+ graphics2D.setColor(bgColor);
graphics2D.fillRect(location.x, location.y, size.width, size.height);
graphics2D.setColor(Color.BLACK);
graphics2D.drawRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(FONT_COLOR);
- graphics2D.setFont(FONT);
- FontMetrics metrics = graphics2D.getFontMetrics(FONT);
- String value = String.valueOf(puzzleElement.getData());
- int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
- int yText =
- location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
- graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
- } else {
- if (type == BinaryType.ONE) {
- graphics2D.setStroke(new BasicStroke(1));
- graphics2D.setColor(Color.LIGHT_GRAY);
- graphics2D.fillRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(Color.BLACK);
- graphics2D.drawRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(FONT_COLOR);
- graphics2D.setFont(FONT);
- FontMetrics metrics = graphics2D.getFontMetrics(FONT);
- String value = String.valueOf(puzzleElement.getData());
- int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
- int yText =
- location.y
- + ((size.height - metrics.getHeight()) / 2)
- + metrics.getAscent();
- graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
-
- } else {
- if (type == BinaryType.UNKNOWN) {
- graphics2D.setStroke(new BasicStroke(0));
- graphics2D.setColor(Color.WHITE);
- graphics2D.fillRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(Color.BLACK);
- graphics2D.drawRect(location.x, location.y, size.width, size.height);
- }
- }
- }
- }
-
- @Override
- public void drawElement(Graphics2D graphics2D) {
- BinaryCell cell = (BinaryCell) puzzleElement;
- BinaryType type = cell.getType();
- if (type == BinaryType.ZERO) {
- graphics2D.setStroke(new BasicStroke(1));
+ drawCenteredText(graphics2D);
+ } else if (type == BinaryType.UNKNOWN) {
+ graphics2D.setStroke(new BasicStroke(0));
graphics2D.setColor(Color.WHITE);
graphics2D.fillRect(location.x, location.y, size.width, size.height);
graphics2D.setColor(Color.BLACK);
graphics2D.drawRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(FONT_COLOR);
- graphics2D.setFont(FONT);
- FontMetrics metrics = graphics2D.getFontMetrics(FONT);
- String value = String.valueOf(puzzleElement.getData());
- int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
- int yText =
- location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
- graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
- } else {
- if (type == BinaryType.ONE) {
- graphics2D.setStroke(new BasicStroke(1));
- graphics2D.setColor(Color.WHITE);
- graphics2D.fillRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(Color.BLACK);
- graphics2D.drawRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(FONT_COLOR);
- graphics2D.setFont(FONT);
- FontMetrics metrics = graphics2D.getFontMetrics(FONT);
- String value = String.valueOf(puzzleElement.getData());
- int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
- int yText =
- location.y
- + ((size.height - metrics.getHeight()) / 2)
- + metrics.getAscent();
- graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
-
- } else {
- if (type == BinaryType.UNKNOWN) {
- graphics2D.setStroke(new BasicStroke(0));
- graphics2D.setColor(Color.WHITE);
- graphics2D.fillRect(location.x, location.y, size.width, size.height);
- graphics2D.setColor(Color.BLACK);
- graphics2D.drawRect(location.x, location.y, size.width, size.height);
- }
- }
}
}
+
+ /**
+ * Helper method to draw the centered text within the cell
+ *
+ * @param graphics2D The graphics object to draw on
+ */
+ private void drawCenteredText(Graphics2D graphics2D) {
+ graphics2D.setColor(FONT_COLOR);
+ graphics2D.setFont(FONT);
+ FontMetrics metrics = graphics2D.getFontMetrics(FONT);
+ String value = String.valueOf(puzzleElement.getData());
+ int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
+ int yText = location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
+ graphics2D.drawString(value, xText, yText);
+ }
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java
index 43ea8caf4..c032b63a9 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java
@@ -33,7 +33,7 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
org.w3c.dom.Element cellsElement = newDocument.createElement("cells");
for (PuzzleElement puzzleElement : board.getPuzzleElements()) {
BinaryCell cell = (BinaryCell) puzzleElement;
- if (cell.getData() != -2) {
+ if (cell.getData() != BinaryType.UNKNOWN.toValue()) {
org.w3c.dom.Element cellElement =
puzzle.getFactory().exportCell(newDocument, puzzleElement);
cellsElement.appendChild(cellElement);
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java
index 746d3b4b6..419789060 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java
@@ -12,16 +12,33 @@ public BinaryImporter(Binary binary) {
super(binary);
}
+ /**
+ * Determines if puzzle uses row and column input
+ *
+ * @return true if row and column input is used, false otherwise
+ */
@Override
public boolean acceptsRowsAndColumnsInput() {
return true;
}
+ /**
+ * Determines if puzzle uses text input
+ *
+ * @return true if text input is used, false otherwise
+ */
@Override
public boolean acceptsTextInput() {
return false;
}
+ /**
+ * Creates an empty board for building
+ *
+ * @param rows the number of rows on the board
+ * @param columns the number of columns on the board
+ * @throws RuntimeException if board can not be created
+ */
@Override
public void initializeBoard(int rows, int columns) {
BinaryBoard binaryBoard = new BinaryBoard(columns, rows);
@@ -48,12 +65,12 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("board")) {
throw new InvalidFileFormatException(
- "binary Importer: cannot find board puzzleElement");
+ "Binary Importer: cannot find board puzzleElement");
}
Element boardElement = (Element) node;
if (boardElement.getElementsByTagName("cells").getLength() == 0) {
throw new InvalidFileFormatException(
- "binary Importer: no puzzleElement found for board");
+ "Binary Importer: no puzzleElement found for board");
}
Element dataElement = (Element) boardElement.getElementsByTagName("cells").item(0);
@@ -76,7 +93,7 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
int height = binaryBoard.getHeight();
if (binaryBoard == null || width % 2 != 0 || height % 2 != 0) {
- throw new InvalidFileFormatException("binary Importer: invalid board dimensions");
+ throw new InvalidFileFormatException("Binary Importer: invalid board dimensions");
}
for (int i = 0; i < elementDataList.getLength(); i++) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/BlankTile.java b/src/main/java/edu/rpi/legup/puzzle/binary/elements/BlankTile.java
deleted file mode 100644
index 8b1378917..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/binary/elements/BlankTile.java
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/binary_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/binary/elements/binary_elements_reference_sheet.txt
new file mode 100644
index 000000000..54db0ee0b
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/binary_elements_reference_sheet.txt
@@ -0,0 +1,2 @@
+BINA-ELEM-0001 : NumberTile
+BINA-ELEM-0002 : UnknownTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java
index 09cca6dc5..6ced37a9c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java
@@ -32,23 +32,27 @@ public CompleteRowColumnDirectRule() {
@Override
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
- ContradictionRule contraRule = new UnbalancedRowOrColumnContradictionRule();
+ ContradictionRule contraRule = new UnbalancedRowColumnContradictionRule();
BinaryCell binaryCell = (BinaryCell) puzzleElement;
BinaryBoard modified = origBoard.copy();
- BinaryCell c = (BinaryCell) modified.getPuzzleElement(puzzleElement);
- // System.out.println("ORIG" + binaryCell.getData());
- // System.out.println("AFTER" + Math.abs(binaryCell.getData() - 1));
- modified.getPuzzleElement(puzzleElement).setData(binaryCell.getData());
- System.out.println(contraRule.checkContradictionAt(modified, puzzleElement));
-
- if (contraRule.checkContradictionAt(modified, puzzleElement) != null) {
+ // Flip the cell and check to see if there will be an unbalanced row/column contradiction,
+ // if so the rule is applied correctly
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+ if (contraRule.checkContradictionAt(modified, puzzleElement) == null) {
return null;
}
- return "Grouping of Three Ones or Zeros not found";
+ return "Unbalanced row/column found";
}
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
@Override
public Board getDefaultBoard(TreeNode node) {
return null;
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java
deleted file mode 100644
index 2e1e96fa5..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package edu.rpi.legup.puzzle.binary.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.ContradictionRule;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.binary.BinaryBoard;
-import edu.rpi.legup.puzzle.binary.BinaryCell;
-
-public class OneTileGapDirectRule extends DirectRule {
- private final String INVALID_USE_MESSAGE = "Number at cell is incorrect";
-
- public OneTileGapDirectRule() {
- super(
- "BINA-BASC-0002",
- "One Tile Gap",
- "If an empty tile is in between the same value, fill the gap with the other value.",
- "edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png");
- }
-
- boolean checkLeftRight(BinaryCell c, BinaryBoard board) {
- int x = c.getLocation().x;
- int y = c.getLocation().y;
- return board.getCell(x - 1, y).getType() != c.getType()
- || board.getCell(x + 1, y).getType() != c.getType();
- }
-
- boolean checkUpDown(BinaryCell c, BinaryBoard board) {
- int x = c.getLocation().x;
- int y = c.getLocation().y;
- return board.getCell(x, y - 1).getType() != c.getType()
- || board.getCell(x, y + 1).getType() != c.getType();
- }
-
- @Override
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
- ContradictionRule contraRule = new ThreeAdjacentContradictionRule();
- BinaryCell binaryCell = (BinaryCell) puzzleElement;
- BinaryBoard modified = origBoard.copy();
-
- // System.out.println("ORIG" + binaryCell.getData());
- // System.out.println("AFTER" + Math.abs(binaryCell.getData() - 1));
- modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
-
- PuzzleElement newP = binaryCell;
-
- System.out.println(contraRule.checkContradictionAt(modified, newP));
-
- if (contraRule.checkContradictionAt(modified, newP) == null) {
- return null;
- }
- modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
-
- return "Grouping of Three Ones or Zeros not found";
- }
-
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java
similarity index 69%
rename from src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java
rename to src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java
index 6e009f123..a7a4ced12 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java
@@ -8,19 +8,28 @@
import edu.rpi.legup.puzzle.binary.BinaryType;
import java.util.ArrayList;
-public class DuplicateRowsOrColumnsContradictionRule extends ContradictionRule {
+public class RepeatedRowColumnContradictionRule extends ContradictionRule {
private final String NO_CONTRADICTION_MESSAGE =
"Does not contain a contradiction at this index";
private final String INVALID_USE_MESSAGE = "Row or column must have a value in each cell";
- public DuplicateRowsOrColumnsContradictionRule() {
+ public RepeatedRowColumnContradictionRule() {
super(
"BINA-CONT-0003",
- "Duplicate Rows Or Columns",
- "There must not be two rows or two columns that are duplicates",
- "edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png");
+ "Repeated Row/Column",
+ "There must not be two of the same row or two of the same column in the puzzle",
+ "edu/rpi/legup/images/binary/rules/RepeatedRowColumnContradictionRule.png");
}
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
BinaryBoard binaryBoard = (BinaryBoard) board;
@@ -29,11 +38,9 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
// Compare each row with row of current cell to see if they are equal, if so the rule is
// applied correctly
ArrayList row = binaryBoard.getRowTypes(cell.getLocation().y);
-
int size = row.size();
-
for (int i = 0; i < size; i++) {
- if (i > cell.getLocation().y) {
+ if (i != cell.getLocation().y) {
ArrayList currRow = binaryBoard.getRowTypes(i);
if (currRow.equals(row)) {
return null;
@@ -44,9 +51,8 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
// Compare each column with column of current cell to see if they are equal, if so the rule
// is applied correctly
ArrayList col = binaryBoard.getColTypes(cell.getLocation().x);
-
for (int i = 0; i < size; i++) {
- if (i > cell.getLocation().x) {
+ if (i != cell.getLocation().x) {
ArrayList currCol = binaryBoard.getColTypes(i);
if (currCol.equals(col)) {
return null;
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java
deleted file mode 100644
index dc2f07c8b..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package edu.rpi.legup.puzzle.binary.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.ContradictionRule;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.binary.BinaryBoard;
-import edu.rpi.legup.puzzle.binary.BinaryCell;
-
-public class SurroundPairDirectRule extends DirectRule {
-
- public SurroundPairDirectRule() {
- super(
- "BINA-BASC-0001",
- "Surround Pair",
- "If two adjacent tiles have the same value, surround the tiles with the other value.",
- "edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png");
- }
-
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
- ContradictionRule contraRule = new ThreeAdjacentContradictionRule();
- BinaryCell binaryCell = (BinaryCell) puzzleElement;
- BinaryBoard modified = origBoard.copy();
-
- // System.out.println("ORIG" + binaryCell.getData());
- // System.out.println("AFTER" + Math.abs(binaryCell.getData() - 1));
- modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
-
- PuzzleElement newP = binaryCell;
-
- System.out.println(contraRule.checkContradictionAt(modified, newP));
-
- if (contraRule.checkContradictionAt(modified, newP) == null) {
- return null;
- }
- modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
-
- return "Grouping of Three Ones or Zeros not found";
- }
-
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/ThreeAdjacentContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ThreeAdjacentContradictionRule.java
deleted file mode 100644
index 075642246..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/ThreeAdjacentContradictionRule.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package edu.rpi.legup.puzzle.binary.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.ContradictionRule;
-import edu.rpi.legup.puzzle.binary.BinaryBoard;
-import edu.rpi.legup.puzzle.binary.BinaryCell;
-import edu.rpi.legup.puzzle.binary.BinaryType;
-
-public class ThreeAdjacentContradictionRule extends ContradictionRule {
- private final String NO_CONTRADICTION_MESSAGE =
- "Does not contain a contradiction at this index";
- private final String INVALID_USE_MESSAGE = "Contradiction must be a zero or one";
-
- public ThreeAdjacentContradictionRule() {
- super(
- "BINA-CONT-0001",
- "Three Adjacent",
- "There must not be three adjacent zeros or three adjacent ones in a row or column",
- "edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png");
- }
-
- @Override
- public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
- BinaryBoard binaryBoard = (BinaryBoard) board;
- int height = binaryBoard.getHeight();
- int width = binaryBoard.getWidth();
-
- BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
- System.out.println("THE CELL IS : " + cell.getType());
- int cellX = cell.getLocation().x;
- int cellY = cell.getLocation().y;
- BinaryCell oneUp = null;
- BinaryCell oneDown = null;
- BinaryCell oneForward = null;
- BinaryCell oneBackward = null;
- BinaryCell twoUp = null;
- BinaryCell twoDown = null;
- BinaryCell twoForward = null;
- BinaryCell twoBackward = null;
- if (binaryBoard.getCell(cellX, cellY + 1) != null) {
- oneUp = binaryBoard.getCell(cellX, cellY + 1);
- }
- if (binaryBoard.getCell(cellX, cellY - 1) != null) {
- oneDown = binaryBoard.getCell(cellX, cellY - 1);
- }
- if (binaryBoard.getCell(cellX + 1, cellY) != null) {
- oneForward = binaryBoard.getCell(cellX + 1, cellY);
- }
- if (binaryBoard.getCell(cellX - 1, cellY) != null) {
- oneBackward = binaryBoard.getCell(cellX - 1, cellY);
- }
- if (binaryBoard.getCell(cellX, cellY + 2) != null) {
- twoUp = binaryBoard.getCell(cellX, cellY + 2);
- }
- if (binaryBoard.getCell(cellX, cellY - 2) != null) {
- twoDown = binaryBoard.getCell(cellX, cellY - 2);
- }
- if (binaryBoard.getCell(cellX + 2, cellY) != null) {
- twoForward = binaryBoard.getCell(cellX + 2, cellY);
- }
- if (binaryBoard.getCell(cellX - 2, cellY) != null) {
- twoBackward = binaryBoard.getCell(cellX - 2, cellY);
- }
-
- if (cell.getType() == BinaryType.ONE || cell.getType() == BinaryType.ZERO) {
- if (twoBackward != null
- && oneBackward != null
- && twoBackward.getType() != BinaryType.UNKNOWN
- && oneBackward.getType() != BinaryType.UNKNOWN) {
- if (twoBackward.getType() == cell.getType()
- && oneBackward.getType() == cell.getType()) {
- System.out.println("1");
- return null;
- }
- }
- if (twoForward != null
- && oneForward != null
- && twoForward.getType() != BinaryType.UNKNOWN
- && oneForward.getType() != BinaryType.UNKNOWN) {
- if (twoForward.getType() == cell.getType()
- && oneForward.getType() == cell.getType()) {
- System.out.println("2");
- return null;
- }
- }
- if (twoDown != null
- && oneDown != null
- && twoDown.getType() != BinaryType.UNKNOWN
- && oneDown.getType() != BinaryType.UNKNOWN) {
- if (twoDown.getType() == cell.getType() && oneDown.getType() == cell.getType()) {
- System.out.println("3");
- return null;
- }
- }
- if (twoUp != null
- && oneUp != null
- && twoUp.getType() != BinaryType.UNKNOWN
- && oneUp.getType() != BinaryType.UNKNOWN) {
- if (twoUp.getType() == cell.getType() && oneUp.getType() == cell.getType()) {
- System.out.println("4");
- return null;
- }
- }
- if (oneBackward != null
- && oneForward != null
- && oneBackward.getType() != BinaryType.UNKNOWN
- && oneForward.getType() != BinaryType.UNKNOWN) {
- if (oneBackward.getType() == cell.getType()
- && oneForward.getType() == cell.getType()) {
- System.out.println("5");
- return null;
- }
- }
- if (oneUp != null
- && oneDown != null
- && oneUp.getType() != BinaryType.UNKNOWN
- && oneDown.getType() != BinaryType.UNKNOWN) {
- if (oneUp.getType() == cell.getType() && oneDown.getType() == cell.getType()) {
- System.out.println("6");
- return null;
- }
- }
- }
- return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
- }
-}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java
similarity index 66%
rename from src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java
rename to src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java
index 301cc6ec1..1d00f4da9 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java
@@ -8,20 +8,29 @@
import edu.rpi.legup.puzzle.binary.BinaryType;
import java.util.Set;
-public class UnbalancedRowOrColumnContradictionRule extends ContradictionRule {
+public class UnbalancedRowColumnContradictionRule extends ContradictionRule {
private final String NO_CONTRADICTION_MESSAGE =
"Does not contain a contradiction at this index";
private final String INVALID_USE_MESSAGE = "Row or column must have a value in each cell";
- public UnbalancedRowOrColumnContradictionRule() {
+ public UnbalancedRowColumnContradictionRule() {
super(
"BINA-CONT-0002",
- "Unbalanced Row Or Column",
+ "Unbalanced Row/Column",
"Each row or column must contain an equal number of zeros and ones",
"edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png");
}
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
BinaryBoard binaryBoard = (BinaryBoard) board;
@@ -41,8 +50,9 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
}
- if (rowNumZeros == size / 2 && rowNumOnes == size / 2) {
- return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ // if there are too many zeros or ones in this row
+ if (rowNumZeros > size / 2 || rowNumOnes > size / 2) {
+ return null;
}
Set col = binaryBoard.getColCells(cell.getLocation().x);
@@ -59,10 +69,11 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
}
- if (colNumZeros == size / 2 && colNumOnes == size / 2) {
- return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ // if there are too many zeros or ones in this column
+ if (colNumZeros > size / 2 || colNumOnes > size / 2) {
+ return null;
}
- return null;
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java
similarity index 64%
rename from src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java
rename to src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java
index 21ee0dd5b..f47fe55b9 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java
@@ -11,16 +11,23 @@
import java.util.ArrayList;
import java.util.List;
-public class OneOrZeroCaseRule extends CaseRule {
+public class ZeroOrOneCaseRule extends CaseRule {
- public OneOrZeroCaseRule() {
+ public ZeroOrOneCaseRule() {
super(
"BINA-CASE-0001",
- "One or Zero",
- "Each blank cell is either a one or a zero.",
- "edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png");
+ "Zero Or One",
+ "Each blank cell is either a zero or a one",
+ "edu/rpi/legup/images/binary/rules/ZeroOrOneCaseRule.png");
}
+ /**
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should be overridden in child classes.
+ *
+ * @param transition transition to check
+ * @return null if the child node logically follow from the parent node, otherwise error message
+ */
@Override
public String checkRuleRaw(TreeTransition transition) {
List childTransitions = transition.getParents().get(0).getChildren();
@@ -52,6 +59,13 @@ public String checkRuleRaw(TreeTransition transition) {
return null;
}
+ /**
+ * Generates a {@link CaseBoard} that includes all blank cells from the given board that this
+ * case rule can be applied to
+ *
+ * @param board The board to find locations where this case rule can be applied
+ * @return A CaseBoard containing pickable elements where the case rule can be applied
+ */
@Override
public CaseBoard getCaseBoard(Board board) {
BinaryBoard binaryBoard = (BinaryBoard) board.copy();
@@ -65,24 +79,44 @@ public CaseBoard getCaseBoard(Board board) {
return caseBoard;
}
+ /**
+ * Gets the possible cases at a specific location based on this case rule
+ *
+ * @param board the current board state
+ * @param puzzleElement equivalent puzzleElement
+ * @return a list of elements the specified could be
+ */
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
Board case1 = board.copy();
PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
- data1.setData(BinaryType.ZERO.toValue());
+ data1.setData(BinaryType.ONE.toValue());
case1.addModifiedData(data1);
cases.add(case1);
Board case2 = board.copy();
PuzzleElement data2 = case2.getPuzzleElement(puzzleElement);
- data2.setData(BinaryType.ONE.toValue());
+ data2.setData(BinaryType.ZERO.toValue());
case2.addModifiedData(data2);
cases.add(case2);
return cases;
}
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule
+ *
+ * @param transition transition to check
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
+ */
@Override
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
return null;
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt
index c8cb0d1b9..619d183a5 100644
--- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt
@@ -1,9 +1,11 @@
-BINA-BASC-0001 : SurroundPairDirectRule
-BINA-BASC-0002 : OneTileGapDirectRule
-BINA-BASC-0003 : CompleteRowColumnDirectRule
+BINA-BASC-0001 : PreventTrioContradictionRule
+BINA-BASC-0002 : CompleteRowColumnDirectRule
+BINA-BASC-0003 : SaveBlockerDirectRule
+BINA-BASC-0004 : UniqueRowColumnDirectRule
-BINA-CONT-0001 : ThreeAdjacentContradictionRule
-BINA-CONT-0002 : UnbalancedRowOrColumnContradictionRule
-BINA-CONT-0003 : DuplicateRowsOrColumnsContradictionRule
+BINA-CONT-0001 : TrioContradictionRule
+BINA-CONT-0002 : UnbalancedRowColumnContradictionRule
+BINA-CONT-0003 : RepeatedRowColumnContradictionRule
+BINA-CONT-0004 : WastedBlockerContradictionRule
-BINA-CASE-0001 : OneOrZeroCaseRule
\ No newline at end of file
+BINA-CASE-0001 : ZeroOrOneCaseRule
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java
index a9e5aa2df..40c5e4a54 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java
@@ -42,13 +42,13 @@ public void setCellType(FillapixCellType type) {
@Override
public void setType(Element e, MouseEvent m) {
switch (e.getElementID()) {
- case "FPIX-PLAC-0001":
+ case "FPIX-ELEM-0001":
this.setCellType(FillapixCellType.BLACK);
break;
- case "FPIX-PLAC-0002":
+ case "FPIX-ELEM-0004":
this.setCellType(FillapixCellType.WHITE);
break;
- case "FPIX-UNPL-0001":
+ case "FPIX-ELEM-0002":
int n = this.getNumber();
switch (m.getButton()) {
case MouseEvent.BUTTON1:
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java
index 1d7c038a3..a6993778d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java
@@ -5,7 +5,7 @@
public class BlackTile extends PlaceableElement {
public BlackTile() {
super(
- "FPIX-PLAC-0001",
+ "FPIX-ELEM-0001",
"Black Tile",
"The black tile",
"edu/rpi/legup/images/fillapix/tiles/BlackTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java
index e869aeaf9..5852c1ad7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java
@@ -1,13 +1,13 @@
package edu.rpi.legup.puzzle.fillapix.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class NumberTile extends NonPlaceableElement {
+public class NumberTile extends PlaceableElement {
private int object_num;
public NumberTile() {
super(
- "FPIX-UNPL-0001",
+ "FPIX-ELEM-0002",
"Number Tile",
"A numbered tile",
"edu/rpi/legup/images/fillapix/tiles/NumberTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java
index 6778c1758..82d0dffb9 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.fillapix.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
super(
- "FPIX-UNPL-0002",
+ "FPIX-ELEM-0003",
"Unknown Tile",
"A blank tile",
"edu/rpi/legup/images/fillapix/tiles/UnknownTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java
index 67065a7e9..b2eedfc09 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java
@@ -5,7 +5,7 @@
public class WhiteTile extends PlaceableElement {
public WhiteTile() {
super(
- "FPIX-PLAC-0002",
+ "FPIX-ELEM-0004",
"White Tile",
"The white tile",
"edu/rpi/legup/images/fillapix/tiles/WhiteTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt
index 0409fa800..1aece4b97 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt
@@ -1,5 +1,4 @@
-FPIX-PLAC-0001 : BlackTile
-FPIX-PLAC-0002 : WhiteTile
-
-FPIX-UNPL-0001 : NumberTile
-FPIX-UNPL-0002 : UnknownTile
\ No newline at end of file
+FPIX-ELEM-0001 : BlackTile
+FPIX-ELEM-0002 : NumberTile
+FPIX-ELEM-0003 : UnknownTile
+FPIX-ELEM-0004 : WhiteTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java
index 860a6c011..f0194bd39 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java
@@ -37,6 +37,9 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
Board case1 = board.copy();
FillapixCell cell1 = (FillapixCell) case1.getPuzzleElement(puzzleElement);
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java
index 7db833f76..f8bb2d4f5 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java
@@ -45,6 +45,9 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList();
+ if (puzzleElement == null) {
+ return cases;
+ }
// get value of cell
FillapixBoard fillapixBoard = (FillapixBoard) board.copy();
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java
index ab95c4658..a73806cd7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java
@@ -47,7 +47,7 @@ public Board generatePuzzle(int difficulty) {
* @return true if the given dimensions are valid for Light Up, false otherwise
*/
public boolean isValidDimensions(int rows, int columns) {
- return rows > 0 && columns > 0;
+ return rows >= 0 && columns >= 0;
}
/**
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java
index 217ef79a8..21084b8c7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java
@@ -134,12 +134,12 @@ public int getNumAdjLite(LightUpCell cell) {
}
/**
- * Gets the number of adjacent cells that are placable
+ * Gets the number of adjacent cells that are placeable
*
* @param cell specified cell
- * @return number of adjacent cells that are placable
+ * @return number of adjacent cells that are placeable
*/
- public int getNumPlacble(LightUpCell cell) {
+ public int getNumPlaceable(LightUpCell cell) {
int num = 0;
Set adjCells = getAdj(cell);
for (LightUpCell c : adjCells) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java
index 8adf84cb4..6d890e67b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java
@@ -16,16 +16,16 @@ public LightUpCell(int valueInt, Point location) {
@Override
public void setType(Element e, MouseEvent m) {
switch (e.getElementID()) {
- case "LTUP-PLAC-0001":
+ case "LTUP-ELEM-0002":
this.data = -4;
break;
- case "LTUP-UNPL-0002":
+ case "LTUP-ELEM-0001":
this.data = -1;
break;
- case "LTUP-UNPL-0003":
+ case "LTUP-ELEM-0004":
this.data = -2;
break;
- case "LTUP-UNPL-0001":
+ case "LTUP-ELEM-0003":
switch (m.getButton()) {
case MouseEvent.BUTTON1:
if (this.data < 0 || this.data > 3) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java
index 2ddb4f754..eed3795d7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.lightup.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class BlackTile extends NonPlaceableElement {
+public class BlackTile extends PlaceableElement {
public BlackTile() {
super(
- "LTUP-UNPL-0002",
+ "LTUP-ELEM-0001",
"Black Tile",
"The black tile",
"edu/rpi/legup/images/lightup/black.gif");
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java
index d238baa56..61ebac3d0 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java
@@ -5,7 +5,7 @@
public class BulbTile extends PlaceableElement {
public BulbTile() {
super(
- "LTUP-PLAC-0001",
+ "LTUP-ELEM-0002",
"Bulb Tile",
"The bulb tile",
"edu/rpi/legup/images/lightup/light.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java
index ae314a4cf..26f9be46c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java
@@ -1,15 +1,15 @@
package edu.rpi.legup.puzzle.lightup.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class NumberTile extends NonPlaceableElement {
+public class NumberTile extends PlaceableElement {
int object_number;
// Follow the default format and resolves the NoSuchMethod error
public NumberTile() {
super(
- "LTUP-UNPL-0001",
+ "LTUP-ELEM-0003",
"Number Tile",
"The number tile",
"edu/rpi/legup/images/lightup/1.gif");
@@ -17,7 +17,7 @@ public NumberTile() {
public NumberTile(int num) {
super(
- "LTUP-UNPL-0001",
+ "LTUP-ELEM-0003",
"Number Tile",
"The number tile",
"edu/rpi/legup/images/lightup/" + num + ".gif");
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java
index 24d420fe8..a724be600 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.lightup.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
super(
- "LTUP-UNPL-0003",
+ "LTUP-ELEM-0004",
"Unknown Tile",
"A blank tile",
"edu/rpi/legup/images/lightup/UnknownTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/lightup_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/lightup_elements_reference_sheet.txt
new file mode 100644
index 000000000..93c97de1c
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/lightup_elements_reference_sheet.txt
@@ -0,0 +1,4 @@
+LTUP-ELEM-0001 : BlackTile
+LTUP-ELEM-0002 : BulbTile
+LTUP-ELEM-0003 : NumberTile
+LTUP-ELEM-0004 : UnknownTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java
index 4ba754731..53efb6587 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java
@@ -44,6 +44,10 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
Board case1 = board.copy();
PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
data1.setData(-4);
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java
index 490122874..f73a34b2d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java
@@ -47,6 +47,11 @@ public CaseBoard getCaseBoard(Board board) {
*/
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+ ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
LightUpBoard lightUpBoard = (LightUpBoard) board;
LightUpCell cell = (LightUpCell) puzzleElement;
Point loc = cell.getLocation();
@@ -96,7 +101,6 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
}
}
- ArrayList cases = new ArrayList<>();
if (numNeeded == 0) {
return cases;
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/TooFewBulbsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/TooFewBulbsContradictionRule.java
index 8cf68e570..de1f85edc 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/TooFewBulbsContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/TooFewBulbsContradictionRule.java
@@ -36,7 +36,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
int bulbs = lightUpBoard.getNumAdj(cell, LightUpCellType.BULB);
- int placeable = lightUpBoard.getNumPlacble(cell);
+ int placeable = lightUpBoard.getNumPlaceable(cell);
if (bulbs + placeable < cell.getData()) {
return null;
diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/BombTile.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/BombTile.java
index 78a5d320c..cd5577eeb 100644
--- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/BombTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/BombTile.java
@@ -1,8 +1,8 @@
package edu.rpi.legup.puzzle.minesweeper.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class BombTile extends NonPlaceableElement {
+public class BombTile extends PlaceableElement {
public BombTile() {
super(
"MINE-UNPL-0001",
diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java
index 447e2840c..6cfc34c8d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java
@@ -1,8 +1,8 @@
package edu.rpi.legup.puzzle.minesweeper.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnsetTile extends NonPlaceableElement {
+public class UnsetTile extends PlaceableElement {
public UnsetTile() {
super(
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeCell.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeCell.java
index c6cd2c64e..1e0e85ed8 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeCell.java
@@ -46,13 +46,13 @@ public NurikabeType getType() {
@Override
public void setType(Element e, MouseEvent m) {
switch (e.getElementID()) {
- case "NURI-PLAC-0001":
+ case "NURI-ELEM-0001":
this.data = -1;
break;
- case "NURI-PLAC-0002":
+ case "NURI-ELEM-0004":
this.data = 0;
break;
- case "NURI-UNPL-0001":
+ case "NURI-ELEM-0002":
switch (m.getButton()) {
case MouseEvent.BUTTON1:
if (this.data <= 0 || this.data > 8) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeExporter.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeExporter.java
index 23efd4724..e01821639 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeExporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeExporter.java
@@ -10,6 +10,13 @@ public NurikabeExporter(Nurikabe nurikabe) {
super(nurikabe);
}
+ /**
+ * Generates an XML element for the nurikabe puzzle board, including its dimensions and the
+ * state of each cell. Nurikabe cells that are not empty are included in the XML.
+ *
+ * @param newDocument The XML document to which the board element belongs.
+ * @return The XML element representing the board.
+ */
@Override
protected org.w3c.dom.Element createBoardElement(Document newDocument) {
NurikabeBoard board;
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/BlackTile.java
index 459a809e0..a7972b9b2 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/BlackTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/BlackTile.java
@@ -5,7 +5,7 @@
public class BlackTile extends PlaceableElement {
public BlackTile() {
super(
- "NURI-PLAC-0001",
+ "NURI-ELEM-0001",
"Black Tile",
"The black tile",
"edu/rpi/legup/images/nurikabe/tiles/BlackTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/NumberTile.java
index 475b278da..2015d990b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/NumberTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/NumberTile.java
@@ -1,13 +1,13 @@
package edu.rpi.legup.puzzle.nurikabe.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class NumberTile extends NonPlaceableElement {
+public class NumberTile extends PlaceableElement {
private int object_num;
public NumberTile() {
super(
- "NURI-UNPL-0001",
+ "NURI-ELEM-0002",
"Number Tile",
"A numbered tile",
"edu/rpi/legup/images/nurikabe/tiles/NumberTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/UnknownTile.java
index 85d47e208..8a18c80cc 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/UnknownTile.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.nurikabe.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
super(
- "NURI-UNPL-0002",
+ "NURI-ELEM-0003",
"Unknown Tile",
"A blank tile",
"edu/rpi/legup/images/nurikabe/tiles/UnknownTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/WhiteTile.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/WhiteTile.java
index 35eb63b81..ae07c6d76 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/WhiteTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/WhiteTile.java
@@ -5,7 +5,7 @@
public class WhiteTile extends PlaceableElement {
public WhiteTile() {
super(
- "NURI-PLAC-0002",
+ "NURI-ELEM-0004",
"White Tile",
"The white tile",
"edu/rpi/legup/images/nurikabe/tiles/WhiteTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/nurikabe_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/nurikabe_elements_reference_sheet.txt
new file mode 100644
index 000000000..667972fd6
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/nurikabe_elements_reference_sheet.txt
@@ -0,0 +1,4 @@
+NURI-ELEM-0001 : BlackTile
+NURI-ELEM-0002 : NumberTile
+NURI-ELEM-0003 : UnknownTile
+NURI-ELEM-0004 : WhiteTile
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/BlackOrWhiteCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/BlackOrWhiteCaseRule.java
index ac0ab6df6..1c87d5cfa 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/BlackOrWhiteCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/BlackOrWhiteCaseRule.java
@@ -24,7 +24,7 @@ public BlackOrWhiteCaseRule() {
/**
* Checks whether the {@link TreeTransition} logically follows from the parent node using this
- * rule. This method is the one that should overridden in child classes.
+ * rule. This method is the one that should be overridden in child classes.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -84,6 +84,10 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
Board case1 = board.copy();
PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
data1.setData(NurikabeType.WHITE.toValue());
diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/FinishRoomCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/FinishRoomCaseRule.java
index 24a261ec9..025212d96 100644
--- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/FinishRoomCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/rules/FinishRoomCaseRule.java
@@ -27,15 +27,16 @@ public FinishRoomCaseRule() {
super(
"NURI-CASE-0002",
"Finish Room",
- "Room can be finished in up to five ways",
+ "Room can be finished in up to nine ways",
"edu/rpi/legup/images/nurikabe/cases/FinishRoom.png");
- this.MAX_CASES = 5;
- this.MIN_CASES = 2;
+ this.MAX_CASES = 9;
+ this.MIN_CASES = 1;
+ this.uniqueCases = new HashSet<>();
}
/**
* Checks whether the {@link TreeTransition} logically follows from the parent node using this
- * rule. This method is the one that should overridden in child classes.
+ * rule. This method is the one that should have overridden in child classes.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -44,18 +45,18 @@ public FinishRoomCaseRule() {
public String checkRuleRaw(TreeTransition transition) {
NurikabeBoard destBoardState = (NurikabeBoard) transition.getBoard();
List childTransitions = transition.getParents().get(0).getChildren();
- if (childTransitions.size() > 5) {
+ if (childTransitions.size() > MAX_CASES) {
return super.getInvalidUseOfRuleMessage()
- + ": This case rule must have 5 or less children.";
+ + ": This case rule must have 9 or less children.";
}
- if (childTransitions.size() < 2) {
+ if (childTransitions.size() < MIN_CASES) {
return super.getInvalidUseOfRuleMessage()
- + ": This case rule must have 2 or more children.";
+ + ": This case rule must have 1 or more children.";
}
if (childTransitions.size() != legitCases) {
return super.getInvalidUseOfRuleMessage()
+ ": Cases can not be removed from the branch.";
- } // stops user from deleting 1 or mose generated cases and still having path show as green
+ } // stops user from deleting 1 or more generated cases and still having path show as green
Set locations = new HashSet<>();
for (TreeTransition t1 : childTransitions) {
locations.add(
@@ -100,14 +101,8 @@ public CaseBoard getCaseBoard(Board board) {
// if found another number tile and it's data is different from the element
// we're working with
if ((d.getType() == NurikabeType.NUMBER)
- && !(d.getData()
- .equals(
- ((NurikabeCell) element)
- .getData()))) { // if found another number tile
- // and it's data is different
- // than the element we're
- // working with
- only = false; // set only to false
+ && !(d.getData().equals(((NurikabeCell) element).getData()))) {
+ only = false;
}
}
// if size of region is 1 less than the number block and the number block is only
@@ -130,6 +125,10 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>(); // makes array list of cases
+ if (puzzleElement == null) {
+ return cases;
+ }
+
NurikabeBoard nuriBoard = (NurikabeBoard) board.copy(); // nurikabe board to edit
NurikabeCell numberCell =
nuriBoard.getCell(
@@ -231,23 +230,9 @@ private void generateCases(
break;
}
}
- if (!alreadyIn) { // if point wasn't already in
- Board casey =
- nuriBoard.copy(); // copy the current board with white tile
- // changed
- PuzzleElement datacasey =
- curr; // gets changed white tile as a puzzle element
- datacasey.setData(
- NurikabeType.WHITE
- .toValue()); // ensure set to white, probably redundant
- casey.addModifiedData(datacasey); // ensure confirmed white change
- regions =
- NurikabeUtilities.getNurikabeRegions(
- nuriBoard); // update regions
- cases.add(casey); // add this case to list of cases
- locations.add(
- here); // add location of new white tile to list of locations so
- // that we don't accidentally add it again later
+ if (unique) {
+ caseBoard.addModifiedData(newCell);
+ cases.add(caseBoard);
}
} else if (newRoomSet.size() < filledRoomSize) {
generateCases(
@@ -301,14 +286,10 @@ private boolean touchesDifferentRoom(
|| (adjacentPoint.x != origPoint.x || adjacentPoint.y != origPoint.y)) {
return true;
}
- curr.setData(NurikabeType.UNKNOWN.toValue()); // set cell type back to unknown
- nuriBoard.addModifiedData(curr); // confirms change back to unknown
- regions = NurikabeUtilities.getNurikabeRegions(nuriBoard); // updates regions
}
}
- legitCases = cases.size();
}
- return cases;
+ return false;
}
/**
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/ShortTruthTableCell.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/ShortTruthTableCell.java
index 75bba369f..ffd7c491d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/ShortTruthTableCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/ShortTruthTableCell.java
@@ -135,22 +135,22 @@ public void setType(Element e, MouseEvent m) {
}
// Red Element
- if (e.getElementID().equals("STTT-PLAC-0002")) {
+ if (e.getElementID().equals("STTT-ELEM-0004")) {
this.data = ShortTruthTableCellType.FALSE;
}
// Green Element
else {
- if (e.getElementID().equals("STTT-PLAC-0001")) {
+ if (e.getElementID().equals("STTT-ELEM-0002")) {
this.data = ShortTruthTableCellType.TRUE;
}
// Unknown Element
else {
- if (e.getElementID().equals("STTT-PLAC-0003")) {
+ if (e.getElementID().equals("STTT-ELEM-0005")) {
this.data = ShortTruthTableCellType.UNKNOWN;
}
// Argument Element
else {
- if (e.getElementID().equals("STTT-UNPL-0001")) {
+ if (e.getElementID().equals("STTT-ELEM-0001")) {
// Prevents non-argument symbols from being changed
if (!(this.symbol >= 'A' && this.symbol <= 'Z')) {
return;
@@ -172,7 +172,7 @@ public void setType(Element e, MouseEvent m) {
}
// And/Or Element
else {
- if (e.getElementID().equals("STTT-UNPL-0002")) {
+ if (e.getElementID().equals("STTT-ELEM-0003")) {
if (m.getButton() == MouseEvent.BUTTON1) {
if (this.symbol == '^') {
this.symbol = '|';
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/ArgumentElement.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/ArgumentElement.java
index 9294fba4e..912fd2672 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/ArgumentElement.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/ArgumentElement.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.shorttruthtable.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class ArgumentElement extends NonPlaceableElement {
+public class ArgumentElement extends PlaceableElement {
public ArgumentElement() {
super(
- "STTT-UNPL-0001",
+ "STTT-ELEM-0001",
"Argument Element",
"Argument of logic statement element",
"edu/rpi/legup/images/shorttruthtable/tiles/LetterTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/GreenElement.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/GreenElement.java
index 783186baa..56221fef3 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/GreenElement.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/GreenElement.java
@@ -5,7 +5,7 @@
public class GreenElement extends PlaceableElement {
public GreenElement() {
super(
- "STTT-PLAC-0001",
+ "STTT-ELEM-0002",
"Green Element",
"A green tile to set certain tiles to true",
"edu/rpi/legup/images/shorttruthtable/tiles/GreenTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/LogicSymbolElement.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/LogicSymbolElement.java
index 5fed4b1df..b82ebc2cb 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/LogicSymbolElement.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/LogicSymbolElement.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.shorttruthtable.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class LogicSymbolElement extends NonPlaceableElement {
+public class LogicSymbolElement extends PlaceableElement {
public LogicSymbolElement() {
super(
- "STTT-UNPL-0002",
+ "STTT-ELEM-0003",
"Logic Symbol Element",
"Logic symbol element",
"edu/rpi/legup/images/shorttruthtable/tiles/ConditionalBiconditionalTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/RedElement.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/RedElement.java
index e2a589b65..2114e62ec 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/RedElement.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/RedElement.java
@@ -5,7 +5,7 @@
public class RedElement extends PlaceableElement {
public RedElement() {
super(
- "STTT-PLAC-0002",
+ "STTT-ELEM-0004",
"Red Element",
"A red tile to set certain tiles to false",
"edu/rpi/legup/images/shorttruthtable/tiles/RedTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/UnknownElement.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/UnknownElement.java
index d475bc05d..52b54f202 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/UnknownElement.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/UnknownElement.java
@@ -5,7 +5,7 @@
public class UnknownElement extends PlaceableElement {
public UnknownElement() {
super(
- "STTT-PLAC-0003",
+ "STTT-ELEM-0005",
"Unknown Element",
"A blank tile",
"edu/rpi/legup/images/shorttruthtable/tiles/UnknownTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/shorttruthtable_elements_reference_sheet b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/shorttruthtable_elements_reference_sheet
index 471631553..c5421169f 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/shorttruthtable_elements_reference_sheet
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/elements/shorttruthtable_elements_reference_sheet
@@ -1,6 +1,5 @@
-STTT-UNPL-0001 : ArgumentElement
-STTT-UNPL-0002 : ConditionalBiconditionalElement
-
-STTT-PLAC-0001 : GreenElement
-STTT-PLAC-0002 : RedElement
-STTT-PLAC-0003 : UnknownElement
\ No newline at end of file
+STTT-ELEM-0001 : ArgumentElement
+STTT-ELEM-0002 : GreenElement
+STTT-ELEM-0003 : LogicSymbolElement
+STTT-ELEM-0004 : RedElement
+STTT-ELEM-0005 : UnknownElement
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRuleAtomic.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRuleAtomic.java
index 58d2068b2..22b49fd77 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRuleAtomic.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRuleAtomic.java
@@ -44,6 +44,9 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
Board case1 = board.copy();
PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
diff --git a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRule_GenericStatement.java b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRule_GenericStatement.java
index 99f771246..8aeb51a46 100644
--- a/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRule_GenericStatement.java
+++ b/src/main/java/edu/rpi/legup/puzzle/shorttruthtable/rules/caserule/CaseRule_GenericStatement.java
@@ -85,6 +85,11 @@ public CaseBoard getCaseBoard(Board board) {
@SuppressWarnings("unchecked")
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+
+ if (puzzleElement == null) {
+ return new ArrayList();
+ }
+
ShortTruthTableBoard sttBoard = ((ShortTruthTableBoard) board);
ShortTruthTableCell cell = sttBoard.getCellFromElement(puzzleElement);
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/Skyscrapers.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/Skyscrapers.java
index df5ba78a3..44f416cef 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/Skyscrapers.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/Skyscrapers.java
@@ -46,7 +46,7 @@ public Board generatePuzzle(int difficulty) {
* @return true if the given dimensions are valid for Skyscrapers, false otherwise
*/
public boolean isValidDimensions(int rows, int columns) {
- return rows >= 4 && rows == columns;
+ return rows >= 3 && rows == columns;
}
/**
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersBoard.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersBoard.java
index 4cd09b254..0fc133786 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersBoard.java
@@ -209,7 +209,7 @@ public void setCell(int x, int y, Element e, MouseEvent m) {
SkyscrapersClue clue = this.getClue(x, y);
if (e == null) return;
if (clue != null) {
- if (!e.getElementID().equals("SKYS-UNPL-0003")) {
+ if (!e.getElementID().equals("SKYS-ELEM-0001")) {
return;
}
@@ -217,10 +217,10 @@ public void setCell(int x, int y, Element e, MouseEvent m) {
if (clue.getData() < dimension.height) {
clue.setData(clue.getData() + 1);
} else {
- clue.setData(0);
+ clue.setData(1);
}
} else {
- if (clue.getData() > 0) {
+ if (clue.getData() > 1) {
clue.setData(clue.getData() - 1);
} else {
clue.setData(dimension.height);
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersCell.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersCell.java
index 1cf9a357b..9e7283b20 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersCell.java
@@ -27,10 +27,10 @@ public SkyscrapersType getType() {
@Override
public void setType(Element e, MouseEvent m) {
switch (e.getElementID()) {
- case "SKYS-UNPL-0001":
+ case "SKYS-ELEM-0002":
this.data = 0;
break;
- case "SKYS-UNPL-0002":
+ case "SKYS-ELEM-0001":
switch (m.getButton()) {
case MouseEvent.BUTTON1:
if (this.data <= 0 || this.data >= this.max) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersClueView.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersClueView.java
index 4c75f0695..cfb3388ff 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersClueView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/SkyscrapersClueView.java
@@ -25,11 +25,11 @@ public SkyscrapersClue getPuzzleElement() {
@Override
public void draw(Graphics2D graphics2D) {
drawElement(graphics2D);
+ if (this.isHover()) {
+ drawHover(graphics2D);
+ }
if (this.isShowCasePicker() && this.isCaseRulePickable()) {
drawCase(graphics2D);
- if (this.isHover()) {
- drawHover(graphics2D);
- }
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/ClueTile.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/ClueTile.java
deleted file mode 100644
index 64c9033e6..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/ClueTile.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package edu.rpi.legup.puzzle.skyscrapers.elements;
-
-import edu.rpi.legup.model.elements.NonPlaceableElement;
-
-public class ClueTile extends NonPlaceableElement {
-
- public ClueTile() {
- super(
- "SKYS-UNPL-0003",
- "Clue Tile",
- "Clue Updater",
- "edu/rpi/legup/images/skyscrapers/tiles/ClueTile.png");
- }
-}
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/NumberTile.java
index 4d6b37c9a..f60e5fe8b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/NumberTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/NumberTile.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.skyscrapers.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class NumberTile extends NonPlaceableElement {
+public class NumberTile extends PlaceableElement {
public NumberTile() {
super(
- "SKYS-UNPL-0002",
+ "SKYS-ELEM-0001",
"Number Tile",
"A numbered tile",
"edu/rpi/legup/images/skyscrapers/tiles/ClueTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/UnknownTile.java
index 2fb21193a..07f6a1238 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/UnknownTile.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.skyscrapers.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
super(
- "SKYS-UNPL-0001",
+ "SKYS-ELEM-0002",
"Unknown",
"A blank tile",
"edu/rpi/legup/images/skyscrapers/tiles/UnknownTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/skyscrapers_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/skyscrapers_elements_reference_sheet.txt
index 604e1824e..14e76a29d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/skyscrapers_elements_reference_sheet.txt
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/skyscrapers_elements_reference_sheet.txt
@@ -1,3 +1,2 @@
-SKYS-UNPL-0001: Unknown Tile
-SKYS-UNPL-0002: Number Tile
-SKYS-UNPL-0003: Clue "Tile"
\ No newline at end of file
+SKYS-ELEM-0001: NumberTile
+SKYS-ELEM-0002: UnknownTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/CellForNumberCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/CellForNumberCaseRule.java
index 45bdadea3..b48962c41 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/CellForNumberCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/CellForNumberCaseRule.java
@@ -61,6 +61,9 @@ public CaseBoard getCaseBoard(Board board) {
public ArrayList getCasesFor(Board board, PuzzleElement puzzleElement, Integer number) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
SkyscrapersClue clue = (SkyscrapersClue) puzzleElement;
SkyscrapersBoard skyscrapersboard = (SkyscrapersBoard) board;
diff --git a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/NumberForCellCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/NumberForCellCaseRule.java
index 145dd6ee2..4f8e1df6b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/NumberForCellCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/rules/NumberForCellCaseRule.java
@@ -47,6 +47,9 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
SkyscrapersCell cell = (SkyscrapersCell) puzzleElement;
SkyscrapersBoard skyscrapersboard = (SkyscrapersBoard) board;
diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt
deleted file mode 100644
index 5a9ec0f0a..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt
+++ /dev/null
@@ -1,235 +0,0 @@
-//StarBattle.java
-
-package edu.rpi.legup.puzzle.starbattle;
-
-import edu.rpi.legup.model.Puzzle;
-import edu.rpi.legup.model.gameboard.Board;
-
-public class StarBattle extends Puzzle {
- public StarBattle() {
- super();
- this.name = "StarBattle";
-
- this.importer = new StarBattleImporter(this);
- this.exporter = new StarBattleExporter(this);
-
- this.factory = new StarBattleCellFactory();
- }
-
- @Override
- public void initializeView() {
- }
-
- @Override
- public Board generatePuzzle(int difficulty) {
- return null;
- }
-
- @Override
- public boolean isBoardComplete(Board board) {
- return true;
- }
-
- @Override
- public void onBoardChange(Board board) {
- }
-}
-
-//StarBattleBoard.java
-
-package edu.rpi.legup.puzzle.lightup;
-
-import edu.rpi.legup.model.gameboard.GridBoard;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-
-import java.awt.*;
-import java.util.HashSet;
-import java.util.Set;
-
-public class StarBattleBoard extends GridBoard {
-
- private int size;
- private vector group_sizes;
-
- /**
- * StarBattleBoard Constructor - create a new Star Battle board
- *
- * @param size size of one side of the star battle board
- */
-
- public StarBattleBoard(int size) {
- super(size, size);
- group_sizes = vector(size);
- }
-
- @Override
- public StarBattleCell getCell(int x, int y) {
- return (StarBattleCell) super.getCell(x, y);
- }
-
-
-}
-
-//StarBattleCell.java
-
-package edu.rpi.legup.puzzle.starbattle;
-
-import edu.rpi.legup.model.gameboard.GridCell;
-
-import java.awt.*;
-import java.util.HashSet;
-import java.util.Set;
-
-public class StarBattleCell extends GridCell {
- private int groupIndex;
- private int max;
-
- /**
- * StarBattleCell Constructor - creates a new StarBattle cell to hold the puzzleElement
- *
- * @param valueInt value of the star battle cell denoting its state
- * @param location location of the cell on the board
- * @param size size of the star battle cell
- */
- public StarBattleCell(int value, Point location, int groupIndex, int size) {
- super(value, location);
- this.groupIndex = groupIndex;
- this.max = size;
- }
-
- @Override
- public void setType(Element e, MouseEvent m) {
- switch (e.getElementID()) {
- case "SBUP-PLAC-0001":
- this.data = -3;
- break;
- case "SBUP-PLAC-0002":
- this.data = -2;
- break;
- case "SBUP-PLAC-0003":
- this.data = -1;
- break;
- case "SBUP-UNPL-0001"://Not sure how button events work
- switch (m.getButton()){
- case MouseEvent.BUTTON1:
- if (this.data < 0 || this.data > 3) {
- this.data = 0;
- }
- else {
- this.data = this.data + 1;
- }
- break;
- case MouseEvent.BUTTON3:
- if (this.data > 0) {
- this.data = this.data - 1;
- }
- else {
- this.data = 3;//Unsure
- }
- break;
- }
- break;
- }
- }
-
- public LightUpCellType getType() {
- switch (data) {
- case -3:
- return LightUpCellType.UNKNOWN;
- case -2:
- return LightUpCellType.STAR;
- case -1:
- return LightUpCellType.BLACK;
- default:
- if (data >= 0) {
- return StarBattleCellType.WHITE;
- }
- }
- return null;
- }
-
- /**
- * Gets the region index of the cell
- *
- * @return group index of the cell
- */
- public int getGroupIndex() {
- return groupIndex;
- }
-
- /**
- * Gets the size of the cell
- *
- * @return size of the cell
- */
-
- public int getMax() {
- return max;
- }
-
-}
-
-//StarBattleCellController.java
-
-package edu.rpi.legup.puzzle.starbattle;
-
-import edu.rpi.legup.controller.ElementController;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-
-import java.awt.event.MouseEvent;
-
-public class StarBattleCellController extends ElementController {
- @Override
- public void changeCell(MouseEvent e, PuzzleElement data) {
- StarBattleCell cell = (StarBattleCell) data;
- if (e.getButton() == MouseEvent.BUTTON1) {
- if (e.isControlDown()) {
- this.boardView.getSelectionPopupMenu().show(boardView, this.boardView.getCanvas().getX() + e.getX(), this.boardView.getCanvas().getY() + e.getY());
- }
- else {
- if (cell.getData() == 0) {
- data.setData(-3);
- }
- else {
- data.setData(cell.getData() + 1);
- }
- }
- }
- else {
- if (e.getButton() == MouseEvent.BUTTON3) {
- if (cell.getData() == -3) {
- data.setData(0);
- }
- else {
- data.setData(cell.getData() - 1);
- }
- }
- }
- }
-}
-
-//StarBattleCellFactory.java
-
-
-
-//StarBattleCellType.java
-package edu.rpi.legup.puzzle.starbattle;
-
-public enum StarBattleType {
- UNKNOWN(-3), STAR(-2), BLACK(-1), WHITE(0);
-
- public int value;
-
- StarBattleCell(int value) {
- this.value = value;
- }
-}
-
-//StarBattleExporter.java
-//StarBattleImporter.java
-//StarBattleView.java
-
-How to run Legup:
-
-./gradlew build
-Java -jar build/libs/Legup.jar
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java
index 99f42886e..c4bbf7297 100644
--- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java
@@ -1,8 +1,8 @@
package edu.rpi.legup.puzzle.starbattle.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class BlackTile extends NonPlaceableElement {
+public class BlackTile extends PlaceableElement {
public BlackTile() {
super(
"STBL-PLAC-0002",
diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java
index 13ada3f4d..793d4dbeb 100644
--- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java
@@ -1,8 +1,8 @@
package edu.rpi.legup.puzzle.starbattle.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class StarTile extends NonPlaceableElement {
+public class StarTile extends PlaceableElement {
public StarTile() {
super(
"STBL-PLAC-0001",
diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java
index 425fb5d5e..30921de8d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java
@@ -1,8 +1,8 @@
package edu.rpi.legup.puzzle.starbattle.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
super(
"STBL-UNPL-0001",
diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/starbattle_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/starbattle_elements_reference_sheet.txt
new file mode 100644
index 000000000..82352bd04
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/starbattle_elements_reference_sheet.txt
@@ -0,0 +1,4 @@
+STBL-ELEM-0001 : BlackTile
+STBL-ELEM-0002 : StarTile
+STBL-ELEM-0003 : UnknownTile
+STBL-ELEM-0004 : WhiteTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java
index df900dcd5..efd86bd7b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java
@@ -84,6 +84,10 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
Board case1 = board.copy();
PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
data1.setData(StarBattleCellType.STAR.value);
diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt
deleted file mode 100644
index f18965fd6..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Case Rules:
-Add Star: STBL-CASE-0001
-Star or Empty: STBL-CASE-0002
-
-Basic Rules:
-Blackout: STBL-BASC-0001
-Columns Within Regions: STBL-BASC-0002
-Columns Within Rows: STBL-BASC-0003
-Finish With Stars: STBL-BASC-0004
-Regions Within Columns: STBL-BASC-0005
-Regions Within Rows: STBL-BASC-0006
-Rows Within Columns: STBL-BASC-0007
-Rows Within Regions: STBL-BASC-0008
-Surround Star: STBL-BASC-0009
-
-Contradiction Rules:
-Too Many Stars: STBL-CONT-0001
-Too Few Stars: STBL-CONT-0002
-Clashing Orbit: STBL-CONT-0003
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/ModelSudokuBoard.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/ModelSudokuBoard.java
new file mode 100644
index 000000000..f7893ca32
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/ModelSudokuBoard.java
@@ -0,0 +1,17 @@
+package edu.rpi.legup.puzzle.sudoku;
+
+public class ModelSudokuBoard {
+ public int getModelRegionNumbers(int index) {
+ int columnMod = index % 3 + 1;
+ int rowMod = ((index / 9) % 3) * 3;
+ return columnMod + rowMod;
+ }
+
+ public int getModelRowNumbers(int index) {
+ return index % 9 + 1;
+ }
+
+ public int getModelColumnNumbers(int index) {
+ return index / 9 + 1;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/PossibleNumberCaseBoard.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/PossibleNumberCaseBoard.java
index 0b6971235..c5f9eec2a 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/PossibleNumberCaseBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/PossibleNumberCaseBoard.java
@@ -2,7 +2,7 @@
import edu.rpi.legup.model.gameboard.CaseBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.puzzle.sudoku.rules.PossibleNumberCaseRule;
+import edu.rpi.legup.puzzle.sudoku.rules.PossibleCellsForNumberRegionCaseRule;
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Set;
@@ -15,7 +15,7 @@ public class PossibleNumberCaseBoard extends CaseBoard {
private Set pickableCols;
public PossibleNumberCaseBoard(
- SudokuBoard baseBoard, PossibleNumberCaseRule caseRule, SudokuCell cell) {
+ SudokuBoard baseBoard, PossibleCellsForNumberRegionCaseRule caseRule, SudokuCell cell) {
super(baseBoard, caseRule);
this.cell = cell;
this.pickableRegions = new HashSet<>();
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/Sudoku.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/Sudoku.java
index 877c92665..c27269536 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/Sudoku.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/Sudoku.java
@@ -29,6 +29,8 @@ public BoardView getBoardView() {
@Override
public void initializeView() {
boardView = new SudokuView((SudokuBoard) currentBoard);
+ boardView.setBoard(currentBoard);
+ addBoardListener(boardView);
}
/**
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCell.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCell.java
index da009a255..75e5820a0 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCell.java
@@ -1,7 +1,9 @@
package edu.rpi.legup.puzzle.sudoku;
+import edu.rpi.legup.model.elements.Element;
import edu.rpi.legup.model.gameboard.GridCell;
import java.awt.*;
+import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Set;
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCellController.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCellController.java
index 9b24f13da..bcad1a0ce 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCellController.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCellController.java
@@ -8,7 +8,7 @@ public class SudokuCellController extends ElementController {
@Override
public void changeCell(MouseEvent e, PuzzleElement data) {
SudokuCell cell = (SudokuCell) data;
- System.out.print(111);
+
if (e.getButton() == MouseEvent.BUTTON1) {
if (e.isControlDown()) {
this.boardView
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuImporter.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuImporter.java
index 68bf1e795..5084279c3 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuImporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuImporter.java
@@ -110,16 +110,6 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
}
}
}
- //
- // for(int y = 0; y < size; y++)
- // {
- // for(int x = 0; x < size; x++)
- // {
- // SudokuCell cell = sudokuBoard.getCell(x, y);
- // System.err.println("(" + x + ", " + y + ") - " +
- // cell.getGroupIndex());
- // }
- // }
puzzle.setCurrentBoard(sudokuBoard);
} catch (NumberFormatException e) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuView.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuView.java
index 9e8dc82ff..474feb342 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuView.java
@@ -30,6 +30,7 @@ public SudokuView(SudokuBoard board) {
// i * elementSize.height);
SudokuElementView element = new SudokuElementView(board.getCell(k, i));
element.setIndex(i * gridSize.width + k);
+ element.setIndex(i * gridSize.width);
element.setSize(elementSize);
element.setLocation(location);
elementViews.add(element);
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/NumberTile.java
index a75f32c5a..a94d10e64 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/NumberTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/NumberTile.java
@@ -3,10 +3,11 @@
import edu.rpi.legup.model.elements.PlaceableElement;
public class NumberTile extends PlaceableElement {
- private int object_num;
-
public NumberTile() {
- super("SUDO-PLAC-0001", "Number Tile", "A numbered tile", null);
- object_num = 0;
+ super(
+ "SUDO-ELEM-0001",
+ "Number Tile",
+ "A number tile",
+ "edu/rpi/legup/images/sudoku/tiles/NumberTile.png");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/sudoku_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/sudoku_elements_reference_sheet.txt
new file mode 100644
index 000000000..b8df27eb6
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/sudoku_elements_reference_sheet.txt
@@ -0,0 +1,2 @@
+SUDO-ELEM-0001 : NumberTile
+SUDO-ELEM-0002 : UnknownTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/AdvancedDeductionDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/AdvancedDeductionDirectRule.java
deleted file mode 100644
index 190679b41..000000000
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/AdvancedDeductionDirectRule.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package edu.rpi.legup.puzzle.sudoku.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
-import edu.rpi.legup.puzzle.sudoku.SudokuCell;
-
-public class AdvancedDeductionDirectRule extends DirectRule {
-
- public AdvancedDeductionDirectRule() {
- super(
- "SUDO-BASC-0001",
- "Advanced Deduction",
- "Use of group logic deduces more answers by means of forced by Location and forced"
- + " by Deduction",
- "edu/rpi/legup/images/sudoku/AdvancedDeduction.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node at the specific
- * puzzleElement index using this rule
- *
- * @param transition transition to check
- * @param puzzleElement equivalent puzzleElement
- * @return null if the child node logically follow from the parent node at the specified
- * puzzleElement, otherwise error message
- */
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- SudokuBoard initialBoard = (SudokuBoard) transition.getParents().get(0).getBoard();
- SudokuBoard finalBoard = (SudokuBoard) transition.getBoard();
-
- SudokuCell cell = (SudokuCell) finalBoard.getPuzzleElement(puzzleElement);
- int index = cell.getIndex();
- int groupSize = initialBoard.getWidth();
- int groupDim = (int) Math.sqrt(groupSize);
- int rowIndex = index / groupSize;
- int colIndex = index % groupSize;
- int relX = rowIndex / groupDim;
- int relY = colIndex % groupDim;
- int groupNum = rowIndex / groupDim * groupDim + colIndex / groupDim;
- boolean[][] possible = new boolean[groupDim][groupDim];
- for (int y = 0; y < groupDim; y++) {
- for (int x = 0; x < groupDim; x++) {
- SudokuCell c = initialBoard.getCell(groupNum, x, y);
- if (c.getData() == cell.getData() && x != relX && y != relY) {
- return super.getRuleName() + ": Duplicate value in sub-region";
- }
- possible[y][x] = c.getData() == 0;
- }
- }
- for (int y = 0; y < groupDim; y++) {
- for (int x = 0; x < groupSize; x++) {
- SudokuCell r = initialBoard.getCell(x, (groupNum / groupDim) * groupDim + y);
- SudokuCell c = initialBoard.getCell((groupNum % groupDim) * groupDim + y, x);
- if (r.getData() == cell.getData()) {
- for (int i = 0; i < groupDim; i++) {
- possible[y][i] = false;
- }
- }
- if (c.getData() == cell.getData()) {
- for (int i = 0; i < groupDim; i++) {
- possible[i][y] = false;
- }
- }
- }
- }
- boolean isForced = false;
- for (int y = 0; y < groupDim; y++) {
- for (int x = 0; x < groupDim; x++) {
- if (possible[y][x] && !isForced) {
- isForced = true;
- } else {
- if (possible[y][x]) {
- return super.getInvalidUseOfRuleMessage() + ": Not forced";
- }
- }
- }
- }
- if (!isForced) {
- return super.getInvalidUseOfRuleMessage() + ": Not forced";
- }
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link
- * TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastCellForNumberDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastCellForNumberDirectRule.java
index fd03ef36c..6544bf7c3 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastCellForNumberDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastCellForNumberDirectRule.java
@@ -15,7 +15,7 @@ public LastCellForNumberDirectRule() {
"SUDO-BASC-0002",
"Last Cell for Number",
"This is the only cell open in its group for some number.",
- "edu/rpi/legup/images/sudoku/forcedByElimination.png");
+ "edu/rpi/legup/images/sudoku/rules/forcedByElimination.png");
}
/**
@@ -32,52 +32,146 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
SudokuBoard finalBoard = (SudokuBoard) transition.getBoard();
SudokuCell cell = (SudokuCell) finalBoard.getPuzzleElement(puzzleElement);
+
+ // Check if empty cell placed
if (cell.getData() == 0) {
return super.getInvalidUseOfRuleMessage() + ": Cell is not forced at this index";
}
- int size = initialBoard.getSize();
-
+ // Get defaults
Set region = initialBoard.getRegion(cell.getGroupIndex());
Set row = initialBoard.getRow(cell.getLocation().y);
Set col = initialBoard.getCol(cell.getLocation().x);
- boolean contains = false;
- if (region.size() == size - 1) {
- for (SudokuCell c : region) {
- if (cell.getData() == c.getData()) {
+ // Check if new cell conflicts group
+ for (SudokuCell c : region) {
+ if (c.getData() == cell.getData()) {
+ return super.getInvalidUseOfRuleMessage() + ": Cell is not forced at this index";
+ }
+ }
+ for (SudokuCell c : row) {
+ if (c.getData() == cell.getData()) {
+ return super.getInvalidUseOfRuleMessage() + ": Cell is not forced at this index";
+ }
+ }
+ for (SudokuCell c : col) {
+ if (c.getData() == cell.getData()) {
+ return super.getInvalidUseOfRuleMessage() + ": Cell is not forced at this index";
+ }
+ }
+
+ // //
+ // Loop to see if the number is constrained to the cell
+ boolean restrained = true;
+ for (SudokuCell c : region) {
+ // Test if its not a valid testing cell
+ if (c.getData() != 0) {
+ continue;
+ }
+ if (c.getLocation().y == cell.getLocation().y
+ && c.getLocation().x == cell.getLocation().x) {
+ continue;
+ }
+ // Check if cell is eligible to hold number
+ Set crow = initialBoard.getRow(c.getLocation().y);
+ Set ccol = initialBoard.getCol(c.getLocation().x);
+ boolean contains = false;
+ for (SudokuCell rc : crow) {
+ if (rc.getData() == cell.getData()) {
contains = true;
- break;
}
}
+ for (SudokuCell cc : ccol) {
+ if (cc.getData() == cell.getData()) {
+ contains = true;
+ }
+ }
+ // Stop if another cell can hold number
if (!contains) {
- return null;
+ restrained = false;
+ break;
}
}
- if (row.size() == size - 1) {
- contains = false;
- for (SudokuCell c : row) {
- if (cell.getData() == c.getData()) {
+ // Output if success
+ if (restrained) {
+ return null;
+ }
+
+ // //
+ // Loop to see if the number is constrained to the cell
+ restrained = true;
+ for (SudokuCell c : row) {
+ // Test if its not a valid testing cell
+ if (c.getData() != 0) {
+ continue;
+ }
+ if (c.getLocation().y == cell.getLocation().y
+ && c.getLocation().x == cell.getLocation().x) {
+ continue;
+ }
+ // Check if cell is eligible to hold number
+ Set cregion = initialBoard.getRegion(c.getGroupIndex());
+ Set ccol = initialBoard.getCol(c.getLocation().x);
+ boolean contains = false;
+ for (SudokuCell rc : cregion) {
+ if (rc.getData() == cell.getData()) {
+ contains = true;
+ }
+ }
+ for (SudokuCell cc : ccol) {
+ if (cc.getData() == cell.getData()) {
contains = true;
- break;
}
}
+ // Stop if another cell can hold number
if (!contains) {
- return null;
+ restrained = false;
+ break;
}
}
- if (col.size() == size - 1) {
- contains = false;
- for (SudokuCell c : col) {
- if (cell.getData() == c.getData()) {
+ // Output if success
+ if (restrained) {
+ return null;
+ }
+
+ // //
+ // Loop to see if the number is constrained to the cell
+ restrained = true;
+ for (SudokuCell c : col) {
+ // Test if its not a valid testing cell
+ if (c.getData() != 0) {
+ continue;
+ }
+ if (c.getLocation().y == cell.getLocation().y
+ && c.getLocation().x == cell.getLocation().x) {
+ continue;
+ }
+ // Check if cell is eligible to hold number
+ Set cregion = initialBoard.getRegion(c.getGroupIndex());
+ Set crow = initialBoard.getRow(c.getLocation().y);
+ boolean contains = false;
+ for (SudokuCell rc : cregion) {
+ if (rc.getData() == cell.getData()) {
contains = true;
- break;
}
}
+ for (SudokuCell cc : crow) {
+ if (cc.getData() == cell.getData()) {
+ contains = true;
+ }
+ }
+ // Stop if another cell can hold number
if (!contains) {
- return null;
+ restrained = false;
+ break;
}
}
+ // Output if success
+ if (restrained) {
+ return null;
+ }
+
+ // Output fail
return super.getInvalidUseOfRuleMessage() + ": Cell is not forced at this index";
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastNumberForCellDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastNumberForCellDirectRule.java
index ca0ac3023..333d91749 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastNumberForCellDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/LastNumberForCellDirectRule.java
@@ -16,7 +16,7 @@ public LastNumberForCellDirectRule() {
"SUDO-BASC-0003",
"Last Number for Cell",
"This is the only number left that can fit in the cell of a group.",
- "edu/rpi/legup/images/sudoku/forcedByDeduction.png");
+ "edu/rpi/legup/images/sudoku/rules/forcedByDeduction.png");
}
/**
@@ -32,28 +32,37 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
SudokuBoard initialBoard = (SudokuBoard) transition.getParents().get(0).getBoard();
SudokuBoard finalBoard = (SudokuBoard) transition.getBoard();
- int index = puzzleElement.getIndex();
+ // Assign basics
int groupSize = initialBoard.getWidth();
int groupDim = (int) Math.sqrt(groupSize);
+
+ // Get position info
+ int index = puzzleElement.getIndex();
int rowIndex = index / groupSize;
int colIndex = index % groupSize;
- int groupNum = rowIndex / groupDim * groupDim + colIndex % groupDim;
+ int groupNum = (rowIndex / groupDim) * groupDim + (colIndex / groupDim);
+
+ // Create hashset of all numbers
HashSet numbers = new HashSet<>();
for (int i = 1; i <= groupSize; i++) {
numbers.add(i);
}
+
+ // Run through region, row, col to see contradicitng numbers
for (int i = 0; i < groupSize; i++) {
SudokuCell cell = initialBoard.getCell(groupNum, i % groupDim, i / groupDim);
numbers.remove(cell.getData());
}
for (int i = 0; i < groupSize; i++) {
- SudokuCell cell = initialBoard.getCell(i, colIndex);
+ SudokuCell cell = initialBoard.getCell(i, rowIndex);
numbers.remove(cell.getData());
}
for (int i = 0; i < groupSize; i++) {
- SudokuCell cell = initialBoard.getCell(rowIndex, i);
+ SudokuCell cell = initialBoard.getCell(colIndex, i);
numbers.remove(cell.getData());
}
+
+ // Check if plausible
if (numbers.size() > 1) {
return super.getInvalidUseOfRuleMessage() + ": The number at the index is not forced";
} else {
@@ -64,7 +73,11 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
+ ": The number at the index is forced but not correct";
}
}
- return null;
+ if (numbers.toArray(new Integer[1])[0] == puzzleElement.getData()) {
+ return null;
+ }
+ return super.getInvalidUseOfRuleMessage()
+ + ": The number at the index is forced but not correct";
}
/**
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberColumnContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberColumnContradictionRule.java
new file mode 100644
index 000000000..c8d627634
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberColumnContradictionRule.java
@@ -0,0 +1,90 @@
+package edu.rpi.legup.puzzle.sudoku.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
+import edu.rpi.legup.puzzle.sudoku.SudokuCell;
+import java.util.HashSet;
+import java.util.Set;
+
+public class NoCellForNumberColumnContradictionRule extends ContradictionRule {
+
+ public NoCellForNumberColumnContradictionRule() {
+ super(
+ "SUDO-CONT-0003",
+ "No Cell for Number (Column)",
+ "Process of elimination yields no valid numbers for an empty cell in a column.",
+ "edu/rpi/legup/images/sudoku/rules/NoCellForNumberColumn.png");
+ }
+
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ SudokuBoard sudokuBoard = (SudokuBoard) board;
+ SudokuCell cell = (SudokuCell) sudokuBoard.getPuzzleElement(puzzleElement);
+ if (cell.getData() != 0) {
+ return super.getNoContradictionMessage();
+ }
+
+ int groupSize = sudokuBoard.getSize();
+
+ Set col = sudokuBoard.getCol(cell.getGroupIndex());
+ Set numbersNotInColumn = new HashSet<>();
+
+ for (int i = 1; i <= groupSize; i++) {
+ numbersNotInColumn.add(i);
+ }
+ for (SudokuCell c : col) {
+ if (c.getData() != 0) {
+ numbersNotInColumn.remove(c.getData());
+ }
+ }
+
+ for (Integer i : numbersNotInColumn) {
+ // Check if number can be in cell
+ boolean canFit = false;
+ for (SudokuCell c : col) {
+ if (c.getData() != 0) {
+ continue;
+ }
+
+ // Get row and col groups
+ Set region = sudokuBoard.getRow(c.getLocation().y);
+ Set row = sudokuBoard.getCol(c.getLocation().x);
+
+ // Check if it alr exists in row or col
+ boolean duplicate = false;
+ for (SudokuCell rc : region) {
+ if (rc.getData() == i) {
+ duplicate = true;
+ }
+ }
+ for (SudokuCell cc : row) {
+ if (cc.getData() == i) {
+ duplicate = true;
+ }
+ }
+
+ // If there is no duplicate it can exist in the region
+ if (!duplicate) {
+ canFit = true;
+ break;
+ }
+ }
+ // If the number can't fit anywhere in region then contradiction
+ if (!canFit) {
+ return null;
+ }
+ }
+ return super.getNoContradictionMessage();
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRegionContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRegionContradictionRule.java
new file mode 100644
index 000000000..f5106b858
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRegionContradictionRule.java
@@ -0,0 +1,90 @@
+package edu.rpi.legup.puzzle.sudoku.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
+import edu.rpi.legup.puzzle.sudoku.SudokuCell;
+import java.util.HashSet;
+import java.util.Set;
+
+public class NoCellForNumberRegionContradictionRule extends ContradictionRule {
+
+ public NoCellForNumberRegionContradictionRule() {
+ super(
+ "SUDO-CONT-0001",
+ "No Cell for Number (Region)",
+ "Process of elimination yields no valid numbers for an empty cell in a region.",
+ "edu/rpi/legup/images/sudoku/rules/NoCellForNumberRegion.png");
+ }
+
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ SudokuBoard sudokuBoard = (SudokuBoard) board;
+ SudokuCell cell = (SudokuCell) sudokuBoard.getPuzzleElement(puzzleElement);
+ if (cell.getData() != 0) {
+ return super.getNoContradictionMessage();
+ }
+
+ int groupSize = sudokuBoard.getSize();
+
+ Set region = sudokuBoard.getRegion(cell.getGroupIndex());
+ Set numbersNotInRegion = new HashSet<>();
+
+ for (int i = 1; i <= groupSize; i++) {
+ numbersNotInRegion.add(i);
+ }
+ for (SudokuCell c : region) {
+ if (c.getData() != 0) {
+ numbersNotInRegion.remove(c.getData());
+ }
+ }
+
+ for (Integer i : numbersNotInRegion) {
+ // Check if number can be in cell
+ boolean canFit = false;
+ for (SudokuCell c : region) {
+ if (c.getData() != 0) {
+ continue;
+ }
+
+ // Get row and col groups
+ Set row = sudokuBoard.getRow(c.getLocation().y);
+ Set col = sudokuBoard.getCol(c.getLocation().x);
+
+ // Check if it alr exists in row or col
+ boolean duplicate = false;
+ for (SudokuCell rc : row) {
+ if (rc.getData() == i) {
+ duplicate = true;
+ }
+ }
+ for (SudokuCell cc : col) {
+ if (cc.getData() == i) {
+ duplicate = true;
+ }
+ }
+
+ // If there is no duplicate it can exist in the region
+ if (!duplicate) {
+ canFit = true;
+ break;
+ }
+ }
+ // If the number can't fit anywhere in region then contradiction
+ if (!canFit) {
+ return null;
+ }
+ }
+ return super.getNoContradictionMessage();
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRowContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRowContradictionRule.java
new file mode 100644
index 000000000..e3f9f764a
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRowContradictionRule.java
@@ -0,0 +1,90 @@
+package edu.rpi.legup.puzzle.sudoku.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
+import edu.rpi.legup.puzzle.sudoku.SudokuCell;
+import java.util.HashSet;
+import java.util.Set;
+
+public class NoCellForNumberRowContradictionRule extends ContradictionRule {
+
+ public NoCellForNumberRowContradictionRule() {
+ super(
+ "SUDO-CONT-0002",
+ "No Cell for Number (Row)",
+ "Process of elimination yields no valid numbers for an empty cell in a row.",
+ "edu/rpi/legup/images/sudoku/rules/NoCellForNumberRow.png");
+ }
+
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ SudokuBoard sudokuBoard = (SudokuBoard) board;
+ SudokuCell cell = (SudokuCell) sudokuBoard.getPuzzleElement(puzzleElement);
+ if (cell.getData() != 0) {
+ return super.getNoContradictionMessage();
+ }
+
+ int groupSize = sudokuBoard.getSize();
+
+ Set row = sudokuBoard.getRow(cell.getGroupIndex());
+ Set numbersNotInRow = new HashSet<>();
+
+ for (int i = 1; i <= groupSize; i++) {
+ numbersNotInRow.add(i);
+ }
+ for (SudokuCell c : row) {
+ if (c.getData() != 0) {
+ numbersNotInRow.remove(c.getData());
+ }
+ }
+
+ for (Integer i : numbersNotInRow) {
+ // Check if number can be in cell
+ boolean canFit = false;
+ for (SudokuCell c : row) {
+ if (c.getData() != 0) {
+ continue;
+ }
+
+ // Get row and col groups
+ Set region = sudokuBoard.getRow(c.getLocation().y);
+ Set col = sudokuBoard.getCol(c.getLocation().x);
+
+ // Check if it alr exists in row or col
+ boolean duplicate = false;
+ for (SudokuCell rc : region) {
+ if (rc.getData() == i) {
+ duplicate = true;
+ }
+ }
+ for (SudokuCell cc : col) {
+ if (cc.getData() == i) {
+ duplicate = true;
+ }
+ }
+
+ // If there is no duplicate it can exist in the region
+ if (!duplicate) {
+ canFit = true;
+ break;
+ }
+ }
+ // If the number can't fit anywhere in region then contradiction
+ if (!canFit) {
+ return null;
+ }
+ }
+ return super.getNoContradictionMessage();
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoSolutionContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoNumberForCellContradictionRule.java
similarity index 72%
rename from src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoSolutionContradictionRule.java
rename to src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoNumberForCellContradictionRule.java
index e44728d3e..6ea8f0a2a 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoSolutionContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoNumberForCellContradictionRule.java
@@ -8,14 +8,14 @@
import java.util.HashSet;
import java.util.Set;
-public class NoSolutionContradictionRule extends ContradictionRule {
+public class NoNumberForCellContradictionRule extends ContradictionRule {
- public NoSolutionContradictionRule() {
+ public NoNumberForCellContradictionRule() {
super(
- "SUDO-CONT-0001",
- "No Solution for Cell",
+ "SUDO-CONT-0004",
+ "No Number for Cell",
"Process of elimination yields no valid numbers for an empty cell.",
- "edu/rpi/legup/images/sudoku/NoSolution.png");
+ "edu/rpi/legup/images/sudoku/rules/NoSolution.png");
}
/**
@@ -41,21 +41,19 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
Set row = sudokuBoard.getRow(cell.getLocation().y);
Set col = sudokuBoard.getCol(cell.getLocation().x);
Set solution = new HashSet<>();
- for (int i = 1; i <= groupSize; i++) {
- solution.add(i);
+ for (SudokuCell s : region) {
+ solution.add(s.getData());
}
-
- for (SudokuCell c : region) {
- solution.remove(c.getData());
- }
- for (SudokuCell c : row) {
- solution.remove(c.getData());
+ for (SudokuCell s : row) {
+ solution.add(s.getData());
}
- for (SudokuCell c : col) {
- solution.remove(c.getData());
+
+ for (SudokuCell s : col) {
+ solution.add(s.getData());
}
+ solution.remove(0);
- if (solution.isEmpty()) {
+ if (solution.size() == 9) {
return null;
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumberCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberColumnCaseRule.java
similarity index 53%
rename from src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumberCaseRule.java
rename to src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberColumnCaseRule.java
index e6ab0e64c..bab0bc79b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumberCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberColumnCaseRule.java
@@ -6,21 +6,26 @@
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.tree.TreeTransition;
import edu.rpi.legup.puzzle.sudoku.GroupType;
-import edu.rpi.legup.puzzle.sudoku.PossibleNumberCaseBoard;
+import edu.rpi.legup.puzzle.sudoku.ModelSudokuBoard;
import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
import edu.rpi.legup.puzzle.sudoku.SudokuCell;
import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
-public class PossibleNumberCaseRule extends CaseRule {
+public class PossibleCellsForNumberColumnCaseRule extends CaseRule {
- public PossibleNumberCaseRule() {
+ // Board math for translating indexes to numbers
+ private ModelSudokuBoard model = new ModelSudokuBoard();
+
+ // Old board for caseBoard reference
+ private SudokuBoard lagBoard;
+
+ public PossibleCellsForNumberColumnCaseRule() {
super(
- "SUDO-CASE-0002",
- "Possible Numbers for Cell",
+ "SUDO-CASE-0004",
+ "Possible Cells for Number - Column",
"An empty cell has a limited set of possible numbers that can fill it.",
- "edu/rpi/legup/images/sudoku/PossibleValues.png");
+ "edu/rpi/legup/images/sudoku/rules/possible_cells_number_column.png");
}
/**
@@ -50,12 +55,12 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
@Override
public CaseBoard getCaseBoard(Board board) {
- SudokuBoard sudokuBoard = (SudokuBoard) board;
- PossibleNumberCaseBoard caseBoard = new PossibleNumberCaseBoard(sudokuBoard, this, null);
- for (int i = 0; i < sudokuBoard.getSize(); i++) {
- caseBoard.addPickableRegion(i);
- caseBoard.addPickableRow(i);
- caseBoard.addPickableCol(i);
+ SudokuBoard sudokuBoard = (SudokuBoard) board.copy();
+ lagBoard = (SudokuBoard) sudokuBoard.copy();
+ CaseBoard caseBoard = new CaseBoard(sudokuBoard, this);
+ for (PuzzleElement puzzleElement : sudokuBoard.getPuzzleElements()) {
+ puzzleElement.setData(model.getModelColumnNumbers(puzzleElement.getIndex()));
+ caseBoard.addPickableElement(puzzleElement);
}
return caseBoard;
}
@@ -69,7 +74,7 @@ public CaseBoard getCaseBoard(Board board) {
*/
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
- return getCases(board, puzzleElement, 1, GroupType.REGION);
+ return getCases(board, puzzleElement, 1, GroupType.COLUMN);
}
/**
@@ -84,48 +89,19 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
public ArrayList getCases(
Board board, PuzzleElement puzzleElement, int value, GroupType groupType) {
ArrayList cases = new ArrayList<>();
- SudokuBoard sudokuBoard = (SudokuBoard) board;
- List caseCells = new ArrayList<>();
- SudokuCell cell = (SudokuCell) puzzleElement;
+ SudokuBoard sudokuBoard = lagBoard;
+ SudokuCell sourceCell = (SudokuCell) puzzleElement;
- Set group;
- if (groupType == GroupType.REGION) {
- group = sudokuBoard.getRegion(cell.getGroupIndex());
- } else {
- if (groupType == GroupType.ROW) {
- group = sudokuBoard.getRow(cell.getLocation().y);
- } else {
- group = sudokuBoard.getCol(cell.getLocation().x);
+ Set group = sudokuBoard.getCol(sourceCell.getLocation().x);
+ for (SudokuCell cell : group) {
+ if (cell.getData() == 0) {
+ Board newCase = sudokuBoard.copy();
+ PuzzleElement element = newCase.getPuzzleElement(cell);
+ element.setData(model.getModelColumnNumbers(sourceCell.getIndex()));
+ newCase.addModifiedData(element);
+ cases.add(newCase);
}
}
-
- for (SudokuCell c : group) {
- if (c.getData() == 0) {
- Set blockableCells = sudokuBoard.getRegion(c.getGroupIndex());
- blockableCells.addAll(sudokuBoard.getRow(c.getLocation().y));
- blockableCells.addAll(sudokuBoard.getCol(c.getLocation().x));
-
- boolean repeat = false;
- for (SudokuCell bc : blockableCells) {
- if (bc.getData() == value) {
- repeat = true;
- break;
- }
- }
- if (!repeat) {
- caseCells.add(c);
- }
- }
- }
-
- for (SudokuCell c : caseCells) {
- Board newCase = sudokuBoard.copy();
- PuzzleElement element = newCase.getPuzzleElement(c);
- element.setData(value);
- newCase.addModifiedData(element);
- cases.add(newCase);
- }
-
return cases;
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRegionCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRegionCaseRule.java
new file mode 100644
index 000000000..47e408369
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRegionCaseRule.java
@@ -0,0 +1,104 @@
+package edu.rpi.legup.puzzle.sudoku.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.CaseBoard;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.sudoku.*;
+import java.util.ArrayList;
+import java.util.Set;
+
+public class PossibleCellsForNumberRegionCaseRule extends CaseRule {
+
+ // Board math for translating indexes to numbers
+ private ModelSudokuBoard model = new ModelSudokuBoard();
+
+ // Old board for caseBoard reference
+ private SudokuBoard lagBoard;
+
+ public PossibleCellsForNumberRegionCaseRule() {
+ super(
+ "SUDO-CASE-0002",
+ "Possible Cells for Number - Region",
+ "An empty cell has a limited set of possible numbers that can fill it.",
+ "edu/rpi/legup/images/sudoku/rules/possible_cells_number_region.png");
+ }
+
+ /**
+ * Checks whether the transition logically follows from the parent node using this rule
+ *
+ * @param transition transition to check
+ * @return null if the child node logically follow from the parent node, otherwise error message
+ */
+ @Override
+ public String checkRuleRaw(TreeTransition transition) {
+ return null;
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule
+ *
+ * @param transition transition to check
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
+ */
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ @Override
+ public CaseBoard getCaseBoard(Board board) {
+ SudokuBoard sudokuBoard = (SudokuBoard) board.copy();
+ lagBoard = (SudokuBoard) sudokuBoard.copy();
+ CaseBoard caseBoard = new CaseBoard(sudokuBoard, this);
+ for (PuzzleElement puzzleElement : sudokuBoard.getPuzzleElements()) {
+ puzzleElement.setData(model.getModelRegionNumbers(puzzleElement.getIndex()));
+ caseBoard.addPickableElement(puzzleElement);
+ }
+ return caseBoard;
+ }
+
+ /**
+ * Gets the possible cases at a specific location based on this case rule
+ *
+ * @param board the current board state
+ * @param puzzleElement equivalent puzzleElement
+ * @return a list of elements the specified could be
+ */
+ @Override
+ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+ return getCases(board, puzzleElement, 1, GroupType.REGION);
+ }
+
+ /**
+ * Gets the possible cases at a specific location based on this case rule
+ *
+ * @param board the current board state
+ * @param puzzleElement equivalent puzzleElement
+ * @param value value that the rule will be applied from
+ * @param groupType group type
+ * @return a list of elements the specified could be
+ */
+ public ArrayList getCases(
+ Board board, PuzzleElement puzzleElement, int value, GroupType groupType) {
+ ArrayList cases = new ArrayList<>();
+ SudokuBoard sudokuBoard = lagBoard;
+ SudokuCell sourceCell = (SudokuCell) puzzleElement;
+
+ Set group = sudokuBoard.getRegion(sourceCell.getGroupIndex());
+ for (SudokuCell cell : group) {
+ if (cell.getData() == 0) {
+ Board newCase = sudokuBoard.copy();
+ PuzzleElement element = newCase.getPuzzleElement(cell);
+ element.setData(model.getModelRegionNumbers(sourceCell.getIndex()));
+ newCase.addModifiedData(element);
+ cases.add(newCase);
+ }
+ }
+ return cases;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRowCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRowCaseRule.java
new file mode 100644
index 000000000..868541377
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRowCaseRule.java
@@ -0,0 +1,107 @@
+package edu.rpi.legup.puzzle.sudoku.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.CaseBoard;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.sudoku.GroupType;
+import edu.rpi.legup.puzzle.sudoku.ModelSudokuBoard;
+import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
+import edu.rpi.legup.puzzle.sudoku.SudokuCell;
+import java.util.ArrayList;
+import java.util.Set;
+
+public class PossibleCellsForNumberRowCaseRule extends CaseRule {
+
+ // Board math for translating indexes to numbers
+ private ModelSudokuBoard model = new ModelSudokuBoard();
+
+ // Old board for caseBoard reference
+ private SudokuBoard lagBoard;
+
+ public PossibleCellsForNumberRowCaseRule() {
+ super(
+ "SUDO-CASE-0003",
+ "Possible Cells for Number - Row",
+ "An empty cell has a limited set of possible numbers that can fill it.",
+ "edu/rpi/legup/images/sudoku/rules/possible_cells_number_row.png");
+ }
+
+ /**
+ * Checks whether the transition logically follows from the parent node using this rule
+ *
+ * @param transition transition to check
+ * @return null if the child node logically follow from the parent node, otherwise error message
+ */
+ @Override
+ public String checkRuleRaw(TreeTransition transition) {
+ return null;
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule
+ *
+ * @param transition transition to check
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
+ */
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ @Override
+ public CaseBoard getCaseBoard(Board board) {
+ SudokuBoard sudokuBoard = (SudokuBoard) board.copy();
+ lagBoard = (SudokuBoard) sudokuBoard.copy();
+ CaseBoard caseBoard = new CaseBoard(sudokuBoard, this);
+ for (PuzzleElement puzzleElement : sudokuBoard.getPuzzleElements()) {
+ puzzleElement.setData(model.getModelRowNumbers(puzzleElement.getIndex()));
+ caseBoard.addPickableElement(puzzleElement);
+ }
+ return caseBoard;
+ }
+
+ /**
+ * Gets the possible cases at a specific location based on this case rule
+ *
+ * @param board the current board state
+ * @param puzzleElement equivalent puzzleElement
+ * @return a list of elements the specified could be
+ */
+ @Override
+ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+ return getCases(board, puzzleElement, 1, GroupType.ROW);
+ }
+
+ /**
+ * Gets the possible cases at a specific location based on this case rule
+ *
+ * @param board the current board state
+ * @param puzzleElement equivalent puzzleElement
+ * @param value value that the rule will be applied from
+ * @param groupType group type
+ * @return a list of elements the specified could be
+ */
+ public ArrayList getCases(
+ Board board, PuzzleElement puzzleElement, int value, GroupType groupType) {
+ ArrayList cases = new ArrayList<>();
+ SudokuBoard sudokuBoard = lagBoard;
+ SudokuCell sourceCell = (SudokuCell) puzzleElement;
+
+ Set group = sudokuBoard.getRow(sourceCell.getLocation().y);
+ for (SudokuCell cell : group) {
+ if (cell.getData() == 0) {
+ Board newCase = sudokuBoard.copy();
+ PuzzleElement element = newCase.getPuzzleElement(cell);
+ element.setData(model.getModelRowNumbers(sourceCell.getIndex()));
+ newCase.addModifiedData(element);
+ cases.add(newCase);
+ }
+ }
+ return cases;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumbersForCellCaseRule.java
similarity index 59%
rename from src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellCaseRule.java
rename to src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumbersForCellCaseRule.java
index fb6da62d4..e17acc26b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumbersForCellCaseRule.java
@@ -5,19 +5,18 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
-import edu.rpi.legup.puzzle.sudoku.SudokuCell;
+import edu.rpi.legup.puzzle.sudoku.*;
import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.List;
-public class PossibleCellCaseRule extends CaseRule {
- public PossibleCellCaseRule() {
+public class PossibleNumbersForCellCaseRule extends CaseRule {
+
+ public PossibleNumbersForCellCaseRule() {
super(
"SUDO-CASE-0001",
- "Possible Cells for Number",
- "A number has a limited set of cells in which it can be placed.",
- "edu/rpi/legup/images/sudoku/possible_cells_number.png");
+ "Possible Numbers for Cell",
+ "An empty cell has a limited set of possible numbers that can fill it.",
+ "edu/rpi/legup/images/sudoku/rules/PossibleValues.png");
}
/**
@@ -66,42 +65,34 @@ public CaseBoard getCaseBoard(Board board) {
*/
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
- ArrayList cases = new ArrayList<>();
- SudokuBoard sudokuBoard = (SudokuBoard) board;
- SudokuCell cell = (SudokuCell) puzzleElement;
-
- Set possibleValue = new HashSet<>();
- for (int i = 1; i <= sudokuBoard.getSize(); i++) {
- possibleValue.add(i);
- }
-
- int groupNum = cell.getGroupIndex();
- for (SudokuCell c : sudokuBoard.getRegion(groupNum)) {
- if (c.getData().equals(c.getData())) {
- possibleValue.remove(c.getData());
- }
- }
-
- int rowNum = cell.getLocation().y;
- for (SudokuCell c : sudokuBoard.getRegion(rowNum)) {
- if (c.getData().equals(c.getData())) {
- possibleValue.remove(c.getData());
- }
- }
+ return getCases(board, puzzleElement, 1, GroupType.REGION);
+ }
- int colNum = cell.getLocation().x;
- for (SudokuCell c : sudokuBoard.getRegion(colNum)) {
- if (c.getData().equals(c.getData())) {
- possibleValue.remove(c.getData());
- }
+ /**
+ * Gets the possible cases at a specific location based on this case rule
+ *
+ * @param board the current board state
+ * @param puzzleElement equivalent puzzleElement
+ * @param value value that the rule will be applied from
+ * @param groupType group type
+ * @return a list of elements the specified could be
+ */
+ public ArrayList getCases(
+ Board board, PuzzleElement puzzleElement, int value, GroupType groupType) {
+ ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
}
- for (Integer i : possibleValue) {
- SudokuBoard newCase = sudokuBoard.copy();
+ SudokuBoard sudokuBoard = (SudokuBoard) board;
+ List caseCells = new ArrayList<>();
+ SudokuCell cell = (SudokuCell) puzzleElement;
- PuzzleElement newCasePuzzleElement = newCase.getPuzzleElement(puzzleElement);
- newCasePuzzleElement.setData(i);
- newCase.addModifiedData(newCasePuzzleElement);
+ for (int i = 1; i <= 9; i++) {
+ Board newCase = sudokuBoard.copy();
+ PuzzleElement element = newCase.getPuzzleElement(puzzleElement);
+ element.setData(i);
+ newCase.addModifiedData(element);
cases.add(newCase);
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/RepeatedNumberContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/RepeatedNumberContradictionRule.java
index 955414e8e..f8172d071 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/RepeatedNumberContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/RepeatedNumberContradictionRule.java
@@ -12,10 +12,10 @@ public class RepeatedNumberContradictionRule extends ContradictionRule {
public RepeatedNumberContradictionRule() {
super(
- "SUDO-CONT-0002",
+ "SUDO-CONT-0005",
"Repeated Numbers",
"Two identical numbers are placed in the same group.",
- "edu/rpi/legup/images/sudoku/RepeatedNumber.png");
+ "edu/rpi/legup/images/sudoku/rules/RepeatedNumber.png");
}
/**
@@ -29,39 +29,51 @@ public RepeatedNumberContradictionRule() {
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ // Get board to check
SudokuBoard sudokuBoard = (SudokuBoard) board;
- SudokuCell cell = (SudokuCell) sudokuBoard.getPuzzleElement(puzzleElement);
- if (cell.getData() == 0) {
- return super.getNoContradictionMessage();
- }
- Set region = sudokuBoard.getRegion(cell.getGroupIndex());
- Set row = sudokuBoard.getRow(cell.getLocation().y);
- Set col = sudokuBoard.getCol(cell.getLocation().x);
+ // Loop all group indexes
+ for (int i = 0; i < 9; i++) {
+ // Get regions and sets to check duplicates
+ Set region = sudokuBoard.getRegion(i);
+ Set regionDup = new HashSet<>();
+
+ Set row = sudokuBoard.getRow(i);
+ Set rowDup = new HashSet<>();
- Set regionDup = new HashSet<>();
- Set rowDup = new HashSet<>();
- Set colDup = new HashSet<>();
+ Set col = sudokuBoard.getCol(i);
+ Set colDup = new HashSet<>();
- for (SudokuCell c : region) {
- if (regionDup.contains(c.getData())) {
- return null;
+ // Check for non zero duplicates to trigger contradiction
+ for (SudokuCell c : region) {
+ if (c.getData() == 0) {
+ continue;
+ }
+ if (regionDup.contains(c.getData())) {
+ return null;
+ }
+ regionDup.add(c.getData());
}
- regionDup.add(c.getData());
- }
- for (SudokuCell c : row) {
- if (rowDup.contains(c.getData())) {
- return null;
+ for (SudokuCell c : row) {
+ if (c.getData() == 0) {
+ continue;
+ }
+ if (rowDup.contains(c.getData())) {
+ return null;
+ }
+ rowDup.add(c.getData());
}
- rowDup.add(c.getData());
- }
- for (SudokuCell c : col) {
- if (colDup.contains(c.getData())) {
- return null;
+ for (SudokuCell c : col) {
+ if (c.getData() == 0) {
+ continue;
+ }
+ if (colDup.contains(c.getData())) {
+ return null;
+ }
+ colDup.add(c.getData());
}
- colDup.add(c.getData());
}
return super.getNoContradictionMessage();
diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/sudoku_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/sudoku_reference_sheet.txt
index a8635330d..ceffa168c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/sudoku_reference_sheet.txt
+++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/sudoku_reference_sheet.txt
@@ -1,9 +1,13 @@
-SUDO-BASC-0001 : AdvancedDeductionDirectRule
SUDO-BASC-0002 : LastCellForNumberDirectRule
SUDO-BASC-0003 : LastNumberForCellDirectRule
-SUDO-CONT-0001 : NoSolutionContradictionRule
-SUDO-CONT-0002 : RepeatedNumberContradictionRule
+SUDO-CONT-0001 : NoCellForNumberRegionContradictionRule
+SUDO-CONT-0002 : NoCellForNumberRowContradictionRule
+SUDO-CONT-0003 : NoCellForNumberColumnContradictionRule
+SUDO-CONT-0004 : NoNumberForCellContradictionRule
+SUDO-CONT-0005 : RepeatedNumberContradictionRule
-SUDO-CASE-0001 : PossibleCellCaseRule
-SUDO-CASE-0002 : PossibleNumberCaseRule
\ No newline at end of file
+SUDO-CASE-0001 : PossibleNumbersForCellCaseRule
+SUDO-CASE-0002 : PossibleCellsForNumberRegionCaseRule
+SUDO-CASE-0003 : PossibleCellsForNumberRowCaseRule
+SUDO-CASE-0004 : PossibleCellsForNumberColumnCaseRule
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTent.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTent.java
index 5ec135a22..35993303a 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTent.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTent.java
@@ -59,7 +59,20 @@ public boolean isValidDimensions(int rows, int columns) {
*/
@Override
public boolean isBoardComplete(Board board) {
- return false;
+ TreeTentBoard treeTentBoard = (TreeTentBoard) board;
+
+ for (ContradictionRule rule : contradictionRules) {
+ if (rule.checkContradiction(treeTentBoard) == null) {
+ return false;
+ }
+ }
+ for (PuzzleElement data : treeTentBoard.getPuzzleElements()) {
+ TreeTentCell cell = (TreeTentCell) data;
+ if (cell.getType() == TreeTentType.UNKNOWN) {
+ return false;
+ }
+ }
+ return true;
}
/**
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/GrassTile.java b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/GrassTile.java
index 5356120a8..1d33b9035 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/GrassTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/GrassTile.java
@@ -6,7 +6,7 @@ public class GrassTile extends PlaceableElement {
public GrassTile() {
super(
- "TREE-PlAC-0002",
+ "TREE-ELEM-0001",
"Grass Tile",
"The grass crest tile",
"edu/rpi/legup/images/treetent/grass.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TentTile.java b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TentTile.java
index 950aebfa7..96124a98d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TentTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TentTile.java
@@ -6,7 +6,7 @@ public class TentTile extends PlaceableElement {
public TentTile() {
super(
- "TREE-PLAC-0001",
+ "TREE-ELEM-0002",
"Tent Tile",
"The tent tile",
"edu/rpi/legup/images/treetent/tent.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TreeTile.java b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TreeTile.java
index d04886ed5..3d94cbfba 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TreeTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/TreeTile.java
@@ -1,12 +1,12 @@
package edu.rpi.legup.puzzle.treetent.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class TreeTile extends NonPlaceableElement {
+public class TreeTile extends PlaceableElement {
public TreeTile() {
super(
- "TREE-UNPL-0001",
+ "TREE-ELEM-0003",
"Tree Tile",
"The tree tile",
"edu/rpi/legup/images/treetent/tree.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/UnknownTile.java
index a54240efd..99b75b60c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/UnknownTile.java
@@ -1,11 +1,11 @@
package edu.rpi.legup.puzzle.treetent.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
super(
- "TREE-UNPL-0002",
+ "TREE-ELEM-0004",
"Unknown Tile",
"The blank tile",
"edu/rpi/legup/images/treetent/UnknownTile.png");
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/treetent_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/treetent_elements_reference_sheet.txt
new file mode 100644
index 000000000..e0cfc1dfa
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/elements/treetent_elements_reference_sheet.txt
@@ -0,0 +1,4 @@
+TREE-ELEM-0001 : GrassTile
+TREE-ELEM-0002 : TentTile
+TREE-ELEM-0003 : TreeTile
+TREE-ELEM-0004 : UnknownTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java
index aaa1a8fbc..8fe9b6873 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java
@@ -61,7 +61,11 @@ public CaseBoard getCaseBoard(Board board) {
*/
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+ if (puzzleElement == null) {
+ return new ArrayList();
+ }
ArrayList cases;
+
List group;
int tentsLeft;
TreeTentClue clue = ((TreeTentClue) puzzleElement);
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTentCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTentCaseRule.java
index bd303174a..cbe91c3a7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTentCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTentCaseRule.java
@@ -60,6 +60,10 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
TreeTentCell cell = (TreeTentCell) puzzleElement;
List adj = ((TreeTentBoard) board).getAdjacent(cell, TreeTentType.TREE);
List lines = ((TreeTentBoard) board).getLines();
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTreeCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTreeCaseRule.java
index 03d039898..153692ad0 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTreeCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/LinkTreeCaseRule.java
@@ -62,6 +62,10 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
TreeTentBoard treeTentBoard = (TreeTentBoard) board;
TreeTentCell cell = (TreeTentCell) puzzleElement;
List adjCells = treeTentBoard.getAdjacent(cell, TreeTentType.TENT);
diff --git a/src/main/java/edu/rpi/legup/ui/CreatePuzzleDialog.java b/src/main/java/edu/rpi/legup/ui/CreatePuzzleDialog.java
index 32ddca34f..bde2df3d5 100644
--- a/src/main/java/edu/rpi/legup/ui/CreatePuzzleDialog.java
+++ b/src/main/java/edu/rpi/legup/ui/CreatePuzzleDialog.java
@@ -69,9 +69,7 @@ public void actionPerformed(ActionEvent e) {
*/
@Override
public void actionPerformed(ActionEvent ae) {
- String game =
- Config.convertDisplayNameToClassName(
- (String) gameBox.getSelectedItem());
+ String game = getGame();
// Check if all 3 TextFields are filled
if (game.equals("ShortTruthTable") && textArea.getText().isEmpty()) {
@@ -91,8 +89,8 @@ public void actionPerformed(ActionEvent ae) {
} else {
homePanel.openEditorWithNewPuzzle(
game,
- Integer.valueOf(rows.getText()),
- Integer.valueOf(columns.getText()));
+ Integer.valueOf(getRows()),
+ Integer.valueOf(getColumns()));
}
setVisible(false);
} catch (IllegalArgumentException e) {
@@ -116,6 +114,12 @@ public void actionPerformed(ActionEvent e) {
}
};
+ /**
+ * Constructs a new CreatePuzzleDialog
+ *
+ * @param parent the parent frame of the dialog
+ * @param homePanel the home panel where the created puzzle will be added
+ */
public CreatePuzzleDialog(JFrame parent, HomePanel homePanel) {
super(parent, true);
diff --git a/src/main/java/edu/rpi/legup/ui/DynamicView.java b/src/main/java/edu/rpi/legup/ui/DynamicView.java
index d6dbfb4c3..fa0004d0b 100644
--- a/src/main/java/edu/rpi/legup/ui/DynamicView.java
+++ b/src/main/java/edu/rpi/legup/ui/DynamicView.java
@@ -16,6 +16,10 @@
import javax.swing.*;
import javax.swing.event.ChangeEvent;
+/**
+ * A JPanel that provides a dynamic view with zooming capabilities for different types of content.
+ * This class supports views such as game boards or proof trees, allowing users to zoom in and out.
+ */
public class DynamicView extends JPanel {
private ScrollView scrollView;
@@ -29,6 +33,12 @@ public class DynamicView extends JPanel {
private static final Font INFO_FONT = MaterialFonts.REGULAR;
private static final Color INFO_COLOR = MaterialColors.GRAY_900;
+ /**
+ * Constructs a new DynamicView with the specified ScrollView and view type
+ *
+ * @param scrollView the ScrollView that provides the content to be displayed and zoomed
+ * @param type the type of dynamic view to set up (e.g., BOARD or PROOF_TREE)
+ */
public DynamicView(ScrollView scrollView, DynamicViewType type) {
this.scrollView = scrollView;
@@ -185,24 +195,49 @@ public void componentResized(ComponentEvent e) {
return zoomWrapper;
}
+ /**
+ * Gets the ScrollView component associated with this DynamicView
+ *
+ * @return the ScrollView component
+ */
public ScrollView getScrollView() {
return this.scrollView;
}
+ /**
+ * Gets the zoom wrapper that contains the zooming controls
+ *
+ * @return the zoom wrapper with zooming controls
+ */
public JPanel getZoomWrapper() {
return this.zoomWrapper;
}
+ /**
+ * Gets the zoomer that contains the zoomer component
+ *
+ * @return the zoomer with the zoomer component
+ */
public JPanel getZoomer() {
return this.zoomer;
}
+ /**
+ * Updates the status label with an informational message
+ *
+ * @param message the informational message to display
+ */
public void updateInfo(String message) {
status.setFont(INFO_FONT);
status.setForeground(INFO_COLOR);
status.setText(message);
}
+ /**
+ * Updates the status label with an error message
+ *
+ * @param message the error message to display
+ */
public void updateError(String message) {
status.setFont(ERROR_FONT);
status.setForeground(ERROR_COLOR);
diff --git a/src/main/java/edu/rpi/legup/ui/HomePanel.java b/src/main/java/edu/rpi/legup/ui/HomePanel.java
index 9e83dc9de..75761c475 100644
--- a/src/main/java/edu/rpi/legup/ui/HomePanel.java
+++ b/src/main/java/edu/rpi/legup/ui/HomePanel.java
@@ -46,40 +46,30 @@ public class HomePanel extends LegupPanel {
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- Object[] items = legupUI.getProofEditor().promptPuzzle();
- if (items == null) {
- // The attempt to prompt a puzzle ended gracefully (cancel)
- return;
- }
- String fileName = (String) items[0];
- File puzzleFile = (File) items[1];
- legupUI.getProofEditor().loadPuzzle(fileName, puzzleFile);
+ legupUI.getProofEditor().loadPuzzle("", null);
}
};
- private ActionListener openPuzzleListener =
- new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- Object[] items = legupUI.getPuzzleEditor().promptPuzzle();
- if (items == null) {
- // The attempt to prompt a puzzle ended gracefully (cancel)
- return;
- }
- String fileName = (String) items[0];
- File puzzleFile = (File) items[1];
- legupUI.getPuzzleEditor().loadPuzzle(fileName, puzzleFile);
- }
- };
-
- public HomePanel(FileDialog fileDialog, JFrame frame, LegupUI legupUI) {
+ /**
+ * Constructs a {@code HomePanel} with the specified {@code JFrame} and {@code LegupUI}.
+ *
+ * @param frame the main application frame
+ * @param legupUI the LEGUP user interface
+ */
+ public HomePanel(JFrame frame, LegupUI legupUI) {
this.legupUI = legupUI;
this.frame = frame;
setLayout(new GridLayout(1, 2));
+ setPreferredSize(new Dimension(440, 250));
initText();
initButtons();
}
+ /**
+ * Creates and returns the menu bar for this panel
+ *
+ * @return the menu bar
+ */
public JMenuBar getMenuBar() {
this.menuBar = new JMenuBar();
JMenu settings = new JMenu("Settings");
@@ -115,6 +105,14 @@ public void makeVisible() {
frame.setJMenuBar(this.getMenuBar());
}
+ /**
+ * Resizes the provided icon to the specified width and height
+ *
+ * @param icon the icon to resize
+ * @param width the target width
+ * @param height the target height
+ * @return the resized icon
+ */
private static ImageIcon resizeButtonIcon(ImageIcon icon, int width, int height) {
Image image = icon.getImage();
Image resizedImage = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
@@ -123,10 +121,10 @@ private static ImageIcon resizeButtonIcon(ImageIcon icon, int width, int height)
/** Initializes the buttons for this panel */
private void initButtons() {
- this.buttons = new JButton[4];
+ this.buttons = new JButton[3];
this.buttons[0] =
- new JButton("Solve Puzzle") {
+ new JButton("Puzzle Solver") {
{
setSize(buttonSize, buttonSize);
setMaximumSize(getSize());
@@ -144,7 +142,7 @@ private void initButtons() {
this.buttons[0].addActionListener(CursorController.createListener(this, openProofListener));
this.buttons[1] =
- new JButton("Create Puzzle") {
+ new JButton("Puzzle Editor") {
{
setSize(buttonSize, buttonSize);
setMaximumSize(getSize());
@@ -158,35 +156,17 @@ private void initButtons() {
this.buttons[1].setIcon(resizeButtonIcon(button1Icon, this.buttonSize, this.buttonSize));
this.buttons[1].setHorizontalTextPosition(AbstractButton.CENTER);
this.buttons[1].setVerticalTextPosition(AbstractButton.BOTTOM);
- this.buttons[1].addActionListener(l -> this.openNewPuzzleDialog());
-
- this.buttons[2] =
- new JButton("Edit Puzzle") {
- {
- setSize(buttonSize, buttonSize);
- setMaximumSize(getSize());
- }
- };
- URL button2IconLocation =
- ClassLoader.getSystemClassLoader()
- .getResource("edu/rpi/legup/images/Legup/homepanel/puzzle_file.png");
- ImageIcon button2Icon = new ImageIcon(button2IconLocation);
- this.buttons[2].setFocusPainted(false);
- this.buttons[2].setIcon(resizeButtonIcon(button2Icon, this.buttonSize, this.buttonSize));
- this.buttons[2].setHorizontalTextPosition(AbstractButton.CENTER);
- this.buttons[2].setVerticalTextPosition(AbstractButton.BOTTOM);
- this.buttons[2].addActionListener(
- CursorController.createListener(this, openPuzzleListener)); // PLACEHOLDER
+ this.buttons[1].addActionListener(l -> this.openPuzzleEditorDialog());
for (int i = 0; i < this.buttons.length - 1; i++) { // -1 to avoid the batch grader button
this.buttons[i].setBounds(200, 200, 700, 700);
}
- this.buttons[3] = new JButton("Batch Grader");
- this.buttons[3].setFocusPainted(false);
- this.buttons[3].setHorizontalTextPosition(AbstractButton.CENTER);
- this.buttons[3].setVerticalTextPosition(AbstractButton.BOTTOM);
+ this.buttons[2] = new JButton("Batch Grader");
+ this.buttons[2].setFocusPainted(false);
+ this.buttons[2].setHorizontalTextPosition(AbstractButton.CENTER);
+ this.buttons[2].setVerticalTextPosition(AbstractButton.BOTTOM);
- this.buttons[3].addActionListener(
+ this.buttons[2].addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -284,7 +264,7 @@ public void checkFolder() {
}
} catch (IOException ex) {
LOGGER.error(ex.getMessage());
- this.buttons[3].addActionListener((ActionEvent e) -> use_xml_to_check());
+ this.buttons[2].addActionListener((ActionEvent e) -> use_xml_to_check());
}
}
@@ -523,7 +503,7 @@ private void render() {
this.removeAll();
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
- this.legupUI.setTitle("LEGUP: A Better Way to Learn Formal Logic");
+ this.legupUI.setTitle("LEGUP: A Better Way To Learn Formal Logic");
JPanel buttons = new JPanel();
buttons.add(Box.createRigidArea(new Dimension(5, 0)));
@@ -531,11 +511,8 @@ private void render() {
buttons.add(Box.createRigidArea(new Dimension(5, 0)));
buttons.add(this.buttons[1]);
buttons.add(Box.createRigidArea(new Dimension(5, 0)));
- buttons.add(this.buttons[2]);
- buttons.add(Box.createRigidArea(new Dimension(5, 0)));
-
JPanel batchGraderButton = new JPanel();
- batchGraderButton.add(this.buttons[3]);
+ batchGraderButton.add(this.buttons[2]);
batchGraderButton.setAlignmentX(Component.CENTER_ALIGNMENT);
this.add(Box.createRigidArea(new Dimension(0, 5)));
@@ -566,6 +543,10 @@ private void openPuzzleEditorDialog() {
}
}
+ /**
+ * Opens a dialog to select a directory, recursively processes the directory to grade puzzles,
+ * and generates a CSV report of the grading results.
+ */
private void checkProofAll() {
/*
* Select dir to grade; recursively grade sub-dirs using traverseDir()
@@ -609,6 +590,14 @@ private void checkProofAll() {
JOptionPane.showMessageDialog(null, "Batch grading complete.");
}
+ /**
+ * Recursively traverses directories to grade puzzles and writes results to a CSV file
+ *
+ * @param folder the folder to traverse
+ * @param writer the BufferedWriter to write results to the CSV file
+ * @param path the current path within the directory structure
+ * @throws IOException if an I/O error occurs while writing to the CSV file
+ */
private void traverseDir(File folder, BufferedWriter writer, String path) throws IOException {
// Recursively traverse directory
GameBoardFacade facade = GameBoardFacade.getInstance();
@@ -661,6 +650,14 @@ private void traverseDir(File folder, BufferedWriter writer, String path) throws
}
}
+ /**
+ * Opens the puzzle editor for the specified puzzle with the specified dimensions
+ *
+ * @param game the name of the game
+ * @param rows the number of rows in the puzzle
+ * @param columns the number of columns in the puzzle
+ * @throws IllegalArgumentException if the dimensions are invalid
+ */
public void openEditorWithNewPuzzle(String game, int rows, int columns)
throws IllegalArgumentException {
if (game.isEmpty()) {
@@ -692,7 +689,7 @@ public void openEditorWithNewPuzzle(String game, int rows, int columns)
}
/**
- * Opens the puzzle editor for the specified game with the given statements
+ * Opens the puzzle editor for the specified puzzle with the given statements
*
* @param game a String containing the name of the game
* @param statements an array of statements
diff --git a/src/main/java/edu/rpi/legup/ui/LegupUI.java b/src/main/java/edu/rpi/legup/ui/LegupUI.java
index 201a2d4c7..75f822a6c 100644
--- a/src/main/java/edu/rpi/legup/ui/LegupUI.java
+++ b/src/main/java/edu/rpi/legup/ui/LegupUI.java
@@ -41,7 +41,7 @@ public static String getOS() {
return os;
}
- /** LegupUI Constructor - creates a new LegupUI to setup the menu and toolbar */
+ /** LegupUI Constructor - creates a new LegupUI to set up the menu and toolbar */
public LegupUI() {
setTitle("LEGUP");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -103,11 +103,17 @@ private void initPanels() {
add(window);
panels = new LegupPanel[3];
- panels[0] = new HomePanel(this.fileDialog, this, this);
+ panels[0] = new HomePanel(this, this);
panels[1] = new ProofEditorPanel(this.fileDialog, this, this);
panels[2] = new PuzzleEditorPanel(this.fileDialog, this, this);
}
+ /**
+ * Displays the specified panel
+ *
+ * @param option the index of the panel to display
+ * @throws InvalidParameterException if the option is out of range
+ */
protected void displayPanel(int option) {
if (option > panels.length || option < 0) {
throw new InvalidParameterException("Invalid option");
@@ -121,10 +127,20 @@ protected void displayPanel(int option) {
repaint();
}
+ /**
+ * Gets the ProofEditorPanel instance
+ *
+ * @return the ProofEditorPanel
+ */
public ProofEditorPanel getProofEditor() {
return (ProofEditorPanel) panels[1];
}
+ /**
+ * Gets the PuzzleEditorPanel instance
+ *
+ * @return the PuzzleEditorPanel
+ */
public PuzzleEditorPanel getPuzzleEditor() {
return (PuzzleEditorPanel) panels[2];
}
@@ -134,17 +150,6 @@ public void repaintTree() {
getProofEditor().repaintTree();
}
- private void directions() {
- JOptionPane.showMessageDialog(
- null,
- "For every move you make, you must provide a rules for it (located in the Rules"
- + " panel).\n"
- + "While working on the edu.rpi.legup.puzzle, you may click on the \"Check\""
- + " button to test your proof for correctness.",
- "Directions",
- JOptionPane.PLAIN_MESSAGE);
- }
-
public void showStatus(String status, boolean error) {
showStatus(status, error, 1);
}
@@ -157,8 +162,13 @@ public void showStatus(String status, boolean error, int timer) {
// TODO: implement
}
- // ask to edu.rpi.legup.save current proof
- public boolean noquit(String instr) {
+ /**
+ * Prompts the user to confirm if they want to exit LEGUP
+ *
+ * @param instr the prompt message
+ * @return true if the user chooses not to quit, false otherwise
+ */
+ public boolean exit(String instr) {
int n = JOptionPane.showConfirmDialog(null, instr, "Confirm", JOptionPane.YES_NO_OPTION);
return n != JOptionPane.YES_OPTION;
}
@@ -168,7 +178,7 @@ public void windowOpened(WindowEvent e) {}
public void windowClosing(WindowEvent e) {
if (GameBoardFacade.getInstance().getHistory().getIndex() > -1) {
- if (noquit("Exiting LEGUP?")) {
+ if (exit("Exiting LEGUP?")) {
this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
} else {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
@@ -190,22 +200,47 @@ public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
+ /**
+ * Gets the BoardView instance from the proof editor
+ *
+ * @return the BoardView
+ */
public BoardView getBoardView() {
return getProofEditor().getBoardView();
}
+ /**
+ * Gets the BoardView instance from the puzzle editor
+ *
+ * @return the BoardView
+ */
public BoardView getEditorBoardView() {
return getPuzzleEditor().getBoardView();
}
+ /**
+ * Gets the DynamicView instance from the proof editor
+ *
+ * @return the DynamicView
+ */
public DynamicView getDynamicBoardView() {
return getProofEditor().getDynamicBoardView();
}
+ /**
+ * Gets the DynamicView instance from the puzzle editor.
+ *
+ * @return the DynamicView
+ */
public DynamicView getEditorDynamicBoardView() {
return getPuzzleEditor().getDynamicBoardView();
}
+ /**
+ * Gets the TreePanel instance from the proof editor
+ *
+ * @return the TreePanel
+ */
public TreePanel getTreePanel() {
return getProofEditor().getTreePanel();
}
diff --git a/src/main/java/edu/rpi/legup/ui/PickGameDialog.java b/src/main/java/edu/rpi/legup/ui/PickGameDialog.java
index ed510c6b6..3b66931a7 100644
--- a/src/main/java/edu/rpi/legup/ui/PickGameDialog.java
+++ b/src/main/java/edu/rpi/legup/ui/PickGameDialog.java
@@ -136,10 +136,20 @@ public void initPuzzles() {
gameBox = new JComboBox(games);
}
+ /**
+ * Gets the selected puzzle file path
+ *
+ * @return the puzzle file path as a String
+ */
public String getPuzzle() {
return puzzleBox.getText();
}
+ /**
+ * Returns the selected puzzle
+ *
+ * @return the selected puzzle as a String
+ */
public String getGame() {
return (String) gameBox.getSelectedItem();
}
diff --git a/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java b/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java
index e9a0df4a2..e90d06640 100644
--- a/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java
+++ b/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java
@@ -53,12 +53,24 @@ public class PreferencesDialog extends JDialog {
}
}
+ /**
+ * Creates a new instance of PreferencesDialog for the proof editor
+ *
+ * @param frame the parent frame
+ * @param rules the RuleFrame associated with the proof editor
+ * @return a new instance of PreferencesDialog
+ */
public static PreferencesDialog CreateDialogForProofEditor(Frame frame, RuleFrame rules) {
PreferencesDialog p = new PreferencesDialog(frame);
p.rulesFrame = rules;
return p;
}
+ /**
+ * Constructs a PreferencesDialog
+ *
+ * @param frame the parent frame
+ */
public PreferencesDialog(Frame frame) {
super(frame);
@@ -108,6 +120,11 @@ public PreferencesDialog(Frame frame) {
setVisible(true);
}
+ /**
+ * Toggles between dark mode and light mode based on the given preferences
+ *
+ * @param prefs the LegupPreferences instance holding user preferences
+ */
private void toggleDarkMode(LegupPreferences prefs) {
try {
if (Boolean.valueOf(prefs.getUserPref(LegupPreferences.DARK_MODE))) {
@@ -121,6 +138,11 @@ private void toggleDarkMode(LegupPreferences prefs) {
}
}
+ /**
+ * Creates the general preferences tab
+ *
+ * @return a JScrollPane containing the general preferences panel
+ */
private JScrollPane createGeneralTab() {
LegupPreferences prefs = LegupPreferences.getInstance();
JScrollPane scrollPane = new JScrollPane();
diff --git a/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java b/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java
index ddabb5705..5ecbd5564 100644
--- a/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java
+++ b/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java
@@ -53,8 +53,8 @@ public class ProofEditorPanel extends LegupPanel implements IHistoryListener {
private DynamicView dynamicBoardView;
private JSplitPane topHalfPanel, mainPanel;
private TitledBorder boardBorder;
-
- private JButton[] toolBarButtons;
+ private JButton[] toolBar1Buttons;
+ private JButton[] toolBar2Buttons;
private JMenu file;
private JMenuItem newPuzzle,
resetPuzzle,
@@ -74,7 +74,8 @@ public class ProofEditorPanel extends LegupPanel implements IHistoryListener {
private JMenu about, help;
private JMenuItem helpLegup, aboutLegup;
- private JToolBar toolBar;
+ private JToolBar toolBar1;
+ private JToolBar toolBar2;
private BoardView boardView;
private JFileChooser folderBrowser;
@@ -88,7 +89,6 @@ public class ProofEditorPanel extends LegupPanel implements IHistoryListener {
public static final int IMD_FEEDBACK = 32;
public static final int INTERN_RO = 64;
public static final int AUTO_JUST = 128;
- static final int[] TOOLBAR_SEPARATOR_BEFORE = {2, 4, 8};
private static final String[] PROFILES = {
"No Assistance",
"Rigorous Proof",
@@ -118,6 +118,13 @@ public class ProofEditorPanel extends LegupPanel implements IHistoryListener {
protected JMenuItem testAI = new JMenuItem("Test AI!");
protected JMenuItem hintAI = new JMenuItem("Hint");
+ /**
+ * Constructs a new {@code ProofEditorPanel} with the specified parameters
+ *
+ * @param fileDialog the {@code FileDialog} used for file operations
+ * @param frame the {@code JFrame} that contains this panel
+ * @param legupUI the {@code LegupUI} instance managing the user interface
+ */
public ProofEditorPanel(FileDialog fileDialog, JFrame frame, LegupUI legupUI) {
this.fileDialog = fileDialog;
this.frame = frame;
@@ -134,7 +141,7 @@ public ProofEditorPanel(FileDialog fileDialog, JFrame frame, LegupUI legupUI) {
public void makeVisible() {
this.removeAll();
- setupToolBar();
+ setupToolBar1();
setupContent();
frame.setJMenuBar(getMenuBar());
}
@@ -165,7 +172,7 @@ public JMenuBar getMenuBar() {
file = new JMenu("File");
newPuzzle = new JMenuItem("Open");
- resetPuzzle = new JMenuItem("Reset Puzzle");
+ resetPuzzle = new JMenuItem("Reset");
// genPuzzle = new JMenuItem("Puzzle Generators"); // TODO: implement puzzle
// generator
saveProofAs = new JMenuItem("Save As"); // create a new file to save
@@ -341,6 +348,7 @@ public JMenuBar getMenuBar() {
} else {
resetPuzzle.setAccelerator(KeyStroke.getKeyStroke('R', InputEvent.CTRL_DOWN_MASK));
}
+
file.addSeparator();
file.add(saveProofAs);
@@ -547,6 +555,7 @@ public Object[] promptPuzzle() {
return null;
}
+ System.out.println(preferences.getSavedPath());
return new Object[] {fileName, puzzleFile};
}
@@ -712,16 +721,14 @@ private void helpTutorial() {
default:
url = "https://github.com/Bram-Hub/Legup/wiki/LEGUP-Tutorial";
}
- Runtime rt = Runtime.getRuntime();
try {
- // rt.exec("rundll32 url.dll,FileProtocolHandler "+url);
java.awt.Desktop.getDesktop().browse(java.net.URI.create(url));
} catch (IOException e) {
e.printStackTrace();
}
}
- // add the new function need to implement
+ // unfinished
public void add_drop() {
// add the mouse event then we can use the new listener to implement and
// we should create a need jbuttom for it to ship the rule we select.
@@ -765,13 +772,22 @@ private void saveProofChange() {
}
}
- // ask to edu.rpi.legup.save current proof
+ /**
+ * Displays a confirmation dialog with a specified message. Returns {@code true} if the user
+ * selects "No" or cancels the action, and {@code false} if the user selects "Yes".
+ *
+ * @param instr the message to display in the confirmation dialog
+ * @return {@code true} if the user chooses not to quit, {@code false} otherwise
+ */
public boolean noquit(String instr) {
int n = JOptionPane.showConfirmDialog(null, instr, "Confirm", JOptionPane.YES_NO_OPTION);
return n != JOptionPane.YES_OPTION;
}
- /** Sets the main content for the edu.rpi.legup.user interface */
+ /**
+ * Configures the layout and components for the main user interface. This includes setting up
+ * panels, split panes, and borders, and adding them to the main content pane.
+ */
protected void setupContent() {
// JPanel consoleBox = new JPanel(new BorderLayout());
JPanel treeBox = new JPanel(new BorderLayout());
@@ -804,16 +820,9 @@ protected void setupContent() {
ruleBox.add(boardPanel);
treeBox.add(ruleBox);
this.add(treeBox);
- // consoleBox.add(treeBox);
- //
- // getContentPane().add(consoleBox);
-
- // JPopupPanel popupPanel = new JPopupPanel();
- // setGlassPane(popupPanel);
- // popupPanel.setVisible(true);
mainPanel.setDividerLocation(mainPanel.getMaximumDividerLocation() + 100);
- // frame.pack();
+
revalidate();
}
@@ -828,68 +837,29 @@ private void setupToolBar1() {
toolBar1.setRollover(true);
setToolBar2Buttons(new JButton[1]);
- // Scale the image icons down to make the buttons smaller
- ImageIcon imageIcon = new ImageIcon(resourceLocation);
- Image image = imageIcon.getImage();
- imageIcon =
- new ImageIcon(
- image.getScaledInstance(
- this.TOOLBAR_ICON_SCALE,
- this.TOOLBAR_ICON_SCALE,
- Image.SCALE_SMOOTH));
-
- JButton button = new JButton(toolBarName, imageIcon);
- button.setFocusPainted(false);
- getToolBarButtons()[i] = button;
- }
+ URL open_url =
+ ClassLoader.getSystemClassLoader()
+ .getResource("edu/rpi/legup/images/Legup/Open.png");
- toolBar = new JToolBar();
- toolBar.setFloatable(false);
- toolBar.setRollover(true);
+ // Scale the image icons down to make the buttons smaller
+ ImageIcon OpenImageIcon = new ImageIcon(open_url);
+ Image OpenImage = OpenImageIcon.getImage();
+ OpenImageIcon =
+ new ImageIcon(
+ OpenImage.getScaledInstance(
+ this.TOOLBAR_ICON_SCALE,
+ this.TOOLBAR_ICON_SCALE,
+ Image.SCALE_SMOOTH));
- for (int i = 0; i < getToolBarButtons().length; i++) {
- for (int s = 0; s < TOOLBAR_SEPARATOR_BEFORE.length; s++) {
- if (i == TOOLBAR_SEPARATOR_BEFORE[s]) {
- toolBar.addSeparator();
- }
- }
- String toolBarName = ToolbarName.values()[i].toString();
+ JButton open = new JButton("Open", OpenImageIcon);
+ open.setFocusPainted(false);
- toolBar.add(getToolBarButtons()[i]);
- getToolBarButtons()[i].setToolTipText(toolBarName);
+ open.addActionListener((ActionEvent) -> loadPuzzle());
- getToolBarButtons()[i].setVerticalTextPosition(SwingConstants.BOTTOM);
- getToolBarButtons()[i].setHorizontalTextPosition(SwingConstants.CENTER);
- }
+ getToolBar2Buttons()[0] = open;
+ toolBar1.add(getToolBar2Buttons()[0]);
- // toolBarButtons[ToolbarName.OPEN_PUZZLE.ordinal()].addActionListener((ActionEvent
- // e) ->
- // promptPuzzle());
- // toolBarButtons[ToolbarName.SAVE.ordinal()].addActionListener((ActionEvent e) ->
- // saveProof());
- // toolBarButtons[ToolbarName.UNDO.ordinal()].addActionListener((ActionEvent e) ->
- // GameBoardFacade.getInstance().getHistory().undo());
- // toolBarButtons[ToolbarName.REDO.ordinal()].addActionListener((ActionEvent e) ->
- // GameBoardFacade.getInstance().getHistory().redo());
- toolBarButtons[ToolbarName.HINT.ordinal()].addActionListener((ActionEvent e) -> {});
- toolBarButtons[ToolbarName.CHECK.ordinal()].addActionListener(
- (ActionEvent e) -> checkProof());
- toolBarButtons[ToolbarName.SUBMIT.ordinal()].addActionListener((ActionEvent e) -> {});
- toolBarButtons[ToolbarName.DIRECTIONS.ordinal()].addActionListener((ActionEvent e) -> {});
-
- toolBarButtons[ToolbarName.CHECK_ALL.ordinal()].addActionListener(
- (ActionEvent e) -> checkProofAll());
-
- // toolBarButtons[ToolbarName.SAVE.ordinal()].setEnabled(false);
- // toolBarButtons[ToolbarName.UNDO.ordinal()].setEnabled(false);
- // toolBarButtons[ToolbarName.REDO.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.HINT.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.CHECK.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.SUBMIT.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.DIRECTIONS.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.CHECK_ALL.ordinal()].setEnabled(true);
-
- this.add(toolBar, BorderLayout.NORTH);
+ this.add(toolBar1, BorderLayout.NORTH);
}
/**
@@ -999,19 +969,19 @@ private void setupToolBar2() {
/**
* Sets the toolbar1 buttons
*
- * @param toolBarButtons toolbar buttons
+ * @param toolBar1Buttons toolbar buttons
*/
- public void setToolBarButtons(JButton[] toolBarButtons) {
- this.toolBarButtons = toolBarButtons;
+ public void setToolBar1Buttons(JButton[] toolBar1Buttons) {
+ this.toolBar1Buttons = toolBar1Buttons;
}
/**
- * Gets the toolbar buttons
+ * Sets the toolbar2 buttons
*
- * @return toolbar buttons
+ * @param toolBar2Buttons toolbar buttons
*/
- public JButton[] getToolBarButtons() {
- return toolBarButtons;
+ public void setToolBar2Buttons(JButton[] toolBar2Buttons) {
+ this.toolBar2Buttons = toolBar2Buttons;
}
/**
@@ -1112,6 +1082,12 @@ private void repaintAll() {
treePanel.repaint();
}
+ /**
+ * Initializes the dynamic board view, updates the tree panel, and sets rules and search panels
+ * based on the provided puzzle. It also updates toolbars and reloads the GUI.
+ *
+ * @param puzzle the puzzle to be displayed
+ */
public void setPuzzleView(Puzzle puzzle) {
this.boardView = puzzle.getBoardView();
@@ -1135,9 +1111,8 @@ public void setPuzzleView(Puzzle puzzle) {
ruleFrame.getContradictionPanel().setRules(puzzle.getContradictionRules());
ruleFrame.getSearchPanel().setSearchBar(puzzle);
- toolBarButtons[ToolbarName.CHECK.ordinal()].setEnabled(true);
- // toolBarButtons[ToolbarName.SAVE.ordinal()].setEnabled(true);
-
+ toolBar1.setVisible(false);
+ setupToolBar2();
reloadGui();
}
@@ -1203,6 +1178,15 @@ private boolean basicCheckProof(int[][] origCells) {
return false;
}
+ /**
+ * Traverses a given directory, grades the proofs found in the directory, and writes the results
+ * to the specified CSV writer.
+ *
+ * @param folder the folder to traverse
+ * @param writer the CSV writer
+ * @param path the current path in the directory traversal
+ * @throws IOException if an error occurs while writing to the CSV file
+ */
private void traverseDir(File folder, BufferedWriter writer, String path) throws IOException {
// Recursively traverse directory
GameBoardFacade facade = GameBoardFacade.getInstance();
@@ -1257,6 +1241,11 @@ private void traverseDir(File folder, BufferedWriter writer, String path) throws
}
}
+ /**
+ * Returns the current board view.
+ *
+ * @return the current {@link BoardView}
+ */
public BoardView getBoardView() {
return boardView;
}
@@ -1270,12 +1259,17 @@ public DynamicView getDynamicBoardView() {
return dynamicBoardView;
}
+ /**
+ * Returns the current tree panel.
+ *
+ * @return the current {@link TreePanel}
+ */
public TreePanel getTreePanel() {
return treePanel;
}
/**
- * Called when a action is pushed onto the edu.rpi.legup.history stack
+ * Called when an action is pushed onto the edu.rpi.legup.history stack
*
* @param command action to push onto the stack
*/
@@ -1283,9 +1277,7 @@ public TreePanel getTreePanel() {
public void onPushChange(ICommand command) {
LOGGER.info("Pushing " + command.getClass().getSimpleName() + " to stack.");
undo.setEnabled(true);
- // toolBarButtons[ToolbarName.UNDO.ordinal()].setEnabled(true);
redo.setEnabled(false);
- // toolBarButtons[ToolbarName.REDO.ordinal()].setEnabled(false);
String puzzleName = GameBoardFacade.getInstance().getPuzzleModule().getName();
File puzzleFile = new File(GameBoardFacade.getInstance().getCurFileName());
@@ -1308,9 +1300,7 @@ public void onClearHistory() {}
@Override
public void onRedo(boolean isBottom, boolean isTop) {
undo.setEnabled(!isBottom);
- // toolBarButtons[ToolbarName.UNDO.ordinal()].setEnabled(!isBottom);
redo.setEnabled(!isTop);
- // toolBarButtons[ToolbarName.REDO.ordinal()].setEnabled(!isTop);
if (isBottom) {
String puzzleName = GameBoardFacade.getInstance().getPuzzleModule().getName();
File puzzleFile = new File(GameBoardFacade.getInstance().getCurFileName());
@@ -1331,9 +1321,7 @@ public void onRedo(boolean isBottom, boolean isTop) {
@Override
public void onUndo(boolean isBottom, boolean isTop) {
undo.setEnabled(!isBottom);
- // toolBarButtons[ToolbarName.UNDO.ordinal()].setEnabled(!isBottom);
redo.setEnabled(!isTop);
- // toolBarButtons[ToolbarName.REDO.ordinal()].setEnabled(!isTop);
String puzzleName = GameBoardFacade.getInstance().getPuzzleModule().getName();
File puzzleFile = new File(GameBoardFacade.getInstance().getCurFileName());
if (isBottom) {
diff --git a/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java b/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java
index 6b65e72f7..7c2ba06ff 100644
--- a/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java
+++ b/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java
@@ -39,12 +39,14 @@ public class PuzzleEditorPanel extends LegupPanel implements IHistoryListener {
private JMenu[] menus;
private JMenuItem helpLegup, aboutLegup;
private JMenuBar menuBar;
- private JToolBar toolBar;
+ private JToolBar toolBar1;
+ private JToolBar toolBar2;
private JFileChooser folderBrowser;
private JFrame frame;
private JButton[] buttons;
JSplitPane splitPanel;
- private JButton[] toolBarButtons;
+ private JButton[] toolBar1Buttons;
+ private JButton[] toolBar2Buttons;
private JPanel elementPanel;
private DynamicView dynamicBoardView;
private BoardView boardView;
@@ -56,7 +58,11 @@ public class PuzzleEditorPanel extends LegupPanel implements IHistoryListener {
private JPanel treePanel;
private LegupUI legupUI;
private EditorElementController editorElementController;
- static final int[] TOOLBAR_SEPARATOR_BEFORE = {2, 4, 8};
+ private CreatePuzzleDialog cpd;
+ private HomePanel hp;
+ private boolean existingPuzzle;
+ private String fileName;
+ private File puzzleFile;
/**
* Constructs a {@code PuzzleEditorPanel} with the specified file dialog, frame, and Legup UI
@@ -124,14 +130,14 @@ public void setMenuBar() {
menus[0] = new JMenu("File");
// file>new
- JMenuItem newPuzzle = new JMenuItem("New");
- newPuzzle.addActionListener((ActionEvent) -> loadPuzzle());
+ JMenuItem openPuzzle = new JMenuItem("Open");
+ openPuzzle.addActionListener((ActionEvent) -> loadPuzzle());
if (os.equals("mac")) {
- newPuzzle.setAccelerator(
+ openPuzzle.setAccelerator(
KeyStroke.getKeyStroke(
- 'N', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+ 'O', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
} else {
- newPuzzle.setAccelerator(KeyStroke.getKeyStroke('N', InputEvent.CTRL_DOWN_MASK));
+ openPuzzle.setAccelerator(KeyStroke.getKeyStroke('O', InputEvent.CTRL_DOWN_MASK));
}
// file>create
JMenuItem createPuzzle = new JMenuItem("Create");
@@ -144,11 +150,11 @@ public void setMenuBar() {
existingPuzzle = false;
});
if (os.equals("mac")) {
- newPuzzle.setAccelerator(
+ createPuzzle.setAccelerator(
KeyStroke.getKeyStroke(
- 'D', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+ 'C', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
} else {
- newPuzzle.setAccelerator(KeyStroke.getKeyStroke('D', InputEvent.CTRL_DOWN_MASK));
+ createPuzzle.setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_DOWN_MASK));
}
JMenuItem exit = new JMenuItem("Exit");
@@ -279,8 +285,7 @@ public void exitEditor() {
@Override
public void makeVisible() {
this.removeAll();
-
- setupToolBar();
+ setupToolBar1();
setupContent();
setMenuBar();
}
@@ -292,21 +297,21 @@ public void makeVisible() {
private void setupToolBar1() {
setToolBar1Buttons(new JButton[2]);
- // Scale the image icons down to make the buttons smaller
- ImageIcon imageIcon = new ImageIcon(resourceLocation);
- Image image = imageIcon.getImage();
- imageIcon =
- new ImageIcon(
- image.getScaledInstance(
- this.TOOLBAR_ICON_SCALE,
- this.TOOLBAR_ICON_SCALE,
- Image.SCALE_SMOOTH));
-
- JButton button = new JButton(toolBarName, imageIcon);
- button.setFocusPainted(false);
- getToolBarButtons()[i] = button;
- lastone = i;
- }
+ URL open_url =
+ ClassLoader.getSystemClassLoader()
+ .getResource("edu/rpi/legup/images/Legup/Open.png");
+ ImageIcon OpenImageIcon = new ImageIcon(open_url);
+ Image OpenImage = OpenImageIcon.getImage();
+ OpenImageIcon =
+ new ImageIcon(
+ OpenImage.getScaledInstance(
+ this.TOOLBAR_ICON_SCALE,
+ this.TOOLBAR_ICON_SCALE,
+ Image.SCALE_SMOOTH));
+
+ JButton open = new JButton("Open", OpenImageIcon);
+ open.setFocusPainted(false);
+ open.addActionListener((ActionEvent) -> loadPuzzle());
getToolBar1Buttons()[0] = open;
@@ -414,81 +419,51 @@ private void setupToolBar2() {
URL save_and_solve =
ClassLoader.getSystemClassLoader()
.getResource("edu/rpi/legup/images/Legup/Check.png");
- ImageIcon imageIcon = new ImageIcon(check_and_save);
- Image image = imageIcon.getImage();
- imageIcon =
+ ImageIcon SaveSolveImageIcon = new ImageIcon(save_and_solve);
+ Image SaveSolveImage = SaveSolveImageIcon.getImage();
+ SaveSolveImageIcon =
new ImageIcon(
- image.getScaledInstance(
+ SaveSolveImage.getScaledInstance(
this.TOOLBAR_ICON_SCALE,
this.TOOLBAR_ICON_SCALE,
Image.SCALE_SMOOTH));
- JButton checkandsave = new JButton("check and Save", imageIcon);
- checkandsave.setFocusPainted(false);
- checkandsave.addActionListener(
+ JButton saveandsolve = new JButton("Save & Solve", SaveSolveImageIcon);
+ saveandsolve.setFocusPainted(false);
+ saveandsolve.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- // savePuzzle();
- String filename = savePuzzle();
- File puzzlename = new File(filename);
- System.out.println(filename);
-
- GameBoardFacade.getInstance().getLegupUI().displayPanel(1);
- GameBoardFacade.getInstance()
- .getLegupUI()
- .getProofEditor()
- .loadPuzzle(filename, new File(filename));
- String puzzleName =
- GameBoardFacade.getInstance().getPuzzleModule().getName();
- frame.setTitle(puzzleName + " - " + puzzlename.getName());
+ if (GameBoardFacade.getInstance().getPuzzleModule() != null) {
+ String filename = savePuzzle();
+ File puzzlename = new File(filename);
+ System.out.println(filename);
+
+ GameBoardFacade.getInstance().getLegupUI().displayPanel(1);
+ GameBoardFacade.getInstance()
+ .getLegupUI()
+ .getProofEditor()
+ .loadPuzzle(filename, new File(filename));
+ String puzzleName =
+ GameBoardFacade.getInstance().getPuzzleModule().getName();
+ frame.setTitle(puzzleName + " - " + puzzlename.getName());
+ }
}
});
- getToolBarButtons()[lastone + 1] = checkandsave;
- System.out.println("it is create new file");
-
- toolBar = new JToolBar();
- toolBar.setFloatable(false);
- toolBar.setRollover(true);
-
- for (int i = 0; i < getToolBarButtons().length - 1; i++) {
- for (int s = 0; s < TOOLBAR_SEPARATOR_BEFORE.length; s++) {
- if (i == TOOLBAR_SEPARATOR_BEFORE[s]) {
- toolBar.addSeparator();
- }
- }
- String toolBarName = ToolbarName.values()[i].toString();
-
- toolBar.add(getToolBarButtons()[i]);
- getToolBarButtons()[i].setToolTipText(toolBarName);
-
- getToolBarButtons()[i].setVerticalTextPosition(SwingConstants.BOTTOM);
- getToolBarButtons()[i].setHorizontalTextPosition(SwingConstants.CENTER);
- }
+ getToolBar2Buttons()[2] = saveandsolve;
+ toolBar2.add(getToolBar2Buttons()[2]);
- // toolBarButtons[ToolbarName.OPEN_PUZZLE.ordinal()].addActionListener((ActionEvent
- // e) ->
- // promptPuzzle());
- // toolBarButtons[ToolbarName.SAVE.ordinal()].addActionListener((ActionEvent e) ->
- // saveProof());
- // toolBarButtons[ToolbarName.UNDO.ordinal()].addActionListener((ActionEvent e) ->
- // GameBoardFacade.getInstance().getHistory().undo());
- // toolBarButtons[ToolbarName.REDO.ordinal()].addActionListener((ActionEvent e) ->
- // GameBoardFacade.getInstance().getHistory().redo());
- toolBarButtons[ToolbarName.HINT.ordinal()].addActionListener((ActionEvent e) -> {});
- toolBarButtons[ToolbarName.SUBMIT.ordinal()].addActionListener((ActionEvent e) -> {});
- toolBarButtons[ToolbarName.DIRECTIONS.ordinal()].addActionListener((ActionEvent e) -> {});
-
- // toolBarButtons[ToolbarName.SAVE.ordinal()].setEnabled(false);
- // toolBarButtons[ToolbarName.UNDO.ordinal()].setEnabled(false);
- // toolBarButtons[ToolbarName.REDO.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.HINT.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.SUBMIT.ordinal()].setEnabled(false);
- toolBarButtons[ToolbarName.DIRECTIONS.ordinal()].setEnabled(false);
-
- this.add(toolBar, BorderLayout.NORTH);
+ this.add(toolBar2, BorderLayout.NORTH);
}
+ /**
+ * Initializes a puzzle based on the provided game name, rows, and columns.
+ *
+ * @param game the name of the game or puzzle to load
+ * @param rows the number of rows in the puzzle
+ * @param columns the number of columns in the puzzle
+ * @throws IllegalArgumentException if the provided arguments are invalid
+ */
public void loadPuzzleFromHome(String game, int rows, int columns)
throws IllegalArgumentException {
GameBoardFacade facade = GameBoardFacade.getInstance();
@@ -502,6 +477,13 @@ public void loadPuzzleFromHome(String game, int rows, int columns)
}
}
+ /**
+ * Initializes a puzzle based on the provided game name and an array of statements.
+ *
+ * @param game the name of the game or puzzle to load
+ * @param statements an array of statements to initialize the puzzle
+ * @throws IllegalArgumentException if the provided arguments are invalid
+ */
public void loadPuzzleFromHome(String game, String[] statements) {
GameBoardFacade facade = GameBoardFacade.getInstance();
try {
@@ -525,7 +507,7 @@ public void loadPuzzleFromHome(String game, String[] statements) {
public Object[] promptPuzzle() {
GameBoardFacade facade = GameBoardFacade.getInstance();
if (facade.getBoard() != null) {
- if (noQuit("Opening a new puzzle?")) {
+ if (noQuit("Open an existing puzzle?")) {
return new Object[0];
}
}
@@ -549,7 +531,6 @@ public Object[] promptPuzzle() {
fileBrowser.setAcceptAllFileFilterUsed(false);
File puzzlePath = fileBrowser.getSelectedFile();
- System.out.println(puzzlePath.getAbsolutePath());
if (puzzlePath != null) {
fileName = puzzlePath.getAbsolutePath();
@@ -594,6 +575,9 @@ public void loadPuzzle(String fileName, File puzzleFile) {
GameBoardFacade.getInstance().loadPuzzleEditor(fileName);
String puzzleName = GameBoardFacade.getInstance().getPuzzleModule().getName();
frame.setTitle(puzzleName + " - " + puzzleFile.getName());
+ existingPuzzle = true;
+ this.fileName = fileName;
+ this.puzzleFile = puzzleFile;
} catch (InvalidFileFormatException e) {
legupUI.displayPanel(0);
LOGGER.error(e.getMessage());
@@ -644,12 +628,22 @@ public BoardView getBoardView() {
return boardView;
}
- public JButton[] getToolBarButtons() {
- return toolBarButtons;
+ /**
+ * Returns the array of buttons for the first toolbar
+ *
+ * @return the array of toolbar1 buttons
+ */
+ public JButton[] getToolBar1Buttons() {
+ return toolBar1Buttons;
}
- public void setToolBarButtons(JButton[] toolBarButtons) {
- this.toolBarButtons = toolBarButtons;
+ /**
+ * Sets the array of buttons for the first toolbar
+ *
+ * @param toolBar1Buttons the array of toolbar1 buttons
+ */
+ public void setToolBar1Buttons(JButton[] toolBar1Buttons) {
+ this.toolBar1Buttons = toolBar1Buttons;
}
/**
@@ -696,13 +690,11 @@ public void setPuzzleView(Puzzle puzzle) {
dynamicBoardView.setBorder(titleBoard);
puzzle.addBoardListener(puzzle.getBoardView());
- System.out.println("Setting elements");
if (this.elementFrame != null) {
elementFrame.setElements(puzzle);
}
-
- toolBarButtons[ToolbarName.CHECK.ordinal()].setEnabled(true);
- // toolBarButtons[ToolbarName.SAVE.ordinal()].setEnabled(true);
+ toolBar1.setVisible(false);
+ setupToolBar2();
}
/** Saves a puzzle */
@@ -768,7 +760,7 @@ private String savePuzzle() {
folderBrowser.setAcceptAllFileFilterUsed(false);
String path = folderBrowser.getSelectedFile().getAbsolutePath();
-
+ preferences.setSavedPath(path);
if (path != null) {
try {
PuzzleExporter exporter = puzzle.getExporter();
@@ -783,6 +775,11 @@ private String savePuzzle() {
return path;
}
+ /**
+ * Returns the current dynamic board view
+ *
+ * @return the dynamic board view
+ */
public DynamicView getDynamicBoardView() {
return dynamicBoardView;
}
diff --git a/src/main/java/edu/rpi/legup/ui/ScrollView.java b/src/main/java/edu/rpi/legup/ui/ScrollView.java
index 4d53cd747..589573154 100644
--- a/src/main/java/edu/rpi/legup/ui/ScrollView.java
+++ b/src/main/java/edu/rpi/legup/ui/ScrollView.java
@@ -293,6 +293,11 @@ public void setSize(Dimension size) {
updateSize();
}
+ /**
+ * Gets the canvas for this {@code ScrollView}
+ *
+ * @return the ZoomablePane instance used as the canvas
+ */
public ZoomablePane getCanvas() {
return canvas;
}
diff --git a/src/main/java/edu/rpi/legup/ui/ToolbarName.java b/src/main/java/edu/rpi/legup/ui/ToolbarName.java
index 5cf9b5923..622d16d8d 100644
--- a/src/main/java/edu/rpi/legup/ui/ToolbarName.java
+++ b/src/main/java/edu/rpi/legup/ui/ToolbarName.java
@@ -5,11 +5,8 @@
* specific toolbar action.
*/
public enum ToolbarName {
- HINT,
- CHECK,
- SUBMIT,
DIRECTIONS,
- CHECK_ALL;
+ CHECK;
/**
* Gets the String representation of the ToolbarName enum
diff --git a/src/main/java/edu/rpi/legup/ui/ZoomWidget.java b/src/main/java/edu/rpi/legup/ui/ZoomWidget.java
index 3207462ed..40f36113f 100644
--- a/src/main/java/edu/rpi/legup/ui/ZoomWidget.java
+++ b/src/main/java/edu/rpi/legup/ui/ZoomWidget.java
@@ -10,6 +10,10 @@
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+/**
+ * The {@code ZoomWidget} displays a zoom icon that, when clicked, shows a popup slider to adjust
+ * the zoom level of the associated {@code ScrollView}.
+ */
public class ZoomWidget extends JLabel {
private ScrollView parent;
private PopupSlider palette = new PopupSlider();
@@ -48,6 +52,11 @@ public PopupSlider() {
slider.addChangeListener(this);
}
+ /**
+ * Handles state changes in the slider by adjusting the zoom level of the {@code ScrollView}
+ *
+ * @param e the {@code ChangeEvent} indicating that the slider's state has changed
+ */
public void stateChanged(ChangeEvent e) {
if (slider.getValueIsAdjusting()) {
parent.zoomTo((double) slider.getValue() / 100.0);
diff --git a/src/main/java/edu/rpi/legup/ui/ZoomablePane.java b/src/main/java/edu/rpi/legup/ui/ZoomablePane.java
index 934d31c53..66af90abd 100644
--- a/src/main/java/edu/rpi/legup/ui/ZoomablePane.java
+++ b/src/main/java/edu/rpi/legup/ui/ZoomablePane.java
@@ -5,6 +5,10 @@
import java.awt.Graphics2D;
import javax.swing.*;
+/**
+ * The {@code ZoomablePane} class is used to display components in a zoomable and scalable manner.
+ * It uses {@code ScrollView} to handle scaling and drawing of the content.
+ */
public class ZoomablePane extends JLayeredPane {
private ScrollView viewer;
diff --git a/src/main/java/edu/rpi/legup/ui/boardview/BoardView.java b/src/main/java/edu/rpi/legup/ui/boardview/BoardView.java
index 0b395c774..18b47d98b 100644
--- a/src/main/java/edu/rpi/legup/ui/boardview/BoardView.java
+++ b/src/main/java/edu/rpi/legup/ui/boardview/BoardView.java
@@ -188,6 +188,11 @@ public ArrayList getElementViews() {
return elementViews;
}
+ /**
+ * Gets the ElementController associated with this board view.
+ *
+ * @return the ElementController
+ */
public ElementController getElementController() {
return elementController;
}
@@ -197,6 +202,11 @@ public void draw(Graphics2D graphics2D) {
drawBoard(graphics2D);
}
+ /**
+ * Draws the board and its elements.
+ *
+ * @param graphics2D the Graphics2D context used for drawing
+ */
public void drawBoard(Graphics2D graphics2D) {
for (ElementView element : elementViews) {
element.draw(graphics2D);
@@ -213,5 +223,10 @@ public void onBoardDataChanged(PuzzleElement puzzleElement) {
repaint();
}
+ /**
+ * Gets the selection popup menu for this board view.
+ *
+ * @return the DataSelectionView associated with this view
+ */
public abstract DataSelectionView getSelectionPopupMenu();
}
diff --git a/src/main/java/edu/rpi/legup/ui/boardview/DataSelectionView.java b/src/main/java/edu/rpi/legup/ui/boardview/DataSelectionView.java
index 44cee38fb..bc40e3d58 100644
--- a/src/main/java/edu/rpi/legup/ui/boardview/DataSelectionView.java
+++ b/src/main/java/edu/rpi/legup/ui/boardview/DataSelectionView.java
@@ -11,6 +11,11 @@
*/
public class DataSelectionView extends JPopupMenu {
+ /**
+ * Constructs a DataSelectionView with the given controller.
+ *
+ * @param controller The ElementController to handle UI events.
+ */
public DataSelectionView(ElementController controller) {
setBackground(Color.GRAY);
setBorder(new BevelBorder(BevelBorder.RAISED));
diff --git a/src/main/java/edu/rpi/legup/ui/boardview/ElementSelection.java b/src/main/java/edu/rpi/legup/ui/boardview/ElementSelection.java
index 5ddbab909..eaa85082d 100644
--- a/src/main/java/edu/rpi/legup/ui/boardview/ElementSelection.java
+++ b/src/main/java/edu/rpi/legup/ui/boardview/ElementSelection.java
@@ -12,16 +12,29 @@ public class ElementSelection {
private ElementView hover;
private Point mousePoint;
+ /**
+ * Constructs an ElementSelection instance with an empty selection and no hover or mouse point
+ */
public ElementSelection() {
this.selection = new ArrayList<>();
this.hover = null;
this.mousePoint = null;
}
+ /**
+ * Gets the list of currently selected ElementViews.
+ *
+ * @return the list of selected ElementViews
+ */
public ArrayList getSelection() {
return selection;
}
+ /**
+ * Gets the first ElementView in the selection, or null if the selection is empty.
+ *
+ * @return the first selected ElementView, or null if there are no selections
+ */
public ElementView getFirstSelection() {
return selection.size() == 0 ? null : selection.get(0);
}
@@ -62,10 +75,20 @@ public void clearSelection() {
selection.clear();
}
+ /**
+ * Gets the currently hovered ElementView.
+ *
+ * @return the currently hovered ElementView, or null if no element is hovered
+ */
public ElementView getHover() {
return hover;
}
+ /**
+ * Sets a new hovered ElementView, updating the hover state of the previous and new elements.
+ *
+ * @param newHovered the new ElementView to be hovered
+ */
public void newHover(ElementView newHovered) {
newHovered.setHover(true);
if (hover != null) {
@@ -82,10 +105,20 @@ public void clearHover() {
}
}
+ /**
+ * Gets the current mouse point location.
+ *
+ * @return the current mouse point location
+ */
public Point getMousePoint() {
return mousePoint;
}
+ /**
+ * Sets the mouse point location.
+ *
+ * @param point the new mouse point location
+ */
public void setMousePoint(Point point) {
this.mousePoint = point;
}
diff --git a/src/main/java/edu/rpi/legup/ui/boardview/ElementView.java b/src/main/java/edu/rpi/legup/ui/boardview/ElementView.java
index 48a33493c..eab13cc1d 100644
--- a/src/main/java/edu/rpi/legup/ui/boardview/ElementView.java
+++ b/src/main/java/edu/rpi/legup/ui/boardview/ElementView.java
@@ -97,8 +97,19 @@ public void drawElement(Graphics2D graphics2D) {
graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
}
+ /**
+ * Draws additional elements for given PuzzleElements (default implementation does nothing).
+ * Overriden in some puzzle element views.
+ *
+ * @param graphics2D the Graphics2D context to use for drawing
+ */
public void drawGiven(Graphics2D graphics2D) {}
+ /**
+ * Draws a hover effect on the ElementView.
+ *
+ * @param graphics2D the Graphics2D context to use for drawing
+ */
public void drawHover(Graphics2D graphics2D) {
graphics2D.setColor(hoverColor);
graphics2D.setStroke(new BasicStroke(2));
@@ -107,6 +118,11 @@ public void drawHover(Graphics2D graphics2D) {
location.x + 1.5f, location.y + 1.5f, size.width - 3, size.height - 3));
}
+ /**
+ * Draws a modified effect on the ElementView.
+ *
+ * @param graphics2D the Graphics2D context to use for drawing
+ */
public void drawModified(Graphics2D graphics2D) {
graphics2D.setColor(puzzleElement.isValid() ? modifiedColor : invalidColor);
graphics2D.setStroke(new BasicStroke(2));
@@ -115,6 +131,11 @@ public void drawModified(Graphics2D graphics2D) {
location.x + 1.5f, location.y + 1.5f, size.width - 3, size.height - 3));
}
+ /**
+ * Draws a case rule picker on the ElementView.
+ *
+ * @param graphics2D the Graphics2D context to use for drawing
+ */
public void drawCase(Graphics2D graphics2D) {
graphics2D.setColor(caseColor);
graphics2D.fill(
@@ -122,6 +143,11 @@ public void drawCase(Graphics2D graphics2D) {
location.x + 1.5f, location.y + 1.5f, size.width - 3, size.height - 3));
}
+ /**
+ * Creates an image representation of the ElementView.
+ *
+ * @return a BufferedImage of the ElementView
+ */
public BufferedImage getImage() {
BufferedImage image =
new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
@@ -203,10 +229,20 @@ public void setPuzzleElement(PuzzleElement data) {
this.puzzleElement = data;
}
+ /**
+ * Checks if the case picker should be shown for this ElementView
+ *
+ * @return true if the case picker should be shown, false otherwise
+ */
public boolean isShowCasePicker() {
return showCasePicker;
}
+ /**
+ * Sets whether the case picker should be shown for this ElementView
+ *
+ * @param showCasePicker true if the case picker should be shown, false otherwise
+ */
public void setShowCasePicker(boolean showCasePicker) {
this.showCasePicker = showCasePicker;
}
@@ -414,11 +450,21 @@ public PathIterator getPathIterator(AffineTransform at, double flatness) {
.getPathIterator(at, flatness);
}
+ /**
+ * Returns the bounding rectangle of this ElementView
+ *
+ * @return a Rectangle representing the bounding box of this ElementView
+ */
@Override
public Rectangle getBounds() {
return new Rectangle(location.x, location.y, size.width, size.height);
}
+ /**
+ * Returns the bounding rectangle of this ElementView as a Rectangle2D
+ *
+ * @return a Rectangle2D representing the bounding box of this ElementView
+ */
@Override
public Rectangle2D getBounds2D() {
return new Rectangle(location.x, location.y, size.width, size.height);
diff --git a/src/main/java/edu/rpi/legup/ui/boardview/GridBoardView.java b/src/main/java/edu/rpi/legup/ui/boardview/GridBoardView.java
index db5ccbc82..e2b8bbc12 100644
--- a/src/main/java/edu/rpi/legup/ui/boardview/GridBoardView.java
+++ b/src/main/java/edu/rpi/legup/ui/boardview/GridBoardView.java
@@ -81,9 +81,9 @@ public void initSize() {
}
/**
- * Helper method to determine the proper dimension of the grid view
+ * Determines the proper dimension of the grid view based on grid size and element size.
*
- * @return proper dimension of the grid view
+ * @return the dimension of the grid view
*/
protected Dimension getProperSize() {
Dimension boardViewSize = new Dimension();
@@ -102,6 +102,11 @@ public DataSelectionView getSelectionPopupMenu() {
return null;
}
+ /**
+ * Gets the size of each element in the grid
+ *
+ * @return the dimension of each element in the grid
+ */
public Dimension getElementSize() {
return this.elementSize;
}
diff --git a/src/main/java/edu/rpi/legup/ui/boardview/SelectionItemView.java b/src/main/java/edu/rpi/legup/ui/boardview/SelectionItemView.java
index e3bb3592f..6a1429a61 100644
--- a/src/main/java/edu/rpi/legup/ui/boardview/SelectionItemView.java
+++ b/src/main/java/edu/rpi/legup/ui/boardview/SelectionItemView.java
@@ -58,6 +58,11 @@ public SelectionItemView(PuzzleElement data) {
this(data, (Integer) data.getData());
}
+ /**
+ * Gets the PuzzleElement associated with this menu item
+ *
+ * @return the PuzzleElement associated with this menu item
+ */
public PuzzleElement getData() {
return data;
}
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleFrame.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleFrame.java
index cf01f3ede..b14091351 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleFrame.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleFrame.java
@@ -131,7 +131,7 @@ public void resetSize() {
/**
* Set the status label to a value. Use resetStatus to clear it.
*
- * @param check true iff we want a check box, if false we'll have a red x box
+ * @param check true if we want a checkbox, if false we'll have a red x box
* @param text the text we're setting the label to display
*/
public void setStatus(boolean check, String text) {
@@ -169,22 +169,47 @@ public RuleController getController() {
return controller;
}
+ /**
+ * Gets the JTabbedPane used in this frame
+ *
+ * @return the JTabbedPane instance
+ */
public JTabbedPane getTabbedPane() {
return tabbedPane;
}
+ /**
+ * Gets the {@code DirectRulePanel} contained in this frame
+ *
+ * @return the {@link DirectRulePanel} instance
+ */
public DirectRulePanel getDirectRulePanel() {
return DirectRulePanel;
}
+ /**
+ * Gets the {@code CaseRulePanel} contained in this frame
+ *
+ * @return the {@link CaseRulePanel} instance
+ */
public CaseRulePanel getCasePanel() {
return casePanel;
}
+ /**
+ * Gets the {@code ContradictionRulePanel} contained in this frame
+ *
+ * @return the {@link ContradictionRulePanel} instance
+ */
public ContradictionRulePanel getContradictionPanel() {
return contradictionPanel;
}
+ /**
+ * Gets the {@code SearchBarPanel} contained in this frame
+ *
+ * @return the {@link SearchBarPanel} instance
+ */
public SearchBarPanel getSearchPanel() {
return searchPanel;
}
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RulePanel.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RulePanel.java
index c5e7327fd..85ddf82b5 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RulePanel.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RulePanel.java
@@ -36,7 +36,7 @@ public RulePanel(RuleFrame ruleFrame) {
}
/**
- * Gets the rule rule buttons
+ * Gets the array of rule buttons
*
* @return rule ruleButtons
*/
@@ -338,28 +338,58 @@ public List extends Rule> getRules() {
return rules;
}
+ /**
+ * Gets the icon associated with this panel
+ *
+ * @return The ImageIcon associated with this panel
+ */
public ImageIcon getIcon() {
return icon;
}
+ /**
+ * Sets the icon for this panel
+ *
+ * @return the ImageIcon associated with this panel
+ */
public void setIcon(ImageIcon icon) {
this.icon = icon;
}
+ /**
+ * Gets the name of this panel
+ *
+ * @return the name of this panel in a String
+ */
@Override
public String getName() {
return name;
}
+ /**
+ * Sets the name of this panel
+ *
+ * @param name the name to set for this panel
+ */
@Override
public void setName(String name) {
this.name = name;
}
+ /**
+ * Gets the tooltip text associated with this panel
+ *
+ * @return the tooltip text of this panel
+ */
public String getToolTip() {
return toolTip;
}
+ /**
+ * Sets the tooltip text for this panel
+ *
+ * @param toolTip the tooltip text to set for this panel
+ */
public void setToolTip(String toolTip) {
this.toolTip = toolTip;
}
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeElementView.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeElementView.java
index 0233ec6d4..e5e523e11 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeElementView.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeElementView.java
@@ -41,7 +41,7 @@ protected TreeElementView(TreeElementType type, TreeElement treeElement) {
public abstract void draw(Graphics2D graphics2D);
/**
- * Gets the span for the sub tree rooted at this view
+ * Gets the span for the subtree rooted at this view
*
* @return span bounded y span
*/
@@ -50,7 +50,7 @@ public double getSpan() {
}
/**
- * Sets the span for the sub tree rooted at this view.
+ * Sets the span for the subtree rooted at this view.
*
* @param span bounded y span
*/
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeNodeView.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeNodeView.java
index 8e9562d10..c9aedaef3 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeNodeView.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeNodeView.java
@@ -266,11 +266,21 @@ public int getRadius() {
return RADIUS;
}
+ /**
+ * Returns the bounding rectangle of this TreeNodeView
+ *
+ * @return a Rectangle representing the bounding box of this TreeNodeView
+ */
@Override
public Rectangle getBounds() {
return new Rectangle(location.x, location.y, DIAMETER, DIAMETER);
}
+ /**
+ * Returns the bounding rectangle of this TreeNodeView as a Rectangle2D
+ *
+ * @return a Rectangle2D representing the bounding box of this TreeNodeView
+ */
@Override
public Rectangle2D getBounds2D() {
return new Rectangle(location.x, location.y, DIAMETER, DIAMETER);
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreePanel.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreePanel.java
index 9efeb8dfb..936b0de95 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreePanel.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreePanel.java
@@ -66,10 +66,20 @@ public TreePanel(/*LegupUI legupUI*/ ) {
updateStatusTimer = 0;
}
+ /**
+ * Repaints the tree view with the provided {@link Tree} object
+ *
+ * @param tree the {@link Tree} object to update the view with
+ */
public void repaintTreeView(Tree tree) {
treeView.updateTreeView(tree);
}
+ /**
+ * Updates the status of the panel based on changes to the {@link Board}
+ *
+ * @param board the {@link Board} object representing the current board state
+ */
public void boardDataChanged(Board board) {
modifiedSinceSave = true;
modifiedSinceUndoPush = true;
@@ -89,18 +99,33 @@ public void updateStatus() {
this.status.setText("");
}
+ /**
+ * Updates the status display with the given status string
+ *
+ * @param statusString the status string to display
+ */
public void updateStatus(String statusString) {
status.setForeground(Color.BLACK);
status.setFont(MaterialFonts.REGULAR);
status.setText(statusString);
}
+ /**
+ * Updates the status display as an error with an error message
+ *
+ * @param error the error message to display
+ */
public void updateError(String error) {
status.setForeground(Color.RED);
status.setFont(MaterialFonts.ITALIC);
status.setText(error);
}
+ /**
+ * Gets the {@link TreeView} instance associated with this panel
+ *
+ * @return the {@link TreeView} instance
+ */
public TreeView getTreeView() {
return treeView;
}
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarButton.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarButton.java
index 2718f733d..232498723 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarButton.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarButton.java
@@ -9,6 +9,12 @@ public class TreeToolBarButton extends JButton {
private TreeToolBarName name;
private final Dimension MINIMUM_DIMENSION = new Dimension(60, 60);
+ /**
+ * Constructs a {@code TreeToolBarButton} with the specified icon and name.
+ *
+ * @param imageIcon the {@link ImageIcon} to be displayed on the button
+ * @param name the {@link TreeToolBarName} associated with this button
+ */
public TreeToolBarButton(ImageIcon imageIcon, TreeToolBarName name) {
super(imageIcon);
this.name = name;
@@ -17,6 +23,11 @@ public TreeToolBarButton(ImageIcon imageIcon, TreeToolBarName name) {
this.setFocusPainted(false);
}
+ /**
+ * Gets the {@link TreeToolBarName} associated with this button
+ *
+ * @return the {@link TreeToolBarName} associated with this button
+ */
public TreeToolBarName getToolBarName() {
return name;
}
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarName.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarName.java
index c805021be..3aec664be 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarName.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolBarName.java
@@ -1,5 +1,9 @@
package edu.rpi.legup.ui.proofeditorui.treeview;
+/**
+ * {@code TreeToolBarName} defines the names of actions represented by buttons in the tree toolbar.
+ * These actions are used for managing tree elements within the UI.
+ */
public enum TreeToolBarName {
ADD_CHILD,
DEL_CHILD,
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeTransitionView.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeTransitionView.java
index 70546616d..5a3aa7d5c 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeTransitionView.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeTransitionView.java
@@ -271,47 +271,67 @@ public void removeParentView(TreeNodeView nodeView) {
}
}
- public Point getEndPoint() {
- return endPoint;
- }
-
- public void setEndPoint(Point endPoint) {
- this.endPoint = endPoint;
- }
-
+ /**
+ * Gets the x-coordinate of the end point of the transition arrow
+ *
+ * @return the x-coordinate of the end point
+ */
public int getEndX() {
return endPoint.x;
}
+ /**
+ * Sets the x-coordinate of the end point of the transition arrow
+ *
+ * @param x the new x-coordinate of the end point
+ */
public void setEndX(int x) {
this.endPoint.x = x;
}
+ /**
+ * Gets the y-coordinate of the end point of the transition arrow
+ *
+ * @return the y-coordinate of the end point
+ */
public int getEndY() {
return endPoint.y;
}
+ /**
+ * Sets the y-coordinate of the end point of the transition arrow
+ *
+ * @param y the new y-coordinate of the end point
+ */
public void setEndY(int y) {
this.endPoint.y = y;
}
- public List getLineStartPoints() {
- return lineStartPoints;
- }
-
- public void setLineStartPoints(List lineStartPoints) {
- this.lineStartPoints = lineStartPoints;
- }
-
+ /**
+ * Gets the start point at the specified index from the list of start points
+ *
+ * @param index the index of the start point to retrieve
+ * @return the start point at the specified index, or null if the index is out of range
+ */
public Point getLineStartPoint(int index) {
return index < lineStartPoints.size() ? lineStartPoints.get(index) : null;
}
+ /**
+ * Returns the bounding rectangle of this TreeTransitionView
+ *
+ * @return a Rectangle representing the bounding box of this TreeTransitionView
+ */
@Override
public Rectangle getBounds() {
return arrowhead.getBounds();
}
+ /**
+ * Returns the bounding rectangle of this TreeTransitionView as a Rectangle2D
+ *
+ * @return a Rectangle2D representing the bounding box of this TreeTransitionView
+ */
@Override
public Rectangle2D getBounds2D() {
return arrowhead.getBounds2D();
diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeView.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeView.java
index 3d74d1e08..65f49ff0a 100644
--- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeView.java
+++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeView.java
@@ -57,6 +57,11 @@ public class TreeView extends ScrollView implements ITreeListener {
private TreeViewSelection selection;
+ /**
+ * Constructs a {@code TreeView} with the specified {@code TreeController}.
+ *
+ * @param treeController the {@code TreeController} used to manage tree operations
+ */
public TreeView(TreeController treeController) {
super(treeController);
currentStateBoxes = new ArrayList<>();
@@ -68,6 +73,11 @@ public TreeView(TreeController treeController) {
selection = new TreeViewSelection();
}
+ /**
+ * Gets the current tree view selection
+ *
+ * @return the {@code TreeViewSelection} object representing the current selection
+ */
public TreeViewSelection getSelection() {
return selection;
}
@@ -137,6 +147,11 @@ private TreeElementView getTreeElementView(Point point, TreeElementView elementV
return null;
}
+ /**
+ * Updates the tree view with the specified {@code Tree}
+ *
+ * @param tree the {@code Tree} to display in the view
+ */
public void updateTreeView(Tree tree) {
this.tree = tree;
if (selection.getSelectedViews().size() == 0) {
@@ -174,8 +189,9 @@ public void reset() {
* button is selected
*/
public void zoomFit() {
- double fitWidth = (viewport.getWidth() - 8.0) / (getSize().width - 200);
- double fitHeight = (viewport.getHeight() - 8.0) / (getSize().height - 120);
+ final int MIN_HEIGHT = 200;
+ double fitWidth = (viewport.getWidth() - 7.0) / (getSize().width - 75);
+ double fitHeight = (viewport.getHeight()) / Math.max((getSize().height - 115), MIN_HEIGHT);
zoomTo(Math.min(fitWidth, fitHeight));
viewport.setViewPosition(new Point(0, viewport.getHeight() / 2));
}
@@ -224,6 +240,11 @@ public void layoutContainer(Container parent) {
};
}
+ /**
+ * Draws the tree view on the provided {@code Graphics2D} context
+ *
+ * @param graphics2D the {@code Graphics2D} context to draw on
+ */
public void draw(Graphics2D graphics2D) {
currentStateBoxes.clear();
Tree tree = GameBoardFacade.getInstance().getTree();
@@ -255,6 +276,12 @@ public void zoomReset() {
viewport.setViewPosition(new Point(0, 0));
}
+ /**
+ * Recursively redraws the tree starting from the specified node view
+ *
+ * @param graphics2D the {@code Graphics2D} context to draw on
+ * @param nodeView the {@code TreeNodeView} to start drawing from
+ */
private void redrawTree(Graphics2D graphics2D, TreeNodeView nodeView) {
if (nodeView != null) {
nodeView.draw(graphics2D);
@@ -265,6 +292,11 @@ private void redrawTree(Graphics2D graphics2D, TreeNodeView nodeView) {
}
}
+ /**
+ * Removes the specified {@code TreeElementView} from the tree view
+ *
+ * @param view the {@code TreeElementView} to remove
+ */
public void removeTreeElement(TreeElementView view) {
if (view.getType() == NODE) {
TreeNodeView nodeView = (TreeNodeView) view;
@@ -424,8 +456,17 @@ public TreeElementView getElementView(TreeElement element) {
return viewMap.get(element);
}
- private void removeTreeNode(TreeNode node) {
+ /**
+ * Removes the specified {@link TreeNode} and its associated views
+ *
+ * @param node the {@link TreeNode} to be removed
+ */
+ public void removeTreeNode(TreeNode node) {
viewMap.remove(node);
+ if (node.getChildren() != null) {
+ node.getChildren().forEach(t -> removeTreeTransition(t));
+ }
+
List children = node.getChildren();
// if child is a case rule, unlock ancestor elements
@@ -452,11 +493,13 @@ private void removeTreeNode(TreeNode node) {
}
// set modifiable if started modifiable
- boolean modifiable =
- tree.getRootNode()
- .getBoard()
- .getPuzzleElement(oldElement)
- .isModifiable();
+ boolean modifiable = false;
+ if (tree != null) {
+ tree.getRootNode()
+ .getBoard()
+ .getPuzzleElement(oldElement)
+ .isModifiable();
+ }
// unmodifiable if already modified
TreeNode modNode = ancestor.getParent().getParents().get(0);
@@ -474,10 +517,14 @@ private void removeTreeNode(TreeNode node) {
}
}
}
- node.getChildren().forEach(t -> removeTreeTransition(t));
}
- private void removeTreeTransition(TreeTransition trans) {
+ /**
+ * Removes the specified {@link TreeTransition} and its associated views
+ *
+ * @param trans the {@link TreeTransition} to be removed
+ */
+ public void removeTreeTransition(TreeTransition trans) {
viewMap.remove(trans);
if (trans.getChildNode() != null) {
removeTreeNode(trans.getChildNode());
@@ -514,12 +561,16 @@ private void removeTreeTransition(TreeTransition trans) {
}
}
+ /**
+ * Adds the specified {@link TreeNode} and its associated views
+ *
+ * @param node the {@link TreeNode} to be added
+ */
private void addTreeNode(TreeNode node) {
TreeTransition parent = node.getParent();
-
TreeNodeView nodeView = new TreeNodeView(node);
- TreeTransitionView parentView = (TreeTransitionView) viewMap.get(parent);
+ TreeTransitionView parentView = (TreeTransitionView) viewMap.get(parent);
nodeView.setParentView(parentView);
parentView.setChildView(nodeView);
@@ -554,20 +605,25 @@ private void addTreeNode(TreeNode node) {
}
}
+ /**
+ * Adds the specified {@link TreeTransition} and its associated views
+ *
+ * @param trans The {@link TreeTransition} to be added
+ */
private void addTreeTransition(TreeTransition trans) {
List parents = trans.getParents();
-
TreeTransitionView transView = new TreeTransitionView(trans);
+
for (TreeNode parent : parents) {
TreeNodeView parentNodeView = (TreeNodeView) viewMap.get(parent);
transView.addParentView(parentNodeView);
parentNodeView.addChildrenView(transView);
+ viewMap.put(trans, transView);
+
// if transition is a new case rule, lock dependent ancestor elements
Rule rule = trans.getRule();
if (rule instanceof CaseRule && parent.getChildren().size() == 1) {
- CaseRule caseRule = (CaseRule) rule;
-
List ancestors = parent.getAncestors();
for (TreeNode ancestor : ancestors) {
// for all ancestors but root
@@ -584,15 +640,16 @@ private void addTreeTransition(TreeTransition trans) {
}
}
- viewMap.put(trans, transView);
-
if (trans.getChildNode() != null) {
addTreeNode(trans.getChildNode());
}
}
- /// New Draw Methods
-
+ /**
+ * Draws the tree using the provided {@link Graphics2D} object
+ *
+ * @param graphics2D the {@link Graphics2D} object used for drawing the tree
+ */
public void drawTree(Graphics2D graphics2D) {
if (tree == null) {
LOGGER.error("Unable to draw tree.");
@@ -618,6 +675,11 @@ public void drawTree(Graphics2D graphics2D) {
}
}
+ /**
+ * Creates views for the given {@link TreeNodeView} and its children
+ *
+ * @param nodeView the {@link TreeNodeView} for which to create views
+ */
public void createViews(TreeNodeView nodeView) {
if (nodeView != null) {
viewMap.put(nodeView.getTreeElement(), nodeView);
diff --git a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java
index bcb69f6c0..1619ecbaa 100644
--- a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java
+++ b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java
@@ -19,45 +19,30 @@ public class ElementFrame extends JPanel {
private EditorElementController controller;
public ElementFrame(EditorElementController controller) {
+
this.controller = controller;
- MaterialTabbedPaneUI tabOverride =
- new MaterialTabbedPaneUI() {
- // this prevents the tabs from moving around when you select them
- @Override
- protected boolean shouldRotateTabRuns(int i) {
- return false;
- }
- };
-
- this.tabbedPane = new JTabbedPane();
- tabbedPane.setUI(tabOverride);
+
JLabel status = new JLabel("", SwingConstants.CENTER);
this.buttonGroup = new ButtonGroup();
- nonPlaceableElementPanel = new NonPlaceableElementPanel(this);
- // nonPlaceableElementPanel.setMinimumSize(new Dimension(100,200));
- tabbedPane.addTab(
- nonPlaceableElementPanel.getName(),
- nonPlaceableElementPanel.getIcon(),
- new JScrollPane(nonPlaceableElementPanel),
- nonPlaceableElementPanel.getToolTip());
+ // Parent panel to hold all elements
+ JPanel elementPanel = new JPanel();
+ elementPanel.setLayout(new BoxLayout(elementPanel, BoxLayout.Y_AXIS));
placeableElementPanel = new PlaceableElementPanel(this);
- // placeableElementPanel.setMinimuSize(new Dimension(100,200));
- tabbedPane.addTab(
- placeableElementPanel.getName(),
- placeableElementPanel.getIcon(),
- new JScrollPane(placeableElementPanel),
- placeableElementPanel.getToolTip());
- tabbedPane.setTabPlacement(JTabbedPane.TOP);
+ placeableElementPanel.setMinimumSize(new Dimension(100, 200));
+ elementPanel.add(new JScrollPane(placeableElementPanel));
+ // Set layout and dimensions for the main panel
setLayout(new BorderLayout());
setMinimumSize(new Dimension(250, 256));
setPreferredSize(new Dimension(330, 256));
- add(tabbedPane);
+ // Add components to the main panel
+ add(elementPanel, BorderLayout.CENTER);
add(status, BorderLayout.SOUTH);
+ // Center-align the titled border
TitledBorder title = BorderFactory.createTitledBorder("Elements");
title.setTitleJustification(TitledBorder.CENTER);
setBorder(title);
@@ -75,8 +60,9 @@ public ButtonGroup getButtonGroup() {
// }
public void setElements(Puzzle puzzle) {
- nonPlaceableElementPanel.setElements(puzzle.getNonPlaceableElements());
- placeableElementPanel.setElements(puzzle.getPlaceableElements());
+ if (puzzle != null) {
+ placeableElementPanel.setElements(puzzle.getPlaceableElements());
+ }
}
public EditorElementController getController() {
diff --git a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementPanel.java b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementPanel.java
index 46198e226..70826d25c 100644
--- a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementPanel.java
+++ b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementPanel.java
@@ -20,7 +20,7 @@ public ElementPanel(ElementFrame eFrame) {
setLayout(new WrapLayout());
}
- public void setElements(List extends Element> elements) {
+ public int setElements(List extends Element> elements) {
this.elements = elements;
clearButtons();
@@ -38,6 +38,7 @@ public void setElements(List extends Element> elements) {
add(elementButtons[i]);
}
revalidate();
+ return elements.size();
}
protected void clearButtons() {
diff --git a/src/main/resources/edu/rpi/legup/images/Legup/Reset.png b/src/main/resources/edu/rpi/legup/images/Legup/Reset.png
new file mode 100644
index 000000000..fd6ffefa0
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/Legup/Reset.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png
index a74654d43..27ccec972 100644
Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png and b/src/main/resources/edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png
deleted file mode 100644
index 214aa5348..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png
deleted file mode 100644
index 73072f2ce..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png
deleted file mode 100644
index b68f67e44..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/PreventTrioDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/PreventTrioDirectRule.png
new file mode 100644
index 000000000..ed0701f26
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/PreventTrioDirectRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/RepeatedRowColumnContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/RepeatedRowColumnContradictionRule.png
new file mode 100644
index 000000000..5cc030a76
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/RepeatedRowColumnContradictionRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/SaveBlockerDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/SaveBlockerDirectRule.png
new file mode 100644
index 000000000..7695ae2da
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/SaveBlockerDirectRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png
deleted file mode 100644
index 67a4e47f3..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png
deleted file mode 100644
index 862408b63..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/TrioContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/TrioContradictionRule.png
new file mode 100644
index 000000000..e292ec9fa
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/TrioContradictionRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png
index 029bd12ac..bd66c16a7 100644
Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png and b/src/main/resources/edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/UniqueRowColumnDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/UniqueRowColumnDirectRule.png
new file mode 100644
index 000000000..7785d198c
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/UniqueRowColumnDirectRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/WastedBlockerContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/WastedBlockerContradictionRule.png
new file mode 100644
index 000000000..8813d7956
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/WastedBlockerContradictionRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/ZeroOrOneCaseRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/ZeroOrOneCaseRule.png
new file mode 100644
index 000000000..7394bff91
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/ZeroOrOneCaseRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/tiles/NumberTile.png b/src/main/resources/edu/rpi/legup/images/binary/tiles/NumberTile.png
new file mode 100644
index 000000000..41fb61dfa
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/tiles/NumberTile.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/tiles/UnknownTile.png b/src/main/resources/edu/rpi/legup/images/binary/tiles/UnknownTile.png
new file mode 100644
index 000000000..9ab9f7481
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/tiles/UnknownTile.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/CellForNumber.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/CellForNumber.png
index 7ab0cdbef..e8cca03b4 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/CellForNumber.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/CellForNumber.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/NumberForCell.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/NumberForCell.png
index fedbbbac8..307d0d754 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/NumberForCell.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/cases/NumberForCell.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/DuplicateNumber.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/DuplicateNumber.png
index 7ba489c2b..6ab3cd769 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/DuplicateNumber.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/DuplicateNumber.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/ExceedingVisibility.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/ExceedingVisibility.png
index ff999f4bc..2f5b5237d 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/ExceedingVisibility.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/ExceedingVisibility.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/InsufficientVisibility.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/InsufficientVisibility.png
index cfe04a503..285451ba1 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/InsufficientVisibility.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/InsufficientVisibility.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/PreemptiveVisibility.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/PreemptiveVisibility.png
index 6d330baa6..6c4a6e457 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/PreemptiveVisibility.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/PreemptiveVisibility.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedCell.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedCell.png
index 76947671d..ae78caf49 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedCell.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedCell.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedNumber.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedNumber.png
index 8862702f1..602f62702 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedNumber.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/contradictions/UnresolvedNumber.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/FixedMax.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/FixedMax.png
index 8a26bbfeb..86a4ee8a0 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/FixedMax.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/FixedMax.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastCell.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastCell.png
index 216a0f3a1..8db8a3bbf 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastCell.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastCell.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastNumber.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastNumber.png
index 1e0555648..dcf4cb2b8 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastNumber.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/LastNumber.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/NEdge.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/NEdge.png
index d3dd36bbc..b238b36aa 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/NEdge.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/NEdge.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/OneEdge.png b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/OneEdge.png
index 40d6ff65f..6841a8034 100644
Binary files a/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/OneEdge.png and b/src/main/resources/edu/rpi/legup/images/skyscrapers/rules/OneEdge.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/black.gif b/src/main/resources/edu/rpi/legup/images/starbattle/black.gif
deleted file mode 100644
index 13381a717..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/black.gif and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png
deleted file mode 100644
index 0383711bb..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png
deleted file mode 100644
index d25340b40..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png
deleted file mode 100644
index cc019752f..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png
deleted file mode 100644
index b468ae6f6..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/empty.gif b/src/main/resources/edu/rpi/legup/images/starbattle/empty.gif
deleted file mode 100644
index 38b91d0a2..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/empty.gif and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png
deleted file mode 100644
index f72fd7d7f..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png
deleted file mode 100644
index 1a88e9d07..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRowsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRowsDirectRule.png
deleted file mode 100644
index 24fb0d48a..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRowsDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png
deleted file mode 100644
index 11cfbf899..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png
deleted file mode 100644
index fde683dcd..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinRowsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinRowsDirectRule.png
deleted file mode 100644
index 30170df40..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinRowsDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png
deleted file mode 100644
index bac64a87c..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png
deleted file mode 100644
index 8907e0475..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/SurroundStar.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/SurroundStar.png
deleted file mode 100644
index 13287f779..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/rules/SurroundStar.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/star.gif b/src/main/resources/edu/rpi/legup/images/starbattle/star.gif
deleted file mode 100644
index e289b287a..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/star.gif and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/AdvancedDeduction.png b/src/main/resources/edu/rpi/legup/images/sudoku/AdvancedDeduction.png
deleted file mode 100644
index d51538baf..000000000
Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/AdvancedDeduction.png and /dev/null differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberColumn.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberColumn.png
new file mode 100644
index 000000000..9dcade64b
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberColumn.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRegion.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRegion.png
new file mode 100644
index 000000000..000dc8b68
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRegion.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRow.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRow.png
new file mode 100644
index 000000000..f984f8365
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRow.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/NoSolution.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoSolution.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/sudoku/NoSolution.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/rules/NoSolution.png
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/PossibleValues.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/PossibleValues.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/sudoku/PossibleValues.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/rules/PossibleValues.png
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/RepeatedNumber.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/RepeatedNumber.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/sudoku/RepeatedNumber.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/rules/RepeatedNumber.png
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/forcedByDeduction.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByDeduction.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/sudoku/forcedByDeduction.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByDeduction.png
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/forcedByElimination.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByElimination.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/sudoku/forcedByElimination.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByElimination.png
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/possible_cells_number.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/sudoku/possible_cells_number.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number.png
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_column.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_column.png
new file mode 100644
index 000000000..2ebdc5823
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_column.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_region.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_region.png
new file mode 100644
index 000000000..cc371e3e9
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_region.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_row.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_row.png
new file mode 100644
index 000000000..80476a428
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_row.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/tem.png b/src/main/resources/edu/rpi/legup/images/sudoku/rules/tem.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/sudoku/tem.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/rules/tem.png
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/white.gif b/src/main/resources/edu/rpi/legup/images/sudoku/tiles/NumberTile.png
similarity index 82%
rename from src/main/resources/edu/rpi/legup/images/starbattle/white.gif
rename to src/main/resources/edu/rpi/legup/images/sudoku/tiles/NumberTile.png
index fc2c683eb..5a8540d02 100644
Binary files a/src/main/resources/edu/rpi/legup/images/starbattle/white.gif and b/src/main/resources/edu/rpi/legup/images/sudoku/tiles/NumberTile.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/UnknownTile.png b/src/main/resources/edu/rpi/legup/images/sudoku/tiles/UnknownTile.png
similarity index 100%
rename from src/main/resources/edu/rpi/legup/images/starbattle/UnknownTile.png
rename to src/main/resources/edu/rpi/legup/images/sudoku/tiles/UnknownTile.png
diff --git a/src/main/resources/edu/rpi/legup/legup/config b/src/main/resources/edu/rpi/legup/legup/config
index 1ee9ed79c..e01767677 100644
--- a/src/main/resources/edu/rpi/legup/legup/config
+++ b/src/main/resources/edu/rpi/legup/legup/config
@@ -34,26 +34,22 @@
fileCreationDisabled="false"/>
-
+ fileCreationDisabled="false"/>
-
-
-
+
+
+
diff --git a/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java b/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java
index 9ba7fb9f3..32a440d13 100644
--- a/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java
+++ b/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java
@@ -78,34 +78,6 @@ public void FinishRoomCaseRule_FinishRoomCaseRuleBaseTest() throws InvalidFileFo
NurikabeCell cell2 = board.getCell(4, 2);
ArrayList cases2 = RULE.getCases(board, cell2);
- Assert.assertEquals(6, cases2.size()); // correctly stops generating possible cases after
- // more than 5 (the max) is found. Would have generated 8 cases
- // FinishRoomCaseRule finny = new FinishRoomCaseRule();
- // finny.checkRuleRaw();
- // "Invalid use of the case rule FinishRoom: This case rule must have 5 or less children."
-
- // getErrorString in auto case rule
- // should display "The selection can produce a max of 5 cases."
- // AutoCaseRuleCommand autoCaseRuleCommand = new AutoCaseRuleCommand(elementView, selection,
- // caseBoard.getCaseRule(), caseBoard, e);
-
- // NurikabeBoard caseyBoard = (NurikabeBoard) cases2.get(0);
- // NurikabeBoard caseyBoard2 = (NurikabeBoard) cases2.get(1);
- // NurikabeBoard caseyBoard3 = (NurikabeBoard) cases2.get(2);
- // NurikabeBoard caseyBoard4 = (NurikabeBoard) cases2.get(3);
- // NurikabeBoard caseyBoard5 = (NurikabeBoard) cases2.get(4);
- // NurikabeBoard caseyBoard6 = (NurikabeBoard) cases2.get(5);
- // NurikabeBoard caseyBoard7 = (NurikabeBoard) cases2.get(6);
- // NurikabeBoard caseyBoard8 = (NurikabeBoard) cases2.get(7);
- //
- // NurikabeType boardy1Type = caseyBoard.getCell(5,5).getType();
- // NurikabeType boardy2Type = caseyBoard2.getCell(6,6).getType();
- // NurikabeType boardy3Type = caseyBoard.getCell(5,5).getType();
- // NurikabeType boardy4Type = caseyBoard2.getCell(6,6).getType();
- // NurikabeType boardy5Type = caseyBoard.getCell(5,5).getType();
- // NurikabeType boardy6Type = caseyBoard2.getCell(6,6).getType();
- // NurikabeType boardy7Type = caseyBoard.getCell(5,5).getType();
- // NurikabeType boardy8Type = caseyBoard2.getCell(6,6).getType();
-
+ Assert.assertEquals(9, cases2.size());
}
}
diff --git a/src/test/java/puzzles/sudoku/rules/LastNumberForCellDirectRuleRegionTest.java b/src/test/java/puzzles/sudoku/rules/LastNumberForCellDirectRuleRegionTest.java
new file mode 100644
index 000000000..f27f38d8a
--- /dev/null
+++ b/src/test/java/puzzles/sudoku/rules/LastNumberForCellDirectRuleRegionTest.java
@@ -0,0 +1,100 @@
+package puzzles.sudoku.rules;
+
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.sudoku.Sudoku;
+import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
+import edu.rpi.legup.puzzle.sudoku.SudokuCell;
+import edu.rpi.legup.puzzle.sudoku.rules.LastNumberForCellDirectRule;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import legup.MockGameBoardFacade;
+import legup.TestUtilities;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class LastNumberForCellDirectRuleRegionTest {
+ private static final LastNumberForCellDirectRule RULE = new LastNumberForCellDirectRule();
+ private static Sudoku sudoku;
+
+ @BeforeClass
+ public static void setUp() {
+ MockGameBoardFacade.getInstance();
+ sudoku = new Sudoku();
+ }
+
+ @Test
+ public void LastNumberForCellDirectRule_FullRegionTest() throws InvalidFileFormatException {
+ // Import board and create transition
+ TestUtilities.importTestBoard(
+ "puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion", sudoku);
+ TreeNode rootNode = sudoku.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ // Loop all numbers at point
+ for (int i = 1; i < 10; i++) {
+ // Reset board
+ SudokuBoard board = (SudokuBoard) transition.getBoard();
+ // Set cell
+ SudokuCell cell1 = board.getCell(2, 5);
+ cell1.setData(i);
+ board.addModifiedData(cell1);
+
+ // Test the case
+ if (i == 9) {
+ Assert.assertNull(RULE.checkRuleAt(transition, cell1));
+ } else {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, cell1));
+ }
+ }
+
+ // Import Board and create transition
+ TestUtilities.importTestBoard(
+ "puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRow", sudoku);
+ rootNode = sudoku.getTree().getRootNode();
+ transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ // Loop all numbers at point
+ for (int i = 1; i < 10; i++) {
+ // Reset board
+ SudokuBoard board = (SudokuBoard) transition.getBoard();
+ // Set cell
+ SudokuCell cell = board.getCell(4, 4);
+ cell.setData(i);
+ board.addModifiedData(cell);
+
+ // Test the case
+ if (i == 5) {
+ Assert.assertNull(RULE.checkRuleAt(transition, cell));
+ } else {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, cell));
+ }
+ }
+
+ // Import Board and create transition
+ TestUtilities.importTestBoard(
+ "puzzles/sudoku/rules/LastNumberForCellDirectRule/FullMixed", sudoku);
+ rootNode = sudoku.getTree().getRootNode();
+ transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ // Loop all numbers at point
+ for (int i = 1; i < 10; i++) {
+ // Reset board
+ SudokuBoard board = (SudokuBoard) transition.getBoard();
+ // Set cell
+ SudokuCell cell = board.getCell(5, 3);
+ cell.setData(i);
+ board.addModifiedData(cell);
+
+ // Test the case
+ if (i == 2) {
+ Assert.assertNull(RULE.checkRuleAt(transition, cell));
+ } else {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, cell));
+ }
+ }
+ }
+}
diff --git a/src/test/java/puzzles/sudoku/rules/RepeatedNumberContradictionRuleTest.java b/src/test/java/puzzles/sudoku/rules/RepeatedNumberContradictionRuleTest.java
new file mode 100644
index 000000000..704167a29
--- /dev/null
+++ b/src/test/java/puzzles/sudoku/rules/RepeatedNumberContradictionRuleTest.java
@@ -0,0 +1,88 @@
+package puzzles.sudoku.rules;
+
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.sudoku.Sudoku;
+import edu.rpi.legup.puzzle.sudoku.SudokuBoard;
+import edu.rpi.legup.puzzle.sudoku.SudokuCell;
+import edu.rpi.legup.puzzle.sudoku.rules.RepeatedNumberContradictionRule;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import legup.MockGameBoardFacade;
+import legup.TestUtilities;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class RepeatedNumberContradictionRuleTest {
+ private static final RepeatedNumberContradictionRule RULE =
+ new RepeatedNumberContradictionRule();
+ private static Sudoku sudoku;
+
+ @BeforeClass
+ public static void setUp() {
+ MockGameBoardFacade.getInstance();
+ sudoku = new Sudoku();
+ }
+
+ @Test
+ public void RepeatedNumberContradictionRule_GlobalTest() throws InvalidFileFormatException {
+ // Import board and create transition
+ TestUtilities.importTestBoard(
+ "puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard7", sudoku);
+ TreeNode rootNode = sudoku.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ // Loop through every cell
+ for (int i = 0; i < 81; i++) {
+ // Reset board
+ SudokuBoard board = (SudokuBoard) transition.getBoard();
+ // Set cell
+ int x = i / 9;
+ int y = i % 9;
+ if (x == 0 && y == 0) {
+ continue;
+ }
+ SudokuCell cell = board.getCell(x, y);
+ cell.setData(7);
+
+ // Test the case
+ if (x == 0 || y == 0 || (x < 3 && y < 3)) {
+ Assert.assertNull(RULE.checkRuleAt(transition, cell));
+ } else {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, cell));
+ }
+ cell.setData(0);
+ }
+ // Import board and create transition
+ TestUtilities.importTestBoard(
+ "puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard4", sudoku);
+ rootNode = sudoku.getTree().getRootNode();
+ transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ // Loop through every cell
+ for (int i = 0; i < 81; i++) {
+ // Reset board
+ SudokuBoard board = (SudokuBoard) transition.getBoard();
+ // Set cell
+ int x = i / 9;
+ int y = i % 9;
+ if ((x == 3 && y == 0) || (x == 6 && y == 8)) {
+ continue;
+ }
+ SudokuCell cell = board.getCell(x, y);
+ cell.setData(4);
+
+ // Test the case
+ if ((x == 3 || y == 0 || x == 6 || y == 8)
+ || (x > 2 && x < 6 && y < 3)
+ || (x > 5 && y > 5)) {
+ Assert.assertNull(RULE.checkRuleAt(transition, cell));
+ } else {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, cell));
+ }
+ cell.setData(0);
+ }
+ }
+}
diff --git a/src/test/resources/puzzles/binary/rules/SurroundPairDirectRule/SurroundTwoZerosWithTwoOnes b/src/test/resources/puzzles/binary/rules/SurroundPairDirectRule/SurroundTwoZerosWithTwoOnes
new file mode 100644
index 000000000..026742fea
--- /dev/null
+++ b/src/test/resources/puzzles/binary/rules/SurroundPairDirectRule/SurroundTwoZerosWithTwoOnes
@@ -0,0 +1,10 @@
+
+
+
+
+ |
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/binary/rules/SurroundPairDirectRule/test b/src/test/resources/puzzles/binary/rules/SurroundPairDirectRule/test
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/puzzles/nurikabe/rules/BlackBetweenRegionsDirectRule/SurroundTwoZerosWithTwoOnes b/src/test/resources/puzzles/nurikabe/rules/BlackBetweenRegionsDirectRule/SurroundTwoZerosWithTwoOnes
new file mode 100644
index 000000000..026742fea
--- /dev/null
+++ b/src/test/resources/puzzles/nurikabe/rules/BlackBetweenRegionsDirectRule/SurroundTwoZerosWithTwoOnes
@@ -0,0 +1,10 @@
+
+
+
+
+ |
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout
deleted file mode 100644
index ddcc4dc9a..000000000
--- a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
\ No newline at end of file
diff --git a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout
deleted file mode 100644
index f2a5b42d9..000000000
--- a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
- | | | |
-
-
-
\ No newline at end of file
diff --git a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout
deleted file mode 100644
index f2a5b42d9..000000000
--- a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
-
- | | | |
-
-
-
-
-
-
- | | | |
-
-
-
\ No newline at end of file
diff --git a/src/test/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/CorneredRegion b/src/test/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/CorneredRegion
new file mode 100644
index 000000000..4d3c57225
--- /dev/null
+++ b/src/test/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/CorneredRegion
@@ -0,0 +1,14 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullMixed b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullMixed
new file mode 100644
index 000000000..55b501fec
--- /dev/null
+++ b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullMixed
@@ -0,0 +1,18 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion
new file mode 100644
index 000000000..58fd02162
--- /dev/null
+++ b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion
@@ -0,0 +1,18 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRow b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRow
new file mode 100644
index 000000000..07e502ed9
--- /dev/null
+++ b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRow
@@ -0,0 +1,18 @@
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
diff --git a/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard4 b/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard4
new file mode 100644
index 000000000..abaa0ba6b
--- /dev/null
+++ b/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard4
@@ -0,0 +1,12 @@
+
+
+
+
+
+ |
+ |
+
+
+
+
+
diff --git a/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard7 b/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard7
new file mode 100644
index 000000000..5692dea64
--- /dev/null
+++ b/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard7
@@ -0,0 +1,11 @@
+
+
+
+
+
+ |
+
+
+
+
+