diff --git a/.gitignore b/.gitignore index bafea84a3..baee37e51 100644 --- a/.gitignore +++ b/.gitignore @@ -92,5 +92,4 @@ gradle-app.setting gradle/wrapper/gradle-wrapper.properties # Visual Studio Code configs -.vscode/* -src/test/java/legup/TestRunner.java +.vscode/* \ No newline at end of file diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index ea640e792..000000000 --- a/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -arguments=--init-script /home/gamma/.cache/jdtls/config/org.eclipse.osgi/55/0/.cp/gradle/init/init.gradle -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) -connection.project.dir= -eclipse.preferences.version=1 -gradle.user.home= -java.home=/usr/lib/jvm/java-21-openjdk-amd64 -jvm.arguments= -offline.mode=false -override.workspace.settings=true -show.console.view=true -show.executions.view=true diff --git a/output_path/test/src/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/TestBoard b/output_path/test/src/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/TestBoard deleted file mode 100644 index a41ad749c..000000000 --- a/output_path/test/src/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/TestBoard +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/output_path/test/src/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion b/output_path/test/src/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion deleted file mode 100644 index 49dae4aa6..000000000 --- a/output_path/test/src/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/output_path/test/src/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/a b/output_path/test/src/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/a deleted file mode 100644 index e69de29bb..000000000 diff --git a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 1 b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 1 deleted file mode 100644 index 42ccf371b..000000000 --- a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 1 +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 2 b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 2 deleted file mode 100644 index d73caa5d2..000000000 --- a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 2 +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 3 b/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 3 deleted file mode 100644 index 99ec9769b..000000000 --- a/puzzles files/binary/10x10 Binary Hard/10x10 Binary Hard 3 +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 1 b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 1 deleted file mode 100644 index d203617c8..000000000 --- a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 1 +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 2 b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 2 deleted file mode 100644 index db56f04f3..000000000 --- a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 2 +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 3 b/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 3 deleted file mode 100644 index 11940a6eb..000000000 --- a/puzzles files/binary/10x10 Binary Medium/10x10 Binary Medium 3 +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index 828a450cf..000000000 --- a/puzzles files/binary/10x10 Binary Very Hard/10x10 Binary Very Hard 1 +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 1 b/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 1 deleted file mode 100644 index 7b22ffc10..000000000 --- a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 1 +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ 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 deleted file mode 100644 index ea8ef93b0..000000000 --- a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 2 +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ 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 deleted file mode 100644 index 0f0ff745e..000000000 --- a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 3 +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 deleted file mode 100644 index da76d067b..000000000 --- a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 4 +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 deleted file mode 100644 index a1ea13988..000000000 --- a/puzzles files/binary/6x6 Binary Easy/6x6 Binary Easy 5 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 1 b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 1 deleted file mode 100644 index 5f7f72a8a..000000000 --- a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 1 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 2 b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 2 deleted file mode 100644 index a4ed30c31..000000000 --- a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 2 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 3 b/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 3 deleted file mode 100644 index fc0e413c1..000000000 --- a/puzzles files/binary/6x6 Binary Hard/6x6 Binary Hard 3 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 1 b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 1 deleted file mode 100644 index a5ab8a2dc..000000000 --- a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 1 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 2 b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 2 deleted file mode 100644 index 4be5fdaad..000000000 --- a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 2 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 3 b/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 3 deleted file mode 100644 index eba370cab..000000000 --- a/puzzles files/binary/6x6 Binary Medium/6x6 Binary Medium 3 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index faa68fa5e..000000000 --- a/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 1 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index 3c707bdaa..000000000 --- a/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 2 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index 217a032d8..000000000 --- a/puzzles files/binary/6x6 Binary Very Hard/6x6 Binary Very Hard 3 +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 1 b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 1 deleted file mode 100644 index befd674f9..000000000 --- a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 1 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 2 b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 2 deleted file mode 100644 index 724426c26..000000000 --- a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 2 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 3 b/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 3 deleted file mode 100644 index 92a96c72b..000000000 --- a/puzzles files/binary/8x8 Binary Easy/8x8 Binary Easy 3 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 1 b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 1 deleted file mode 100644 index 34eaf8388..000000000 --- a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 1 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 2 b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 2 deleted file mode 100644 index 9ef23277e..000000000 --- a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 2 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 3 b/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 3 deleted file mode 100644 index 287ff6f68..000000000 --- a/puzzles files/binary/8x8 Binary Hard/8x8 Binary Hard 3 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 1 b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 1 deleted file mode 100644 index 47dae23dc..000000000 --- a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 1 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 2 b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 2 deleted file mode 100644 index ae4cb8bb0..000000000 --- a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 2 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 3 b/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 3 deleted file mode 100644 index 2f951ecc4..000000000 --- a/puzzles files/binary/8x8 Binary Medium/8x8 Binary Medium 3 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index 9c875523b..000000000 --- a/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 1 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index 14f2e4ad2..000000000 --- a/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 2 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index ad319a4b7..000000000 --- a/puzzles files/binary/8x8 Binary Very Hard/8x8 Binary Very Hard 3 +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/puzzles files/light-color-theme.txt b/puzzles files/light-color-theme.txt deleted file mode 100644 index 5c45bc71b..000000000 --- a/puzzles files/light-color-theme.txt +++ /dev/null @@ -1,99 +0,0 @@ -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 new file mode 100644 index 000000000..b86e16ff2 --- /dev/null +++ b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..110dd9abe --- /dev/null +++ b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal1.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..49efeba59 --- /dev/null +++ b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal2.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..855943612 --- /dev/null +++ b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..c1d7770f6 --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..cab0a0a5e --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..70b81e376 --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..c541ece06 --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..02dd5d6c0 --- /dev/null +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..0df84ef62 --- /dev/null +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..725c91d7f --- /dev/null +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 1016838c7..8a8e9665d 100644 --- a/src/main/java/edu/rpi/legup/app/Config.java +++ b/src/main/java/edu/rpi/legup/app/Config.java @@ -12,11 +12,6 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -/** - * The {@code Config} class manages the configuration for puzzles by loading configuration data - * from an XML file. It provides methods to access puzzle class names, display names, and their - * file creation statuses - */ public class Config { private static final Logger Logger = LogManager.getLogger(Config.class.getName()); @@ -79,13 +74,6 @@ public static String convertClassNameToDisplayName(String className) { return displayName; } - /** - * Converts the display name of the puzzle back to its corresponding class name. - * For example: convertDisplayNameToClassName("Tree Tent") returns "TreeTent" - * - * @param displayName the display name of the puzzle - * @return the class name of the puzzle as a String - */ public static String convertDisplayNameToClassName(String displayName) { String className = ""; for (int i = 0; i < displayName.length(); i++) { @@ -96,11 +84,6 @@ 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()) { @@ -109,12 +92,6 @@ public List getPuzzleNames() { return names; } - /** - * Returns a list of the display names of the puzzles that can have files created and edited within - * the proof editor - * - * @return a List of puzzle display names as Strings with file creation enabled - */ public List getFileCreationEnabledPuzzleNames() { List names = new LinkedList(); for (String puzzle : this.getFileCreationEnabledPuzzles()) { diff --git a/src/main/java/edu/rpi/legup/app/GameBoardFacade.java b/src/main/java/edu/rpi/legup/app/GameBoardFacade.java index 835041c3c..c928c1209 100644 --- a/src/main/java/edu/rpi/legup/app/GameBoardFacade.java +++ b/src/main/java/edu/rpi/legup/app/GameBoardFacade.java @@ -31,10 +31,6 @@ import org.w3c.dom.Node; import org.xml.sax.SAXException; -/** - * {@code GameBoardFacade} is a class designed to manage the game board operations within the application. - * It integrates various components such as UI elements, puzzle management, and history tracking - */ public class GameBoardFacade implements IHistorySubject { private static final Logger LOGGER = LogManager.getLogger(GameBoardFacade.class.getName()); @@ -76,9 +72,6 @@ public static synchronized GameBoardFacade getInstance() { return instance; } - /** - * Initializes the UI components - */ public void initializeUI() { EventQueue.invokeLater( () -> { @@ -90,29 +83,18 @@ 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); this.history.clear(); } - /** - * Clears the current puzzle - */ public void clearPuzzle() { this.puzzle = null; this.curFileName = null; this.history.clear(); } - /** - * Sets up the configuration by initializing the Config object - */ public static void setupConfig() { Config config = null; try { @@ -123,21 +105,11 @@ 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; } @@ -196,62 +168,53 @@ public boolean validateTextInput(String game, String[] statements) throws Runtim } /** - * Loads an empty puzzle with the specified dimensions + * Loads an empty puzzle * * @param game name of the puzzle * @param rows the number of rows on the board * @param columns the number of columns on the board */ public void loadPuzzle(String game, int rows, int columns) throws RuntimeException { - if (!game.equals("")) { - String qualifiedClassName = config.getPuzzleClassForName(game); - LOGGER.debug("Loading " + qualifiedClassName); + 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) { - LOGGER.error("Puzzle importer is null"); - throw new RuntimeException("Puzzle importer null"); - } + PuzzleImporter importer = puzzle.getImporter(); + if (importer == null) { + LOGGER.error("Puzzle importer is null"); + throw new RuntimeException("Puzzle importer null"); + } - // Theoretically, this exception should never be thrown, since LEGUP should not be - // allowing the user to give row/column input for a puzzle that doesn't support it - if (!importer.acceptsRowsAndColumnsInput()) { - throw new IllegalArgumentException( - puzzle.getName() + " does not accept rows and columns input"); - } + // Theoretically, this exception should never be thrown, since LEGUP should not be + // allowing the user to give row/column input for a puzzle that doesn't support it + if (!importer.acceptsRowsAndColumnsInput()) { + throw new IllegalArgumentException( + puzzle.getName() + " does not accept rows and columns input"); + } - setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle"); - importer.initializePuzzle(rows, columns); + setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle"); + importer.initializePuzzle(rows, columns); - puzzle.initializeView(); - // - // puzzle.getBoardView().onTreeElementChanged(puzzle.getTree().getRootNode()); - setPuzzleEditor(puzzle); - } catch (IllegalArgumentException exception) { - throw new IllegalArgumentException(exception.getMessage()); - } catch (ClassNotFoundException - | NoSuchMethodException - | InvocationTargetException - | IllegalAccessException - | InstantiationException e) { - LOGGER.error(e); - throw new RuntimeException("Puzzle creation error"); - } + puzzle.initializeView(); + // + // puzzle.getBoardView().onTreeElementChanged(puzzle.getTree().getRootNode()); + setPuzzleEditor(puzzle); + } catch (IllegalArgumentException exception) { + throw new IllegalArgumentException(exception.getMessage()); + } catch (ClassNotFoundException + | NoSuchMethodException + | InvocationTargetException + | IllegalAccessException + | InstantiationException e) { + LOGGER.error(e); + throw new RuntimeException("Puzzle creation error"); } - } - /** - * 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); @@ -294,10 +257,10 @@ public void loadPuzzle(String game, String[] statements) { } /** - * Loads a puzzle file from the specified file + * Loads a puzzle file * * @param fileName file name of the board file - * @throws InvalidFileFormatException if the file format is invalid or if the file cannot be created + * @throws InvalidFileFormatException if input is invalid */ public void loadPuzzle(String fileName) throws InvalidFileFormatException { try { @@ -310,12 +273,6 @@ public void loadPuzzle(String fileName) throws InvalidFileFormatException { } } - /** - * Loads a puzzle into the editor from the specified file name - * - * @param fileName the name of the file to load - * @throws InvalidFileFormatException if the file format is invalid or if the file cannot be created - */ public void loadPuzzleEditor(String fileName) throws InvalidFileFormatException { try { loadPuzzleEditor(new FileInputStream(fileName)); @@ -327,12 +284,6 @@ public void loadPuzzleEditor(String fileName) throws InvalidFileFormatException } } - /** - * Loads a puzzle into the editor from the specified input stream - * - * @param inputStream the input stream to load the puzzle from - * @throws InvalidFileFormatException if the input stream cannot be processed or the file format is invalid - */ public void loadPuzzleEditor(InputStream inputStream) throws InvalidFileFormatException { Document document; try { diff --git a/src/main/java/edu/rpi/legup/app/InvalidConfigException.java b/src/main/java/edu/rpi/legup/app/InvalidConfigException.java index c66b23ec2..a570e7d44 100644 --- a/src/main/java/edu/rpi/legup/app/InvalidConfigException.java +++ b/src/main/java/edu/rpi/legup/app/InvalidConfigException.java @@ -1,14 +1,6 @@ package edu.rpi.legup.app; -/** - * {@code InvalidConfigException} is a custom exception class for handling invalid configuration 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 03b8be8d9..12433d7e4 100644 --- a/src/main/java/edu/rpi/legup/app/LegupPreferences.java +++ b/src/main/java/edu/rpi/legup/app/LegupPreferences.java @@ -4,10 +4,6 @@ import java.util.Map; import java.util.prefs.Preferences; -/** - * {@code LegupPreferences} is a class responsible for managing user preferences within the application. - * It uses Java's Preferences API to store and retrieve preferences, and it provides methods for accessing and updating these preferences. - */ public class LegupPreferences { private static LegupPreferences instance; @@ -77,10 +73,9 @@ public class LegupPreferences { } /** - * Gets the legup preferences singleton instance - * This method ensures that only one instance of LegupPreferences exists + * Gets the legup preferences singleton instance. * - * @return the singleton instance of LegupPreferences + * @return legup preferences */ public static LegupPreferences getInstance() { if (instance == null) { @@ -89,40 +84,30 @@ public static LegupPreferences getInstance() { return instance; } - /** - * Private constructor to prevent instantiation from outside the class - * Use {@link #getInstance()} to access the singleton instance - */ + /** Private LegupPreferences Singleton Constructor */ private LegupPreferences() {} /** * Gets the user preference by the string key * * @param key key name of the preference - * @return value of the preference or {@code null} if the preference does not exist + * @return value of the preference */ public String getUserPref(String key) { return preferencesMap.get(key); } /** - * Sets the user preference for the specified key to the provided value + * Gets the user preference by the string key, value pair * - * @param key key to set for the preference - * @param value value to set for the preference + * @param key key name of the preference + * @param value value of 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; @@ -135,20 +120,10 @@ 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 47ef70e17..57ce107ac 100644 --- a/src/main/java/edu/rpi/legup/controller/Controller.java +++ b/src/main/java/edu/rpi/legup/controller/Controller.java @@ -5,10 +5,6 @@ import java.awt.event.*; import javax.swing.*; -/** - * {@code Controller} is an abstract class designed to handle various mouse events and provide control functionality for a {@code ScrollView}. - * It implements several mouse event interfaces to manage interactions such as panning and zooming within a {@code ScrollView} - */ public abstract class Controller implements MouseMotionListener, MouseListener, MouseWheelListener { protected ScrollView viewer; private int x, y; @@ -23,11 +19,6 @@ 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/CursorController.java b/src/main/java/edu/rpi/legup/controller/CursorController.java index 6a3ab018d..2706bd522 100644 --- a/src/main/java/edu/rpi/legup/controller/CursorController.java +++ b/src/main/java/edu/rpi/legup/controller/CursorController.java @@ -6,10 +6,6 @@ import java.util.Timer; import java.util.TimerTask; -/** - * {@code CursorController} provides functionality for managing the cursor appearance during actions that take a certain amount of time. - * It allows for the display of a busy cursor while an action is being processed and reverts to the default cursor afterward - */ public class CursorController { public static final Cursor BUSY_CURSOR = new Cursor(Cursor.WAIT_CURSOR); public static final Cursor DEFAULT_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR); diff --git a/src/main/java/edu/rpi/legup/controller/EditorElementController.java b/src/main/java/edu/rpi/legup/controller/EditorElementController.java index 040610137..5a23885af 100644 --- a/src/main/java/edu/rpi/legup/controller/EditorElementController.java +++ b/src/main/java/edu/rpi/legup/controller/EditorElementController.java @@ -9,10 +9,6 @@ import java.awt.event.ActionListener; import javax.swing.*; -/** - * {@code EditorElementController} manages actions related to UI elements within the puzzle editor environment. - * It handles button presses, updates element selection, and manages visual states of buttons - */ public class EditorElementController implements ActionListener { protected Object lastSource; protected ElementController elementController; @@ -24,33 +20,19 @@ 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 436b078b9..5840650e1 100644 --- a/src/main/java/edu/rpi/legup/controller/ElementController.java +++ b/src/main/java/edu/rpi/legup/controller/ElementController.java @@ -26,17 +26,13 @@ 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 handle ui events associated interacting with a + * ElementController Constructor controller to handles ui events associated interacting with a * {@link BoardView} */ public ElementController() { @@ -90,7 +86,6 @@ 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; @@ -142,8 +137,17 @@ 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/controller/RuleController.java b/src/main/java/edu/rpi/legup/controller/RuleController.java index 491e02f74..6e88dc4be 100644 --- a/src/main/java/edu/rpi/legup/controller/RuleController.java +++ b/src/main/java/edu/rpi/legup/controller/RuleController.java @@ -16,11 +16,6 @@ import java.awt.event.ActionListener; import java.util.List; -/** - * The RuleController class is responsible for handling UI events related to rule buttons - * in the RulePanel of the Legup application. It implements ActionListener to process action - * events triggered by rule buttons and applies rules to the puzzle accordingly - */ public class RuleController implements ActionListener { protected Object lastSource; diff --git a/src/main/java/edu/rpi/legup/controller/TreeController.java b/src/main/java/edu/rpi/legup/controller/TreeController.java index 2b12268ac..80fdee1af 100644 --- a/src/main/java/edu/rpi/legup/controller/TreeController.java +++ b/src/main/java/edu/rpi/legup/controller/TreeController.java @@ -11,10 +11,6 @@ import java.awt.event.MouseWheelEvent; import javax.swing.*; -/** - * The TreeController class handles UI events from a TreePanel. - * It extends the Controller class to provide specific behavior for tree interactions - */ public class TreeController extends Controller { /** * TreeController Constructor creates a controller object to listen to ui events from a {@link diff --git a/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java b/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java index 92a887f71..12b39cd85 100644 --- a/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java +++ b/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java @@ -10,11 +10,6 @@ import java.util.List; import java.util.Map; - -/** - * The AddTreeElementCommand class represents a command to add tree elements to the proof tree. - * It extends the PuzzleCommand class to handle the addition of tree elements and undo operation. - */ public class AddTreeElementCommand extends PuzzleCommand { private TreeViewSelection selection; @@ -32,10 +27,7 @@ public AddTreeElementCommand(TreeViewSelection selection) { this.addChild = new HashMap<>(); } - /** - * Executes the command to add selected tree elements to the tree. - * Updates the puzzle and tree view accordingly - */ + /** Executes an command */ @Override public void executeCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); @@ -103,10 +95,7 @@ public String getErrorString() { return null; } - /** - * Undoes the command by removing the added tree elements. - * Updates the puzzle and tree view accordingly - */ + /** Undoes an command */ @Override public void undoCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); diff --git a/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java b/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java index ad89ab636..02dffae44 100644 --- a/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java +++ b/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java @@ -10,11 +10,6 @@ import java.util.List; import java.util.Map; -/** - * The ApplyDefaultDirectRuleCommand class represents a command to apply a default direct rule - * to selected tree nodes in the proof tree. - * It extends the PuzzleCommand class to handle rule application and undo operation. - */ public class ApplyDefaultDirectRuleCommand extends PuzzleCommand { private TreeViewSelection selection; @@ -74,10 +69,7 @@ public String getErrorString() { return null; } - /** - * Executes the command to apply the default rule to the selected tree nodes. - * Updates the puzzle and tree view accordingly. - */ + /** Executes an command */ @Override public void executeCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); @@ -117,10 +109,7 @@ public void executeCommand() { puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection)); } - /** - * Undoes the command by removing the applied default rule from the tree nodes. - * Updates the puzzle and tree view accordingly. - */ + /** Undoes an command */ @Override public void undoCommand() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); diff --git a/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java b/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java index b86cda6ea..97192e145 100644 --- a/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java +++ b/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java @@ -13,11 +13,6 @@ import java.awt.event.MouseEvent; import java.util.*; -/** - * The AutoCaseRuleCommand class represents a command to automatically apply a case rule to a - * selected tree node in the proof tree. - * It extends the PuzzleCommand class to handle case rule application and undo operation. - */ public class AutoCaseRuleCommand extends PuzzleCommand { private ElementView elementView; @@ -51,10 +46,7 @@ public AutoCaseRuleCommand( this.caseTrans = new ArrayList<>(); } - /** - * Executes the command to apply the case rule to the selected tree node. - * Updates the puzzle and tree view accordingly. - */ + /** Executes an command */ @Override public void executeCommand() { Tree tree = getInstance().getTree(); @@ -64,10 +56,11 @@ public void executeCommand() { TreeNode node = (TreeNode) selection.getFirstSelection().getTreeElement(); if (caseTrans.isEmpty()) { - List cases = caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()); + List cases = + caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()); for (Board board : cases) { final TreeTransition transition = (TreeTransition) tree.addTreeElement(node); - //board.setModifiable(false); + board.setModifiable(false); transition.setBoard(board); transition.setRule(caseRule); transition.setSelection(elementView.getPuzzleElement().copy()); @@ -118,11 +111,13 @@ public String getErrorString() { return "The selected data element is not pickable with this case rule."; } - if (caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()).size() == 0) { + if (caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()).size() + == 0) { return "The selection must produce at least one case"; } - int numberOfCaseRules = caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()).size(); + int numberOfCaseRules = + caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()).size(); System.out.println("Number of cases:" + numberOfCaseRules); if (numberOfCaseRules > caseRule.MAX_CASES) { return "The selection can produce a max of " + caseRule.MAX_CASES + " cases"; @@ -134,10 +129,7 @@ public String getErrorString() { return null; } - /** - * Undoes the command by removing the applied case rules from the tree node. - * Updates the puzzle and tree view accordingly - */ + /** Undoes an command */ @Override public void undoCommand() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); diff --git a/src/main/java/edu/rpi/legup/history/CommandError.java b/src/main/java/edu/rpi/legup/history/CommandError.java index 26959cccd..35b7bb15b 100644 --- a/src/main/java/edu/rpi/legup/history/CommandError.java +++ b/src/main/java/edu/rpi/legup/history/CommandError.java @@ -1,16 +1,10 @@ package edu.rpi.legup.history; -/** - * The CommandError enum represents various error conditions that can occur when executing or - * validating commands related to tree elements in the proof tree. - * Each error condition is associated with a descriptive message. - */ public enum CommandError { NO_SELECTED_VIEWS("The selection does not have any tree elements."), ONE_SELECTED_VIEW("The selection must have exactly one tree element."), UNMODIFIABLE_BOARD("The selection contains a board which is not modifiable."), UNMODIFIABLE_DATA("The selection contains a board where the data element is not modifiable."), - UNMODIFIABLE_DATA_CASE_RULE("The proof tree contains a future case rule, causing previous transitions to become unmodifiable."), CONTAINS_ROOT("The selection contains the root tree node."), ONE_CHILD("The selection contains a tree node that does not have exactly one child."), ADD_WITH_CHILD("The selection contains a tree transition that already has a child tree node."), @@ -24,20 +18,10 @@ 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 326490e28..f47c0405d 100644 --- a/src/main/java/edu/rpi/legup/history/CommandState.java +++ b/src/main/java/edu/rpi/legup/history/CommandState.java @@ -1,9 +1,5 @@ package edu.rpi.legup.history; -/** - * The CommandState enum represents the various states that a command can be in during its lifecycle. - * Each state is associated with a descriptive name. - */ public enum CommandState { CREATED("Created"), EXECUTED("Executed"), @@ -12,20 +8,10 @@ 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 e82197898..0469685c1 100644 --- a/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java +++ b/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java @@ -7,11 +7,6 @@ import edu.rpi.legup.ui.proofeditorui.treeview.*; import java.util.List; -/** - * The DeleteTreeElementCommand class represents a command to delete tree elements from a proof tree. - * It extends PuzzleCommand and implements the functionality to remove selected tree elements and - * handle undo operations. - */ public class DeleteTreeElementCommand extends PuzzleCommand { private TreeViewSelection selection; @@ -25,41 +20,35 @@ public DeleteTreeElementCommand(TreeViewSelection selection) { this.selection = selection.copy(); } - /** - * Executes the delete command, removing the selected tree elements from the tree. - */ + /** Executes an command */ @Override public void executeCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); List selectedViews = selection.getSelectedViews(); - if (selectedViews.isEmpty()) { - return; - } TreeElementView firstSelectedView = selectedViews.get(0); TreeElementView newSelectedView; if (firstSelectedView.getType() == TreeElementType.NODE) { - //System.out.println("FIRST SELECTION NODE, total selection views: " + selectedViews.size()); TreeNodeView nodeView = (TreeNodeView) firstSelectedView; newSelectedView = nodeView.getParentView(); } else { - //System.out.println("FIRST SELECTION TRANS, total selection views: " + selectedViews.size()); TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView; newSelectedView = transitionView.getParentViews().get(0); } for (TreeElementView selectedView : selectedViews) { - System.out.println("DELETED"); TreeElement element = selectedView.getTreeElement(); tree.removeTreeElement(element); puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(element)); } final TreeViewSelection newSelection = new TreeViewSelection(newSelectedView); - puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(newSelectedView.getTreeElement())); - puzzle.notifyTreeListeners((ITreeListener listener) -> listener.onTreeSelectionChanged(newSelection)); + puzzle.notifyBoardListeners( + listener -> listener.onTreeElementChanged(newSelectedView.getTreeElement())); + puzzle.notifyTreeListeners( + (ITreeListener listener) -> listener.onTreeSelectionChanged(newSelection)); } /** @@ -84,9 +73,7 @@ public String getErrorString() { return null; } - /** - * Undoes the delete command, re-adding the previously deleted tree elements. - */ + /** Undoes an command */ @Override public void undoCommand() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); diff --git a/src/main/java/edu/rpi/legup/history/EditDataCommand.java b/src/main/java/edu/rpi/legup/history/EditDataCommand.java index a629aa085..d65f03d66 100644 --- a/src/main/java/edu/rpi/legup/history/EditDataCommand.java +++ b/src/main/java/edu/rpi/legup/history/EditDataCommand.java @@ -9,19 +9,10 @@ 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 javax.swing.*; -import java.awt.*; import java.awt.event.MouseEvent; import java.util.List; -/** - * The EditDataCommand class represents a command to edit the data of a puzzle element within - * a tree transition. It extends PuzzleCommand and provides functionality to execute and undo - * changes made to puzzle elements. - */ public class EditDataCommand extends PuzzleCommand { private TreeTransition transition; private PuzzleElement savePuzzleElement; @@ -35,7 +26,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 are being edited + * @param selection currently selected tree puzzleElement views that is being edited * @param event mouse event */ public EditDataCommand(ElementView elementView, TreeViewSelection selection, MouseEvent event) { @@ -47,9 +38,7 @@ public EditDataCommand(ElementView elementView, TreeViewSelection selection, Mou this.transition = null; } - /** - * Executes the edit data command, modifying the puzzle element and propagating changes - */ + /** Executes a command */ @SuppressWarnings("unchecked") @Override public void executeCommand() { @@ -65,13 +54,16 @@ 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 { @@ -81,6 +73,7 @@ public void executeCommand() { } Board prevBoard = transition.getParents().get(0).getBoard(); + boardView.getElementController().changeCell(event, puzzleElement); if (prevBoard.getPuzzleElement(selectedPuzzleElement).equalsData(puzzleElement)) { @@ -109,54 +102,35 @@ 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()) { - flashTreeViewRed(); - return CommandError.UNMODIFIABLE_DATA.toString(); + } else { + if (!board.getPuzzleElement(selectedPuzzleElement).isModifiable()) { + 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(); } } } return null; } - /** - * Causes the TreeView background to flash red for a short duration when an error occurs. - */ - private void flashTreeViewRed() { - TreeView treeView = getInstance().getLegupUI().getTreePanel().getTreeView(); - Color originalColor = treeView.getBackground(); - treeView.setBackground(MaterialColors.RED_700); - Timer timer = new Timer(400, e -> treeView.setBackground(originalColor)); - timer.setRepeats(false); - timer.start(); - } - - /** - * Undoes the edit data command, restoring the previous state of the puzzle element. - */ + /** Undoes an command */ @SuppressWarnings("unchecked") @Override public void undoCommand() { diff --git a/src/main/java/edu/rpi/legup/history/History.java b/src/main/java/edu/rpi/legup/history/History.java index b244e8f88..371284f8c 100644 --- a/src/main/java/edu/rpi/legup/history/History.java +++ b/src/main/java/edu/rpi/legup/history/History.java @@ -6,10 +6,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * The History class manages a stack of commands for undo and redo operations on the board and tree structure. - * It maintains a list of commands and a current index to track the position in the history stack. - */ public class History { private static final Logger LOGGER = LogManager.getLogger(History.class.getName()); @@ -18,8 +14,9 @@ public class History { private int curIndex; /** - * Constructs a History object to keep track of changes and allow undo and redo operations. - * The history is implemented as a stack, with curIndex pointing to the top of the stack. + * History Constructor this holds information about changes to the board and Tree structure for + * undoing and redoing operations. Though history is an List, it is implemented like a stack. + * The curIndex points to the top of the stack (where the last change was made). */ public History() { history = new ArrayList<>(); @@ -47,18 +44,13 @@ public void pushChange(ICommand command) { } } - /** - * Undoes the last action by calling the undo method of the command at the current index. - * Updates the current index and notifies listeners. - */ + /** Undoes an action */ public void undo() { synchronized (lock) { if (curIndex > -1) { ICommand command = history.get(curIndex--); command.undo(); LOGGER.info("Undoed " + command.getClass().getSimpleName()); - - GameBoardFacade.getInstance() .notifyHistoryListeners( l -> l.onUndo(curIndex < 0, curIndex == history.size() - 1)); @@ -66,10 +58,7 @@ public void undo() { } } - /** - * Redoes the next action by calling the redo method of the command at the current index. - * Updates the current index and notifies listeners. - */ + /** Redoes an action */ public void redo() { synchronized (lock) { if (curIndex < history.size() - 1) { @@ -83,9 +72,7 @@ public void redo() { } } - /** - * Clears all actions from the history stack and resets the current index - */ + /** Clears all actions from the history stack */ public void clear() { history.clear(); curIndex = -1; diff --git a/src/main/java/edu/rpi/legup/history/ICommand.java b/src/main/java/edu/rpi/legup/history/ICommand.java index 4f867dbab..913d9daaf 100644 --- a/src/main/java/edu/rpi/legup/history/ICommand.java +++ b/src/main/java/edu/rpi/legup/history/ICommand.java @@ -1,13 +1,7 @@ package edu.rpi.legup.history; -/** - * The ICommand interface defines the structure for command objects in a command pattern. - * It provides methods to execute, undo, redo commands, and to check if a command can be executed. - */ public interface ICommand { - /** - * Executes the command. The specific behavior depends on the implementation - */ + /** Executes a command */ void execute(); /** @@ -25,13 +19,9 @@ public interface ICommand { */ String getError(); - /** - * Undoes the command. Reverts the changes made by the execute method - */ + /** Undoes a command */ void undo(); - /** - * Redoes the command. Re-applies the changes made by the execute method after undoing - */ + /** Redoes a command */ void redo(); } diff --git a/src/main/java/edu/rpi/legup/history/IHistoryListener.java b/src/main/java/edu/rpi/legup/history/IHistoryListener.java index 48690168d..f464941d6 100644 --- a/src/main/java/edu/rpi/legup/history/IHistoryListener.java +++ b/src/main/java/edu/rpi/legup/history/IHistoryListener.java @@ -1,21 +1,15 @@ package edu.rpi.legup.history; -/** - * The IHistoryListener interface defines methods for listening to changes in the history of commands. - * Implementations of this interface can respond to events related to command history such as pushing, - * undoing, redoing commands, and clearing the history. - */ public interface IHistoryListener { - /** - * Called when a command is pushed onto the history stack. + * Called when a action is pushed onto the edu.rpi.legup.history stack * - * @param command the command that was pushed onto the stack + * @param command action to push onto the stack */ void onPushChange(ICommand command); /** - * Called when a command is undone. + * Called when an action 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 @@ -23,15 +17,13 @@ public interface IHistoryListener { void onUndo(boolean isBottom, boolean isTop); /** - * Called when a command is redone. + * Called when an action 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 */ void onRedo(boolean isBottom, boolean isTop); - /** - * Called when the history stack is cleared. - */ + /** Called when the edu.rpi.legup.history is cleared */ void onClearHistory(); } diff --git a/src/main/java/edu/rpi/legup/history/IHistorySubject.java b/src/main/java/edu/rpi/legup/history/IHistorySubject.java index 431adbb93..78fefff00 100644 --- a/src/main/java/edu/rpi/legup/history/IHistorySubject.java +++ b/src/main/java/edu/rpi/legup/history/IHistorySubject.java @@ -2,31 +2,25 @@ import java.util.function.Consumer; -/** - * The IHistorySubject interface defines methods for managing and notifying listeners - * about changes in the command history. Implementations of this interface can add, remove, - * and notify history listeners. - */ public interface IHistorySubject { - /** - * Adds a history listener to receive updates about changes in the command history. + * Adds a history listener * - * @param listener the listener to add + * @param listener listener to add */ void addHistoryListener(IHistoryListener listener); /** - * Removes a history listener, so it no longer receives updates about changes in the command history. + * Removes a history listener * - * @param listener the listener to remove + * @param listener listener to remove */ void removeHistoryListener(IHistoryListener listener); /** - * Notifies all registered listeners about a change in the command history. + * Notifies listeners * - * @param algorithm a Consumer function that takes an IHistoryListener and performs some action with it + * @param algorithm algorithm to notify the listeners with */ void notifyHistoryListeners(Consumer algorithm); } diff --git a/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java b/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java index 201babb9e..71d072328 100644 --- a/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java +++ b/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java @@ -1,18 +1,7 @@ package edu.rpi.legup.history; -/** - * The InvalidCommandStateTransition exception is thrown when an invalid state transition - * is attempted on a PuzzleCommand - */ 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/MergeCommand.java b/src/main/java/edu/rpi/legup/history/MergeCommand.java index c2851bced..f234a0884 100644 --- a/src/main/java/edu/rpi/legup/history/MergeCommand.java +++ b/src/main/java/edu/rpi/legup/history/MergeCommand.java @@ -10,10 +10,6 @@ import java.util.List; import java.util.Set; -/** - * The MergeCommand class represents a command to merge selected tree nodes into a single node - * and create a transition to represent the merge - */ public class MergeCommand extends PuzzleCommand { private TreeViewSelection selection; private TreeTransition transition; @@ -28,9 +24,7 @@ public MergeCommand(TreeViewSelection selection) { this.transition = null; } - /** - * Executes the merge command - */ + /** Executes an command */ @Override public void executeCommand() { List selectedViews = selection.getSelectedViews(); @@ -77,9 +71,7 @@ public void executeCommand() { puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection)); } - /** - * Undoes the merge command - */ + /** Undoes an command */ @Override public void undoCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); diff --git a/src/main/java/edu/rpi/legup/history/PuzzleCommand.java b/src/main/java/edu/rpi/legup/history/PuzzleCommand.java index d4385b3e8..3768e3cbd 100644 --- a/src/main/java/edu/rpi/legup/history/PuzzleCommand.java +++ b/src/main/java/edu/rpi/legup/history/PuzzleCommand.java @@ -1,27 +1,18 @@ package edu.rpi.legup.history; -/** - * The PuzzleCommand class is an abstract base class for commands that can be executed, undone, and redone - * within the puzzle model. It implements the ICommand interface and maintains the state and error handling - * for the command. - */ public abstract class PuzzleCommand implements ICommand { private CommandState state; private boolean isCached; private String cachedError; - /** - * Puzzle Command Constructor for creating an undoable and redoable change to the model - */ + /** Puzzle Command Constructor for creating an undoable and redoable change to the model. */ protected PuzzleCommand() { this.state = CommandState.CREATED; this.isCached = false; this.cachedError = null; } - /** - * Executes the command if it can be executed - */ + /** Executes an command */ @Override public final void execute() { if (canExecute()) { @@ -30,9 +21,7 @@ public final void execute() { } } - /** - * Determines whether the command can be executed by checking the error state - */ + /** Determines whether this command can be executed */ @Override public final boolean canExecute() { cachedError = getError(); @@ -63,21 +52,13 @@ public final String getError() { */ public abstract String getErrorString(); - /** - * Executes the command. - * This method must be implemented by subclasses to define the command's execution behavior. - */ + /** Executes an command */ public abstract void executeCommand(); - /** - * Undoes the command. - * This method must be implemented by subclasses to define the command's undo behavior. - */ + /** Undoes an command */ public abstract void undoCommand(); - /** - * Redoes the command. This method is called if the command was previously undone. - */ + /** Redoes an command */ public void redoCommand() { if (state == CommandState.UNDOED) { executeCommand(); @@ -87,9 +68,7 @@ public void redoCommand() { } } - /** - * Undoes the command if it was executed or redone - */ + /** Undoes an command */ @Override public final void undo() { if (state == CommandState.EXECUTED || state == CommandState.REDOED) { @@ -100,9 +79,7 @@ public final void undo() { } } - /** - * Redoes the command if it was previously undone. - */ + /** Redoes an command */ public final void redo() { if (state == CommandState.UNDOED) { redoCommand(); diff --git a/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java b/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java index 6827436e8..7737ecfd3 100644 --- a/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java +++ b/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java @@ -12,10 +12,6 @@ import java.util.List; import java.util.Map; -/** - * The ValidateCaseRuleCommand class represents a command for validating a CaseRule in the tree structure. - * It extends the PuzzleCommand class and implements the ICommand interface. - */ public class ValidateCaseRuleCommand extends PuzzleCommand { private TreeViewSelection selection; @@ -37,9 +33,7 @@ public ValidateCaseRuleCommand(TreeViewSelection selection, CaseRule caseRule) { this.addNode = new HashMap<>(); } - /** - * Executes the command to validate the CaseRule - */ + /** Executes an command */ @Override public void executeCommand() { Tree tree = getInstance().getTree(); @@ -111,10 +105,7 @@ public String getErrorString() { return null; } - - /** - * Undoes the validation command, restoring the previous state - */ + /** Undoes an command */ @Override public void undoCommand() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); diff --git a/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java b/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java index b106a6072..8737b4008 100644 --- a/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java +++ b/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java @@ -10,10 +10,6 @@ import java.util.List; import java.util.Map; -/** - * The ValidateContradictionRuleCommand class represents a command for validating and applying a ContradictionRule - * within a tree structure. It extends the PuzzleCommand class and implements the ICommand interface. - */ public class ValidateContradictionRuleCommand extends PuzzleCommand { private TreeViewSelection selection; @@ -35,9 +31,7 @@ public ValidateContradictionRuleCommand(TreeViewSelection selection, Contradicti this.addTran = new HashMap<>(); } - /** - * Executes the command to validate and apply the ContradictionRule. - */ + /** Executes a command */ @Override public void executeCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); @@ -90,12 +84,7 @@ public void executeCommand() { final TreeElement finalTreeElement; if (firstSelectedView.getType() == TreeElementType.NODE) { TreeNodeView nodeView = (TreeNodeView) firstSelectedView; - if (!nodeView.getChildrenViews().isEmpty()) { - finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement(); - } - else { - finalTreeElement = null; - } + finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement(); } else { TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView; if (transitionView.getChildView() != null) { @@ -136,9 +125,7 @@ public String getErrorString() { return null; } - /** - * Undoes the validation command, restoring the previous state. - */ + /** Undoes a command */ @Override public void undoCommand() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); diff --git a/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java b/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java index f7694cc0a..d9c063464 100644 --- a/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java +++ b/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java @@ -6,19 +6,11 @@ import edu.rpi.legup.model.rules.Rule; import edu.rpi.legup.model.tree.*; import edu.rpi.legup.ui.proofeditorui.treeview.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import java.util.HashMap; import java.util.List; import java.util.Map; -/** - * The ValidateDirectRuleCommand class represents a command for validating and applying a DirectRule - * to a set of selected tree elements. It extends the PuzzleCommand class and implements the ICommand interface. - */ public class ValidateDirectRuleCommand extends PuzzleCommand { - private static final Logger LOGGER = LogManager.getLogger(History.class.getName()); private TreeViewSelection selection; private Map oldRules; @@ -38,9 +30,7 @@ public ValidateDirectRuleCommand(TreeViewSelection selection, DirectRule rule) { this.addNode = new HashMap<>(); } - /** - * Executes the command to validate and apply the DirectRule. - */ + /** Executes an command */ @Override public void executeCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); @@ -52,15 +42,14 @@ 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(); + oldRules.put(transition, transition.getRule()); transition.setRule(newRule); @@ -77,46 +66,21 @@ public void executeCommand() { final TreeNode finalNode = childNode; puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(finalNode)); } - - TreeElementView childView = treeView.getElementView(childNode); - if (childView == null) { - LOGGER.error("Child view is null for child node: " + childNode); - continue; - } - newSelection.addToSelection(childView); + newSelection.addToSelection(treeView.getElementView(childNode)); } - 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)); } - /** * Gets the reason why the command cannot be executed * @@ -146,9 +110,7 @@ public String getErrorString() { return null; } - /** - * Undoes the validation command, restoring the previous state. - */ + /** Undoes an command */ @Override public void undoCommand() { Tree tree = GameBoardFacade.getInstance().getTree(); @@ -162,10 +124,8 @@ public void undoCommand() { transitionView = nodeView.getChildrenViews().get(0); } else { 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 6cc92f347..7971c95af 100644 --- a/src/main/java/edu/rpi/legup/model/Puzzle.java +++ b/src/main/java/edu/rpi/legup/model/Puzzle.java @@ -35,11 +35,6 @@ import org.w3c.dom.Node; import org.xml.sax.SAXException; -/** - * Abstract class representing a puzzle. - * The Puzzle class manages the core components of a puzzle game, including the board, rules, and elements. - * It also handles importing and exporting puzzle configurations and notifies listeners about changes. - */ public abstract class Puzzle implements IBoardSubject, ITreeSubject { private static final Logger LOGGER = LogManager.getLogger(Puzzle.class.getName()); @@ -58,6 +53,7 @@ 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() { @@ -69,15 +65,12 @@ public Puzzle() { this.caseRules = new ArrayList<>(); this.placeableElements = new ArrayList<>(); + this.nonPlaceableElements = new ArrayList<>(); registerRules(); registerPuzzleElements(); } - /** - * Registers puzzle elements from the package of the derived class. - * Scans for classes annotated with {@link RegisterElement} and initializes them. - */ private void registerPuzzleElements() { String packageName = this.getClass().getPackage().toString().replace("package ", ""); @@ -86,10 +79,6 @@ private void registerPuzzleElements() { for (Class c : possElements) { - String classPackageName = c.getPackage().getName(); - if (!classPackageName.startsWith("edu.rpi.legup.puzzle.") || !classPackageName.endsWith(".elements")) { - continue; - } System.out.println("possible element: " + c.getName()); // check that the element is not abstract @@ -106,6 +95,9 @@ private void registerPuzzleElements() { case PLACEABLE: this.addPlaceableElement((PlaceableElement) element); break; + case NONPLACEABLE: + this.addNonPlaceableElement((NonPlaceableElement) element); + break; default: break; } @@ -116,15 +108,19 @@ 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); } } - /** - * Registers rules from the package of the derived class. - * Scans for classes annotated with {@link RegisterRule} and initializes them. - */ private void registerRules() { String packageName = this.getClass().getPackage().toString().replace("package ", ""); @@ -133,10 +129,6 @@ private void registerRules() { for (Class c : possRules) { - String classPackageName = c.getPackage().getName(); - if (!classPackageName.startsWith("edu.rpi.legup.puzzle.") || !classPackageName.endsWith(".rules")) { - continue; - } System.out.println("possible rule: " + c.getName()); // check that the rule is not abstract @@ -171,14 +163,20 @@ 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); } } - /** - * Initializes the view. Called by the invoker of the class - */ + /** Initializes the view. Called by the invoker of the class */ public abstract void initializeView(); /** @@ -201,10 +199,10 @@ public boolean isValidDimensions(int rows, int columns) { } /** - * Checks if the provided text input is valid for the puzzle. + * Checks if the given array of statements is valid text input for the given puzzle * - * @param statements array of statements to check - * @return true if input is valid, false otherwise + * @param statements + * @return */ public boolean isValidTextInput(String[] statements) { return statements.length > 0; @@ -336,15 +334,14 @@ 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 * @@ -363,15 +360,14 @@ 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 * @@ -584,10 +580,9 @@ 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. + * Adds a board listener * - * @param listener The IBoardListener to be added to the list of listeners. + * @param listener listener to add */ @Override public void addBoardListener(IBoardListener listener) { @@ -595,10 +590,9 @@ 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. + * Removes a board listener * - * @param listener The IBoardListener to be removed from the list of listeners. + * @param listener listener to remove */ @Override public void removeBoardListener(IBoardListener listener) { @@ -606,10 +600,9 @@ public void removeBoardListener(IBoardListener listener) { } /** - * Notifies all registered board listeners about changes. - * The provided algorithm is applied to each listener to process the notification. + * Notifies listeners * - * @param algorithm A Consumer function that takes an IBoardListener and performs operations to notify the listener. + * @param algorithm algorithm to notify the listeners with */ @Override public void notifyBoardListeners(Consumer algorithm) { @@ -617,10 +610,9 @@ public void notifyBoardListeners(Consumer algorithm) { } /** - * Adds a tree listener to the list of listeners. - * This allows the puzzle to notify the listener about changes to the tree. + * Adds a board listener * - * @param listener The ITreeListener to be added to the list of listeners. + * @param listener listener to add */ @Override public void addTreeListener(ITreeListener listener) { @@ -628,10 +620,9 @@ 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. + * Removes a tree listener * - * @param listener The ITreeListener to be removed from the list of listeners. + * @param listener listener to remove */ @Override public void removeTreeListener(ITreeListener listener) { @@ -639,10 +630,9 @@ public void removeTreeListener(ITreeListener listener) { } /** - * Notifies all registered tree listeners about changes. - * The provided algorithm is applied to each listener to process the notification. + * Notifies listeners * - * @param algorithm A Consumer function that takes an ITreeListener and performs operations to notify the listener. + * @param algorithm algorithm to notify the listeners with */ @Override public void notifyTreeListeners(Consumer algorithm) { @@ -650,10 +640,9 @@ public void notifyTreeListeners(Consumer algorithm) { } /** - * Checks if the puzzle is valid. - * The implementation of this method can vary based on the specific criteria for puzzle validity. + * Check if the puzzle is valid * - * @return true if the puzzle is valid, false otherwise. + * @return if the puzzle is valid */ public boolean checkValidity() { return true; diff --git a/src/main/java/edu/rpi/legup/model/PuzzleExporter.java b/src/main/java/edu/rpi/legup/model/PuzzleExporter.java index 234d0f25c..a052a736a 100644 --- a/src/main/java/edu/rpi/legup/model/PuzzleExporter.java +++ b/src/main/java/edu/rpi/legup/model/PuzzleExporter.java @@ -20,11 +20,6 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; -/** - * Abstract class for exporting puzzle data to XML format. - * This class provides functionality to export a puzzle object, including its board and tree structure, to an XML file. - * Subclasses must implement methods to create specific elements for the board and the tree. - */ public abstract class PuzzleExporter { private static final Logger LOGGER = LogManager.getLogger(PuzzleExporter.class.getName()); @@ -96,22 +91,8 @@ public void exportPuzzle(String fileName) throws ExportFileException { } } - /** - * Creates an XML element representing the board of the puzzle. - * Subclasses must implement this method to provide the XML structure for the board. - * - * @param newDocument The XML document to create elements within. - * @return An XML element representing the puzzle's board. - */ protected abstract Element createBoardElement(Document newDocument); - /** - * Creates an XML element representing the proof of the puzzle, including its tree structure. - * This method is used to generate the proof section of the XML, which contains the tree representation. - * - * @param newDocument The XML document to create elements within. - * @return An XML element representing the proof of the puzzle. - */ protected Element createProofElement(Document newDocument) { org.w3c.dom.Element proofElement = newDocument.createElement("proof"); org.w3c.dom.Element treeElement = createTreeElement(newDocument); @@ -119,13 +100,6 @@ protected Element createProofElement(Document newDocument) { return proofElement; } - /** - * Creates an XML element representing the tree structure of the puzzle. - * This method traverses the tree nodes and transitions, and creates XML elements for each. - * - * @param newDocument The XML document to create elements within. - * @return An XML element representing the puzzle's tree structure. - */ protected Element createTreeElement(Document newDocument) { org.w3c.dom.Element treeElement = newDocument.createElement("tree"); diff --git a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java index b1e8a2dd9..0902478db 100644 --- a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java +++ b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java @@ -13,12 +13,6 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; -/** - * Abstract class for importing puzzle data from various sources into a puzzle object. - * This class provides methods to initialize and set up a puzzle, including its board and proof structure, - * from different input formats such as dimensions, statements, or XML files. - * Subclasses must implement methods to handle specific formats for board initialization and proof creation. - */ public abstract class PuzzleImporter { private static final Logger LOGGER = LogManager.getLogger(PuzzleImporter.class.getName()); @@ -52,13 +46,6 @@ public void initializePuzzle(int rows, int columns) throws RuntimeException { } } - /** - * Initializes the puzzle with the given array of statements - * - * @param statements the statements used to initialize the puzzle - * @throws InputMismatchException if the input statements are invalid - * @throws IllegalArgumentException if the statements are not suitable for initializing the puzzle - */ public void initializePuzzle(String[] statements) throws InputMismatchException, IllegalArgumentException { // Note: Error checking for the statements will be left up to the puzzles that support @@ -68,10 +55,10 @@ public void initializePuzzle(String[] statements) } /** - * Initializes the puzzle attributes from the XML document node + * Initializes the puzzle attributes * - * @param node the XML document node representing the puzzle - * @throws InvalidFileFormatException if the file format is invalid + * @param node xml document node + * @throws InvalidFileFormatException if file is invalid */ public void initializePuzzle(Node node) throws InvalidFileFormatException { if (node.getNodeName().equalsIgnoreCase("puzzle")) { @@ -124,29 +111,22 @@ public void initializePuzzle(Node node) throws InvalidFileFormatException { } /** - * Initializes the board with the specified number of rows and columns. + * Creates the board for building * - * @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 + * @param rows number of rows on the puzzle + * @param columns number of columns on the puzzle + * @throws RuntimeException if board can not be created */ public abstract void initializeBoard(int rows, int columns); /** - * Initializes the board from the XML document node. + * Creates an empty board for building * - * @param node the XML document node representing the board - * @throws InvalidFileFormatException if the file format is invalid + * @param node xml document node + * @throws InvalidFileFormatException if file is invalid */ public abstract void initializeBoard(Node node) throws InvalidFileFormatException; - /** - * Initializes the board using an array of statements. - * - * @param statements the statements used to initialize the board - * @throws UnsupportedOperationException if the operation is not supported - * @throws IllegalArgumentException if the statements are not suitable for initializing the board - */ public abstract void initializeBoard(String[] statements) throws UnsupportedOperationException, IllegalArgumentException; @@ -314,7 +294,6 @@ protected void createTree(Node node) throws InvalidFileFormatException { } } - protected void validateTreeStructure( HashMap nodes, HashMap transitions) throws InvalidFileFormatException { @@ -389,13 +368,6 @@ protected void validateTreeStructure( } } - /** - * Updates the board state based on the changes specified in the TreeTransition. - * - * @param transition the TreeTransition object representing the transition to be updated - * @param transElement the XML node containing the transition data - * @throws InvalidFileFormatException if the XML node format is incorrect or unknown nodes are encountered - */ protected void makeTransitionChanges(TreeTransition transition, Node transElement) throws InvalidFileFormatException { if (transition.getRule() instanceof MergeRule) { @@ -439,10 +411,6 @@ protected void makeTransitionChanges(TreeTransition transition, Node transElemen } } - /** - * Creates a default proof tree with a single root node. The root node is initialized with the current board state. - * The created tree is then set as the proof tree for the puzzle. - */ protected void createDefaultTree() { TreeNode root = new TreeNode(puzzle.getCurrentBoard()); root.setRoot(true); @@ -452,7 +420,7 @@ protected void createDefaultTree() { } /** - * Gets the result of building the Puzzle object. + * Gets the result of building the Puzzle * * @return puzzle */ diff --git a/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java b/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java index c473e0ecd..c4c1ed273 100644 --- a/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java +++ b/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java @@ -5,9 +5,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** - * Annotation for registering puzzle classes with the puzzle framework. - */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface RegisterPuzzle {} 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 0adbbaf91..8b75d075d 100644 --- a/src/main/java/edu/rpi/legup/model/elements/Element.java +++ b/src/main/java/edu/rpi/legup/model/elements/Element.java @@ -4,10 +4,6 @@ import java.awt.image.BufferedImage; import javax.swing.*; -/** - * The Element class serves as an abstract base class for various elements used in the system. - * It handles basic properties such as ID, name, description, and image associated with the element. - */ @RegisterElement public abstract class Element { protected String elementID; @@ -21,14 +17,6 @@ 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; @@ -38,9 +26,6 @@ public Element(String elementID, String elementName, String description, String loadImage(); } - /** - * Loads the image for the element and resizes it to a width of 100 pixels while maintaining aspect ratio - */ private void loadImage() { if (imageName != null) { this.image = new ImageIcon(ClassLoader.getSystemClassLoader().getResource(imageName)); @@ -62,65 +47,30 @@ 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/elements/ElementType.java b/src/main/java/edu/rpi/legup/model/elements/ElementType.java index 4fee79d4f..dff4fe04f 100644 --- a/src/main/java/edu/rpi/legup/model/elements/ElementType.java +++ b/src/main/java/edu/rpi/legup/model/elements/ElementType.java @@ -1,9 +1,6 @@ package edu.rpi.legup.model.elements; -/** - * Enum representing the different types of elements that can be used in the system - */ public enum ElementType { - PLACEABLE - //NONPLACEABLE COMBINED ALL PLACEABLE AND NONPLACEABLE INTO JUST ONE CATEGORY + PLACEABLE, + NONPLACEABLE } diff --git a/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java b/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java index 019001128..4ab0ab509 100644 --- a/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java +++ b/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java @@ -1,9 +1,9 @@ -//package edu.rpi.legup.model.elements; -// -//public abstract class NonPlaceableElement extends Element { -// public NonPlaceableElement( -// String elementID, String elementName, String description, String imageName) { -// super(elementID, elementName, description, imageName); -// this.elementType = ElementType.PLACEABLE; -// } -//} +package edu.rpi.legup.model.elements; + +public abstract class NonPlaceableElement extends Element { + public NonPlaceableElement( + String elementID, String elementName, String description, String imageName) { + super(elementID, elementName, description, imageName); + this.elementType = ElementType.NONPLACEABLE; + } +} diff --git a/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java b/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java index 79a0dcff8..133658700 100644 --- a/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java +++ b/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java @@ -1,19 +1,6 @@ package edu.rpi.legup.model.elements; -/** - * Abstract class representing elements that can be placed within the system. - * Inherits from the {@link Element} class and sets the {@link ElementType} to {@link ElementType#PLACEABLE}. - */ public abstract class PlaceableElement extends Element { - - /** - * Constructs a PlaceableElement with the specified details - * - * @param elementID Unique identifier for the element - * @param elementName Name of the element - * @param description Description of the element - * @param imageName Name of the image file representing the element - */ public PlaceableElement( String elementID, String elementName, String description, String imageName) { super(elementID, elementName, description, imageName); diff --git a/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java b/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java index 5f59ad795..368ecc8d1 100644 --- a/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java +++ b/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java @@ -3,11 +3,6 @@ import java.lang.annotation.*; import java.lang.annotation.ElementType; -/** - * Annotation to mark classes as elements that should be registered. - * This annotation is used to indicate that a class is an element within the system and should be registered - * for use within the application. - */ @Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) 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 4544caa36..d8bdf5199 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/Board.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/Board.java @@ -5,11 +5,6 @@ import java.util.List; import java.util.Set; -/** - * Abstract class representing a game board. - * This class provides functionality for managing puzzle elements, tracking modifications, - * and determining if the board is modifiable. - */ public abstract class Board { protected List puzzleElements; @@ -36,24 +31,21 @@ public Board(int size) { } /** - * Gets a specific {@link PuzzleElement} from the board. + * Gets a specific {@link PuzzleElement} on this board. * - * @param puzzleElement the puzzle element to retrieve - * @return the puzzle element at the corresponding index, or null if not found + * @param puzzleElement equivalent puzzleElement + * @return equivalent puzzleElement on this board */ 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 the puzzleElement to set at the index + * @param puzzleElement new puzzleElement at the index */ public void setPuzzleElement(int index, PuzzleElement puzzleElement) { if (index < puzzleElements.size()) { @@ -62,7 +54,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 14dcb8609..fa3625a43 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java @@ -5,108 +5,49 @@ import java.util.HashSet; import java.util.Set; -/** - * Represents a game board with specific rules for selecting puzzle elements. - * Extends the abstract `Board` class and adds functionality for handling pickable elements and case rules. - */ public class CaseBoard extends Board { protected Board baseBoard; 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(); } - - /** - * Performs a deep copy of this CaseBoard. - * CURRENTLY NOT IMPLEMENTED AND RETURNS NULL - * - * @return a new copy of the CaseBoard - */ public CaseBoard copy() { return null; } 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 131feb122..bfc785bdd 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java @@ -5,9 +5,6 @@ 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 7338132f8..9593690ce 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java @@ -6,11 +6,6 @@ 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/GridCell.java b/src/main/java/edu/rpi/legup/model/gameboard/GridCell.java index 5d6fe1ff3..a33c3ec80 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/GridCell.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/GridCell.java @@ -2,13 +2,6 @@ import java.awt.*; -/** - * GridCell represents a cell within a grid-based board. It holds data of type T and tracks its location - * on the board using a {@link Point}. The class extends from PuzzleElement and supports deep copying of - * the grid cell. - * - * @param the type of data held by the GridCell - */ public class GridCell extends PuzzleElement { protected Point location; 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 b2a10a153..c41d5e1b2 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java @@ -3,12 +3,6 @@ import java.util.ArrayList; import java.util.List; -/** - * GridRegion represents a collection of cells within a grid. It manages a list of cells and provides - * methods to add, remove, and retrieve cells from the region. - * - * @param the type of cell managed by the GridRegion - */ public abstract class GridRegion { protected List regionCells; @@ -30,7 +24,7 @@ public void addCell(T cell) { /** * Removes the cell from the region * - * @param cell cell to be removed from the region + * @param cell cell to be remove from the region */ public void removeCell(T cell) { regionCells.remove(cell); @@ -53,4 +47,9 @@ 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 a92b3efb0..4ce030a04 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java @@ -3,18 +3,11 @@ import edu.rpi.legup.model.elements.Element; import java.awt.event.MouseEvent; -/** - * PuzzleElement represents a single element in a puzzle grid. It holds data and provides various - * methods to manage and retrieve its properties, including modifiability, modification status, and validity. - * - * @param the type of data held by the PuzzleElement - */ public abstract class PuzzleElement { protected int index; protected T data; protected boolean isModifiable; protected boolean isModified; - protected boolean isModifiableCaseRule; protected boolean isGiven; protected boolean isValid; protected int casesDepended; @@ -24,7 +17,6 @@ public PuzzleElement() { this.index = -1; this.data = null; this.isModifiable = true; - this.isModifiableCaseRule = true; this.isModified = false; this.isGiven = false; this.isValid = true; @@ -81,24 +73,6 @@ 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 fa440369c..461128562 100644 --- a/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java +++ b/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java @@ -4,10 +4,6 @@ import edu.rpi.legup.model.gameboard.PuzzleElement; import edu.rpi.legup.model.tree.TreeElement; -/** - * IBoardListener defines methods for receiving notifications about changes to the board, - * including updates to tree elements, case boards, and puzzle elements. - */ public interface IBoardListener { /** * Called when the tree element has changed. @@ -17,7 +13,7 @@ public interface IBoardListener { void onTreeElementChanged(TreeElement treeElement); /** - * Called when a case board has been added to the view. + * Called when the 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 53bfe444b..c7bf13141 100644 --- a/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java +++ b/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java @@ -2,10 +2,6 @@ import java.util.function.Consumer; -/** - * IBoardSubject defines methods for managing and notifying board listeners. - * It allows for adding and removing listeners, and for notifying them using a specified algorithm. - */ public interface IBoardSubject { /** * Adds a board listener. @@ -22,7 +18,7 @@ public interface IBoardSubject { void removeBoardListener(IBoardListener listener); /** - * Notifies all the listeners using the specified algorithm. + * Notifies all of 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/ITreeListener.java b/src/main/java/edu/rpi/legup/model/observer/ITreeListener.java index c5a0355ca..d5e7fdb2d 100644 --- a/src/main/java/edu/rpi/legup/model/observer/ITreeListener.java +++ b/src/main/java/edu/rpi/legup/model/observer/ITreeListener.java @@ -3,10 +3,6 @@ import edu.rpi.legup.model.tree.TreeElement; import edu.rpi.legup.ui.proofeditorui.treeview.TreeViewSelection; -/** - * ITreeListener defines methods for handling events related to changes in the tree. - * Implementations of this interface are notified of additions, removals, and selection changes in the tree. - */ public interface ITreeListener { /** * Called when a {@link TreeElement} is added to the tree. 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 0b0aee348..66d5d9a5e 100644 --- a/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java +++ b/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java @@ -2,13 +2,9 @@ import java.util.function.Consumer; -/** - * ITreeSubject defines methods for managing and notifying listeners about changes to the tree model. - * Implementations of this interface handle adding, removing, and notifying listeners. - */ public interface ITreeSubject { /** - * Adds a tree listener. + * Adds a board listener. * * @param listener listener to add */ @@ -22,7 +18,7 @@ public interface ITreeSubject { void removeTreeListener(ITreeListener listener); /** - * Notifies all the tree listeners using the specified algorithm. + * Notifies all of the listeners using the specified algorithm. * * @param algorithm algorithm used to notify the listeners */ diff --git a/src/main/java/edu/rpi/legup/model/rules/CaseRule.java b/src/main/java/edu/rpi/legup/model/rules/CaseRule.java index ee5c91229..ab2cc8f0d 100644 --- a/src/main/java/edu/rpi/legup/model/rules/CaseRule.java +++ b/src/main/java/edu/rpi/legup/model/rules/CaseRule.java @@ -11,10 +11,6 @@ import java.util.List; import java.util.Set; -/** - * CaseRule is an abstract class representing a rule that can be applied with multiple cases in a puzzle board. - * It defines methods for applying and checking the rule, as well as retrieving the necessary elements. - */ public abstract class CaseRule extends Rule { private final String INVALID_USE_MESSAGE; diff --git a/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java b/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java index cd2e20081..b38a95fd2 100644 --- a/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java +++ b/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java @@ -6,10 +6,6 @@ import edu.rpi.legup.model.gameboard.PuzzleElement; import edu.rpi.legup.model.tree.TreeTransition; -/** - * ContradictionRule is an abstract class representing a rule that identifies contradictions in a puzzle. - * It provides methods to check for contradictions both globally and at specific puzzle elements. - */ public abstract class ContradictionRule extends Rule { private final String NO_CONTRADICTION_MESSAGE = diff --git a/src/main/java/edu/rpi/legup/model/rules/DirectRule.java b/src/main/java/edu/rpi/legup/model/rules/DirectRule.java index 613574989..d550bc02c 100644 --- a/src/main/java/edu/rpi/legup/model/rules/DirectRule.java +++ b/src/main/java/edu/rpi/legup/model/rules/DirectRule.java @@ -7,10 +7,6 @@ import edu.rpi.legup.model.tree.TreeNode; import edu.rpi.legup.model.tree.TreeTransition; -/** - * DirectRule is an abstract class representing a direct rule for transitions in a puzzle. - * It provides methods for checking whether transitions and specific puzzle elements follow the rule. - */ public abstract class DirectRule extends Rule { /** * DirectRule Constructor creates a new basic rule. 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 f7bd887f3..f7badcd8b 100644 --- a/src/main/java/edu/rpi/legup/model/rules/MergeRule.java +++ b/src/main/java/edu/rpi/legup/model/rules/MergeRule.java @@ -10,10 +10,6 @@ import java.util.ArrayList; import java.util.List; -/** - * MergeRule is an implementation of a rule that merges multiple nodes into one. - * It validates if the merging of nodes is done correctly. - */ public class MergeRule extends Rule { /** MergeRule Constructor merges to board states together */ public MergeRule() { @@ -27,7 +23,7 @@ public MergeRule() { /** * Checks whether the transition logically follows from the parent node using this rule. This - * method is the one that should have overridden in child classes + * method is the one that should 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/RegisterRule.java b/src/main/java/edu/rpi/legup/model/rules/RegisterRule.java index d357e0d86..c1fe0b88c 100644 --- a/src/main/java/edu/rpi/legup/model/rules/RegisterRule.java +++ b/src/main/java/edu/rpi/legup/model/rules/RegisterRule.java @@ -2,11 +2,6 @@ import java.lang.annotation.*; -/** - * Annotation to register a class as a rule in the system. - * This annotation can be applied to rule classes to indicate that they should be registered - * in the rule system. - */ @Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) 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 107e72712..f70bb2889 100644 --- a/src/main/java/edu/rpi/legup/model/rules/Rule.java +++ b/src/main/java/edu/rpi/legup/model/rules/Rule.java @@ -8,12 +8,6 @@ import java.awt.image.BufferedImage; import javax.swing.ImageIcon; -/** - * Abstract base class for defining rules. - * This class encapsulates the common functionality and attributes of all rules, - * including rule identification, description, image handling, and validation logic. - * Subclasses must provide implementations for specific rule checking logic. - */ @RegisterRule public abstract class Rule { protected String ruleID; @@ -165,11 +159,6 @@ 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/rules/RuleType.java b/src/main/java/edu/rpi/legup/model/rules/RuleType.java index e72118e3c..06aa1844b 100644 --- a/src/main/java/edu/rpi/legup/model/rules/RuleType.java +++ b/src/main/java/edu/rpi/legup/model/rules/RuleType.java @@ -1,9 +1,5 @@ package edu.rpi.legup.model.rules; -/** - * Enumeration representing different types of rules in the rule-based system. - * This enum categorizes rules into various types based on their functionality and application. - */ public enum RuleType { BASIC, CASE, 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 3e68015a1..a0746db87 100644 --- a/src/main/java/edu/rpi/legup/model/tree/Tree.java +++ b/src/main/java/edu/rpi/legup/model/tree/Tree.java @@ -1,20 +1,11 @@ package edu.rpi.legup.model.tree; -import edu.rpi.legup.controller.TreeController; import edu.rpi.legup.model.gameboard.Board; -import edu.rpi.legup.model.rules.CaseRule; -import edu.rpi.legup.ui.proofeditorui.treeview.TreeView; - import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -/** - * Represents a tree structure in a puzzle. - * The tree consists of {@link TreeNode}s and {@link TreeTransition}s - * and allows adding, removing, and validating elements. - */ public class Tree { private TreeNode rootNode; @@ -33,12 +24,6 @@ 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); @@ -46,12 +31,13 @@ public TreeTransition addNewTransition(TreeNode treeNode) { return transition; } - /** - * Adds a tree element (node or transition) to the tree. - * - * @param element the tree element to add - * @return the added tree element - */ + public TreeNode addNode(TreeTransition transition) { + TreeNode treeNode = new TreeNode(transition.getBoard().copy()); + transition.setChildNode(treeNode); + treeNode.setParent(transition); + return treeNode; + } + public TreeElement addTreeElement(TreeElement element) { if (element.getType() == TreeElementType.NODE) { TreeNode treeNode = (TreeNode) element; @@ -60,55 +46,30 @@ public TreeElement addTreeElement(TreeElement element) { } else { TreeTransition transition = (TreeTransition) element; Board copyBoard = transition.board.copy(); - copyBoard.setModifiable(true); + copyBoard.setModifiable(false); 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); } } @@ -135,10 +96,10 @@ public Set getLeafTreeElements() { } /** - * Gets a Set of TreeNodes that are leaf nodes from the subtree rooted at the specified node + * Gets a Set of TreeNodes that are leaf nodes from the sub tree rooted at the specified node * * @param node node that is input - * @return Set of TreeNodes that are leaf nodes from the subtree + * @return Set of TreeNodes that are leaf nodes from the sub tree */ 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 2f6f45e4d..59f75acf3 100644 --- a/src/main/java/edu/rpi/legup/model/tree/TreeElement.java +++ b/src/main/java/edu/rpi/legup/model/tree/TreeElement.java @@ -2,9 +2,6 @@ import edu.rpi.legup.model.gameboard.Board; -/** - * Represents an element in a tree structure, which can be either a {@link TreeNode} or a {@link TreeTransition}. - */ public abstract class TreeElement { protected TreeElementType type; protected Board board; @@ -27,7 +24,7 @@ public TreeElement(TreeElementType type) { public abstract boolean isContradictoryBranch(); /** - * Recursively determines if the subtree rooted at this tree puzzleElement is valid by checking + * Recursively determines if the sub-tree 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/TreeElementType.java b/src/main/java/edu/rpi/legup/model/tree/TreeElementType.java index 3a6dbb124..67437a535 100644 --- a/src/main/java/edu/rpi/legup/model/tree/TreeElementType.java +++ b/src/main/java/edu/rpi/legup/model/tree/TreeElementType.java @@ -1,9 +1,5 @@ package edu.rpi.legup.model.tree; -/** - * Enum representing the type of a tree element. - * Tree elements can be either nodes or transitions in the tree structure. - */ public enum TreeElementType { NODE, TRANSITION 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 85a5e717b..a2ac7cb21 100644 --- a/src/main/java/edu/rpi/legup/model/tree/TreeNode.java +++ b/src/main/java/edu/rpi/legup/model/tree/TreeNode.java @@ -4,11 +4,6 @@ import edu.rpi.legup.utility.DisjointSets; import java.util.*; -/** - * Represents a node in a tree structure. Extends {@link TreeElement}. - * A {@code TreeNode} contains a board, references to its parent and children transitions, and indicates - * if it is the root node of the tree. - */ public class TreeNode extends TreeElement { private TreeTransition parent; private List children; @@ -61,9 +56,9 @@ public boolean isValidBranch() { } /** - * Gets a list of the ancestors of this node + * Gets all of the ancestors of this node * - * @return list of all the ancestors for this node + * @return list of all of the ancestors for this node */ public List getAncestors() { List ancestors = new ArrayList<>(); @@ -331,10 +326,6 @@ public void setRoot(boolean isRoot) { this.isRoot = isRoot; } - /** - * Clears all children transitions from this tree node. - * After calling this method, the node will have no child transitions. - */ public void clearChildren() { this.children.clear(); } diff --git a/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java b/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java index 9e441ac55..e79cd4b96 100644 --- a/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java +++ b/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java @@ -8,11 +8,6 @@ import java.util.ArrayList; import java.util.List; -/** - * Represents a transition between two nodes in a tree structure within a game. - * A transition is responsible for propagating changes through the tree and managing - * and verifying the associated rules and puzzle elements. - */ public class TreeTransition extends TreeElement { private ArrayList parents; private TreeNode childNode; @@ -337,25 +332,6 @@ public void setChildNode(TreeNode childNode) { this.childNode = childNode; } - /** - * Removes the child to this tree transition - * - * @param child child to remove - */ - public void removeChild(TreeNode child) { - parents.remove(child); - } - - /** - * Add the child to this tree transition - * - * @param child child to add - */ - public void addChild(TreeNode child) { - parents.add(child); - } - - /** * Gets the rule associated with this transition * 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 d2dd0b181..773513cda 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java @@ -36,12 +36,18 @@ public Board generatePuzzle(int difficulty) { return null; } - /** - * Determines if the current board is a valid state - * - * @param board board to check for validity - * @return true if board is valid, false otherwise - */ + // /** + // * 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; + // } + @Override public boolean isBoardComplete(Board board) { BinaryBoard binaryBoard = (BinaryBoard) board; @@ -60,24 +66,6 @@ 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) {} - - - /** - * 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 && rows == columns; - } } 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 34819410b..35c37b1a1 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java @@ -2,7 +2,7 @@ import edu.rpi.legup.model.gameboard.GridBoard; import edu.rpi.legup.model.gameboard.PuzzleElement; - +import java.awt.*; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -20,13 +20,6 @@ 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() @@ -39,12 +32,6 @@ 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++) { @@ -54,26 +41,6 @@ public Set getRowCells(int rowNum) { return row; } - /** - * Get all the binary cells in a column - * - * @param colNum column number - * @return set of all binary cells in specified colNum - */ - public Set getColCells(int colNum) { - Set col = new HashSet<>(); - for (int i = 0; i < size; i++) { - col.add(getCell(colNum, i)); - } - return col; - } - - /** - * Get all the binary types in a row - * - * @param rowNum row number - * @return ArrayList of all binary types in specified rowNum - */ public ArrayList getRowTypes(int rowNum) { ArrayList row = new ArrayList(); for (int i = 0; i < size; i++) { @@ -83,12 +50,6 @@ public ArrayList getRowTypes(int rowNum) { return row; } - /** - * Get all the binary types in a column - * - * @param colNum column number - * @return ArrayList of all binary types in specified colNum - */ public ArrayList getColTypes(int colNum) { ArrayList col = new ArrayList(); for (int i = 0; i < size; i++) { @@ -98,12 +59,17 @@ public ArrayList getColTypes(int colNum) { return col; } - /** - * Get a copy of the binary board - * @return copy of current BinaryBoard - */ + public Set getCol(int colNum) { + Set col = new HashSet<>(); + for (int i = 0; i < size; i++) { + col.add(getCell(colNum, i)); + } + return col; + } + @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 d09f7115e..9007215ad 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java @@ -1,27 +1,13 @@ 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 { - /** - * 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); + public BinaryCell(int valueInt, Point location) { + super(valueInt, location); } - /** - * Gets the type of this BinaryCell - * - * @return type of BinaryCell - */ public BinaryType getType() { switch (data) { case 0: @@ -38,11 +24,6 @@ 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()); @@ -51,36 +32,4 @@ public BinaryCell copy() { copy.setGiven(isGiven); return copy; } - - /** - * Sets the type of this BinaryCell - * - * @param e element to set the type of this binary cell to - */ - @Override - public void setType(Element e, MouseEvent m) { - if (e.getElementName().equals("Number Tile")) { - if (m.getButton() == MouseEvent.BUTTON1) { - if (this.data == 2) { - this.data = 0; - } - else { - this.data = this.data + 1; - } - } - else { - if (m.getButton() == MouseEvent.BUTTON3) { - if (this.data > 0) { - this.data = this.data - 1; - } - else { - this.data = 2; - } - } - } - } - else { // unknown tile - this.data = 2; - } - } -} \ No newline at end of file +} 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 a819177d6..890c26656 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java @@ -10,14 +10,7 @@ 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")) { @@ -52,13 +45,6 @@ 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 caf62f3fe..0bad559d9 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java @@ -6,16 +6,6 @@ public class BinaryController extends ElementController { - /** - * Handles cell state changes in the binary puzzle when a mouse event occurs - * If the left mouse button is clicked: - * - If the control key is held down, shows a context menu at the mouse position - * - Otherwise, toggles the cell data state between 0, 1, and 2 in a cyclic manner - * If the right mouse button is clicked, the cell state is also toggled between 2, 1, and 0 - * - * @param e MouseEvent triggered by the user interaction - * @param data PuzzleElement representing the cell being modified - */ @Override public void changeCell(MouseEvent e, PuzzleElement data) { BinaryCell cell = (BinaryCell) data; @@ -40,13 +30,13 @@ public void changeCell(MouseEvent e, PuzzleElement data) { } } else { if (e.getButton() == MouseEvent.BUTTON3) { - if (cell.getData() == 2) { + if (cell.getData() == 0) { data.setData(1); } else { if (cell.getData() == 1) { - data.setData(0); - } else { data.setData(2); + } else { + data.setData(0); } } } 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 f5ea33d4a..9ac99c958 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java @@ -7,8 +7,6 @@ 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); @@ -24,66 +22,99 @@ public BinaryCell getPuzzleElement() { return (BinaryCell) super.getPuzzleElement(); } - - /** - * Draws the cells provided in the puzzle's .xml file with light gray background - * - * @param graphics2D The graphics object to draw on - */ @Override public void drawGiven(Graphics2D graphics2D) { - drawCell(graphics2D, GIVEN_COLOR); + BinaryCell cell = (BinaryCell) puzzleElement; + BinaryType type = cell.getType(); + if (type == BinaryType.ZERO) { + 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.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); + } + } + } } - /** - * Draws new cells being added to board with white background - * - * @param graphics2D The graphics object to draw on - */ @Override public void drawElement(Graphics2D graphics2D) { - drawCell(graphics2D, ELEMENT_COLOR); - } - - /** - * Helper method to handle drawing the cell based on its type and background color - * - * @param graphics2D The graphics object to draw on - * @param bgColor The background color for the cell - */ - private void drawCell(Graphics2D graphics2D, Color bgColor) { BinaryCell cell = (BinaryCell) puzzleElement; BinaryType type = cell.getType(); - - if (type == BinaryType.ZERO || type == BinaryType.ONE) { + if (type == BinaryType.ZERO) { graphics2D.setStroke(new BasicStroke(1)); - 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); - 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); - /** - * 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); + } 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); + } + } + } } } - 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 f12a07378..cd58314b6 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java @@ -10,13 +10,6 @@ public BinaryExporter(Binary binary) { super(binary); } - /** - * Generates an XML element for the binary puzzle board, including its dimensions and the - * state of each cell. Binary cells that are not in the `UNKNOWN` state 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) { BinaryBoard board; @@ -33,7 +26,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() != BinaryType.UNKNOWN.toValue()) { + if (cell.getData() != -2) { 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 8a4bad01e..2fc5b09ef 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java @@ -12,33 +12,16 @@ 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); @@ -65,12 +48,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); @@ -93,7 +76,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++) { @@ -127,11 +110,6 @@ public void initializeBoard(Node node) throws InvalidFileFormatException { } } - /** - * Initializes a board with text - * @param statements the text being used - * @throws UnsupportedOperationException Binary does not use text input - */ @Override public void initializeBoard(String[] statements) throws UnsupportedOperationException { throw new UnsupportedOperationException("Binary cannot accept text input"); diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java index f03f2ee08..6e3413d7a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java @@ -1,23 +1,10 @@ package edu.rpi.legup.puzzle.binary; -/** - * Enum representing the possible states of a binary puzzle cell - * - * The states include: - * - ZERO: Represents a cell with a value of 0 - * - ONE: Represents a cell with a value of 1 - * - UNKNOWN: Represents an empty cell - * - */ public enum BinaryType { - ZERO, // Enum constant 0 - ONE, // Enum constant 1 - UNKNOWN; // Enum constant 2 + ZERO, + ONE, + UNKNOWN; - /** - * The `toValue` method returns the ordinal value of the enum constant, - * which can be used to convert the enum to an integer representation. - */ public int toValue() { return this.ordinal(); } diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java index e1869de6b..b11554f28 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java @@ -7,13 +7,6 @@ public class BinaryView extends GridBoardView { - /** Creates and arranges the visual components for each cell in the binary puzzle. Initializes - * the view by setting up the board controller, binary controller, and the grid dimensions. - * For each cell in the BinaryBoard, it creates a corresponding BinaryElementView, sets its index, - * size, and location, and adds it to the list of element views to be displayed. - * - * @param board The BinaryBoard representing the current state of the binary puzzle - */ public BinaryView(BinaryBoard board) { super(new BoardController(), new BinaryController(), board.getDimension()); 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 new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/BlankTile.java @@ -0,0 +1 @@ + diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java index e996e246b..8b1378917 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java @@ -1,14 +1 @@ -package edu.rpi.legup.puzzle.binary.elements; - -import edu.rpi.legup.model.elements.PlaceableElement; - -public class NumberTile extends PlaceableElement { - public NumberTile() { - super( - "BINA-ELEM-0001", - "Number Tile", - "A number tile", - "edu/rpi/legup/images/binary/tiles/NumberTile.png"); - } -} \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/binary/elements/UnknownTile.java deleted file mode 100644 index 8c60ea8c3..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/elements/UnknownTile.java +++ /dev/null @@ -1,13 +0,0 @@ -package edu.rpi.legup.puzzle.binary.elements; - -import edu.rpi.legup.model.elements.PlaceableElement; - -public class UnknownTile extends PlaceableElement { - public UnknownTile() { - super( - "BINA-ELEM-0002", - "Unknown Tile", - "A blank tile", - "edu/rpi/legup/images/binary/tiles/UnknownTile.png"); - } -} \ No newline at end of file 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 deleted file mode 100644 index 54db0ee0b..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/elements/binary_elements_reference_sheet.txt +++ /dev/null @@ -1,2 +0,0 @@ -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 359433685..e38c6b78d 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 @@ -14,9 +14,8 @@ public class CompleteRowColumnDirectRule extends DirectRule { public CompleteRowColumnDirectRule() { super( "BINA-BASC-0003", - "Complete Row/Column", - "If a row/column of length n contains n/2 of a single value, the remaining " + - "cells must contain the other value", + "Complete Row Column", + "If a row/column of length n contains n/2 of a single value, the remaining cells must contain the other value", "edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png"); } @@ -32,27 +31,23 @@ public CompleteRowColumnDirectRule() { @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard(); - ContradictionRule contraRule = new UnbalancedRowColumnContradictionRule(); + ContradictionRule contraRule = new UnbalancedRowOrColumnContradictionRule(); BinaryCell binaryCell = (BinaryCell) puzzleElement; BinaryBoard modified = origBoard.copy(); + BinaryCell c = (BinaryCell) modified.getPuzzleElement(puzzleElement); - // 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) { + // 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) { return null; } - return "Unbalanced row/column found"; + return "Grouping of Three Ones or Zeros not 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/RepeatedRowColumnContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java similarity index 60% rename from src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java rename to src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java index 13eb35283..8b0d88ae4 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java @@ -8,38 +8,30 @@ import edu.rpi.legup.puzzle.binary.BinaryType; import java.util.ArrayList; -public class RepeatedRowColumnContradictionRule extends ContradictionRule { +public class DuplicateRowsOrColumnsContradictionRule 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 RepeatedRowColumnContradictionRule() { + public DuplicateRowsOrColumnsContradictionRule() { super( "BINA-CONT-0003", - "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"); + "Duplicate Rows Or Columns", + "There must not be two rows or two columns that are duplicates", + "edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.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; BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(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; @@ -47,10 +39,10 @@ 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/EliminateTheImpossibleDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/EliminateTheImpossibleDirectRule.java deleted file mode 100644 index 02c1c2c31..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/EliminateTheImpossibleDirectRule.java +++ /dev/null @@ -1,201 +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.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; -//import edu.rpi.legup.puzzle.binary.BinaryType; -// -//import java.util.LinkedList; -//import java.util.Queue; -//import java.lang.Math.*; -//import java.lang.reflect.Array; -//import java.util.ArrayList; -// -//public class EliminateTheImpossibleDirectRule extends DirectRule { -// private final String INVALID_USE_MESSAGE = "Number at cell is incorrect"; -// -// public EliminateTheImpossibleDirectRule() { -// super( -// "BINA-BASC-0004", -// "Eliminate The Impossible", -// "Out of the remaining empty cells in this row or column, this digit must go here, otherwise there will be a future contradiction", -// "edu/rpi/legup/images/binary/rules/EliminateTheImpossibleDirectRule.png"); -// } -// -// // Function to generate all binary strings -// void generatePossibilitites(int spots, ArrayList possibilities, int zeroCount, int oneCount) -// // This function generates all the possible combinations of 0s and 1s for a -// // certain size, it does this -// // by basically just counting from 0 to the number - 1, so if you want all the -// // possible combinations for 3 -// // spots, you can just count in binary from 0 to 7 (taking 3 spots, so from 000 -// // to 111). To be practical, -// // the function does not return an array with all the possibilities as an array, -// // but populates the -// // arraylist you pass in (possibilities) -// { -// if (zeroCount + oneCount != spots) { -// System.out.println("INVALID INPUT"); -// return; -// } -// -// if (zeroCount == spots) { -// String zero = ""; -// for (int i = 0; i < spots; i++) { -// zero = zero + "0"; -// } -// possibilities.add(zero); -// -// } -// int count = (int) Math.pow(2, spots) - 1; -// int finalLen = spots; -// Queue q = new LinkedList(); -// q.add("1"); -// -// while (count-- > 0) { -// String s1 = q.peek(); -// q.remove(); -// -// String newS1 = s1; -// int curLen = newS1.length(); -// int runFor = spots - curLen; -// if (curLen < finalLen) { -// for (int i = 0; i < runFor; i++) { -// newS1 = "0" + newS1; -// } -// } -// int curZeros = 0; -// int curOnes = 0; -// -// for (int i = 0; i < spots; i++) { -// if (newS1.charAt(i) == '0') { -// curZeros++; -// } -// if (newS1.charAt(i) == '1') { -// curOnes++; -// } -// } -// -// if (zeroCount == curZeros && oneCount == curOnes) { -// possibilities.add(newS1); -// } -// String s2 = s1; -// q.add(s1 + "0"); -// q.add(s2 + "1"); -// } -// } -// -// @Override -// public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { -// // This function should first check if there are three open spaces, if so, -// // continue, else figure out -// // how many spots are open, all the possible binary combinations that could be -// // put there, and by -// // analyzing the common factors, logically determine which number has a set -// // spot, meaning that we know -// // that a certain spot must be a zero or a one -// -// BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard(); -// BinaryCell binaryCell = (BinaryCell) puzzleElement; -// -// //Getting the row where the user clicked -// ArrayList row = origBoard.listRowCells(binaryCell.getLocation().y); -// int size = row.size(); -// int rowNumZeros = 0; -// int rowNumOnes = 0; -// -// for (BinaryCell item : row) { -// if (item.getType() == BinaryType.ZERO) { -// rowNumZeros++; -// } else if (item.getType() == BinaryType.ONE) { -// rowNumOnes++; -// } -// } -// -// ArrayList rowResult = new ArrayList(); -// -// // To call generatePossibilitites(), you must call it and pass in the amount of -// // unknown spots left, -// // an ArrayList that will be populated with the possible results (in String -// // form), the amount of zeros left and ones left -// generatePossibilitites((size - rowNumZeros - rowNumOnes), rowResult, size / 2 - rowNumZeros, size / 2 - rowNumOnes); -// -// // Create deep copies of each row -// ArrayList> rowCopies = new ArrayList<>(); -// for (int i = 0; i < rowResult.size(); i++) { -// ArrayList newRow = new ArrayList<>(); -// for (BinaryCell cell : row) { -// newRow.add(cell.copy()); -// } -// rowCopies.add(newRow); -// } -// -// System.out.println("Number of possible binary combinations: " + rowCopies.size()); -// -// ArrayList> nonContraRows = new ArrayList<>(); -// int rowIdx = 0; -// for(ArrayList curRow : rowCopies){ -// int charIdx = 0; -// System.out.println(rowResult.get(rowIdx)); -// for(int i = 0; i < curRow.size(); i++) { -// if (curRow.get(i).getData() == 2) { -// if (rowResult.get(rowIdx).charAt(charIdx) == '0') { -// curRow.get(i).setData(0); -// } -// else if (rowResult.get(rowIdx).charAt(charIdx) == '1') { -// curRow.get(i).setData(1); -// } -// charIdx++; -// } -// System.out.print(curRow.get(i).getData() + " "); -// } -// -// boolean threeAdjacent = false; -// int count = 1; -// for(int i = 1; i < curRow.size(); i++) { -// if (curRow.get(i).getData() == curRow.get(i-1).getData()) { -// count++; -// if (count == 3) { -// threeAdjacent = true; -// break; -// } -// } else { -// count = 1; -// } -// } -// -// if (!threeAdjacent) { -// nonContraRows.add(curRow); -// } -// -// rowIdx++; -// System.out.println(); -// } -// -// System.out.println("Number of non contradiction rows: " + nonContraRows.size()); -// int colNum = binaryCell.getLocation().x; -// boolean invalid = false; -// for(int i = 0; i < nonContraRows.size(); i++) { -// if (nonContraRows.get(i).get(colNum).getData() != binaryCell.getData()) { -// invalid = true; -// break; -// } -// } -// -// if (!invalid) { -// return null; -// } -// -// return "This cell can either be a 0 or a 1"; -// -// } -// -// @Override -// public Board getDefaultBoard(TreeNode node) { -// return null; -// } -//} diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java similarity index 56% rename from src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java rename to src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java index 3ae7a424d..70549cd72 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java @@ -11,23 +11,16 @@ import java.util.ArrayList; import java.util.List; -public class ZeroOrOneCaseRule extends CaseRule { +public class OneOrZeroCaseRule extends CaseRule { - public ZeroOrOneCaseRule() { + public OneOrZeroCaseRule() { super( "BINA-CASE-0001", - "Zero Or One", - "Each blank cell is either a zero or a one", - "edu/rpi/legup/images/binary/rules/ZeroOrOneCaseRule.png"); + "One or Zero", + "Each blank cell is either a one or a zero.", + "edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.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(); @@ -39,30 +32,26 @@ public String checkRuleRaw(TreeTransition transition) { TreeTransition case2 = childTransitions.get(1); if (case1.getBoard().getModifiedData().size() != 1 || case2.getBoard().getModifiedData().size() != 1) { - return super.getInvalidUseOfRuleMessage() + ": This case rule must have 1 modified cell for each case."; + return super.getInvalidUseOfRuleMessage() + + ": This case rule must have 1 modified cell for each case."; } BinaryCell mod1 = (BinaryCell) case1.getBoard().getModifiedData().iterator().next(); BinaryCell mod2 = (BinaryCell) case2.getBoard().getModifiedData().iterator().next(); if (!mod1.getLocation().equals(mod2.getLocation())) { - return super.getInvalidUseOfRuleMessage() + ": This case rule must modify the same cell for each case."; + return super.getInvalidUseOfRuleMessage() + + ": This case rule must modify the same cell for each case."; } if (!((mod1.getType() == BinaryType.ZERO && mod2.getType() == BinaryType.ONE) || (mod2.getType() == BinaryType.ZERO && mod1.getType() == BinaryType.ONE))) { - return super.getInvalidUseOfRuleMessage() + ": This case rule must modify an empty cell."; + return super.getInvalidUseOfRuleMessage() + + ": This case rule must an empty white and black cell."; } 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(); @@ -76,44 +65,24 @@ 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.ONE.toValue()); + data1.setData(BinaryType.ZERO.toValue()); case1.addModifiedData(data1); cases.add(case1); Board case2 = board.copy(); PuzzleElement data2 = case2.getPuzzleElement(puzzleElement); - data2.setData(BinaryType.ZERO.toValue()); + data2.setData(BinaryType.ONE.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/OneTileGapDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java new file mode 100644 index 000000000..2e1e96fa5 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java @@ -0,0 +1,64 @@ +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/PreventTrioDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/PreventTrioDirectRule.java deleted file mode 100644 index 745e35d4e..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/PreventTrioDirectRule.java +++ /dev/null @@ -1,58 +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.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 PreventTrioDirectRule extends DirectRule { - private final String INVALID_USE_MESSAGE = "Number at cell is incorrect"; - - public PreventTrioDirectRule() { - super( - "BINA-BASC-0001", - "Prevent Trio", - "If a trio contradiction state could appear, use the opposite digit to prevent the trio", - "edu/rpi/legup/images/binary/rules/PreventTrioDirectRule.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 - */ - @Override - public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { - BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard(); - TrioContradictionRule contraRule = new TrioContradictionRule(); - BinaryCell binaryCell = (BinaryCell) puzzleElement; - BinaryBoard modified = origBoard.copy(); - - // Flip the cell and check to see if there will be a trio contradiction, if so the rule is applied correctly - modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1)); - if (contraRule.checkContradictionAt(modified, binaryCell) == null) { - return null; - } - - return "Trio 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; - } -} \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/SaveBlockerDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SaveBlockerDirectRule.java deleted file mode 100644 index 5f76c4f59..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/SaveBlockerDirectRule.java +++ /dev/null @@ -1,60 +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.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 SaveBlockerDirectRule extends DirectRule { - - private final String INVALID_USE_MESSAGE = "Number at cell is incorrect"; - - public SaveBlockerDirectRule() { - super( - "BINA-BASC-0003", - "Save Blocker", - "If a future trio could appear in this row/col, save the digit that could block that trio", - "edu/rpi/legup/images/binary/rules/SaveBlockerDirectRule.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) { - BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard(); - WastedBlockerContradictionRule contraRule = new WastedBlockerContradictionRule(); - BinaryCell binaryCell = (BinaryCell) puzzleElement; - BinaryBoard modified = origBoard.copy(); - - // Flip the cell and check to see if a blocker digit is wasted, if so the rule is applied correctly - modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1)); - if (contraRule.checkContradictionAt(modified, binaryCell) == null) { - return null; - } - - return "Wasted Digit 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/SurroundPairDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java new file mode 100644 index 000000000..dc2f07c8b --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java @@ -0,0 +1,48 @@ +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 new file mode 100644 index 000000000..075642246 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ThreeAdjacentContradictionRule.java @@ -0,0 +1,127 @@ +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/TrioContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/TrioContradictionRule.java deleted file mode 100644 index dce7fe371..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/TrioContradictionRule.java +++ /dev/null @@ -1,185 +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 TrioContradictionRule 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 TrioContradictionRule() { - super( - "BINA-CONT-0001", - "Trio", - "There must not be three adjacent zeros or three adjacent ones in a row or column", - "edu/rpi/legup/images/binary/rules/TrioContradictionRule.png"); - } - - /** - * This method checks the surrounding cells of a given puzzle element at a specified distance - * in both the vertical and horizontal directions - * - * @param board The board where the puzzle elements are located - * @param puzzleElement The puzzle element from which the distance is calculated - * @param n The distance away from the puzzle element to retrieve the surrounding cells - * @return An array of BinaryCells representing the surrounding cells - */ - public BinaryCell[] getCellsNAway(Board board, PuzzleElement puzzleElement, int n) { - BinaryBoard binaryBoard = (BinaryBoard) board; - BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement); - int cellX = cell.getLocation().x; - int cellY = cell.getLocation().y; - - BinaryCell[] cells = new BinaryCell[4]; // [0] up x, [1] down x, [2] right x, [3] left x - cells[0] = null; - cells[1] = null; - cells[2] = null; - cells[3] = null; - - if (binaryBoard.getCell(cellX, cellY + n) != null) { - cells[0] = binaryBoard.getCell(cellX, cellY + n); - } - if (binaryBoard.getCell(cellX, cellY - n) != null) { - cells[1] = binaryBoard.getCell(cellX, cellY - n); - } - if (binaryBoard.getCell(cellX + n, cellY) != null) { - cells[2] = binaryBoard.getCell(cellX + n, cellY); - } - if (binaryBoard.getCell(cellX - n, cellY) != null) { - cells[3] = binaryBoard.getCell(cellX - n, cellY); - } - - return cells; - } - - /** - * Checks whether the cell and its two surrounding cells form a trio of zeros or ones; - * If a trio is found, it indicates a contradiction - * - * @param board The board where the puzzle elements are located - * @param puzzleElement The puzzle element to check for contradiction - * @return true if no contradiction is found, false if contradiction detected - */ - public boolean checkSurroundPair(Board board, PuzzleElement puzzleElement) { - BinaryBoard binaryBoard = (BinaryBoard) board; - BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement); - - // [0] up n, [1] down n, [2] right n, [3] left n - BinaryCell[] cellsOneAway = getCellsNAway(board, puzzleElement, 1); - BinaryCell[] cellsTwoAway = getCellsNAway(board, puzzleElement, 2); - - if (cell.getType() == BinaryType.ONE || cell.getType() == BinaryType.ZERO) { - // left one and left two - if (cellsOneAway[3] != null - && cellsTwoAway[3] != null - && cellsOneAway[3].getType() != BinaryType.UNKNOWN - && cellsTwoAway[3].getType() != BinaryType.UNKNOWN) { - if (cellsOneAway[3].getType() == cell.getType() - && cellsTwoAway[3].getType() == cell.getType()) { - return false; - } - } - // right one and right two - if (cellsOneAway[2] != null - && cellsTwoAway[2] != null - && cellsOneAway[2].getType() != BinaryType.UNKNOWN - && cellsTwoAway[2].getType() != BinaryType.UNKNOWN) { - if (cellsOneAway[2].getType() == cell.getType() - && cellsTwoAway[2].getType() == cell.getType()) { - return false; - } - } - // down one and down two - if (cellsOneAway[1] != null - && cellsTwoAway[1] != null - && cellsOneAway[1].getType() != BinaryType.UNKNOWN - && cellsTwoAway[1].getType() != BinaryType.UNKNOWN) { - if (cellsOneAway[1].getType() == cell.getType() - && cellsTwoAway[1].getType() == cell.getType()) { - return false; - } - } - // up one and up two - if (cellsOneAway[0] != null - && cellsTwoAway[0] != null - && cellsOneAway[0].getType() != BinaryType.UNKNOWN - && cellsTwoAway[0].getType() != BinaryType.UNKNOWN) { - if (cellsOneAway[0].getType() == cell.getType() - && cellsTwoAway[0].getType() == cell.getType()) { - return false; - } - } - } - - return true; - } - - /** - * Checks whether there are two of the same cell type separated by one cell that also has - * the same type in any direction. If a trio is found, it indicates a contradiction - * - * @param board The board where the puzzle elements are located - * @param puzzleElement The puzzle element to check for contradiction - * @return true if no contradiction is found, false if contradiction detected - */ - public boolean checkOneTileGap(Board board, PuzzleElement puzzleElement) { - BinaryBoard binaryBoard = (BinaryBoard) board; - BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement); - - // [0] up n, [1] down n, [2] right n, [3] left n - BinaryCell[] cellsOneAway = getCellsNAway(board, puzzleElement, 1); - - if (cell.getType() == BinaryType.ONE || cell.getType() == BinaryType.ZERO) { - // left one and right one - if (cellsOneAway[3] != null - && cellsOneAway[2] != null - && cellsOneAway[3].getType() != BinaryType.UNKNOWN - && cellsOneAway[2].getType() != BinaryType.UNKNOWN) { - if (cellsOneAway[3].getType() == cell.getType() - && cellsOneAway[2].getType() == cell.getType()) { - return false; - } - } - // down one and up one - if (cellsOneAway[1] != null - && cellsOneAway[0] != null - && cellsOneAway[1].getType() != BinaryType.UNKNOWN - && cellsOneAway[0].getType() != BinaryType.UNKNOWN) { - if (cellsOneAway[1].getType() == cell.getType() - && cellsOneAway[0].getType() == cell.getType()) { - return false; - } - } - } - return true; - } - - /** - * 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) { - - boolean surroundPairValid = checkSurroundPair(board, puzzleElement); - if (!surroundPairValid) { - return null; - } - boolean oneTileGapValid = checkOneTileGap(board, puzzleElement); - if (!oneTileGapValid) { - return null; - } - - return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE; - } -} diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java similarity index 64% rename from src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java rename to src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java index 82f658013..5089b3b5f 100644 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java @@ -6,32 +6,22 @@ import edu.rpi.legup.puzzle.binary.BinaryBoard; import edu.rpi.legup.puzzle.binary.BinaryCell; import edu.rpi.legup.puzzle.binary.BinaryType; - import java.util.Set; -public class UnbalancedRowColumnContradictionRule extends ContradictionRule { +public class UnbalancedRowOrColumnContradictionRule 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 UnbalancedRowColumnContradictionRule() { + public UnbalancedRowOrColumnContradictionRule() { super( "BINA-CONT-0002", - "Unbalanced Row/Column", + "Unbalanced Row Or 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; @@ -51,13 +41,11 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { } } - // if there are too many zeros or ones in this row - if (rowNumZeros > size / 2 || rowNumOnes > size / 2) { - return null; + if (rowNumZeros == size / 2 && rowNumOnes == size / 2) { + return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE; } - - Set col = binaryBoard.getColCells(cell.getLocation().x); + Set col = binaryBoard.getCol(cell.getLocation().x); size = col.size(); int colNumZeros = 0; @@ -71,11 +59,10 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { } } - // if there are too many zeros or ones in this column - if (colNumZeros > size / 2 || colNumOnes > size / 2) { - return null; + if (colNumZeros == size / 2 && colNumOnes == size / 2) { + return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE; } - return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE; + return null; } } diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UniqueRowColumnDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UniqueRowColumnDirectRule.java deleted file mode 100644 index 3f90510e3..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UniqueRowColumnDirectRule.java +++ /dev/null @@ -1,288 +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.DirectRule; -import edu.rpi.legup.model.tree.TreeNode; -import edu.rpi.legup.model.tree.TreeTransition; -import edu.rpi.legup.puzzle.binary.Binary; -import edu.rpi.legup.puzzle.binary.BinaryBoard; -import edu.rpi.legup.puzzle.binary.BinaryCell; -import edu.rpi.legup.puzzle.binary.BinaryType; - -import java.lang.reflect.Array; -import java.util.ArrayList; - -public class UniqueRowColumnDirectRule extends DirectRule { - private final String INVALID_USE_MESSAGE = "Number at cell is incorrect"; - - public UniqueRowColumnDirectRule() { - super( - "BINA-BASC-0004", - "Unique Row/Column", - "If an unfinished row/column only differs by empty cells from a finished one, " + - "fill contradicting empty cells with opposite digit to prevent a repeated row/column", - "edu/rpi/legup/images/binary/rules/UniqueRowColumnDirectRule.png"); - } - - /** - * Counts the number of empty (UNKNOWN) cells in a given sequence - * - * @param seq The sequence of BinaryType elements to check - * @return The number of empty (UNKNOWN) cells in the sequence - */ - private int getNumEmpty(ArrayList seq) { - int numEmpty = 0; - for (BinaryType t : seq) { - if (t.equals(BinaryType.UNKNOWN)) { - numEmpty++; - } - } - return numEmpty; - } - - /** - * Checks if there is a valid opposite digit to prevent a repeated row/column - * - * @param seq The sequence (row or column) to check - * @param origBoard The original board - * @param binaryCell The binary cell being checked - * @param rowOrColumn Flag to indicate whether checking a row (0) or a column (1) - * @return Null if a valid opposite digit is found, otherwise an error message - */ - private String checkOppositeDigitDifference(ArrayList seq, BinaryBoard origBoard, - BinaryCell binaryCell, int rowOrColumn) { - // rowOrColumn : 0 for row, 1 for column - - int numEmpty = getNumEmpty(seq); - if (numEmpty > 2) { - return "Row/Column must have at most 2 empty cells"; - } - - boolean valid = false; - for (int i = 0; i < seq.size(); i++) { - ArrayList currSeq; - // Get the sequence (row or column) from the original board to compare - if (rowOrColumn == 0) { - if (i == binaryCell.getLocation().y) { - continue; - } - currSeq = origBoard.getRowTypes(i); - } else { - if (i == binaryCell.getLocation().x) { - continue; - } - currSeq = origBoard.getColTypes(i); - } - - int numDifferentCells = 0; - for (int j = 0; j < currSeq.size(); j++) { - int numEmptyInCurrSeq = getNumEmpty(currSeq); - // If the current sequence has empty cells, it's not valid for comparison - if (numEmptyInCurrSeq != 0) { - valid = false; - break; - } - // Count differences between the sequences, stopping if more than 1 difference is found - if (!seq.get(j).equals(currSeq.get(j)) && !seq.get(j).equals(BinaryType.UNKNOWN)) { - if (++numDifferentCells > 1 || numEmpty != 1) { - valid = false; - break; - } - } - - // Check if there's a contradiction with the current cell, if not mark as valid - if (currSeq.get(j).equals(BinaryType.ZERO) && seq.get(j).equals(BinaryType.UNKNOWN) - && binaryCell.getType().equals(BinaryType.ONE)) { - if ((rowOrColumn == 0 && binaryCell.getLocation().x == j) || rowOrColumn == 1 - && binaryCell.getLocation().y == j) { - valid = true; - } - } - else if (currSeq.get(j).equals(BinaryType.ONE) && seq.get(j).equals(BinaryType.UNKNOWN) - && binaryCell.getType().equals(BinaryType.ZERO)) { - if ((rowOrColumn == 0 && binaryCell.getLocation().x == j) || rowOrColumn == 1 - && binaryCell.getLocation().y == j) { - valid = true; - } - } - } - // Exit if a valid sequence is found - if (valid) { - break; - } - } - - if (valid) { - return null; - } - return "There does not exist an opposite digit difference in "; - } - - /** - * Checks if there is one digit remaining in a sequence that can be filled to avoid repeating - * another sequence on the board - * - * @param seq The sequence (row or column) to check - * @param origBoard The original board - * @param binaryCell The binary cell being checked - * @param rowOrColumn Flag to indicate whether checking a row (0) or a column (1) - * @param zeroOrOne Flag to indicate whether checking for 0s (0) or 1s (1) - * @return Null if the rule can be applied, otherwise an error message - */ - private String checkRemainingOneDigitDifference(ArrayList seq, BinaryBoard origBoard, - BinaryCell binaryCell, int rowOrColumn, int zeroOrOne) { - // zeroOrOne: zero for 0, one for 1 - - for (int i = 0; i < seq.size(); i++) { - ArrayList currSeq; - if (rowOrColumn == 0) { - if (i == binaryCell.getLocation().y) { - continue; - } - currSeq = origBoard.getRowTypes(i); - } - else { - if (i == binaryCell.getLocation().x) { - continue; - } - currSeq = origBoard.getColTypes(i); - } - - boolean valid = true; - for (int j = 0; j < currSeq.size(); j++) { - int numEmptyInCurrSeq = getNumEmpty(currSeq); - // If the current sequence has empty cells, it's not valid for comparison - if (numEmptyInCurrSeq != 0) { - valid = false; - break; - } - // Check if there is a cell difference from this seq and current seq - if (!seq.get(j).equals(currSeq.get(j)) && !seq.get(j).equals(BinaryType.UNKNOWN)) { - valid = false; - break; - } - } - // Determine if the current sequence can be modified to prevent repetition - if (valid) { - BinaryType currSeqCell = currSeq.get(binaryCell.getLocation().x); - if (rowOrColumn == 0) { - currSeqCell = currSeq.get(binaryCell.getLocation().x); - } else if (rowOrColumn == 1) { - currSeqCell = currSeq.get(binaryCell.getLocation().y); - } - - // Check if this sequence has only one more zero remaining and current sequence fills that zero in, - // if so, zero in this seq must go in another cell to prevent repetition - if (zeroOrOne == 0) { - if (currSeqCell.equals(BinaryType.ZERO) && binaryCell.getType().equals(BinaryType.ONE)) { - return null; - } - } - // Check if this sequence has only one more one remaining and current sequence fills that one in, - // if so, one in this seq must go in another cell to prevent repetition - else if (zeroOrOne == 1) { - if (currSeqCell.equals(BinaryType.ONE) && binaryCell.getType().equals(BinaryType.ZERO)) { - return null; - } - } - } - } - - - return "There does not exist a sequence that can be prevented by a remaining digit difference"; - } - - /** - * 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) { - BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard(); - BinaryCell binaryCell = (BinaryCell) puzzleElement; - - // Check if filling the current cell with the opposite digit would prevent repetition with another row - ArrayList row = origBoard.getRowTypes(binaryCell.getLocation().y); - if (checkOppositeDigitDifference(row, origBoard, binaryCell, 0) == null) { - return null; - } - int numZeros = 0; - int numOnes = 0; - for (int i = 0; i < row.size(); i++) { - if (row.get(i).equals(BinaryType.ZERO)) { - numZeros++; - } - else if (row.get(i).equals(BinaryType.ONE)) { - numOnes++; - } - } - - // Check if only one more zero is needed, then see this row will be repeated by another row - // if current cell is filled in with last zero as well - if (numZeros == row.size()/2 - 1) { - if (checkRemainingOneDigitDifference(row, origBoard, binaryCell, 0, 0) == null) { - return null; - } - } - - // Check if only one more one is needed, then see this row will be repeated by another row - // if current cell is filled in with last one as well - if (numOnes == row.size()/2 - 1) { - if (checkRemainingOneDigitDifference(row, origBoard, binaryCell, 0, 1) == null) { - return null; - } - } - - // Check if filling the current cell with the opposite digit would prevent repetition with another column - ArrayList col = origBoard.getColTypes(binaryCell.getLocation().x); - if (checkOppositeDigitDifference(col, origBoard, binaryCell, 1) == null) { - return null; - } - - numZeros = 0; - numOnes = 0; - for (int i = 0; i < col.size(); i++) { - if (col.get(i).equals(BinaryType.ZERO)) { - numZeros++; - } - else if (col.get(i).equals(BinaryType.ONE)) { - numOnes++; - } - } - - // Check if only one more zero is needed, then see this column will be repeated by another column - // if current cell is filled in with last zero as well - if (numZeros == col.size()/2 - 1) { - if (checkRemainingOneDigitDifference(col, origBoard, binaryCell, 1, 0) == null) { - return null; - } - } - - // Check if only one more one is needed, then see this column will be repeated by another column - // if current cell is filled in with last one as well - if (numOnes == col.size()/2 - 1) { - if (checkRemainingOneDigitDifference(col, origBoard, binaryCell, 1, 1) == null) { - return null; - } - } - - return "There is no row/column that forces this cell to be a " + binaryCell.getData().toString(); - } - - /** - * 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/WastedBlockerContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/WastedBlockerContradictionRule.java deleted file mode 100644 index e7ab51b41..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/binary/rules/WastedBlockerContradictionRule.java +++ /dev/null @@ -1,178 +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; - -import java.util.ArrayList; - -public class WastedBlockerContradictionRule extends ContradictionRule { - private final String NO_CONTRADICTION_MESSAGE = "Does not contain a contradiction at this index"; - - public WastedBlockerContradictionRule() { - super( - "BINA-CONT-0004", - "Wasted Blocker", - "There exists a cell in this row/column that allocates a digit unnecessarily and" + - " will cause a future trio to appear", - "edu/rpi/legup/images/binary/rules/WastedBlockerContradictionRule.png"); - } - - /* - i [ n ] j - i -> digit on left (0 if no digit exists) - n -> number of empty cells - j -> digit on right (0 if no digit exists) - neededZeros = ( n + i + j ) / 3 - */ - /** - * Calculates the number of zeros needed in a sequence based on the values on either side and the number of empty cells. - * - * @param leftVal The value on the left side of the empty cells - * @param rightVal The value on the right side of the empty cells - * @param emptyCellsInCurSec The number of empty cells in the current section - * @return The number of zeros needed in the sequence - */ - private int calculateNeededZeros(int leftVal, int rightVal, int emptyCellsInCurSec) { - int leftCopy = leftVal; - int rightCopy = rightVal; - if (leftCopy == -1) { - leftCopy = 0; - } - if (rightCopy == -1) { - rightCopy = 0; - } - return ((emptyCellsInCurSec + leftCopy + rightCopy) / 3); - } - - /* - i [ n ] j - i -> digit on left (1 if no digit exists) - n -> number of empty cells - j -> digit on right (1 if no digit exists) - neededOnes = ( n + ( 1 - i ) + ( 1 - j ) ) / 3 - */ - /** - * Calculates the number of ones needed in a sequence based on the values on either side and the number of empty cells - * - * @param leftVal The value on the left side of the empty cells - * @param rightVal The value on the right side of the empty cells - * @param emptyCellsInCurSec The number of empty cells in the current section - * @return The number of ones needed in the sequence - */ - private int calculateNeededOnes(int leftVal, int rightVal, int emptyCellsInCurSec) { - int leftCopy = leftVal; - int rightCopy = rightVal; - if (leftCopy == -1) { - leftCopy = 1; - } - if (rightCopy == -1) { - rightCopy = 1; - } - return ((emptyCellsInCurSec + (1 - leftCopy) + (1 - rightCopy)) / 3); - } - - /** - * Checks a sequence (row or column) to see if a wasted blocker digit is used - * - * @param seq The sequence to check - * @return Null if the sequence contains a contradiction, otherwise an error message - */ - private String checkSequence(ArrayList seq) { - int numZeros = 0; - int numOnes = 0; - boolean emptyCell = false; - int emptyCellsInCurSec = 0; - int neededZeros = 0; - int neededOnes = 0; - - for (int i = 0; i < seq.size(); i++) { - if (seq.get(i).equals(BinaryType.ZERO) || seq.get(i).equals(BinaryType.ONE)) { - if (seq.get(i).equals(BinaryType.ZERO)) { - numZeros++; - } else if (seq.get(i).equals(BinaryType.ONE)) { - numOnes++; - } - - if (emptyCell) { - if (emptyCellsInCurSec > 1) { // Ignore case where there is only one empty cell - int leftVal; - int rightVal; - // Check if left cell is out of bounds - if (i-emptyCellsInCurSec-1 < 0) { - leftVal = -1; - } else { - leftVal = seq.get(i-emptyCellsInCurSec-1).toValue(); - } - rightVal = seq.get(i).toValue(); - neededZeros += calculateNeededZeros(leftVal, rightVal, emptyCellsInCurSec); - neededOnes += calculateNeededOnes(leftVal, rightVal, emptyCellsInCurSec); - } - emptyCell = false; - emptyCellsInCurSec = 0; - } - } else { - if (!emptyCell) { - emptyCell = true; - } - emptyCellsInCurSec++; - } - } - - // Check last cell is empty - if (emptyCell) { - if (emptyCellsInCurSec > 1) { // Ignore case where there is only one empty cell - int leftVal; - int rightVal; - // Check if left cell is out of bounds - if (seq.size()-1-emptyCellsInCurSec-1 < 0) { - leftVal = -1; - } else { - leftVal = seq.get(seq.size()-1-emptyCellsInCurSec).toValue(); - } - rightVal = -1; - neededZeros += calculateNeededZeros(leftVal, rightVal, emptyCellsInCurSec); - neededOnes += calculateNeededOnes(leftVal, rightVal, emptyCellsInCurSec); - } - } - - // Check if the number of needed zeros or ones exceeds half the sequence length - // If so, return null to indicate contradiction has occurred - if ((numZeros + neededZeros > seq.size()/2) || (numOnes + neededOnes > seq.size()/2)) { - return null; - } - - return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE; - } - - /** - * 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; - BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement); - - ArrayList row = binaryBoard.getRowTypes(cell.getLocation().y); - if (checkSequence(row) == null) { - return null; - } - - ArrayList col = binaryBoard.getColTypes(cell.getLocation().x); - if (checkSequence(col) == null) { - return null; - } - - return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE; - } -} 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 619d183a5..c8cb0d1b9 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,11 +1,9 @@ -BINA-BASC-0001 : PreventTrioContradictionRule -BINA-BASC-0002 : CompleteRowColumnDirectRule -BINA-BASC-0003 : SaveBlockerDirectRule -BINA-BASC-0004 : UniqueRowColumnDirectRule +BINA-BASC-0001 : SurroundPairDirectRule +BINA-BASC-0002 : OneTileGapDirectRule +BINA-BASC-0003 : CompleteRowColumnDirectRule -BINA-CONT-0001 : TrioContradictionRule -BINA-CONT-0002 : UnbalancedRowColumnContradictionRule -BINA-CONT-0003 : RepeatedRowColumnContradictionRule -BINA-CONT-0004 : WastedBlockerContradictionRule +BINA-CONT-0001 : ThreeAdjacentContradictionRule +BINA-CONT-0002 : UnbalancedRowOrColumnContradictionRule +BINA-CONT-0003 : DuplicateRowsOrColumnsContradictionRule -BINA-CASE-0001 : ZeroOrOneCaseRule \ No newline at end of file +BINA-CASE-0001 : OneOrZeroCaseRule \ 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 40c5e4a54..a9e5aa2df 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-ELEM-0001": + case "FPIX-PLAC-0001": this.setCellType(FillapixCellType.BLACK); break; - case "FPIX-ELEM-0004": + case "FPIX-PLAC-0002": this.setCellType(FillapixCellType.WHITE); break; - case "FPIX-ELEM-0002": + case "FPIX-UNPL-0001": 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 a6993778d..1d7c038a3 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-ELEM-0001", + "FPIX-PLAC-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 5852c1ad7..e869aeaf9 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class NumberTile extends PlaceableElement { +public class NumberTile extends NonPlaceableElement { private int object_num; public NumberTile() { super( - "FPIX-ELEM-0002", + "FPIX-UNPL-0001", "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 82d0dffb9..6778c1758 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class UnknownTile extends PlaceableElement { +public class UnknownTile extends NonPlaceableElement { public UnknownTile() { super( - "FPIX-ELEM-0003", + "FPIX-UNPL-0002", "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 b2eedfc09..67065a7e9 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-ELEM-0004", + "FPIX-PLAC-0002", "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 1aece4b97..0409fa800 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,4 +1,5 @@ -FPIX-ELEM-0001 : BlackTile -FPIX-ELEM-0002 : NumberTile -FPIX-ELEM-0003 : UnknownTile -FPIX-ELEM-0004 : WhiteTile \ No newline at end of file +FPIX-PLAC-0001 : BlackTile +FPIX-PLAC-0002 : WhiteTile + +FPIX-UNPL-0001 : NumberTile +FPIX-UNPL-0002 : UnknownTile \ 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 f0194bd39..860a6c011 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,9 +37,6 @@ 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 f8bb2d4f5..7db833f76 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,9 +45,6 @@ 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 a73806cd7..ab95c4658 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 21084b8c7..217ef79a8 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 placeable + * Gets the number of adjacent cells that are placable * * @param cell specified cell - * @return number of adjacent cells that are placeable + * @return number of adjacent cells that are placable */ - public int getNumPlaceable(LightUpCell cell) { + public int getNumPlacble(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 6d890e67b..8adf84cb4 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-ELEM-0002": + case "LTUP-PLAC-0001": this.data = -4; break; - case "LTUP-ELEM-0001": + case "LTUP-UNPL-0002": this.data = -1; break; - case "LTUP-ELEM-0004": + case "LTUP-UNPL-0003": this.data = -2; break; - case "LTUP-ELEM-0003": + case "LTUP-UNPL-0001": 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 eed3795d7..2ddb4f754 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class BlackTile extends PlaceableElement { +public class BlackTile extends NonPlaceableElement { public BlackTile() { super( - "LTUP-ELEM-0001", + "LTUP-UNPL-0002", "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 61ebac3d0..d238baa56 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-ELEM-0002", + "LTUP-PLAC-0001", "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 26f9be46c..ae314a4cf 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class NumberTile extends PlaceableElement { +public class NumberTile extends NonPlaceableElement { int object_number; // Follow the default format and resolves the NoSuchMethod error public NumberTile() { super( - "LTUP-ELEM-0003", + "LTUP-UNPL-0001", "Number Tile", "The number tile", "edu/rpi/legup/images/lightup/1.gif"); @@ -17,7 +17,7 @@ public NumberTile() { public NumberTile(int num) { super( - "LTUP-ELEM-0003", + "LTUP-UNPL-0001", "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 a724be600..24d420fe8 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class UnknownTile extends PlaceableElement { +public class UnknownTile extends NonPlaceableElement { public UnknownTile() { super( - "LTUP-ELEM-0004", + "LTUP-UNPL-0003", "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 deleted file mode 100644 index 93c97de1c..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/lightup_elements_reference_sheet.txt +++ /dev/null @@ -1,4 +0,0 @@ -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 53efb6587..4ba754731 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,10 +44,6 @@ 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 f73a34b2d..490122874 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,11 +47,6 @@ 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(); @@ -101,6 +96,7 @@ 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 de1f85edc..8cf68e570 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.getNumPlaceable(cell); + int placeable = lightUpBoard.getNumPlacble(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 cd5577eeb..78a5d320c 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class BombTile extends PlaceableElement { +public class BombTile extends NonPlaceableElement { 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 6cfc34c8d..447e2840c 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class UnsetTile extends PlaceableElement { +public class UnsetTile extends NonPlaceableElement { 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 1e0e85ed8..c6cd2c64e 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-ELEM-0001": + case "NURI-PLAC-0001": this.data = -1; break; - case "NURI-ELEM-0004": + case "NURI-PLAC-0002": this.data = 0; break; - case "NURI-ELEM-0002": + case "NURI-UNPL-0001": switch (m.getButton()) { case MouseEvent.BUTTON1: if (this.data <= 0 || this.data > 8) { diff --git a/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeController.java b/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeController.java index f2fad0d50..158abe7b4 100644 --- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeController.java +++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeController.java @@ -6,16 +6,6 @@ public class NurikabeController extends ElementController { - /** - * Handles cell state changes in the nurikabe puzzle when a mouse event occurs - * If the left mouse button is clicked: - * - If the control key is held down, shows a context menu at the mouse position - * - Otherwise, toggles the cell data state between 0, -1, and -2 in a cyclic manner - * If the right mouse button is clicked, the cell data state is also toggled between -2, -1, and 0 - * - * @param e MouseEvent triggered by the user interaction - * @param data PuzzleElement representing the cell being modified - */ @Override public void changeCell(MouseEvent e, PuzzleElement data) { NurikabeCell cell = (NurikabeCell) data; 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 e01821639..23efd4724 100644 --- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeExporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/nurikabe/NurikabeExporter.java @@ -10,13 +10,6 @@ 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 a7972b9b2..459a809e0 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-ELEM-0001", + "NURI-PLAC-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 2015d990b..475b278da 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class NumberTile extends PlaceableElement { +public class NumberTile extends NonPlaceableElement { private int object_num; public NumberTile() { super( - "NURI-ELEM-0002", + "NURI-UNPL-0001", "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 8a18c80cc..85d47e208 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class UnknownTile extends PlaceableElement { +public class UnknownTile extends NonPlaceableElement { public UnknownTile() { super( - "NURI-ELEM-0003", + "NURI-UNPL-0002", "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 ae07c6d76..35eb63b81 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-ELEM-0004", + "NURI-PLAC-0002", "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 deleted file mode 100644 index 667972fd6..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/nurikabe/elements/nurikabe_elements_reference_sheet.txt +++ /dev/null @@ -1,4 +0,0 @@ -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 1c87d5cfa..ac0ab6df6 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 be overridden in child classes. + * rule. This method is the one that should 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,10 +84,6 @@ 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 dd8943cdb..4901cfa6f 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 @@ -17,24 +17,24 @@ import java.util.Set; public class FinishRoomCaseRule extends CaseRule { - private int legitCases = 0; // placeholder for amount of cases originally generated in case user tries to delete - private Set uniqueCases; // stores the unique case hashes + private int legitCases = + 0; // placeholder for amount of cases originally generated in case user tries to delete + // cases public FinishRoomCaseRule() { super( "NURI-CASE-0002", "Finish Room", - "Room can be finished in up to nine ways", + "Room can be finished in up to five ways", "edu/rpi/legup/images/nurikabe/cases/FinishRoom.png"); - this.MAX_CASES = 9; - this.MIN_CASES = 1; - this.uniqueCases = new HashSet<>(); + this.MAX_CASES = 5; + this.MIN_CASES = 2; } /** * Checks whether the {@link TreeTransition} logically follows from the parent node using this - * rule. This method is the one that should have overridden in child classes. + * rule. This method is the one that should overridden in child classes. * * @param transition transition to check * @return null if the child node logically follow from the parent node, otherwise error message @@ -43,18 +43,18 @@ public FinishRoomCaseRule() { public String checkRuleRaw(TreeTransition transition) { NurikabeBoard destBoardState = (NurikabeBoard) transition.getBoard(); List childTransitions = transition.getParents().get(0).getChildren(); - if (childTransitions.size() > MAX_CASES) { + if (childTransitions.size() > 5) { return super.getInvalidUseOfRuleMessage() - + ": This case rule must have 9 or less children."; + + ": This case rule must have 5 or less children."; } - if (childTransitions.size() < MIN_CASES) { + if (childTransitions.size() < 2) { return super.getInvalidUseOfRuleMessage() - + ": This case rule must have 1 or more children."; + + ": This case rule must have 2 or more children."; } if (childTransitions.size() != legitCases) { return super.getInvalidUseOfRuleMessage() + ": Cases can not be removed from the branch."; - } // stops user from deleting 1 or more generated cases and still having path show as green + } // stops user from deleting 1 or mose generated cases and still having path show as green Set locations = new HashSet<>(); for (TreeTransition t1 : childTransitions) { locations.add( @@ -84,20 +84,31 @@ public CaseBoard getCaseBoard(Board board) { DisjointSets regions = NurikabeUtilities.getNurikabeRegions(nurikabeBoard); nurikabeBoard.setModifiable(false); - for (PuzzleElement element : nurikabeBoard.getPuzzleElements()) { // loops all puzzle elements - if (((NurikabeCell) element).getType() == NurikabeType.NUMBER) { // if the tile is a white number block - Set disRow = regions.getSet(((NurikabeCell) element)); // store the row of the white region - boolean only = true; // placeholder boolean of if the element being tested is the only number block in the room or not - + for (PuzzleElement element : + nurikabeBoard.getPuzzleElements()) { // loops all puzzle elements + if (((NurikabeCell) element).getType() + == NurikabeType.NUMBER) { // if the tile is a white number block + Set disRow = + regions.getSet( + ((NurikabeCell) element)); // store the row of the white region + boolean only = + true; // placeholder boolean of if the element being tested is the only + // number block in the room or not for (NurikabeCell d : disRow) { // loops through tiles in the room - // 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()))) { - only = false; + && !(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 } } - // if size of region is 1 less than the number block and the number block is only number block in the region - if (disRow.size() < ((NurikabeCell) element).getData() && only) { + if (disRow.size() + 1 == ((NurikabeCell) element).getData() + && only) { // if size of region is 1 less than the number block and the + // number block is only number block in the region caseBoard.addPickableElement(element); // add that room as a pickable element } } @@ -115,19 +126,16 @@ 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( - ((NurikabeCell) puzzleElement).getLocation().x, - ((NurikabeCell) puzzleElement).getLocation().y - ); // number cell whose room we want to fill - - Point origPoint = new Point(numberCell.getLocation().x, numberCell.getLocation().y); - int filledRoomSize = numberCell.getData(); // size of room we want afterward - + NurikabeCell numbaCell = + nuriBoard.getCell( + ((NurikabeCell) puzzleElement).getLocation().x, + ((NurikabeCell) puzzleElement) + .getLocation() + .y); // number cell whose room we want to fill + int filledRoomSize = numbaCell.getData(); // size of room we want afterward + Set locations = + new HashSet<>(); // locations where white space is added to finish room Point left = new Point(-1, 0); Point right = new Point(1, 0); Point bot = new Point(0, -1); @@ -137,114 +145,92 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) { directions.add(right); directions.add(top); directions.add(bot); - - Set checkedPoints = new HashSet<>(); // add all into checked points and continue at start of loop if inside - DisjointSets regions = NurikabeUtilities.getNurikabeRegions(nuriBoard); // gathers regions - Set numberCellRegion = regions.getSet(numberCell); // set of white spaces - - for (NurikabeCell d : numberCellRegion) { // loops through white spaces - generateCases(nuriBoard, d, filledRoomSize, directions, checkedPoints, cases, origPoint); - } - - legitCases = cases.size(); - return cases; - } - - /** - * Recursively generates possible cases for filling a room with white cells based on the current - * board state and specified parameters. - * - * @param nuriBoard the current Nurikabe board state - * @param currentCell the current cell being evaluated - * @param filledRoomSize the target size for the room being filled - * @param directions the set of possible directions to expand the room - * @param checkedPoints the set of points already evaluated to avoid redundancy - * @param cases the list of valid board cases generated - * @param origPoint the original point of the number cell initiating the room filling - */ - private void generateCases(NurikabeBoard nuriBoard, NurikabeCell currentCell, int filledRoomSize, - Set directions, Set checkedPoints, ArrayList cases, Point origPoint) { - for (Point direction : directions) { - Point newPoint = new Point( - currentCell.getLocation().x + direction.x, - currentCell.getLocation().y + direction.y - ); - - if (newPoint.x < 0 || newPoint.y < 0 || - newPoint.x >= nuriBoard.getWidth() || newPoint.y >= nuriBoard.getHeight()) { - continue; // out of bounds - } - - NurikabeCell newCell = nuriBoard.getCell(newPoint.x, newPoint.y); - if (checkedPoints.contains(newPoint)) { - continue; // already checked + Set checkedPoints = + new HashSet<>(); // add all into checked points and continue at start of loop if + // inside + DisjointSets regions = + NurikabeUtilities.getNurikabeRegions(nuriBoard); // gathers regions + Set disRow = regions.getSet(numbaCell); // set of white spaces + for (NurikabeCell d : disRow) { // loops through white spaces + if (cases.size() >= 6) { // no need to check this many cases + // throw new IllegalStateException("Too many cases"); + continue; // crash/runtime protection } - - if (newCell.getType() == NurikabeType.UNKNOWN) { - newCell.setData(NurikabeType.WHITE.toValue()); // changes adjacent cell color to white - newCell.setModifiable(false); - checkedPoints.add(newPoint); - - DisjointSets regions = NurikabeUtilities.getNurikabeRegions(nuriBoard); // update regions variable - Set newRoomSet = regions.getSet(newCell); // gets set of cells in room with new white cell added - - if (!touchesDifferentRoom(nuriBoard, newCell, filledRoomSize, directions, origPoint)) { - if (newRoomSet.size() == filledRoomSize) { // if adding white fills the room to exact size of - // number block and doesn't connect with another room - Board caseBoard = nuriBoard.copy(); - // check if case for board already exists - boolean unique = true; - for (Board board : cases) { - if (caseBoard.equalsBoard(board)) { - unique = false; + for (Point direction : directions) { + if (cases.size() >= 6) { // no need to check this many cases + // throw new IllegalStateException("Too many cases"); + continue; // crash/runtime protection + } + if (!((nuriBoard.getWidth() > (d.getLocation().x + direction.x) + && (nuriBoard.getHeight() > d.getLocation().y + direction.y) + && (d.getLocation().x + direction.x >= 0) + && (d.getLocation().y + direction.y >= 0)))) { + continue; // if next location check would be outside of grid then continue + } + NurikabeCell curr = + nuriBoard.getCell( + d.getLocation().x + direction.x, d.getLocation().y + direction.y); + if (checkedPoints.contains(curr.getLocation())) { + continue; // if we already checked whether or not making this tile white would + // complete the room then continue + } + checkedPoints.add( + curr.getLocation()); // adds location to checkedPoints so we don't check + // it again and accidentally add + if (curr.getType() + == NurikabeType + .UNKNOWN) { // found adjacent space to region that is currently + // unknown + curr.setData( + NurikabeType.WHITE.toValue()); // changes adjacent cell color to white + nuriBoard.addModifiedData(curr); // adds modified before check + regions = NurikabeUtilities.getNurikabeRegions(nuriBoard); // update regions + Set disCreatedRow = + regions.getSet( + curr); // gets set of created row with new white cell added + if (disCreatedRow.size() + == filledRoomSize) { // If adding white fills the room to exact size of + // number block and doesn't connect with another + // room + Point here = curr.getLocation(); // gets current location of new white tile + // that fills room + boolean alreadyIn = + false; // sets whether or not the tile has already been added to + // false + for (Point p : + locations) { // loops through locations of previously added tiles + if (p == here) { // if point is already in + alreadyIn = true; // change already in to true break; } } - if (unique) { - caseBoard.addModifiedData(newCell); - cases.add(caseBoard); + 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 } - } else if (newRoomSet.size() < filledRoomSize) { - generateCases(nuriBoard, newCell, filledRoomSize, directions, checkedPoints, cases, origPoint); - } - } - newCell.setData(NurikabeType.UNKNOWN.toValue()); - newCell.setModifiable(true); - checkedPoints.remove(newPoint); - } - } - } - - /** - * Determines if a given cell touches a different room by checking adjacent cells in specified directions. - * - * @param board the current Nurikabe board state - * @param cell the cell being evaluated - * @param origRoomSize the size of the original room being filled - * @param directions the set of possible directions to check around the cell - * @param origPoint the original point of the number cell initiating the room filling - * @return true if the cell touches a different room, false otherwise - */ - private boolean touchesDifferentRoom(NurikabeBoard board, NurikabeCell cell, int origRoomSize, Set directions, Point origPoint) { - for (Point direction : directions) { - Point adjacentPoint = new Point( - cell.getLocation().x + direction.x, - cell.getLocation().y + direction.y - ); - - if (adjacentPoint.x >= 0 && adjacentPoint.y >= 0 && - adjacentPoint.x < board.getWidth() && adjacentPoint.y < board.getHeight()) { // check if out of bounds - NurikabeCell adjacentCell = board.getCell(adjacentPoint.x, adjacentPoint.y); - // check if the adjacent cell is a number cell - if (adjacentCell.getType() == NurikabeType.NUMBER) { - // check if it's different from the original number cell - if (origRoomSize != adjacentCell.getData() || (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 false; + return cases; } /** 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 ffd7c491d..75bba369f 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-ELEM-0004")) { + if (e.getElementID().equals("STTT-PLAC-0002")) { this.data = ShortTruthTableCellType.FALSE; } // Green Element else { - if (e.getElementID().equals("STTT-ELEM-0002")) { + if (e.getElementID().equals("STTT-PLAC-0001")) { this.data = ShortTruthTableCellType.TRUE; } // Unknown Element else { - if (e.getElementID().equals("STTT-ELEM-0005")) { + if (e.getElementID().equals("STTT-PLAC-0003")) { this.data = ShortTruthTableCellType.UNKNOWN; } // Argument Element else { - if (e.getElementID().equals("STTT-ELEM-0001")) { + if (e.getElementID().equals("STTT-UNPL-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-ELEM-0003")) { + if (e.getElementID().equals("STTT-UNPL-0002")) { 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 912fd2672..9294fba4e 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class ArgumentElement extends PlaceableElement { +public class ArgumentElement extends NonPlaceableElement { public ArgumentElement() { super( - "STTT-ELEM-0001", + "STTT-UNPL-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 56221fef3..783186baa 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-ELEM-0002", + "STTT-PLAC-0001", "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 b82ebc2cb..5fed4b1df 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class LogicSymbolElement extends PlaceableElement { +public class LogicSymbolElement extends NonPlaceableElement { public LogicSymbolElement() { super( - "STTT-ELEM-0003", + "STTT-UNPL-0002", "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 2114e62ec..e2a589b65 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-ELEM-0004", + "STTT-PLAC-0002", "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 52b54f202..d475bc05d 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-ELEM-0005", + "STTT-PLAC-0003", "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 c5421169f..471631553 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,5 +1,6 @@ -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 +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 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 22b49fd77..58d2068b2 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,9 +44,6 @@ 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 8aeb51a46..99f771246 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,11 +85,6 @@ 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 44f416cef..df5ba78a3 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 >= 3 && rows == columns; + return rows >= 4 && 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 0fc133786..4cd09b254 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-ELEM-0001")) { + if (!e.getElementID().equals("SKYS-UNPL-0003")) { 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(1); + clue.setData(0); } } else { - if (clue.getData() > 1) { + if (clue.getData() > 0) { 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 9e7283b20..1cf9a357b 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-ELEM-0002": + case "SKYS-UNPL-0001": this.data = 0; break; - case "SKYS-ELEM-0001": + case "SKYS-UNPL-0002": 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 0e6345ff1..5a49a1476 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); + } } } @@ -54,19 +54,6 @@ public void drawElement(Graphics2D graphics2D) { int xText = location.x + (size.width - metrics.stringWidth(value)) / 2; int yText = location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent(); - - // REPRESENT NO CLUE AS EMPTY STRING INSTEAD OF 0, SOLVING PUZZLES WITH NO CLUE IS CURRENTLY NOT WORKING - // IF YOU ARE IMPLEMENTING NO CLUE FUNCTIONALITY, UNCOMMENT BELOW CODE AND DELETE OTHER IF STATEMENT, - // ADDITIONALLY, GO TO SkyscrapersBoard AND EDIT LINES 220 AND 223 SO YOU CAN CYCLE FOR NO CLUE - // IN THE SKYSCRAPERS PUZZLE EDITOR -// if (value.equals("0")) { -// value = ""; -// } - if (value.equals("0")) { - value = "1"; - clue.setData(1); - } - graphics2D.drawString(value, xText, yText); } } 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 new file mode 100644 index 000000000..64c9033e6 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/skyscrapers/elements/ClueTile.java @@ -0,0 +1,14 @@ +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 f60e5fe8b..4d6b37c9a 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class NumberTile extends PlaceableElement { +public class NumberTile extends NonPlaceableElement { public NumberTile() { super( - "SKYS-ELEM-0001", + "SKYS-UNPL-0002", "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 07f6a1238..2fb21193a 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class UnknownTile extends PlaceableElement { +public class UnknownTile extends NonPlaceableElement { public UnknownTile() { super( - "SKYS-ELEM-0002", + "SKYS-UNPL-0001", "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 14e76a29d..604e1824e 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,2 +1,3 @@ -SKYS-ELEM-0001: NumberTile -SKYS-ELEM-0002: UnknownTile \ No newline at end of file +SKYS-UNPL-0001: Unknown Tile +SKYS-UNPL-0002: Number Tile +SKYS-UNPL-0003: Clue "Tile" \ 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 b48962c41..45bdadea3 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,9 +61,6 @@ 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 4f8e1df6b..145dd6ee2 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,9 +47,6 @@ 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 new file mode 100644 index 000000000..5a9ec0f0a --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt @@ -0,0 +1,235 @@ +//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 c4bbf7297..99f42886e 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class BlackTile extends PlaceableElement { +public class BlackTile extends NonPlaceableElement { 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 793d4dbeb..13ada3f4d 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class StarTile extends PlaceableElement { +public class StarTile extends NonPlaceableElement { 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 30921de8d..425fb5d5e 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class UnknownTile extends PlaceableElement { +public class UnknownTile extends NonPlaceableElement { 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 deleted file mode 100644 index 82352bd04..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/starbattle_elements_reference_sheet.txt +++ /dev/null @@ -1,4 +0,0 @@ -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 efd86bd7b..df900dcd5 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,10 +84,6 @@ 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 new file mode 100644 index 000000000..f18965fd6 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt @@ -0,0 +1,19 @@ +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 deleted file mode 100644 index f7893ca32..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/ModelSudokuBoard.java +++ /dev/null @@ -1,17 +0,0 @@ -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 c5f9eec2a..0b6971235 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.PossibleCellsForNumberRegionCaseRule; +import edu.rpi.legup.puzzle.sudoku.rules.PossibleNumberCaseRule; 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, PossibleCellsForNumberRegionCaseRule caseRule, SudokuCell cell) { + SudokuBoard baseBoard, PossibleNumberCaseRule 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 c27269536..877c92665 100644 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/Sudoku.java +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/Sudoku.java @@ -29,8 +29,6 @@ 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 4e194ae2c..006e6c0a5 100644 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCell.java +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuCell.java @@ -1,9 +1,7 @@ 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; @@ -15,10 +13,10 @@ public class SudokuCell extends GridCell { /** * SudokuCell Constructor - creates a new Sudoku cell to hold the puzzleElement * - * @param value value of the sudoku cell - * @param location location of the cell on the board + * @param value value of the sudoku cell + * @param location location of the cell on the board * @param groupIndex index of the group the cell is in on the board - * @param size size of the sudoku cell + * @param size size of the sudoku cell */ public SudokuCell(int value, Point location, int groupIndex, int size) { super(value, location); @@ -61,36 +59,4 @@ public SudokuCell copy() { copy.setGiven(isGiven); return copy; } - - /** - * Sets the type of this NurikabeCell - * - * @param e element to set the type of this nurikabe cell to - */ - @Override - public void setType(Element e, MouseEvent m) { - if (e.getElementName().equals("Number Tile")) { - if (m.getButton() == MouseEvent.BUTTON1) { - if (this.data <= 0 || this.data > 8) { - this.data = 1; - } - else { - this.data = this.data + 1; - } - } - else { - if (m.getButton() == MouseEvent.BUTTON3) { - if (this.data > 1) { - this.data = this.data - 1; - } - else { - this.data = 9; - } - } - } - } - else if (e.getElementName().equals("Unknown Tile")) { - this.data = 0; - } - } } 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 bcad1a0ce..9b24f13da 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 5084279c3..68bf1e795 100644 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuImporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuImporter.java @@ -110,6 +110,16 @@ 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 d2a8d95ab..aa58f9a23 100644 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuView.java +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/SudokuView.java @@ -22,15 +22,10 @@ public SudokuView(SudokuBoard board) { for (int k = 0; k < gridSize.width; k++) { Point location = new Point( - k * elementSize.width + (k / minorSize) * 4 + 5,// - i * elementSize.height + (i / minorSize) * 4 + 5); -// Point location = -// new Point( -// k * elementSize.width, -// i * elementSize.height); + k * elementSize.width + (k / minorSize) * 4 + 5, + i * elementSize.height + (i / minorSize) * 4 + 5); 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 b8f4a596c..12183d70d 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 @@ -1,14 +1,26 @@ - package edu.rpi.legup.puzzle.sudoku.elements; import edu.rpi.legup.model.elements.PlaceableElement; public class NumberTile extends PlaceableElement { + private int object_num; + public NumberTile() { - super( - "SUDO-ELEM-0001", - "Number Tile", - "A number tile", - "edu/rpi/legup/images/sudoku/tiles/NumberTile.png"); + super("SUDO-PLAC-0001", "Number Tile", "A numbered tile", null); + object_num = 0; + } + + /** + * @return this object's tile number... + */ + public int getTileNumber() { + return object_num; + } + + /** + * @param num Amount to set tile object to. + */ + public void setTileNumber(int num) { + object_num = num; } -} \ No newline at end of file +} diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/UnknownTile.java deleted file mode 100644 index 162ba46d1..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/UnknownTile.java +++ /dev/null @@ -1,13 +0,0 @@ -package edu.rpi.legup.puzzle.sudoku.elements; - -import edu.rpi.legup.model.elements.PlaceableElement; - -public class UnknownTile extends PlaceableElement { - public UnknownTile() { - super( - "SUDO-ELEM-0002", - "Unknown Tile", - "A blank tile", - "edu/rpi/legup/images/sudoku/tiles/UnknownTile.png"); - } -} \ No newline at end of file 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 deleted file mode 100644 index b8df27eb6..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/elements/sudoku_elements_reference_sheet.txt +++ /dev/null @@ -1,2 +0,0 @@ -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 new file mode 100644 index 000000000..190679b41 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/AdvancedDeductionDirectRule.java @@ -0,0 +1,99 @@ +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 6544bf7c3..fd03ef36c 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/rules/forcedByElimination.png"); + "edu/rpi/legup/images/sudoku/forcedByElimination.png"); } /** @@ -32,146 +32,52 @@ 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"; } - // Get defaults + int size = initialBoard.getSize(); + Set region = initialBoard.getRegion(cell.getGroupIndex()); Set row = initialBoard.getRow(cell.getLocation().y); Set col = initialBoard.getCol(cell.getLocation().x); - // 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()) { + boolean contains = false; + if (region.size() == size - 1) { + for (SudokuCell c : region) { + if (cell.getData() == c.getData()) { contains = true; + break; } } - for (SudokuCell cc : ccol) { - if (cc.getData() == cell.getData()) { - contains = true; - } - } - // Stop if another cell can hold number if (!contains) { - restrained = false; - break; + return null; } } - // 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()) { + if (row.size() == size - 1) { + contains = false; + for (SudokuCell c : row) { + if (cell.getData() == c.getData()) { contains = true; + break; } } - // Stop if another cell can hold number if (!contains) { - restrained = false; - break; + return null; } } - // 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()) { + if (col.size() == size - 1) { + contains = false; + for (SudokuCell c : col) { + if (cell.getData() == c.getData()) { contains = true; + break; } } - for (SudokuCell cc : crow) { - if (cc.getData() == cell.getData()) { - contains = true; - } - } - // Stop if another cell can hold number if (!contains) { - restrained = false; - break; + return null; } } - // 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 333d91749..ca0ac3023 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/rules/forcedByDeduction.png"); + "edu/rpi/legup/images/sudoku/forcedByDeduction.png"); } /** @@ -32,37 +32,28 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem SudokuBoard initialBoard = (SudokuBoard) transition.getParents().get(0).getBoard(); SudokuBoard finalBoard = (SudokuBoard) transition.getBoard(); - // Assign basics + int index = puzzleElement.getIndex(); 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); - - // Create hashset of all numbers + int groupNum = rowIndex / groupDim * groupDim + colIndex % groupDim; 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, rowIndex); + SudokuCell cell = initialBoard.getCell(i, colIndex); numbers.remove(cell.getData()); } for (int i = 0; i < groupSize; i++) { - SudokuCell cell = initialBoard.getCell(colIndex, i); + SudokuCell cell = initialBoard.getCell(rowIndex, i); numbers.remove(cell.getData()); } - - // Check if plausible if (numbers.size() > 1) { return super.getInvalidUseOfRuleMessage() + ": The number at the index is not forced"; } else { @@ -73,11 +64,7 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem + ": The number at the index is forced but not correct"; } } - if (numbers.toArray(new Integer[1])[0] == puzzleElement.getData()) { - return null; - } - return super.getInvalidUseOfRuleMessage() - + ": The number at the index is forced but not correct"; + return null; } /** 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 deleted file mode 100644 index c8d627634..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberColumnContradictionRule.java +++ /dev/null @@ -1,90 +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.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 deleted file mode 100644 index f5106b858..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRegionContradictionRule.java +++ /dev/null @@ -1,90 +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.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 deleted file mode 100644 index e3f9f764a..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoCellForNumberRowContradictionRule.java +++ /dev/null @@ -1,90 +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.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/NoNumberForCellContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoSolutionContradictionRule.java similarity index 72% rename from src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoNumberForCellContradictionRule.java rename to src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoSolutionContradictionRule.java index 6ea8f0a2a..e44728d3e 100644 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoNumberForCellContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/NoSolutionContradictionRule.java @@ -8,14 +8,14 @@ import java.util.HashSet; import java.util.Set; -public class NoNumberForCellContradictionRule extends ContradictionRule { +public class NoSolutionContradictionRule extends ContradictionRule { - public NoNumberForCellContradictionRule() { + public NoSolutionContradictionRule() { super( - "SUDO-CONT-0004", - "No Number for Cell", + "SUDO-CONT-0001", + "No Solution for Cell", "Process of elimination yields no valid numbers for an empty cell.", - "edu/rpi/legup/images/sudoku/rules/NoSolution.png"); + "edu/rpi/legup/images/sudoku/NoSolution.png"); } /** @@ -41,19 +41,21 @@ 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 (SudokuCell s : region) { - solution.add(s.getData()); - } - for (SudokuCell s : row) { - solution.add(s.getData()); + for (int i = 1; i <= groupSize; i++) { + solution.add(i); } - for (SudokuCell s : col) { - solution.add(s.getData()); + for (SudokuCell c : region) { + solution.remove(c.getData()); + } + for (SudokuCell c : row) { + solution.remove(c.getData()); + } + for (SudokuCell c : col) { + solution.remove(c.getData()); } - solution.remove(0); - if (solution.size() == 9) { + if (solution.isEmpty()) { return null; } diff --git a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumbersForCellCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellCaseRule.java similarity index 59% rename from src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumbersForCellCaseRule.java rename to src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellCaseRule.java index e17acc26b..fb6da62d4 100644 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumbersForCellCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellCaseRule.java @@ -5,18 +5,19 @@ 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 edu.rpi.legup.puzzle.sudoku.SudokuBoard; +import edu.rpi.legup.puzzle.sudoku.SudokuCell; import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; -public class PossibleNumbersForCellCaseRule extends CaseRule { - - public PossibleNumbersForCellCaseRule() { +public class PossibleCellCaseRule extends CaseRule { + public PossibleCellCaseRule() { super( "SUDO-CASE-0001", - "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"); + "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"); } /** @@ -65,34 +66,42 @@ public CaseBoard getCaseBoard(Board board) { */ @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<>(); - if (puzzleElement == null) { - return cases; - } - SudokuBoard sudokuBoard = (SudokuBoard) board; - List caseCells = new ArrayList<>(); SudokuCell cell = (SudokuCell) puzzleElement; - for (int i = 1; i <= 9; i++) { - Board newCase = sudokuBoard.copy(); - PuzzleElement element = newCase.getPuzzleElement(puzzleElement); - element.setData(i); - newCase.addModifiedData(element); + 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()); + } + } + + int colNum = cell.getLocation().x; + for (SudokuCell c : sudokuBoard.getRegion(colNum)) { + if (c.getData().equals(c.getData())) { + possibleValue.remove(c.getData()); + } + } + + for (Integer i : possibleValue) { + SudokuBoard newCase = sudokuBoard.copy(); + + PuzzleElement newCasePuzzleElement = newCase.getPuzzleElement(puzzleElement); + newCasePuzzleElement.setData(i); + newCase.addModifiedData(newCasePuzzleElement); cases.add(newCase); } 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 deleted file mode 100644 index 47e408369..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRegionCaseRule.java +++ /dev/null @@ -1,104 +0,0 @@ -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 deleted file mode 100644 index 868541377..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberRowCaseRule.java +++ /dev/null @@ -1,107 +0,0 @@ -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/PossibleCellsForNumberColumnCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumberCaseRule.java similarity index 53% rename from src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberColumnCaseRule.java rename to src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumberCaseRule.java index bab0bc79b..e6ab0e64c 100644 --- a/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleCellsForNumberColumnCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/PossibleNumberCaseRule.java @@ -6,26 +6,21 @@ 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.PossibleNumberCaseBoard; 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 PossibleCellsForNumberColumnCaseRule extends CaseRule { +public class PossibleNumberCaseRule extends CaseRule { - // Board math for translating indexes to numbers - private ModelSudokuBoard model = new ModelSudokuBoard(); - - // Old board for caseBoard reference - private SudokuBoard lagBoard; - - public PossibleCellsForNumberColumnCaseRule() { + public PossibleNumberCaseRule() { super( - "SUDO-CASE-0004", - "Possible Cells for Number - Column", + "SUDO-CASE-0002", + "Possible Numbers for Cell", "An empty cell has a limited set of possible numbers that can fill it.", - "edu/rpi/legup/images/sudoku/rules/possible_cells_number_column.png"); + "edu/rpi/legup/images/sudoku/PossibleValues.png"); } /** @@ -55,12 +50,12 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem @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.getModelColumnNumbers(puzzleElement.getIndex())); - caseBoard.addPickableElement(puzzleElement); + 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); } return caseBoard; } @@ -74,7 +69,7 @@ public CaseBoard getCaseBoard(Board board) { */ @Override public ArrayList getCases(Board board, PuzzleElement puzzleElement) { - return getCases(board, puzzleElement, 1, GroupType.COLUMN); + return getCases(board, puzzleElement, 1, GroupType.REGION); } /** @@ -89,19 +84,48 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) { public ArrayList getCases( Board board, PuzzleElement puzzleElement, int value, GroupType groupType) { ArrayList cases = new ArrayList<>(); - SudokuBoard sudokuBoard = lagBoard; - SudokuCell sourceCell = (SudokuCell) puzzleElement; + SudokuBoard sudokuBoard = (SudokuBoard) board; + List caseCells = new ArrayList<>(); + SudokuCell cell = (SudokuCell) puzzleElement; - 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); + 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); } } + + 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/RepeatedNumberContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/sudoku/rules/RepeatedNumberContradictionRule.java index f8172d071..955414e8e 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-0005", + "SUDO-CONT-0002", "Repeated Numbers", "Two identical numbers are placed in the same group.", - "edu/rpi/legup/images/sudoku/rules/RepeatedNumber.png"); + "edu/rpi/legup/images/sudoku/RepeatedNumber.png"); } /** @@ -29,51 +29,39 @@ 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(); + } - // 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 region = sudokuBoard.getRegion(cell.getGroupIndex()); + Set row = sudokuBoard.getRow(cell.getLocation().y); + Set col = sudokuBoard.getCol(cell.getLocation().x); - Set col = sudokuBoard.getCol(i); - Set colDup = new HashSet<>(); + Set regionDup = new HashSet<>(); + Set rowDup = new HashSet<>(); + Set colDup = new HashSet<>(); - // 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()); + for (SudokuCell c : region) { + if (regionDup.contains(c.getData())) { + return null; } + regionDup.add(c.getData()); + } - for (SudokuCell c : row) { - if (c.getData() == 0) { - continue; - } - if (rowDup.contains(c.getData())) { - return null; - } - rowDup.add(c.getData()); + for (SudokuCell c : row) { + if (rowDup.contains(c.getData())) { + return null; } + rowDup.add(c.getData()); + } - for (SudokuCell c : col) { - if (c.getData() == 0) { - continue; - } - if (colDup.contains(c.getData())) { - return null; - } - colDup.add(c.getData()); + for (SudokuCell c : col) { + if (colDup.contains(c.getData())) { + return null; } + 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 ceffa168c..a8635330d 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,13 +1,9 @@ +SUDO-BASC-0001 : AdvancedDeductionDirectRule SUDO-BASC-0002 : LastCellForNumberDirectRule SUDO-BASC-0003 : LastNumberForCellDirectRule -SUDO-CONT-0001 : NoCellForNumberRegionContradictionRule -SUDO-CONT-0002 : NoCellForNumberRowContradictionRule -SUDO-CONT-0003 : NoCellForNumberColumnContradictionRule -SUDO-CONT-0004 : NoNumberForCellContradictionRule -SUDO-CONT-0005 : RepeatedNumberContradictionRule +SUDO-CONT-0001 : NoSolutionContradictionRule +SUDO-CONT-0002 : RepeatedNumberContradictionRule -SUDO-CASE-0001 : PossibleNumbersForCellCaseRule -SUDO-CASE-0002 : PossibleCellsForNumberRegionCaseRule -SUDO-CASE-0003 : PossibleCellsForNumberRowCaseRule -SUDO-CASE-0004 : PossibleCellsForNumberColumnCaseRule \ No newline at end of file +SUDO-CASE-0001 : PossibleCellCaseRule +SUDO-CASE-0002 : PossibleNumberCaseRule \ 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 4b0113232..68c97865d 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTent.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTent.java @@ -3,8 +3,6 @@ import edu.rpi.legup.model.Puzzle; import edu.rpi.legup.model.gameboard.Board; import edu.rpi.legup.model.gameboard.PuzzleElement; -import edu.rpi.legup.model.rules.ContradictionRule; - import java.util.List; public class TreeTent extends Puzzle { @@ -60,20 +58,7 @@ public boolean isValidDimensions(int rows, int columns) { */ @Override public boolean isBoardComplete(Board board) { - 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; + return false; } /** 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 1d33b9035..5356120a8 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-ELEM-0001", + "TREE-PlAC-0002", "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 96124a98d..950aebfa7 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-ELEM-0002", + "TREE-PLAC-0001", "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 3d94cbfba..d04886ed5 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class TreeTile extends PlaceableElement { +public class TreeTile extends NonPlaceableElement { public TreeTile() { super( - "TREE-ELEM-0003", + "TREE-UNPL-0001", "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 99b75b60c..a54240efd 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.PlaceableElement; +import edu.rpi.legup.model.elements.NonPlaceableElement; -public class UnknownTile extends PlaceableElement { +public class UnknownTile extends NonPlaceableElement { public UnknownTile() { super( - "TREE-ELEM-0004", + "TREE-UNPL-0002", "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 deleted file mode 100644 index e0cfc1dfa..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/elements/treetent_elements_reference_sheet.txt +++ /dev/null @@ -1,4 +0,0 @@ -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 8fe9b6873..aaa1a8fbc 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,11 +61,7 @@ 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 cbe91c3a7..bd303174a 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,10 +60,6 @@ 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 153692ad0..03d039898 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,10 +62,6 @@ 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 b1aa24eca..70fbea033 100644 --- a/src/main/java/edu/rpi/legup/ui/CreatePuzzleDialog.java +++ b/src/main/java/edu/rpi/legup/ui/CreatePuzzleDialog.java @@ -10,10 +10,6 @@ import java.util.Objects; import javax.swing.*; -/** - * Provides the user interface components for creating a new puzzle in the Legup application. - * This package includes classes for displaying dialog boxes to configure and initialize puzzles. - */ public class CreatePuzzleDialog extends JDialog { private HomePanel homePanel; @@ -21,13 +17,6 @@ public class CreatePuzzleDialog extends JDialog { private JComboBox gameBox; private ActionListener gameBoxListener = new ActionListener() { - /** - * An ActionListener that handles changes in the drop-down menu for selecting puzzle types. - * When a new item is selected in the drop-down menu, this listener updates the visibility of - * the text input area and the row/column input fields based on the selected puzzle type. - * If "ShortTruthTable" is selected, the text input area is shown and the row/column fields are hidden. - * For other puzzle types, the row/column fields are shown and the text input area is hidden. - */ @Override public void actionPerformed(ActionEvent e) { JComboBox comboBox = (JComboBox) e.getSource(); @@ -68,7 +57,9 @@ public void actionPerformed(ActionEvent e) { */ @Override public void actionPerformed(ActionEvent ae) { - String game = getGame(); + String game = + Config.convertDisplayNameToClassName( + (String) gameBox.getSelectedItem()); // Check if all 3 TextFields are filled if (game.equals("ShortTruthTable") && textArea.getText().isEmpty()) { @@ -77,8 +68,8 @@ public void actionPerformed(ActionEvent ae) { } if (!game.equals("ShortTruthTable") && (game.isEmpty() - || getRows().isEmpty() - || getColumns().isEmpty())) { + || rows.getText().isEmpty() + || columns.getText().isEmpty())) { System.out.println("Unfilled fields"); return; } @@ -90,8 +81,8 @@ public void actionPerformed(ActionEvent ae) { } else { homePanel.openEditorWithNewPuzzle( game, - Integer.valueOf(getRows()), - Integer.valueOf(getColumns())); + Integer.valueOf(rows.getText()), + Integer.valueOf(columns.getText())); } setVisible(false); } catch (IllegalArgumentException e) { @@ -115,12 +106,6 @@ 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); @@ -199,10 +184,6 @@ public CreatePuzzleDialog(JFrame parent, HomePanel homePanel) { cancel.addActionListener(cursorPressedCancel); } - /** - * Initializes the puzzle options available for selection in the dialog. - * The options are retrieved from the game board facade and sorted alphabetically. - */ public void initPuzzles() { this.games = GameBoardFacade.getInstance() @@ -213,12 +194,7 @@ public void initPuzzles() { gameBox = new JComboBox(this.games); } - - /** - * Handles the action events for the dialog, including interactions with the Ok and Cancel buttons - * - * @param e The action event to be processed - */ + // ^This method seems useless and never got covered public void actionPerformed(ActionEvent e) { if (e.getSource() == ok) { String game = Config.convertDisplayNameToClassName((String) gameBox.getSelectedItem()); @@ -235,7 +211,9 @@ public void actionPerformed(ActionEvent e) { } this.setVisible(false); } catch (IllegalArgumentException exception) { - // Do nothing. This is here to prevent the dialog from closing if the dimensions are invalid. + // Don't do anything. This is here to prevent the dialog from closing if the + // dimensions are + // invalid. } } else { if (e.getSource() == cancel) { @@ -245,38 +223,4 @@ public void actionPerformed(ActionEvent e) { } } } - - /** - * Retrieves the selected game from the combo box - * - * @return the class name of the selected game - */ - public String getGame() { - return Config.convertDisplayNameToClassName((String) gameBox.getSelectedItem()); - } - - /** - * Retrieves the number of rows specified in the dialog - * - * @return the number of rows as a string - */ - public String getRows() { - return rows.getText(); - } - - /** - * Retrieves the number of columns specified in the dialog - * - * @return the number of columns as a string - */ - public String getColumns() { - return columns.getText(); - } - - /** - * Retrieves the text entered in the text area, split by new lines. - * - * @return an array of strings, each representing as a line of text - */ - public String[] getTextArea() { return textArea.getText().split("\n"); } } diff --git a/src/main/java/edu/rpi/legup/ui/DynamicView.java b/src/main/java/edu/rpi/legup/ui/DynamicView.java index 344885783..8d3024c86 100644 --- a/src/main/java/edu/rpi/legup/ui/DynamicView.java +++ b/src/main/java/edu/rpi/legup/ui/DynamicView.java @@ -16,10 +16,6 @@ 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; @@ -33,12 +29,6 @@ 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; @@ -195,65 +185,34 @@ 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); status.setText(message); } - /** - * Clears the status label - */ public void resetStatus() { status.setText(""); } - /** - * Resets the view to its default state and zooms the content to fit the screen - */ public void reset() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); Board board1 = GameBoardFacade.getInstance().getBoard(); @@ -262,9 +221,6 @@ public void reset() { this.getScrollView().zoomFit(); } - /** - * Fits the board view to the screen - */ protected void fitBoardViewToScreen() { scrollView.zoomFit(); } diff --git a/src/main/java/edu/rpi/legup/ui/DynamicViewType.java b/src/main/java/edu/rpi/legup/ui/DynamicViewType.java index d161f5b9c..8c2f285cd 100644 --- a/src/main/java/edu/rpi/legup/ui/DynamicViewType.java +++ b/src/main/java/edu/rpi/legup/ui/DynamicViewType.java @@ -1,13 +1,5 @@ package edu.rpi.legup.ui; -/** - * An enumeration representing the different types of dynamic views supported by the application. - * The two types of views are: - *
    - *
  • {@code BOARD} - Represents a dynamic view of a game board
  • - *
  • {@code PROOF_TREE} - Represents a dynamic view of a proof tree
  • - *
- */ public enum DynamicViewType { BOARD, PROOF_TREE diff --git a/src/main/java/edu/rpi/legup/ui/HomePanel.java b/src/main/java/edu/rpi/legup/ui/HomePanel.java index f12ffdbf0..11f51eb0e 100644 --- a/src/main/java/edu/rpi/legup/ui/HomePanel.java +++ b/src/main/java/edu/rpi/legup/ui/HomePanel.java @@ -25,12 +25,6 @@ import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -/** - * The {@code HomePanel} class represents the home panel of the LEGUP application. - * This panel provides buttons for functionalities of opening the proof editor, - * opening the puzzle editor, and performing batch grading. It also includes a menu bar with - * options for preferences. - */ public class HomePanel extends LegupPanel { private static final Logger LOGGER = LogManager.getLogger(HomePanel.class.getName()); private LegupUI legupUI; @@ -42,37 +36,44 @@ public class HomePanel extends LegupPanel { private final int buttonSize = 100; - /** - * Initialize the proof solver to an empty panel with no puzzle - */ private ActionListener openProofListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - legupUI.getProofEditor().loadPuzzle("", null); + 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); } }; - /** - * 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) { + 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) { 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"); @@ -101,37 +102,23 @@ public JMenuBar getMenuBar() { return this.menuBar; } - /** - * Makes the panel visible and sets the menu bar of the frame - */ @Override public void makeVisible() { render(); 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); return new ImageIcon(resizedImage); } - /** - * Initializes the buttons for this panel - */ private void initButtons() { - this.buttons = new JButton[3]; + this.buttons = new JButton[4]; this.buttons[0] = - new JButton("Puzzle Solver") { + new JButton("Solve Puzzle") { { setSize(buttonSize, buttonSize); setMaximumSize(getSize()); @@ -149,7 +136,7 @@ private void initButtons() { this.buttons[0].addActionListener(CursorController.createListener(this, openProofListener)); this.buttons[1] = - new JButton("Puzzle Editor") { + new JButton("Create Puzzle") { { setSize(buttonSize, buttonSize); setMaximumSize(getSize()); @@ -163,17 +150,35 @@ 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.openPuzzleEditorDialog()); + this.buttons[1].addActionListener(l -> this.openNewPuzzleDialog()); - 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[2] = new JButton("Batch Grader"); + 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 + + 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[3].addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -187,10 +192,6 @@ public void actionPerformed(ActionEvent e) { }); } - /** - * Opens a folder chooser dialog and grades puzzles in the selected folder. - * The results are written to a CSV file. - */ public void checkFolder() { GameBoardFacade facade = GameBoardFacade.getInstance(); /* @@ -271,17 +272,13 @@ public void checkFolder() { } } catch (IOException ex) { LOGGER.error(ex.getMessage()); - this.buttons[2].addActionListener((ActionEvent e) -> use_xml_to_check()); + this.buttons[3].addActionListener((ActionEvent e) -> use_xml_to_check()); } } /** - * Processes XML files within a selected directory and generates a CSV report on their "solved?" status. - * The method allows the user to select a directory, and evaluates each XML file for a "solved?" status. - * Results are saved in a "result.csv" file. - * - * @effect Selects a directory, processes each XML file to check for "solved?" status, - * and writes results to "result.csv". Opens the CSV file upon completion. + * @effect batch grade using .xml parser - go through a collection of files and report their + * "solved?" status */ private void use_xml_to_check() { /* Select a folder, go through each .xml file in the subfolders, look for "isSolved" flag */ @@ -480,10 +477,6 @@ public void endDocument() throws SAXException { } } - /** - * Initializes the text labels for the user interface. - * Sets up labels for welcome message, led by Bram, and version information. - */ private void initText() { // TODO: add version text after auto-changing version label is implemented. (text[2] = // version) @@ -505,14 +498,11 @@ private void initText() { this.text[1] = credits; } - /** - * Renders the user interface components - */ 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))); @@ -520,8 +510,11 @@ 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[2]); + batchGraderButton.add(this.buttons[3]); batchGraderButton.setAlignmentX(Component.CENTER_ALIGNMENT); this.add(Box.createRigidArea(new Dimension(0, 5))); @@ -533,28 +526,11 @@ private void render() { this.add(Box.createRigidArea(new Dimension(0, 5))); } - /** - * Opens the puzzle editor dialog with no selected puzzle, leaving a blank panel - * - * @throws IllegalArgumentException if the configuration parameters are invalid (should never happen) - */ - private void openPuzzleEditorDialog() { - String game = ""; - int r = 0; - int c = 0; - - try { - this.openEditorWithNewPuzzle(game, r, c); - } catch (IllegalArgumentException e) { - System.out.println("Failed to open editor with new puzzle"); - e.printStackTrace(System.out); - } + private void openNewPuzzleDialog() { + CreatePuzzleDialog cpd = new CreatePuzzleDialog(this.frame, this); + cpd.setVisible(true); } - /** - * 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() @@ -598,14 +574,6 @@ 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(); @@ -658,48 +626,28 @@ 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.equals("")) { - this.legupUI.displayPanel(2); - this.legupUI.getPuzzleEditor().loadPuzzleFromHome(game, rows, columns); - } - else { - // Validate the dimensions - GameBoardFacade facade = GameBoardFacade.getInstance(); - boolean isValidDimensions = facade.validateDimensions(game, rows, columns); - if (!isValidDimensions) { - JOptionPane.showMessageDialog( - null, - "The dimensions you entered are invalid. Please double check \n" - + "the number of rows and columns and try again.", - "ERROR: Invalid Dimensions", - JOptionPane.ERROR_MESSAGE); - throw new IllegalArgumentException("ERROR: Invalid dimensions given"); - } - - if (this.legupUI == null) { - System.err.println("Error: legupUI is null in HomePanel"); - return; - } - - // Set game type on the puzzle editor - this.legupUI.displayPanel(2); - this.legupUI.getPuzzleEditor().loadPuzzleFromHome(game, rows, columns); + // Validate the dimensions + GameBoardFacade facade = GameBoardFacade.getInstance(); + boolean isValidDimensions = facade.validateDimensions(game, rows, columns); + if (!isValidDimensions) { + JOptionPane.showMessageDialog( + null, + "The dimensions you entered are invalid. Please double check \n" + + "the number of rows and columns and try again.", + "ERROR: Invalid Dimensions", + JOptionPane.ERROR_MESSAGE); + throw new IllegalArgumentException("ERROR: Invalid dimensions given"); } + // Set game type on the puzzle editor + this.legupUI.displayPanel(2); + this.legupUI.getPuzzleEditor().loadPuzzleFromHome(game, rows, columns); } /** - * Opens the puzzle editor for the specified puzzle with the given statements + * Opens the puzzle editor for the specified game 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/LegupPanel.java b/src/main/java/edu/rpi/legup/ui/LegupPanel.java index 38c44cbe4..d16167b3d 100644 --- a/src/main/java/edu/rpi/legup/ui/LegupPanel.java +++ b/src/main/java/edu/rpi/legup/ui/LegupPanel.java @@ -2,18 +2,9 @@ import javax.swing.*; -/** - * An abstract base class for panels in the LEGUP application. - * This class extends {@link JPanel} and defines common properties and methods - * for all panels in the LEGUP user interface - * (currently only implements toolbar scale) - */ public abstract class LegupPanel extends JPanel { /** Alerts panel that it will be going visible now */ protected final int TOOLBAR_ICON_SCALE = 40; - /** - * Abstract method to make the panel visible - */ public abstract void makeVisible(); } diff --git a/src/main/java/edu/rpi/legup/ui/LegupUI.java b/src/main/java/edu/rpi/legup/ui/LegupUI.java index 30857f05f..eb8b1663c 100644 --- a/src/main/java/edu/rpi/legup/ui/LegupUI.java +++ b/src/main/java/edu/rpi/legup/ui/LegupUI.java @@ -14,11 +14,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * The main user interface class for the LEGUP application. - * This class extends {@link JFrame} and implements {@link WindowListener} - * to manage the overall window and provide functionality for displaying various panels. - */ public class LegupUI extends JFrame implements WindowListener { private static final Logger LOGGER = LogManager.getLogger(LegupUI.class.getName()); @@ -41,7 +36,7 @@ public static String getOS() { return os; } - /** LegupUI Constructor - creates a new LegupUI to set up the menu and toolbar */ + /** LegupUI Constructor - creates a new LegupUI to setup the menu and toolbar */ public LegupUI() { setTitle("LEGUP"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -96,27 +91,17 @@ public void keyTyped(KeyEvent e) { setVisible(true); } - /** - * Initializes the panels used in the UI. - * Sets up the layout and adds panels to the window. - */ private void initPanels() { window = new JPanel(); window.setLayout(new BorderLayout()); add(window); panels = new LegupPanel[3]; - panels[0] = new HomePanel(this, this); + panels[0] = new HomePanel(this.fileDialog, 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"); @@ -130,31 +115,29 @@ 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]; } - /** - * Repaints the tree view in the proof editor. - */ 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); } @@ -167,13 +150,8 @@ public void showStatus(String status, boolean error, int timer) { // TODO: implement } - /** - * 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) { + // ask to edu.rpi.legup.save current proof + public boolean noquit(String instr) { int n = JOptionPane.showConfirmDialog(null, instr, "Confirm", JOptionPane.YES_NO_OPTION); return n != JOptionPane.YES_OPTION; } @@ -183,7 +161,7 @@ public void windowOpened(WindowEvent e) {} public void windowClosing(WindowEvent e) { if (GameBoardFacade.getInstance().getHistory().getIndex() > -1) { - if (exit("Exiting LEGUP?")) { + if (noquit("Exiting LEGUP?")) { this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); } else { this.setDefaultCloseOperation(EXIT_ON_CLOSE); @@ -205,47 +183,22 @@ 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 a6501e2a0..f703ffcbc 100644 --- a/src/main/java/edu/rpi/legup/ui/PickGameDialog.java +++ b/src/main/java/edu/rpi/legup/ui/PickGameDialog.java @@ -15,11 +15,6 @@ import javax.swing.JLabel; import javax.swing.JTextField; -/** - * A dialog for selecting a game. - * This class extends {@link JDialog} and implements {@link ActionListener} - * to handle user interactions for selecting a game type and puzzle file. - */ public class PickGameDialog extends JDialog implements ActionListener { JLabel gameLabel = new JLabel("Game:"); String[] games; @@ -111,10 +106,6 @@ public PickGameDialog(JFrame parent, boolean pickBothAtOnce) { c.add(autojustifyCheckBox); } - /** - * Initializes the available games and puzzles. - * Populates the {@link JComboBox} with game types and sets up the puzzle options. - */ public void initPuzzles() { Object[] o = GameBoardFacade.getInstance().getConfig().getPuzzleClassNames().toArray(); @@ -137,31 +128,14 @@ 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(); } - /** - * Handles action events for the dialog components. - * Responds to user interactions such as selecting a puzzle, choosing a puzzle file, - * and pressing the 'Ok' or 'Cancel' buttons. - * - * @param e the action event - */ public void actionPerformed(ActionEvent e) { if (e.getSource() == gameBox) { int index = gameBox.getSelectedIndex(); diff --git a/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java b/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java index c8639f796..475f4bb68 100644 --- a/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java +++ b/src/main/java/edu/rpi/legup/ui/PreferencesDialog.java @@ -17,12 +17,6 @@ import javax.imageio.ImageIO; import javax.swing.*; -/** - * A dialog for managing user preferences in the LEGUP application. - * This dialog allows users to configure various settings such as screen mode, - * update preferences, work directory path, and specific features related to board and tree views. - * Users can access this dialog from the home screen or proof editor. - */ public class PreferencesDialog extends JDialog { private RuleFrame rulesFrame; @@ -53,24 +47,12 @@ 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); @@ -120,11 +102,6 @@ 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))) { @@ -138,11 +115,6 @@ 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(); @@ -363,15 +335,6 @@ private JScrollPane createPuzzleTab(Puzzle puzzle) { return scrollPane; } - /** - * Creates a JPanel that represents a single row for a rule in the rule list. - * Each row displays the rule's name and an area for showing keyboard shortcuts - * associated with the rule. The keyboard shortcuts are dynamically updated based - * on user input. - * - * @param rule the rule object to be displayed - * @return a JPanel representing the row for the rule - */ private JPanel createRuleRow(Rule rule) { JPanel ruleRow = new JPanel(); ruleRow.setLayout(new BorderLayout()); @@ -424,14 +387,6 @@ public void keyPressed(KeyEvent e) { return ruleRow; } - /** - * Creates a JPanel containing a left-aligned label with the specified text. - * This label is typically used for section headings or descriptive text in the - * preferences dialog. - * - * @param text the text to be displayed on the label - * @return a JPanel containing the left-aligned label - */ private JPanel createLeftLabel(String text) { JPanel labelRow = new JPanel(); labelRow.setLayout(new BorderLayout()); @@ -445,24 +400,12 @@ private JPanel createLeftLabel(String text) { return labelRow; } - /** - * Creates a JSeparator with a maximum height of 5 pixels. - * This separator is used to visually divide sections in the preferences dialog. - * - * @return a JSeparator with a fixed height - */ private JSeparator createLineSeparator() { JSeparator separator = new JSeparator(); separator.setMaximumSize(new Dimension(Integer.MAX_VALUE, 5)); return separator; } - /** - * Applies the current user preferences and updates the associated components. - * This method retrieves user preferences from the dialog's components and stores - * them in the {@link LegupPreferences} instance. It also updates the rule panels - * in the rules frame if it is not null. - */ public void applyPreferences() { LegupPreferences prefs = LegupPreferences.getInstance(); prefs.setUserPref(LegupPreferences.WORK_DIRECTORY, workDirectory.getText()); diff --git a/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java b/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java index 88c1ee427..645a2c0d7 100644 --- a/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java +++ b/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java @@ -17,7 +17,6 @@ import edu.rpi.legup.ui.boardview.BoardView; import edu.rpi.legup.ui.proofeditorui.rulesview.RuleFrame; import edu.rpi.legup.ui.proofeditorui.treeview.TreePanel; -import edu.rpi.legup.ui.proofeditorui.treeview.TreeTransitionView; import edu.rpi.legup.ui.proofeditorui.treeview.TreeViewSelection; import edu.rpi.legup.user.Submission; import java.awt.*; @@ -37,14 +36,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * {@code ProofEditorPanel} is a panel that serves as the main user interface - * component for the proof editing functionality of LEGUP. It provides - * the graphical components and interactive elements necessary for editing and managing - * proofs, including toolbars, menus, and views for different aspects of proof editing. - * It also manages interactions with the rest of the application and updates the UI - * based on user actions and application state changes. - */ public class ProofEditorPanel extends LegupPanel implements IHistoryListener { private static final Logger LOGGER = LogManager.getLogger(ProofEditorPanel.class.getName()); private JMenuBar mBar; @@ -55,8 +46,8 @@ public class ProofEditorPanel extends LegupPanel implements IHistoryListener { private DynamicView dynamicBoardView; private JSplitPane topHalfPanel, mainPanel; private TitledBorder boardBorder; - private JButton[] toolBar1Buttons; - private JButton[] toolBar2Buttons; + + private JButton[] toolBarButtons; private JMenu file; private JMenuItem newPuzzle, resetPuzzle, @@ -76,8 +67,7 @@ public class ProofEditorPanel extends LegupPanel implements IHistoryListener { private JMenu about, help; private JMenuItem helpLegup, aboutLegup; - private JToolBar toolBar1; - private JToolBar toolBar2; + private JToolBar toolBar; private BoardView boardView; private JFileChooser folderBrowser; @@ -91,6 +81,7 @@ 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", @@ -120,13 +111,6 @@ 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; @@ -135,44 +119,22 @@ public ProofEditorPanel(FileDialog fileDialog, JFrame frame, LegupUI legupUI) { setPreferredSize(new Dimension(800, 700)); } - /** - * Makes the panel visible by setting up the toolbar and content components. - * This method also sets the menu bar of the frame to the one used by this panel. - */ @Override public void makeVisible() { this.removeAll(); - setupToolBar1(); + setupToolBar(); setupContent(); frame.setJMenuBar(getMenuBar()); } - /** - * Constructs and returns the {@code JMenuBar} for this panel. - * It populates it with various {@code JMenu} and {@code JMenuItem} components related - * to file operations, editing, viewing, and proof management. - * The menu bar includes: - *
    - *
  • {@code File} menu with options to open a new puzzle, reset the puzzle, save the proof, - * access preferences, and exit the editor.
  • - *
  • {@code Edit} menu with options for undo, redo, and fitting the board or tree to the screen.
  • - *
  • {@code Proof} menu with options for adding, deleting, merging, collapsing elements, - * and toggling settings related to rule applications and feedback.
  • - *
  • {@code About} menu with options to view information about the application and access help resources.
  • - *
- *

- * Accelerator keys are set based on the operating system (Mac or non-Mac). - * - * @return the {@code JMenuBar} instance containing the menus and menu items for this panel - */ public JMenuBar getMenuBar() { if (mBar != null) return mBar; mBar = new JMenuBar(); file = new JMenu("File"); newPuzzle = new JMenuItem("Open"); - resetPuzzle = new JMenuItem("Reset"); + resetPuzzle = new JMenuItem("Reset Puzzle"); // genPuzzle = new JMenuItem("Puzzle Generators"); // TODO: implement puzzle // generator saveProofAs = new JMenuItem("Save As"); // create a new file to save @@ -348,7 +310,6 @@ public JMenuBar getMenuBar() { } else { resetPuzzle.setAccelerator(KeyStroke.getKeyStroke('R', InputEvent.CTRL_DOWN_MASK)); } - file.addSeparator(); file.add(saveProofAs); @@ -496,10 +457,6 @@ public void actionPerformed(ActionEvent e) { return mBar; } - /** - * Clears the current puzzle, resets the UI to display the initial panel, - * and nullifies the references to the tree panel and board view. - */ public void exitEditor() { // Wipes the puzzle entirely as if LEGUP just started GameBoardFacade.getInstance().clearPuzzle(); @@ -508,13 +465,7 @@ public void exitEditor() { boardView = null; } - /** - * Opens a file chooser dialog allowing the user to select a directory. It uses the user's - * preferred directory or the last saved path if available. The selected directory is used - * to set the new working directory. - * - * @return an array containing the file name and the selected file, or {@code null} if the operation was canceled - */ + // File opener public Object[] promptPuzzle() { GameBoardFacade facade = GameBoardFacade.getInstance(); if (facade.getBoard() != null) { @@ -554,16 +505,9 @@ public Object[] promptPuzzle() { return null; } - System.out.println(preferences.getSavedPath()); return new Object[] {fileName, puzzleFile}; } - /** - * Calls {@link #promptPuzzle()} to get the file information and then loads the puzzle using - * the provided file name and file object. Updates the frame title to reflect the puzzle name. - * If the file is not valid or an error occurs, an error message is shown, and the user is - * prompted to try loading another puzzle. - */ public void loadPuzzle() { Object[] items = promptPuzzle(); // Return if items == null (cancel) @@ -575,19 +519,7 @@ public void loadPuzzle() { loadPuzzle(fileName, puzzleFile); } - /** - * Attempts to load a puzzle from the given file. If successful, it updates the - * UI to display the puzzle and changes the frame title to include the puzzle name. If the - * file is invalid or cannot be read, it shows an appropriate error message and prompts the - * user to try loading another puzzle. - * - * @param fileName the name of the file to load - * @param puzzleFile the file object representing the puzzle file - */ public void loadPuzzle(String fileName, File puzzleFile) { - if (puzzleFile == null && fileName.equals("")) { - legupUI.displayPanel(1); - } if (puzzleFile != null && puzzleFile.exists()) { try { legupUI.displayPanel(1); @@ -622,11 +554,7 @@ public void loadPuzzle(String fileName, File puzzleFile) { } } - /** - * Uses the current puzzle and its associated exporter to save the puzzle data - * to the file currently being used. If the puzzle or exporter is null, or if an error occurs - * during export, the method will catch the exception and print the stack trace. - */ + /** save the proof in the current file */ private void direct_save() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); if (puzzle == null) { @@ -646,11 +574,7 @@ private void direct_save() { } } - /** - * Opens a file chooser dialog for the user to select a directory. The chosen directory is used - * to determine where the puzzle file will be saved. If an exporter is available, it will be used - * to export the puzzle data to the selected path. - */ + /** Create a new file and save proof to it */ private void saveProofAs() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); if (puzzle == null) { @@ -688,11 +612,6 @@ private void saveProofAs() { } // Hyperlink for help button; links to wiki page for tutorials - /** - * Opens the default web browser to a help page related to the type of puzzle currently being used. - * The URL is chosen based on the name of the puzzle. If the puzzle type is not recognized, a general - * tutorial page is opened. - */ private void helpTutorial() { // redirecting to certain help link in wiki Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); @@ -720,14 +639,16 @@ 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(); } } - // unfinished + // add the new function need to implement 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. @@ -744,11 +665,7 @@ public void actionPerformed(ActionEvent e) { panel.add(moveing_buttom); } - /** - * Saves the puzzle using the current file name and shows a message dialog to - * confirm that the save operation was successful. If the puzzle or exporter is null, or if - * an error occurs during export, the method will catch the exception and print the stack trace. - */ + // Quick save proof to the current file with a pop window to show "successfully saved" private void saveProofChange() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); if (puzzle == null) { @@ -771,22 +688,13 @@ private void saveProofChange() { } } - /** - * 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 - */ + // ask to edu.rpi.legup.save current proof public boolean noquit(String instr) { int n = JOptionPane.showConfirmDialog(null, instr, "Confirm", JOptionPane.YES_NO_OPTION); return n != JOptionPane.YES_OPTION; } - /** - * 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. - */ + /** Sets the main content for the edu.rpi.legup.user interface */ protected void setupContent() { // JPanel consoleBox = new JPanel(new BorderLayout()); JPanel treeBox = new JPanel(new BorderLayout()); @@ -819,191 +727,110 @@ protected void setupContent() { ruleBox.add(boardPanel); treeBox.add(ruleBox); this.add(treeBox); + // consoleBox.add(treeBox); + // + // getContentPane().add(consoleBox); - mainPanel.setDividerLocation(mainPanel.getMaximumDividerLocation() + 100); + // JPopupPanel popupPanel = new JPopupPanel(); + // setGlassPane(popupPanel); + // popupPanel.setVisible(true); + mainPanel.setDividerLocation(mainPanel.getMaximumDividerLocation() + 100); + // frame.pack(); revalidate(); } - /** - * Initializes the first toolbar, configures its appearance, and adds an 'Open' button - * with an associated icon. An action listener is attached to the button to trigger the loading of - * a puzzle when clicked. - */ - private void setupToolBar1() { - toolBar1 = new JToolBar(); - toolBar1.setFloatable(false); - toolBar1.setRollover(true); - setToolBar2Buttons(new JButton[1]); - - URL open_url = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Open.png"); - - // 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)); - - JButton open = new JButton("Open", OpenImageIcon); - open.setFocusPainted(false); - - open.addActionListener((ActionEvent) -> loadPuzzle()); - - getToolBar2Buttons()[0] = open; - toolBar1.add(getToolBar2Buttons()[0]); - - this.add(toolBar1, BorderLayout.NORTH); - } + private void setupToolBar() { + setToolBarButtons(new JButton[ToolbarName.values().length]); + for (int i = 0; i < ToolbarName.values().length; i++) { + String toolBarName = ToolbarName.values()[i].toString(); + URL resourceLocation = + ClassLoader.getSystemClassLoader() + .getResource("edu/rpi/legup/images/Legup/" + toolBarName + ".png"); + + // 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; + } - /** - * Initializes the second toolbar, configures its appearance, and adds four buttons each - * with associated icons. Action listeners are attached to each button to trigger their respective - * actions when clicked: - *

    - *
  • 'Directions' button triggers the `directionsToolButton` method.
  • - *
  • 'Undo' button triggers the undo action in the puzzle's history.
  • - *
  • 'Redo' button triggers the redo action in the puzzle's history.
  • - *
  • 'Check' button triggers the `checkProof` method.
  • - *
- */ - private void setupToolBar2() { - toolBar2 = new JToolBar(); - toolBar2.setFloatable(false); - toolBar2.setRollover(true); - setToolBar2Buttons(new JButton[4]); - - URL directions_url = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Directions.png"); - - ImageIcon DirectionsImageIcon = new ImageIcon(directions_url); - Image DirectionsImage = DirectionsImageIcon.getImage(); - DirectionsImageIcon = - new ImageIcon( - DirectionsImage.getScaledInstance( - this.TOOLBAR_ICON_SCALE, - this.TOOLBAR_ICON_SCALE, - Image.SCALE_SMOOTH)); - - JButton directions = new JButton("Directions", DirectionsImageIcon); - directions.setFocusPainted(false); - directions.addActionListener((ActionEvent) -> directionsToolButton()); - - getToolBar2Buttons()[0] = directions; - toolBar2.add(getToolBar2Buttons()[0]); - - URL undo_url = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Undo.png"); - - ImageIcon UndoImageIcon = new ImageIcon(undo_url); - Image UndoImage = UndoImageIcon.getImage(); - UndoImageIcon = - new ImageIcon( - UndoImage.getScaledInstance( - this.TOOLBAR_ICON_SCALE, - this.TOOLBAR_ICON_SCALE, - Image.SCALE_SMOOTH)); - - JButton undo = new JButton("Undo", UndoImageIcon); - undo.setFocusPainted(false); - undo.addActionListener((ActionEvent) -> GameBoardFacade.getInstance().getHistory().undo()); + toolBar = new JToolBar(); + toolBar.setFloatable(false); + toolBar.setRollover(true); - getToolBar2Buttons()[1] = undo; - toolBar2.add(getToolBar2Buttons()[1]); - - URL redo_url = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Redo.png"); - - ImageIcon RedoImageIcon = new ImageIcon(redo_url); - Image RedoImage = RedoImageIcon.getImage(); - RedoImageIcon = - new ImageIcon( - RedoImage.getScaledInstance( - this.TOOLBAR_ICON_SCALE, - this.TOOLBAR_ICON_SCALE, - Image.SCALE_SMOOTH)); - - JButton redo = new JButton("Redo", RedoImageIcon); - redo.setFocusPainted(false); - redo.addActionListener((ActionEvent) -> { - GameBoardFacade.getInstance().getHistory().redo(); - }); - - getToolBar2Buttons()[2] = redo; - toolBar2.add(getToolBar2Buttons()[2]); - - URL check_url = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Check.png"); - - ImageIcon CheckImageIcon = new ImageIcon(check_url); - Image CheckImage = CheckImageIcon.getImage(); - CheckImageIcon = - new ImageIcon( - CheckImage.getScaledInstance( - this.TOOLBAR_ICON_SCALE, - this.TOOLBAR_ICON_SCALE, - Image.SCALE_SMOOTH)); - - JButton check = new JButton("Check", CheckImageIcon); - check.setFocusPainted(false); - check.addActionListener((ActionEvent) -> checkProof()); - - getToolBar2Buttons()[3] = check; - toolBar2.add(getToolBar2Buttons()[3]); - - - this.add(toolBar2, BorderLayout.NORTH); - } + 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(); - /** - * Sets the toolbar1 buttons - * - * @param toolBar1Buttons toolbar buttons - */ - public void setToolBar1Buttons(JButton[] toolBar1Buttons) { - this.toolBar1Buttons = toolBar1Buttons; - } + toolBar.add(getToolBarButtons()[i]); + getToolBarButtons()[i].setToolTipText(toolBarName); - /** - * Sets the toolbar2 buttons - * - * @param toolBar2Buttons toolbar buttons - */ - public void setToolBar2Buttons(JButton[] toolBar2Buttons) { - this.toolBar2Buttons = toolBar2Buttons; + getToolBarButtons()[i].setVerticalTextPosition(SwingConstants.BOTTOM); + getToolBarButtons()[i].setHorizontalTextPosition(SwingConstants.CENTER); + } + + // 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); } /** - * Gets the toolbar1 buttons + * Sets the toolbar buttons * - * @return toolbar1 buttons + * @param toolBarButtons toolbar buttons */ - public JButton[] getToolBar1Buttons() { - return toolBar1Buttons; + public void setToolBarButtons(JButton[] toolBarButtons) { + this.toolBarButtons = toolBarButtons; } /** - * Gets the toolbar2 buttons + * Gets the toolbar buttons * - * @return toolbar2 buttons + * @return toolbar buttons */ - public JButton[] getToolBar2Buttons() { - return toolBar2Buttons; + public JButton[] getToolBarButtons() { + return toolBarButtons; } - /** - * Uses the {@link GameBoardFacade} to obtain the current puzzle and board. If the puzzle is complete, - * it notifies the user of a correct proof. If not, it alerts the user that the board is not solved. - */ + /** Checks the proof for correctness */ private void checkProof() { GameBoardFacade facade = GameBoardFacade.getInstance(); Tree tree = GameBoardFacade.getInstance().getTree(); @@ -1030,58 +857,14 @@ private void checkProof() { } } - /** - * Retrieves the puzzle name from the `GameBoardFacade` and opens a corresponding rules page in the default web browser. - * - * @throws IOException if an error occurs while trying to open the web page - */ - private void directionsToolButton() { - String puzzleName = GameBoardFacade.getInstance().getPuzzleModule().getName(); - //System.out.println(puzzleName); - try { - if (puzzleName.equals("Fillapix")) { - java.awt.Desktop.getDesktop() - .browse(URI.create("https://github.com/Bram-Hub/LEGUP/wiki/Fill-a-pix-rules")); - } - else if (puzzleName.equals("LightUp")) { - java.awt.Desktop.getDesktop() - .browse(URI.create("https://github.com/Bram-Hub/LEGUP/wiki/Light-up-rules")); - } - else if (puzzleName.equals("TreeTent")) { - java.awt.Desktop.getDesktop() - .browse(URI.create("https://github.com/Bram-Hub/LEGUP/wiki/Tree-tent-rules")); - } - else if (puzzleName.equals("ShortTruthTables")) { - java.awt.Desktop.getDesktop() - .browse(URI.create("https://github.com/Bram-Hub/LEGUP/wiki/Short-truth-table-rules")); - } - else { - java.awt.Desktop.getDesktop() - .browse(URI.create("https://github.com/Bram-Hub/LEGUP/wiki/" + puzzleName + "-rules")); - } - } catch (IOException e) { - LOGGER.error("Can't open web page"); - } - } - - /** - * Repaints the board view and tree panel - */ private void repaintAll() { boardView.repaint(); 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(); - dynamicBoardView = new DynamicView(boardView, DynamicViewType.BOARD); this.topHalfPanel.setRightComponent(dynamicBoardView); this.topHalfPanel.setVisible(true); @@ -1102,20 +885,16 @@ public void setPuzzleView(Puzzle puzzle) { ruleFrame.getContradictionPanel().setRules(puzzle.getContradictionRules()); ruleFrame.getSearchPanel().setSearchBar(puzzle); - toolBar1.setVisible(false); - setupToolBar2(); + toolBarButtons[ToolbarName.CHECK.ordinal()].setEnabled(true); + // toolBarButtons[ToolbarName.SAVE.ordinal()].setEnabled(true); + reloadGui(); } - /** - * Calls {@code repaintTree()} to refresh the tree view. - */ public void reloadGui() { repaintTree(); } - /** - * Updates the tree view displayed in the tree panel to reflect the current state of the tree. - */ + public void repaintTree() { treePanel.repaintTreeView(GameBoardFacade.getInstance().getTree()); } @@ -1170,15 +949,6 @@ 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(); @@ -1233,36 +1003,20 @@ 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; } - - /** - * Returns the current dynamic board view. - * - * @return the current {@link DynamicView} - */ public DynamicView getDynamicBoardView() { return dynamicBoardView; } - /** - * Returns the current tree panel. - * - * @return the current {@link TreePanel} - */ public TreePanel getTreePanel() { return treePanel; } /** - * Called when an action is pushed onto the edu.rpi.legup.history stack + * Called when a action is pushed onto the edu.rpi.legup.history stack * * @param command action to push onto the stack */ @@ -1270,19 +1024,22 @@ 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()); frame.setTitle(puzzleName + " - " + puzzleFile.getName() + " *"); } - /** - * Updates the state of the undo and redo buttons to reflect that there are no actions - * available to undo or redo. It disables both buttons when the history is cleared. - */ + /** Called when the history is cleared */ @Override public void onClearHistory() { + // undo.setEnabled(false); + // toolBarButtons[ToolbarName.UNDO.ordinal()].setEnabled(false); + // redo.setEnabled(false); + // toolBarButtons[ToolbarName.REDO.ordinal()].setEnabled(false); } /** @@ -1294,7 +1051,9 @@ 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()); @@ -1315,7 +1074,9 @@ 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) { @@ -1359,10 +1120,6 @@ public void showStatus(String status, boolean error, int timer) { // TODO: implement } - - /** - * Zooms the tree view to fit within the available screen space - */ protected void fitTreeViewToScreen() { this.treePanel.getTreeView().zoomFit(); } diff --git a/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java b/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java index 2f3c16eac..f50c8d6fc 100644 --- a/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java +++ b/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java @@ -10,14 +10,9 @@ import edu.rpi.legup.history.IHistoryListener; import edu.rpi.legup.model.Puzzle; import edu.rpi.legup.model.PuzzleExporter; -import edu.rpi.legup.model.tree.Tree; -import edu.rpi.legup.model.tree.TreeNode; -import edu.rpi.legup.model.tree.TreeTransition; import edu.rpi.legup.save.ExportFileException; import edu.rpi.legup.save.InvalidFileFormatException; -import edu.rpi.legup.ui.HomePanel; import edu.rpi.legup.ui.boardview.BoardView; -import edu.rpi.legup.ui.proofeditorui.treeview.TreeViewSelection; import edu.rpi.legup.ui.puzzleeditorui.elementsview.ElementFrame; import java.awt.*; import java.awt.event.ActionEvent; @@ -27,32 +22,24 @@ import java.io.IOException; import java.net.URI; import java.net.URL; -import java.util.List; import java.util.Objects; import javax.swing.*; import javax.swing.border.TitledBorder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * Represents the panel used for puzzle editor in the LEGUP. - * This panel includes a variety of UI components such as toolbars, menus, and split panes. - * It handles puzzle file operations, including creating and editing puzzles. - */ public class PuzzleEditorPanel extends LegupPanel implements IHistoryListener { private static final Logger LOGGER = LogManager.getLogger(PuzzleEditorPanel.class.getName()); private JMenu[] menus; private JMenuItem helpLegup, aboutLegup; private JMenuBar menuBar; - private JToolBar toolBar1; - private JToolBar toolBar2; + private JToolBar toolBar; private JFileChooser folderBrowser; private JFrame frame; private JButton[] buttons; JSplitPane splitPanel; - private JButton[] toolBar1Buttons; - private JButton[] toolBar2Buttons; + private JButton[] toolBarButtons; private JPanel elementPanel; private DynamicView dynamicBoardView; private BoardView boardView; @@ -64,19 +51,8 @@ public class PuzzleEditorPanel extends LegupPanel implements IHistoryListener { private JPanel treePanel; private LegupUI legupUI; private EditorElementController editorElementController; - 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 instance - * - * @param fileDialog the file dialog used for file operations - * @param frame the main application frame - * @param legupUI the Legup UI instance - */ + static final int[] TOOLBAR_SEPARATOR_BEFORE = {2, 4, 8}; + public PuzzleEditorPanel(FileDialog fileDialog, JFrame frame, LegupUI legupUI) { this.fileDialog = fileDialog; this.frame = frame; @@ -85,10 +61,6 @@ public PuzzleEditorPanel(FileDialog fileDialog, JFrame frame, LegupUI legupUI) { setPreferredSize(new Dimension(800, 700)); } - /** - * Sets up the content of the panel, including the layout and UI components. - * Initializes and configures the {@code DynamicView} and {@code ElementFrame}, and adds them to the panel. - */ protected void setupContent() { JSplitPane splitPanel; JPanel elementBox = new JPanel(new BorderLayout()); @@ -120,11 +92,6 @@ protected void setupContent() { revalidate(); } - /** - * Configures the menu bar with menus and menu items for the application. - * Adds actions for opening, creating, and exiting puzzles. - * Also sets up help and about menu items. - */ public void setMenuBar() { String os = LegupUI.getOS(); menuBar = new JMenuBar(); @@ -136,33 +103,28 @@ public void setMenuBar() { menus[0] = new JMenu("File"); // file>new - JMenuItem openPuzzle = new JMenuItem("Open"); - openPuzzle.addActionListener((ActionEvent) -> loadPuzzle()); + JMenuItem newPuzzle = new JMenuItem("New"); + newPuzzle.addActionListener((ActionEvent) -> loadPuzzle()); if (os.equals("mac")) { - openPuzzle.setAccelerator( + newPuzzle.setAccelerator( KeyStroke.getKeyStroke( - 'O', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + 'N', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); } else { - openPuzzle.setAccelerator(KeyStroke.getKeyStroke('O', InputEvent.CTRL_DOWN_MASK)); + newPuzzle.setAccelerator(KeyStroke.getKeyStroke('N', InputEvent.CTRL_DOWN_MASK)); } - // file>create - JMenuItem createPuzzle = new JMenuItem("Create"); - createPuzzle.addActionListener((ActionEvent) -> { - hp = new HomePanel(this.frame, this.legupUI); - cpd = new CreatePuzzleDialog(this.frame, hp); - cpd.setLocationRelativeTo(null); - cpd.setVisible(true); - existingPuzzle = false; - }); + // file>save + JMenuItem savePuzzle = new JMenuItem("Save As"); + savePuzzle.addActionListener((ActionEvent) -> savePuzzle()); + JMenuItem directSavePuzzle = new JMenuItem("Direct Save Proof "); + directSavePuzzle.addActionListener((ActionEvent) -> direct_save()); if (os.equals("mac")) { - createPuzzle.setAccelerator( + newPuzzle.setAccelerator( KeyStroke.getKeyStroke( - 'C', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + 'D', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); } else { - createPuzzle.setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_DOWN_MASK)); + newPuzzle.setAccelerator(KeyStroke.getKeyStroke('D', InputEvent.CTRL_DOWN_MASK)); } - JMenuItem exit = new JMenuItem("Exit"); exit.addActionListener((ActionEvent) -> exitEditor()); if (os.equals("mac")) { @@ -172,9 +134,9 @@ public void setMenuBar() { } else { exit.setAccelerator(KeyStroke.getKeyStroke('Q', InputEvent.CTRL_DOWN_MASK)); } - menus[0].add(openPuzzle); - menus[0].add(createPuzzle); - //menus[0].add(directSavePuzzle); + menus[0].add(newPuzzle); + menus[0].add(savePuzzle); + menus[0].add(directSavePuzzle); menus[0].add(exit); // EDIT @@ -185,8 +147,7 @@ public void setMenuBar() { redo = new JMenuItem("Redo"); fitBoardToScreen = new JMenuItem("Fit Board to Screen"); - // TODO: Undo operation currently does not get updated correctly in history - //menus[1].add(undo); + menus[1].add(undo); undo.addActionListener((ActionEvent) -> GameBoardFacade.getInstance().getHistory().undo()); if (os.equals("mac")) { undo.setAccelerator( @@ -196,8 +157,8 @@ public void setMenuBar() { undo.setAccelerator(KeyStroke.getKeyStroke('Z', InputEvent.CTRL_DOWN_MASK)); } - // TODO: Redo operation currently does not get updated correctly in history - //menus[1].add(redo); + menus[1].add(redo); + // Created action to support two keybinds (CTRL-SHIFT-Z, CTRL-Y) Action redoAction = new AbstractAction() { @@ -271,12 +232,6 @@ public void actionPerformed(ActionEvent e) { frame.setJMenuBar(menuBar); } - /** - * Exits the puzzle editor and resets the application state to its initial condition. - * This method clears the current puzzle from the {@code GameBoardFacade}, - * resets the display to the initial panel, and nullifies references to the - * tree panel and board view. - */ public void exitEditor() { // Wipes the puzzle entirely as if LEGUP just started GameBoardFacade.getInstance().clearPuzzle(); @@ -285,188 +240,118 @@ public void exitEditor() { boardView = null; } - /** - * Makes the panel visible by setting up the toolbar, content, and menu bar. - * This method is called to refresh the panel's user interface. - */ @Override public void makeVisible() { this.removeAll(); - setupToolBar1(); + + setupToolBar(); setupContent(); setMenuBar(); } - /** - * Sets up the first toolbar with buttons for opening and creating puzzles. - * This method initializes the toolbar buttons with their icons and actions. - */ - private void setupToolBar1() { - setToolBar1Buttons(new JButton[2]); - - 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; - - toolBar1 = new JToolBar(); - toolBar1.setFloatable(false); - toolBar1.setRollover(true); - toolBar1.add(getToolBar1Buttons()[0]); - - URL create_url = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Open Puzzle.png"); - ImageIcon CreateImageIcon = new ImageIcon(create_url); - Image CreateImage = CreateImageIcon.getImage(); - CreateImageIcon = - new ImageIcon( - CreateImage.getScaledInstance( - this.TOOLBAR_ICON_SCALE, - this.TOOLBAR_ICON_SCALE, - Image.SCALE_SMOOTH)); - - JButton create = new JButton("Create", CreateImageIcon); - create.setFocusPainted(false); - create.addActionListener((ActionEvent) -> { - hp = new HomePanel(this.frame, this.legupUI); - cpd = new CreatePuzzleDialog(this.frame, hp); - cpd.setLocationRelativeTo(null); - cpd.setVisible(true); - existingPuzzle = false; - }); - getToolBar1Buttons()[1] = create; - - toolBar1.setFloatable(false); - toolBar1.setRollover(true); - toolBar1.add(getToolBar1Buttons()[1]); - - this.add(toolBar1, BorderLayout.NORTH); - } - - /** - * Sets up the second toolbar with buttons for resetting, saving, and saving & solving puzzles. - * This method initializes the toolbar buttons with their icons and actions. - */ - private void setupToolBar2() { - toolBar2 = new JToolBar(); - toolBar2.setFloatable(false); - toolBar2.setRollover(true); - setToolBar2Buttons(new JButton[3]); - - URL reset = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Reset.png"); - ImageIcon ResetImageIcon = new ImageIcon(reset); - Image ResetImage = ResetImageIcon.getImage(); - ResetImageIcon = - new ImageIcon( - ResetImage.getScaledInstance( - this.TOOLBAR_ICON_SCALE, - this.TOOLBAR_ICON_SCALE, - Image.SCALE_SMOOTH)); - - JButton resetButton = new JButton("Reset", ResetImageIcon); - resetButton.setFocusPainted(false); - - resetButton.addActionListener( - a -> { - if (existingPuzzle) { - legupUI.getPuzzleEditor().loadPuzzle(fileName, puzzleFile); - } - else { - if (cpd.getGame().equals("ShortTruthTable")) { - GameBoardFacade.getInstance().loadPuzzle(cpd.getGame(), cpd.getTextArea()); - } - else { - GameBoardFacade.getInstance().loadPuzzle(cpd.getGame(), Integer.valueOf(cpd.getRows()), Integer.valueOf(cpd.getColumns())); - } - } - }); - - getToolBar2Buttons()[0] = resetButton; - toolBar2.add(getToolBar2Buttons()[0]); - - URL save_as = - ClassLoader.getSystemClassLoader() - .getResource("edu/rpi/legup/images/Legup/Save.png"); - ImageIcon SaveAsImageIcon = new ImageIcon(save_as); - Image SaveAsImage = SaveAsImageIcon.getImage(); - SaveAsImageIcon = - new ImageIcon( - SaveAsImage.getScaledInstance( - this.TOOLBAR_ICON_SCALE, - this.TOOLBAR_ICON_SCALE, - Image.SCALE_SMOOTH)); - - JButton saveas = new JButton("Save As", SaveAsImageIcon); - saveas.setFocusPainted(false); - saveas.addActionListener((ActionEvent) -> savePuzzle()); - - getToolBar2Buttons()[1] = saveas; - toolBar2.add(getToolBar2Buttons()[1]); + private void setupToolBar() { + setToolBarButtons(new JButton[ToolbarName.values().length + 1]); + int lastone = 0; + for (int i = 0; i < ToolbarName.values().length - 1; i++) { + String toolBarName = ToolbarName.values()[i].toString(); + URL resourceLocation = + ClassLoader.getSystemClassLoader() + .getResource("edu/rpi/legup/images/Legup/" + toolBarName + ".png"); + + // 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 save_and_solve = + URL check_and_save = ClassLoader.getSystemClassLoader() .getResource("edu/rpi/legup/images/Legup/Check.png"); - ImageIcon SaveSolveImageIcon = new ImageIcon(save_and_solve); - Image SaveSolveImage = SaveSolveImageIcon.getImage(); - SaveSolveImageIcon = + ImageIcon imageIcon = new ImageIcon(check_and_save); + Image image = imageIcon.getImage(); + imageIcon = new ImageIcon( - SaveSolveImage.getScaledInstance( + image.getScaledInstance( this.TOOLBAR_ICON_SCALE, this.TOOLBAR_ICON_SCALE, Image.SCALE_SMOOTH)); - JButton saveandsolve = new JButton("Save & Solve", SaveSolveImageIcon); - saveandsolve.setFocusPainted(false); - saveandsolve.addActionListener( + JButton checkandsave = new JButton("check and Save", imageIcon); + checkandsave.setFocusPainted(false); + checkandsave.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - 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()); - } + // 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()); } }); - getToolBar2Buttons()[2] = saveandsolve; - toolBar2.add(getToolBar2Buttons()[2]); + getToolBarButtons()[lastone + 1] = checkandsave; + System.out.println("it is create new file"); - this.add(toolBar2, BorderLayout.NORTH); + 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); + } + + // 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); } - /** - * 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(); @@ -480,13 +365,6 @@ 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 { @@ -499,17 +377,11 @@ public void loadPuzzleFromHome(String game, String[] statements) { } } - /** - * Prompts the user to select a puzzle file to open. - * Opens a file chooser dialog and returns the selected file's name and file object. - * If a puzzle is currently loaded, prompts the user to confirm if they want to open a new puzzle. - * - * @return an array containing the selected file name and file object, or null if the operation was canceled - */ + // File opener public Object[] promptPuzzle() { GameBoardFacade facade = GameBoardFacade.getInstance(); if (facade.getBoard() != null) { - if (noQuit("Open an existing puzzle?")) { + if (noQuit("Opening a new puzzle?")) { return new Object[0]; } } @@ -533,6 +405,7 @@ public Object[] promptPuzzle() { fileBrowser.setAcceptAllFileFilterUsed(false); File puzzlePath = fileBrowser.getSelectedFile(); + System.out.println(puzzlePath.getAbsolutePath()); if (puzzlePath != null) { fileName = puzzlePath.getAbsolutePath(); @@ -547,11 +420,6 @@ public Object[] promptPuzzle() { return new Object[] {fileName, puzzleFile}; } - /** - * Loads a puzzle by prompting the user to select a puzzle file. - * If the user cancels the operation, no action is taken. If a puzzle file is selected, - * it will be loaded using the file name and file object. - */ public void loadPuzzle() { Object[] items = promptPuzzle(); // Return if items == null (cancel) @@ -563,14 +431,6 @@ public void loadPuzzle() { loadPuzzle(fileName, puzzleFile); } - /** - * Loads a puzzle from the specified file. - * If the puzzle file is valid and exists, it loads the puzzle and updates the UI. - * If the file format is invalid, an error message is displayed. - * - * @param fileName the name of the puzzle file - * @param puzzleFile the file object representing the puzzle file - */ public void loadPuzzle(String fileName, File puzzleFile) { if (puzzleFile != null && puzzleFile.exists()) { try { @@ -578,9 +438,6 @@ 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()); @@ -594,103 +451,42 @@ public void loadPuzzle(String fileName, File puzzleFile) { } } - /** - * Displays a confirmation dialog with the given instruction message. - * The method returns true if the user selected "No" or cancelled the dialog, - * and false if the user selected "Yes". - * - * @param instr the instruction message to display in the confirmation dialog - * @return true if the user selected "No" or canceled; false if the user selected "Yes" - */ public boolean noQuit(String instr) { int n = JOptionPane.showConfirmDialog(null, instr, "Confirm", JOptionPane.YES_NO_OPTION); return n != JOptionPane.YES_OPTION; } - /** - * {@inheritDoc} - */ @Override public void onPushChange(ICommand command) {} - /** - * {@inheritDoc} - */ @Override public void onUndo(boolean isBottom, boolean isTop) {} - /** - * {@inheritDoc} - */ @Override public void onRedo(boolean isBottom, boolean isTop) {} - /** - * {@inheritDoc} - */ @Override public void onClearHistory() { + // undo.setEnabled(false); + // redo.setEnabled(false); } - - /** - * Returns the current board view - * - * @return the board view - */ public BoardView getBoardView() { return boardView; } - /** - * Returns the array of buttons for the first toolbar - * - * @return the array of toolbar1 buttons - */ - public JButton[] getToolBar1Buttons() { - return toolBar1Buttons; - } - - /** - * Sets the array of buttons for the first toolbar - * - * @param toolBar1Buttons the array of toolbar1 buttons - */ - public void setToolBar1Buttons(JButton[] toolBar1Buttons) { - this.toolBar1Buttons = toolBar1Buttons; + public JButton[] getToolBarButtons() { + return toolBarButtons; } - /** - * Returns the array of buttons for the second toolbar - * - * @return the array of toolbar2 buttons - */ - public JButton[] getToolBar2Buttons() { - return toolBar2Buttons; + public void setToolBarButtons(JButton[] toolBarButtons) { + this.toolBarButtons = toolBarButtons; } - /** - * Sets the array of buttons for the second toolbar - * - * @param toolBar2Buttons the array of toolbar2 buttons - */ - public void setToolBar2Buttons(JButton[] toolBar2Buttons) { - this.toolBar2Buttons = toolBar2Buttons; - } - - /** - * Repaints the current board view - */ private void repaintAll() { boardView.repaint(); } - /** - * Sets the puzzle view based on the provided puzzle object. - * Updates the UI components to display the new puzzle. - * - * @param puzzle the puzzle object to display - */ public void setPuzzleView(Puzzle puzzle) { this.boardView = puzzle.getBoardView(); editorElementController.setElementController(boardView.getElementController()); @@ -706,11 +502,13 @@ public void setPuzzleView(Puzzle puzzle) { dynamicBoardView.setBorder(titleBoard); puzzle.addBoardListener(puzzle.getBoardView()); + System.out.println("Setting elements"); if (this.elementFrame != null) { elementFrame.setElements(puzzle); } - toolBar1.setVisible(false); - setupToolBar2(); + + toolBarButtons[ToolbarName.CHECK.ordinal()].setEnabled(true); + // toolBarButtons[ToolbarName.SAVE.ordinal()].setEnabled(true); } /** Saves a puzzle */ @@ -733,13 +531,6 @@ private void direct_save() { } } - /** - * Saves the current puzzle to a user-selected directory. - * Prompts the user to select a directory and saves the puzzle to that directory. - * Returns the path where the puzzle was saved. - * - * @return the path where the puzzle was saved, or an empty string if the save operation was canceled - */ private String savePuzzle() { Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); if (puzzle == null) { @@ -776,7 +567,7 @@ private String savePuzzle() { folderBrowser.setAcceptAllFileFilterUsed(false); String path = folderBrowser.getSelectedFile().getAbsolutePath(); - preferences.setSavedPath(path); + if (path != null) { try { PuzzleExporter exporter = puzzle.getExporter(); @@ -791,11 +582,6 @@ 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 18aff4d1c..0bf8335a2 100644 --- a/src/main/java/edu/rpi/legup/ui/ScrollView.java +++ b/src/main/java/edu/rpi/legup/ui/ScrollView.java @@ -6,10 +6,6 @@ import java.util.logging.Logger; import javax.swing.*; -/** - * ScrollView extends {@link JScrollPane} to provide a customizable view with zoom and scroll capabilities. - * It uses a {@link ZoomablePane} as the canvas and allows for zooming and scrolling with respect to the canvas content. - */ public class ScrollView extends JScrollPane { private static final Logger LOGGER = Logger.getLogger(ScrollView.class.getName()); @@ -169,11 +165,6 @@ public void zoom(int n, Point point) { revalidate(); } - /** - * Adjusts the zoom level to the given scale and centers the viewport on the current center point - * - * @param newScale the new scale to set - */ public void zoomTo(double newScale) { // check zoom bounds if (newScale < minScale) { @@ -291,11 +282,6 @@ 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 53936a141..ba02ebd2e 100644 --- a/src/main/java/edu/rpi/legup/ui/ToolbarName.java +++ b/src/main/java/edu/rpi/legup/ui/ToolbarName.java @@ -1,12 +1,11 @@ package edu.rpi.legup.ui; -/** - * This enum defines constants for toolbar names used in the user interface. - * Each represents a specific toolbar action. - */ public enum ToolbarName { + HINT, + CHECK, + SUBMIT, DIRECTIONS, - CHECK; + CHECK_ALL; /** * 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 34e828250..aa5b65c4e 100644 --- a/src/main/java/edu/rpi/legup/ui/ZoomWidget.java +++ b/src/main/java/edu/rpi/legup/ui/ZoomWidget.java @@ -10,10 +10,6 @@ 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(); @@ -36,17 +32,12 @@ public ZoomWidget(ScrollView parent) { addMouseListener(open); } - /** - * A {@code JPopupMenu} subclass that contains a vertical slider for adjusting zoom level. - */ + /** */ private class PopupSlider extends JPopupMenu implements ChangeListener { private static final long serialVersionUID = 8225019381200459814L; private JSlider slider; - /** - * Constructs a {@code PopupSlider} with a vertical slider - */ public PopupSlider() { slider = new JSlider(SwingConstants.VERTICAL, 0, 400, 200); slider.setMajorTickSpacing(25); @@ -56,11 +47,6 @@ 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 66af90abd..934d31c53 100644 --- a/src/main/java/edu/rpi/legup/ui/ZoomablePane.java +++ b/src/main/java/edu/rpi/legup/ui/ZoomablePane.java @@ -5,10 +5,6 @@ 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 fa3ec70b7..ca03f1e25 100644 --- a/src/main/java/edu/rpi/legup/ui/boardview/BoardView.java +++ b/src/main/java/edu/rpi/legup/ui/boardview/BoardView.java @@ -11,10 +11,6 @@ import java.awt.*; import java.util.ArrayList; -/** - * An abstract class representing a view for a board in the puzzle game. - * It handles the visual representation and user interactions with the board elements. - */ public abstract class BoardView extends ScrollView implements IBoardListener { protected TreeElement treeElement; protected Board board; @@ -129,9 +125,6 @@ public void setBoard(Board board) { } } - /** - * Configures the view to handle case interactions - */ protected void setCasePickable() { CaseBoard caseBoard = (CaseBoard) board; Board baseBoard = caseBoard.getBaseBoard(); @@ -190,26 +183,15 @@ public ArrayList getElementViews() { return elementViews; } - /** - * Gets the ElementController associated with this board view. - * - * @return the ElementController - */ public ElementController getElementController() { return elementController; } - @Override 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); @@ -226,10 +208,5 @@ 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 a3d82b461..cedfa08fe 100644 --- a/src/main/java/edu/rpi/legup/ui/boardview/DataSelectionView.java +++ b/src/main/java/edu/rpi/legup/ui/boardview/DataSelectionView.java @@ -5,17 +5,8 @@ import javax.swing.*; import javax.swing.border.BevelBorder; -/** - * DataSelectionView is a popup menu used for selecting data elements. - * It extends JPopupMenu and is styled with a gray background and a raised bevel border. - */ 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 9ad4132d6..8e6f2cb18 100644 --- a/src/main/java/edu/rpi/legup/ui/boardview/ElementSelection.java +++ b/src/main/java/edu/rpi/legup/ui/boardview/ElementSelection.java @@ -3,48 +3,25 @@ import java.awt.*; import java.util.ArrayList; -/** - * ElementSelection manages the selection and hover states of ElementViews. - * It maintains a list of selected elements, the currently hovered element, and the mouse point location. - */ public class ElementSelection { private ArrayList selection; 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); } - /** - * Toggles the selection state of an ElementView. - * If the ElementView is currently selected, it is deselected. Otherwise, it is selected. - * - * @param elementView the ElementView to toggle - */ public void toggleSelection(ElementView elementView) { if (selection.contains(elementView)) { selection.remove(elementView); @@ -55,20 +32,12 @@ public void toggleSelection(ElementView elementView) { } } - /** - * Sets a new selection, clearing the previous selection and selecting the specified ElementView. - * - * @param elementView the ElementView to select - */ public void newSelection(ElementView elementView) { clearSelection(); selection.add(elementView); elementView.setSelected(true); } - /** - * Clears the selection and deselects all ElementViews - */ public void clearSelection() { for (ElementView elementView : selection) { elementView.setSelected(false); @@ -76,20 +45,10 @@ 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) { @@ -98,9 +57,6 @@ public void newHover(ElementView newHovered) { hover = newHovered; } - /** - * Clears the current hover state if there exists one - */ public void clearHover() { if (hover != null) { hover.setHover(false); @@ -108,20 +64,10 @@ 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 ad6cd3d3f..83b2cb099 100644 --- a/src/main/java/edu/rpi/legup/ui/boardview/ElementView.java +++ b/src/main/java/edu/rpi/legup/ui/boardview/ElementView.java @@ -9,10 +9,6 @@ import java.awt.image.BufferedImage; import javax.swing.*; -/** - * ElementView represents a visual representation of a PuzzleElement. - * It handles drawing, selection, hover states, and interaction with the PuzzleElement. - */ public abstract class ElementView implements Shape { protected int index; protected Point location; @@ -77,11 +73,6 @@ public void draw(Graphics2D graphics2D) { } } - /** - * Draws the basic element representation (e.g., border, text) on the provided Graphics2D context. - * - * @param graphics2D the Graphics2D context to use for drawing - */ public void drawElement(Graphics2D graphics2D) { graphics2D.setStroke(new BasicStroke(1)); graphics2D.draw( @@ -96,19 +87,8 @@ 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)); @@ -117,11 +97,6 @@ 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)); @@ -130,11 +105,6 @@ 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( @@ -142,11 +112,6 @@ 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); @@ -228,20 +193,10 @@ 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; } @@ -326,13 +281,6 @@ public JMenuItem getSelectionMenuItem() { return item; } - /** - * Determines if the specified point (x, y) is within the bounds of this ElementView - * - * @param x the x-coordinate of the point to check - * @param y the y-coordinate of the point to check - * @return {@code true} if the point is within the bounds of this ElementView; {@code false} otherwise - */ @Override public boolean contains(double x, double y) { return x >= location.x @@ -341,38 +289,17 @@ public boolean contains(double x, double y) { && y <= location.y + size.height; } - /** - * Determines if the specified Point2D object is within the bounds of this ElementView - * - * @param point the Point2D object representing the point to check - * @return {@code true} if the point is within the bounds of this ElementView; {@code false} otherwise - */ @Override public boolean contains(Point2D point) { return contains(point.getX(), point.getY()); } - /** - * Determines if the specified rectangle defined by (x, y, width, height) intersects with the bounds of this ElementView. - * - * @param x The x-coordinate of the rectangle to check - * @param y The y-coordinate of the rectangle to check - * @param width The width of the rectangle to check - * @param height The height of the rectangle to check - * @return {@code true} if the rectangle intersects with the bounds of this ElementView; {@code false} otherwise - */ @Override public boolean intersects(double x, double y, double width, double height) { return (x + width >= location.x && x <= location.x + size.width) || (y + height >= location.y && y <= location.y + size.height); } - /** - * Determines if the specified Rectangle2D object intersects with the bounds of this ElementView. - * - * @param rectangle2D the Rectangle2D object representing the rectangle to check - * @return {@code true} if the rectangle intersects with the bounds of this ElementView; {@code false} otherwise - */ @Override public boolean intersects(Rectangle2D rectangle2D) { return intersects( @@ -382,27 +309,12 @@ public boolean intersects(Rectangle2D rectangle2D) { rectangle2D.getHeight()); } - /** - * Determines if the specified rectangle defined by (x, y, width, height) is entirely contained within the bounds of this ElementView - * - * @param x the x-coordinate of the rectangle to check - * @param y the y-coordinate of the rectangle to check - * @param width the width of the rectangle to check - * @param height the height of the rectangle to check - * @return {@code true} if the rectangle is entirely contained within the bounds of this ElementView; {@code false} otherwise - */ @Override public boolean contains(double x, double y, double width, double height) { return (x + width >= location.x && x <= location.x + size.width) && (y + height >= location.y && y <= location.y + size.height); } - /** - * Determines if the specified Rectangle2D object is entirely contained within the bounds of this ElementView. - * - * @param rectangle2D the Rectangle2D object representing the rectangle to check - * @return {@code true} if the rectangle is entirely contained within the bounds of this ElementView; {@code false} otherwise - */ @Override public boolean contains(Rectangle2D rectangle2D) { return contains( @@ -412,48 +324,22 @@ public boolean contains(Rectangle2D rectangle2D) { rectangle2D.getHeight()); } - - /** - * Returns an iterator over the path geometry of this ElementView. The iterator provides access to the path's - * segments and their coordinates, which can be used for rendering or hit testing. - * - * @param at the AffineTransform to apply to the path geometry - * @return a PathIterator that iterates over the path geometry of this ElementView - */ @Override public PathIterator getPathIterator(AffineTransform at) { return new Rectangle(location.x, location.y, size.width, size.height).getPathIterator(at); } - /** - * Returns an iterator over the path geometry of this ElementView with the specified flatness. The iterator provides - * access to the path's segments and their coordinates, which can be used for rendering or hit testing. - * - * @param at the AffineTransform to apply to the path geometry - * @param flatness the maximum distance that the line segments can deviate from the true path - * @return a PathIterator that iterates over the path geometry of this ElementView - */ @Override public PathIterator getPathIterator(AffineTransform at, double flatness) { return new Rectangle(location.x, location.y, size.width, size.height) .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 1baa34b3a..c40303192 100644 --- a/src/main/java/edu/rpi/legup/ui/boardview/GridBoardView.java +++ b/src/main/java/edu/rpi/legup/ui/boardview/GridBoardView.java @@ -5,11 +5,6 @@ import java.awt.Color; import java.awt.Dimension; -/** - * A view class for a grid-based board that displays elements in a grid layout. - * This class extends BoardView and is responsible for managing and rendering - * grid-based elements. - */ public class GridBoardView extends BoardView { protected Dimension gridSize; protected Dimension elementSize; @@ -56,14 +51,6 @@ public GridElementView getElement(int index) { return null; } - /** - * Retrieves the GridElementView at the specified grid coordinates (xIndex, yIndex). - * Returns null if the coordinates are out of bounds. - * - * @param xIndex the x-coordinate (column) of the element view to retrieve - * @param yIndex the y-coordinate (row) of the element view to retrieve - * @return the GridElementView at the specified coordinates, or null if out of bounds - */ public GridElementView getElement(int xIndex, int yIndex) { if (xIndex < gridSize.width && yIndex < gridSize.height) { return (GridElementView) elementViews.get(yIndex * gridSize.width + xIndex); @@ -71,10 +58,7 @@ public GridElementView getElement(int xIndex, int yIndex) { return null; } - /** - * Initializes the initial dimension of the viewport for the GridBoardView. - * Sets the size of the board view and adjusts the zoom to fit. - */ + /** Initializes the initial dimension of the viewport for the GridBoardView */ @Override public void initSize() { setSize(getProperSize()); @@ -82,9 +66,9 @@ public void initSize() { } /** - * Determines the proper dimension of the grid view based on grid size and element size. + * Helper method to determine the proper dimension of the grid view * - * @return the dimension of the grid view + * @return proper dimension of the grid view */ protected Dimension getProperSize() { Dimension boardViewSize = new Dimension(); @@ -93,21 +77,10 @@ protected Dimension getProperSize() { return boardViewSize; } - /** - * Retrieves the selection popup menu for data selection. - * Currently returns null as there is no implementation. - * - * @return null - */ 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/GridElementView.java b/src/main/java/edu/rpi/legup/ui/boardview/GridElementView.java index 31e8fcd6c..440b3a693 100644 --- a/src/main/java/edu/rpi/legup/ui/boardview/GridElementView.java +++ b/src/main/java/edu/rpi/legup/ui/boardview/GridElementView.java @@ -2,11 +2,6 @@ import edu.rpi.legup.model.gameboard.GridCell; -/** - * A view class for a grid cell element in the board. - * This class extends ElementView and represents a specific type of element view - * associated with a GridCell. - */ public class GridElementView extends ElementView { public GridElementView(GridCell cell) { super(cell); 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 15deb86d1..b2d3e31dd 100644 --- a/src/main/java/edu/rpi/legup/ui/boardview/SelectionItemView.java +++ b/src/main/java/edu/rpi/legup/ui/boardview/SelectionItemView.java @@ -3,68 +3,28 @@ import edu.rpi.legup.model.gameboard.PuzzleElement; import javax.swing.*; -/** - * A menu item view class that represents a selectable item in a menu, associated with a PuzzleElement. - * This class extends JMenuItem and provides additional functionality to - * handle PuzzleElement data. - */ public class SelectionItemView extends JMenuItem { private PuzzleElement data; - /** - * Constructs a SelectionItemView with the specified PuzzleElement and icon. - * Initializes the menu item with the given icon and associates it with the - * provided PuzzleElement. - * - * @param data the PuzzleElement associated with this menu item - * @param icon the icon to be displayed on the menu item - */ public SelectionItemView(PuzzleElement data, Icon icon) { super(icon); this.data = data; } - /** - * Constructs a SelectionItemView with the specified PuzzleElement and display text. - * Initializes the menu item with the given display text and associates it with the - * provided PuzzleElement. - * - * @param data the PuzzleElement associated with this menu item - * @param display the text to be displayed on the menu item - */ public SelectionItemView(PuzzleElement data, String display) { super(display); this.data = data; } - /** - * Constructs a SelectionItemView with the specified PuzzleElement and display integer. - * Initializes the menu item with the integer converted to a string and associates it with - * the provided PuzzleElement. - * - * @param data the PuzzleElement associated with this menu item - * @param display the integer to be displayed on the menu item - */ public SelectionItemView(PuzzleElement data, int display) { super(String.valueOf(display)); this.data = data; } - /** - * Constructs a SelectionItemView with the specified PuzzleElement. - * Initializes the menu item with the data's integer representation as display text. - * - * @param data the PuzzleElement associated with this menu item - */ 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/CaseRulePanel.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/CaseRulePanel.java index 849c5c145..1fb0a16ab 100644 --- a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/CaseRulePanel.java +++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/CaseRulePanel.java @@ -2,12 +2,6 @@ import javax.swing.ImageIcon; -/** - * The {@code CaseRulePanel} class is a specialized panel that represents case rules - * within a {@link RuleFrame}. It extends the {@link RulePanel} and provides - * specific functionality and UI components related to case rules. - * This class initializes with an icon and name that are specific to case rules. - */ public class CaseRulePanel extends RulePanel { /** * CaseRulePanel Constructor creates a CaseRulePanel diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/ContradictionRulePanel.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/ContradictionRulePanel.java index 5bed7e17d..f695491fb 100644 --- a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/ContradictionRulePanel.java +++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/ContradictionRulePanel.java @@ -2,14 +2,7 @@ import javax.swing.*; -/** - * The {@code ContradictionRulePanel} class is a specialized panel that represents contradiction rules - * within a {@link RuleFrame}. It extends the {@link RulePanel} and provides - * specific functionality and UI components related to contradiction rules. - * This class initializes with an icon and name that are specific to contradiction rules. - */ - - public class ContradictionRulePanel extends RulePanel { +public class ContradictionRulePanel extends RulePanel { /** * ContradictionRulePanel Constructor creates a ContradictionRulePanel * diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/DirectRulePanel.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/DirectRulePanel.java index c1562eb70..2795f2df7 100644 --- a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/DirectRulePanel.java +++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/DirectRulePanel.java @@ -4,13 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * The {@code DirectRulePanel} class is a specialized panel that represents direct rules - * within a {@link RuleFrame}. It extends the {@link RulePanel} and provides - * specific functionality and UI components related to direct rules. - * This class initializes with an icon and name that are specific to direct rules. - */ - public class DirectRulePanel extends RulePanel { +public class DirectRulePanel extends RulePanel { private static final Logger LOGGER = LogManager.getLogger(DirectRulePanel.class.getName()); /** diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleButton.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleButton.java index 7222603bc..e9c274250 100644 --- a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleButton.java +++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/RuleButton.java @@ -3,11 +3,6 @@ import edu.rpi.legup.model.rules.Rule; import javax.swing.*; -/** - * The {@code RuleButton} class is a custom button that represents a rule in the user interface. - * It extends {@link JButton} and is designed to display a rule's name and icon. - * The button is initialized with a {@link Rule} object, which provides the name and icon for the button. - */ public class RuleButton extends JButton { private Rule rule; 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 3131f474d..6279f93a4 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 @@ -10,13 +10,6 @@ import javax.swing.*; import javax.swing.border.TitledBorder; -/** - * The {@code RuleFrame} class is a panel that contains and manages multiple rule-related panels - * within a tabbed interface. It extends {@link JPanel} and organizes the display of various rule types - * such as direct rules, contradiction rules, and case rules. - * The frame uses a {@link JTabbedPane} to allow users to switch between different rule panels. - * It also includes a search bar panel and a status label for displaying additional information. - */ public class RuleFrame extends JPanel { private static final String checkBox = " \u2714 "; private static final String xBox = " \u2718 "; @@ -35,12 +28,6 @@ public class RuleFrame extends JPanel { private RuleController controller; - /** - * Constructs a new {@code RuleFrame} instance. - * Initializes the frame with tabs for the different rule panels, a search bar panel, and a status label. - * - * @param controller the {@link RuleController} instance that manages the rules for this frame - */ public RuleFrame(RuleController controller) { MaterialTabbedPaneUI tabOverride = @@ -131,7 +118,7 @@ public void resetSize() { /** * Set the status label to a value. Use resetStatus to clear it. * - * @param check true if we want a checkbox, if false we'll have a red x box + * @param check true iff we want a check box, 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,47 +156,22 @@ 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 4c9ebf882..5d985d5c2 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 @@ -9,10 +9,6 @@ import java.util.List; import javax.swing.*; -/** - * Abstract base class for panels displaying rules. Each subclass will represent a specific type - * of rule panel (e.g., DirectRulePanel, CaseRulePanel). - */ public abstract class RulePanel extends JPanel { protected ImageIcon icon; protected String name; @@ -36,7 +32,7 @@ public RulePanel(RuleFrame ruleFrame) { } /** - * Gets the array of rule buttons + * Gets the rule rule buttons * * @return rule ruleButtons */ @@ -59,30 +55,20 @@ public void setRules(List rules) { Rule rule = rules.get(i); ruleButtons[i] = new RuleButton(rule); - ruleButtons[i].setPreferredSize(new Dimension(150, 150)); // adjust the size of each RuleButton - - if (rule.getRuleName().length() > 18) { - ruleButtons[i].setFont(new Font("Segoe UI", Font.PLAIN, 11)); - } - if (rule.getRuleName().length() > 20) { - ruleButtons[i].setFont(new Font("Segoe UI", Font.PLAIN, 10)); - } - System.out.println(ruleButtons[i].getFont().getName()); - + ruleButtons[i].setPreferredSize( + new Dimension(150, 150)); // adjust the size of each RuleButton ruleButtons[i].setHorizontalTextPosition(JButton.CENTER); ruleButtons[i].setVerticalTextPosition(JButton.BOTTOM); ruleFrame.getButtonGroup().add(ruleButtons[i]); - ruleButtons[i].setToolTipText(rule.getRuleName() + ": " + rule.getDescription()); // showing description + ruleButtons[i].setToolTipText( + rule.getRuleName() + ": " + rule.getDescription()); // showing description ruleButtons[i].addActionListener(ruleFrame.getController()); add(ruleButtons[i]); } revalidate(); } - /** - * Updates the rules displayed by reloading images and setting the rules again. - */ public void updateRules() { for (Rule rule : rules) { rule.loadImage(); @@ -338,58 +324,28 @@ public List 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/rulesview/SearchBarPanel.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/SearchBarPanel.java index 842859ce2..aba4707cd 100644 --- a/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/SearchBarPanel.java +++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/rulesview/SearchBarPanel.java @@ -2,11 +2,6 @@ import javax.swing.*; - -/** - * The {@code SearchBarPanel} class creates a panel that allows users to search for rules within the rule frame. - * This panel provides a search bar for entering rule names and finding corresponding rules. - */ public class SearchBarPanel extends RulePanel { /** * SearchBarPanel Constructor creates a SearchBarPanel 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 228e69950..33c04717d 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 @@ -4,12 +4,6 @@ import edu.rpi.legup.model.tree.TreeElementType; import java.awt.*; -/** - * Abstract base class for views of tree elements in the tree structure. - * This class implements the Shape interface to support custom drawing and interaction - * with tree elements. - * It holds properties for rendering, interaction, and layout of the tree elements. - */ public abstract class TreeElementView implements Shape { protected TreeElement treeElement; protected double span; @@ -42,7 +36,7 @@ protected TreeElementView(TreeElementType type, TreeElement treeElement) { public abstract void draw(Graphics2D graphics2D); /** - * Gets the span for the subtree rooted at this view + * Gets the span for the sub tree rooted at this view * * @return span bounded y span */ @@ -51,7 +45,7 @@ public double getSpan() { } /** - * Sets the span for the subtree rooted at this view. + * Sets the span for the sub tree 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 0e2a31bbf..990d96620 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 @@ -7,12 +7,6 @@ import java.awt.geom.*; import java.util.ArrayList; -/** - * Represents a view of a tree node in the tree structure. - * This class extends {@link TreeElementView} and provides specific rendering and interaction - * functionality for tree nodes. It includes visual properties and methods to manage the - * node's appearance, location, and its relationships with other nodes. - */ public class TreeNodeView extends TreeElementView { static final int RADIUS = 25; static final int DIAMETER = 2 * RADIUS; @@ -266,119 +260,51 @@ 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); } - /** - * Determines if the specified point (x, y) is within the bounds of this TreeNodeView - * - * @param x the x-coordinate of the point to check - * @param y the y-coordinate of the point to check - * @return {@code true} if the point is within the bounds of this TreeNodeView; {@code false} otherwise - */ @Override public boolean contains(double x, double y) { return Math.sqrt(Math.pow(x - location.x, 2) + Math.pow(y - location.y, 2)) <= RADIUS; } - /** - * Determines if the specified Point2D object is within the bounds of this TreeNodeView - * - * @param p the Point2D object representing the point to check - * @return {@code true} if the point is within the bounds of this TreeNodeView; {@code false} otherwise - */ @Override public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); } - /** - * Determines if the specified rectangle defined by (x, y, width, height) intersects with the bounds of this TreeNodeView. - * - * @param x The x-coordinate of the rectangle to check - * @param y The y-coordinate of the rectangle to check - * @param w The width of the rectangle to check - * @param h The height of the rectangle to check - * @return {@code true} if the rectangle intersects with the bounds of this TreeNodeView; {@code false} otherwise - */ @Override public boolean intersects(double x, double y, double w, double h) { return false; } - /** - * Determines if the specified Rectangle2D object intersects with the bounds of this TreeNodeView. - * - * @param r the Rectangle2D object representing the rectangle to check - * @return {@code true} if the rectangle intersects with the bounds of this TreeNodeView; {@code false} otherwise - */ @Override public boolean intersects(Rectangle2D r) { return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - /** - * Determines if the specified rectangle defined by (x, y, width, height) is entirely contained within the bounds of this TreeNodeView - * - * @param x the x-coordinate of the rectangle to check - * @param y the y-coordinate of the rectangle to check - * @param w the width of the rectangle to check - * @param h the height of the rectangle to check - * @return {@code true} if the rectangle is entirely contained within the bounds of this TreeNodeView; {@code false} otherwise - */ @Override public boolean contains(double x, double y, double w, double h) { return false; } - /** - * Determines if the specified Rectangle2D object is entirely contained within the bounds of this TreeNodeView. - * - * @param r the Rectangle2D object representing the rectangle to check - * @return {@code true} if the rectangle is entirely contained within the bounds of this TreeNodeView; {@code false} otherwise - */ @Override public boolean contains(Rectangle2D r) { return false; } - /** - * Returns an iterator over the path geometry of this TreeNodeView. The iterator provides access to the path's - * segments and their coordinates, which can be used for rendering or hit testing. - * - * @param at the AffineTransform to apply to the path geometry - * @return a PathIterator that iterates over the path geometry of this TreeNodeView - */ @Override public PathIterator getPathIterator(AffineTransform at) { return null; } - /** - * Returns an iterator over the path geometry of this TreeNodeView with the specified flatness. The iterator provides - * access to the path's segments and their coordinates, which can be used for rendering or hit testing. - * - * @param at the AffineTransform to apply to the path geometry - * @param flatness the maximum distance that the line segments can deviate from the true path - * @return a PathIterator that iterates over the path geometry of this TreeNodeView - */ @Override public PathIterator getPathIterator(AffineTransform at, double flatness) { return null; 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 4bef664bd..b6a29f2b5 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 @@ -17,12 +17,6 @@ import javax.swing.JPanel; import javax.swing.border.TitledBorder; - -/** - * {@code TreePanel} is a JPanel that manages and displays a tree view with associated toolbar and status information. - * It provides methods to interact with the tree view, such as adding, deleting, and merging tree elements, - * and updating the status based on actions performed. - */ public class TreePanel extends JPanel { public boolean modifiedSinceSave = false; public boolean modifiedSinceUndoPush = false; @@ -35,9 +29,6 @@ public class TreePanel extends JPanel { private JLabel status; - /** - * Constructs a {@code TreePanel} and initializes the UI components. - */ public TreePanel(/*LegupUI legupUI*/ ) { // this.legupUI = legupUI; @@ -69,20 +60,10 @@ 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; @@ -90,11 +71,6 @@ public void boardDataChanged(Board board) { // colorTransitions(); } - /** - * Updates the status display based on the status timer. - * If the timer is greater than 0, the status will not be updated. - * Otherwise, it clears the status text. - */ public void updateStatus() { updateStatusTimer = ((updateStatusTimer - 1) > 0) ? (updateStatusTimer - 1) : 0; if (updateStatusTimer > 0) { @@ -103,41 +79,22 @@ 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; } - /** - * Adds a new tree element by executing an {@link AddTreeElementCommand}. - * If the command cannot be executed, it updates the status display with an error and error message. - */ public void add() { TreeViewSelection selection = treeView.getSelection(); @@ -150,10 +107,6 @@ public void add() { } } - /** - * Deletes the selected tree element by executing a {@link DeleteTreeElementCommand}. - * If the command cannot be executed, it updates the status display with an error and an error message. - */ public void delete() { TreeViewSelection selection = treeView.getSelection(); @@ -166,10 +119,6 @@ public void delete() { } } - /** - * Merges selected tree elements by executing a {@link MergeCommand}. - * If the command cannot be executed, it updates the status display with an error and an error message. - */ public void merge() { TreeViewSelection selection = treeView.getSelection(); @@ -182,10 +131,6 @@ public void merge() { } } - /** - * Toggles the collapsed state of the selected tree elements. - * If an element is collapsed, it will be expanded, and vice versa. - */ public void collapse() { TreeViewSelection selection = treeView.getSelection(); for (TreeElementView view : selection.getSelectedViews()) { 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 214c735df..002092155 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 @@ -3,20 +3,11 @@ import java.awt.Dimension; import javax.swing.*; -/** - * {@code TreeToolBarButton} is a JButton that represents a button in the tree toolbar. - */ 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; @@ -25,11 +16,6 @@ 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 3aec664be..c805021be 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,9 +1,5 @@ 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/TreeToolbarPanel.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolbarPanel.java index 500ed29c5..8f3ebfc23 100644 --- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolbarPanel.java +++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeToolbarPanel.java @@ -3,11 +3,6 @@ import java.awt.*; import javax.swing.*; - -/** - * {@code TreeToolbarPanel} is a JPanel that provides a toolbar for managing tree elements in the tree view. - * It includes buttons for adding, deleting, merging, and collapsing nodes. - */ public class TreeToolbarPanel extends JPanel { private TreePanel treePanel; private TreeToolBarButton addChild, delChild, merge, collapse; 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 25c67bb5a..b022ac596 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 @@ -10,11 +10,6 @@ import java.util.ArrayList; import java.util.List; -/** - * {@code TreeTransitionView} is a visual representation of a tree transition in the tree view. - * It extends TreeElementView and displays a transition arrow between tree nodes and handles various - * visual states such as selection, hover, and correctness. - */ public class TreeTransitionView extends TreeElementView { static final int RADIUS = 25; static final int DIAMETER = 2 * RADIUS; @@ -271,165 +266,87 @@ public void removeParentView(TreeNodeView nodeView) { } } - /** - * Gets the x-coordinate of the end point of the transition arrow - * - * @return the x-coordinate of the end point - */ + public Point getEndPoint() { + return endPoint; + } + + public void setEndPoint(Point endPoint) { + this.endPoint = endPoint; + } + 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; } - /** - * 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 List getLineStartPoints() { + return lineStartPoints; + } + + public void setLineStartPoints(List lineStartPoints) { + this.lineStartPoints = lineStartPoints; + } + 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(); } - /** - * Determines if the specified point (x, y) is within the bounds of this TreeTransitionView - * - * @param x the x-coordinate of the point to check - * @param y the y-coordinate of the point to check - * @return {@code true} if the point is within the bounds of this TreeTransitionView; {@code false} otherwise - */ @Override public boolean contains(double x, double y) { return arrowhead.contains(x, y); } - /** - * Determines if the specified Point2D object is within the bounds of this TreeTransitionView - * - * @param p the Point2D object representing the point to check - * @return {@code true} if the point is within the bounds of this TreeTransitionView; {@code false} otherwise - */ @Override public boolean contains(Point2D p) { return arrowhead != null && arrowhead.contains(p); } - /** - * Determines if the specified rectangle defined by (x, y, width, height) intersects with the bounds of this TreeTransitionView. - * - * @param x The x-coordinate of the rectangle to check - * @param y The y-coordinate of the rectangle to check - * @param w The width of the rectangle to check - * @param h The height of the rectangle to check - * @return {@code true} if the rectangle intersects with the bounds of this TreeTransitionView; {@code false} otherwise - */ @Override public boolean intersects(double x, double y, double w, double h) { return arrowhead.intersects(x, y, w, h); } - /** - * Determines if the specified Rectangle2D object intersects with the bounds of this TreeTransitionView. - * - * @param r the Rectangle2D object representing the rectangle to check - * @return {@code true} if the rectangle intersects with the bounds of this TreeTransitionView; {@code false} otherwise - */ @Override public boolean intersects(Rectangle2D r) { return arrowhead.intersects(r); } - /** - * Determines if the specified rectangle defined by (x, y, width, height) is entirely contained within the bounds of this TreeTransitionView - * - * @param x the x-coordinate of the rectangle to check - * @param y the y-coordinate of the rectangle to check - * @param w the width of the rectangle to check - * @param h the height of the rectangle to check - * @return {@code true} if the rectangle is entirely contained within the bounds of this TreeTransitionView; {@code false} otherwise - */ @Override public boolean contains(double x, double y, double w, double h) { return arrowhead.contains(x, y, w, h); } - /** - * Determines if the specified Rectangle2D object is entirely contained within the bounds of this TreeTransitionView. - * - * @param r the Rectangle2D object representing the rectangle to check - * @return {@code true} if the rectangle is entirely contained within the bounds of this TreeTransitionView; {@code false} otherwise - */ @Override public boolean contains(Rectangle2D r) { return arrowhead.contains(r); } - /** - * Returns an iterator over the path geometry of this TreeTransitionView. The iterator provides access to the path's - * segments and their coordinates, which can be used for rendering or hit testing. - * - * @param at the AffineTransform to apply to the path geometry - * @return a PathIterator that iterates over the path geometry of this TreeTransitionView - */ @Override public PathIterator getPathIterator(AffineTransform at) { return arrowhead.getPathIterator(at); } - /** - * Returns an iterator over the path geometry of this TreeTransitionView with the specified flatness. The iterator provides - * access to the path's segments and their coordinates, which can be used for rendering or hit testing. - * - * @param at the AffineTransform to apply to the path geometry - * @param flatness the maximum distance that the line segments can deviate from the true path - * @return a PathIterator that iterates over the path geometry of this TreeTransitionView - */ @Override public PathIterator getPathIterator(AffineTransform at, double flatness) { return arrowhead.getPathIterator(at, flatness); 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 490cf1480..f491009b4 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 @@ -26,12 +26,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * The {@code TreeView} class provides a graphical representation of a {@code Tree} structure, - * allowing interaction and visualization of tree elements, transitions, and selections. - * It extends {@code ScrollView} and implements {@code ITreeListener} to respond to updates - * in the tree structure. - */ public class TreeView extends ScrollView implements ITreeListener { private static final Logger LOGGER = LogManager.getLogger(TreeView.class.getName()); @@ -57,11 +51,6 @@ 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<>(); @@ -73,11 +62,6 @@ 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; } @@ -147,11 +131,6 @@ 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) { @@ -169,9 +148,6 @@ public void setTree(Tree tree) { this.tree = tree; } - /** - * Updates the size of the tree view based on the bounds of its tree - */ public void updateTreeSize() { if (GameBoardFacade.getInstance().getTree() == null) { return; @@ -179,23 +155,15 @@ public void updateTreeSize() { setSize(bounds.getSize()); } - /** - * Resets the view if the tree bounds have been modified - */ public void reset() { if (bounds.x != 0 || bounds.y != 0) { updateTreeSize(); } } - /** - * Adjusts the zoom level to fit the entire tree within the viewport when - * the Resize Proof button is selected - */ public void zoomFit() { - 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); + double fitWidth = (viewport.getWidth() - 8.0) / (getSize().width - 200); + double fitHeight = (viewport.getHeight() - 8.0) / (getSize().height - 120); zoomTo(Math.min(fitWidth, fitHeight)); viewport.setViewPosition(new Point(0, viewport.getHeight() / 2)); } @@ -244,11 +212,6 @@ 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(); @@ -271,20 +234,11 @@ public void draw(Graphics2D graphics2D) { } } - /** - * Resets the zoom level to its default state and positions the viewport from the top-left corner - */ public void zoomReset() { zoomTo(1.0); 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); @@ -295,11 +249,6 @@ 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; @@ -333,9 +282,6 @@ public void drawMouseOver(Graphics2D g) { } } - /** - * Resets the view by clearing the current tree, root node view, and selection - */ public void resetView() { this.tree = null; this.rootNodeView = null; @@ -461,17 +407,8 @@ public TreeElementView getElementView(TreeElement element) { return viewMap.get(element); } - /** - * Removes the specified {@link TreeNode} and its associated views - * - * @param node the {@link TreeNode} to be removed - */ - public void removeTreeNode(TreeNode node) { + private 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 @@ -498,13 +435,11 @@ public void removeTreeNode(TreeNode node) { } // set modifiable if started modifiable - boolean modifiable = false; - if (tree != null) { - tree.getRootNode() - .getBoard() - .getPuzzleElement(oldElement) - .isModifiable(); - } + boolean modifiable = + tree.getRootNode() + .getBoard() + .getPuzzleElement(oldElement) + .isModifiable(); // unmodifiable if already modified TreeNode modNode = ancestor.getParent().getParents().get(0); @@ -522,58 +457,22 @@ public void removeTreeNode(TreeNode node) { } } } + node.getChildren().forEach(t -> removeTreeTransition(t)); } - /** - * Removes the specified {@link TreeTransition} and its associated views - * - * @param trans the {@link TreeTransition} to be removed - */ - public void removeTreeTransition(TreeTransition trans) { + private void removeTreeTransition(TreeTransition trans) { viewMap.remove(trans); if (trans.getChildNode() != null) { removeTreeNode(trans.getChildNode()); } - - // Update transition modifiability if removing a case rule - List parents = trans.getParents(); - for (TreeNode parent : parents) { - // if transition is a case rule, unlock ancestor elements up until latest case rule or root node - boolean nextAncestorIsCaseRule = false; - Rule rule = trans.getRule(); - if (rule instanceof CaseRule) { - List ancestors = parent.getAncestors(); - for (int i = 0; i < ancestors.size(); i++) { - if (ancestors.get(i).getParent() == null) { - continue; - } - if (nextAncestorIsCaseRule) { - break; - } - for (PuzzleElement element : parent.getBoard().getPuzzleElements()) { - PuzzleElement curElement = ancestors.get(i).getParent().getBoard().getPuzzleElement(element); - if (!curElement.isModifiableCaseRule()) { - curElement.setModifiableCaseRule(true); - } - } - if (ancestors.get(i).getParent().getRule() instanceof CaseRule) { - nextAncestorIsCaseRule = true; - } - } - } - } } - /** - * 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); + TreeNodeView nodeView = new TreeNodeView(node); TreeTransitionView parentView = (TreeTransitionView) viewMap.get(parent); + nodeView.setParentView(parentView); parentView.setChildView(nodeView); @@ -593,7 +492,8 @@ private void addTreeNode(TreeNode node) { continue; } for (PuzzleElement element : - caseRule.dependentElements(node.getBoard(), node.getChildren().get(0).getSelection())) { + caseRule.dependentElements( + node.getBoard(), node.getChildren().get(0).getSelection())) { // increment and lock PuzzleElement oldElement = ancestor.getParent().getBoard().getPuzzleElement(element); @@ -607,50 +507,47 @@ 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); + 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 if (ancestor.getParent() == null) { continue; } - - for (PuzzleElement element : parent.getBoard().getPuzzleElements()) { - PuzzleElement curElement = ancestor.getParent().getBoard().getPuzzleElement(element); - curElement.setModifiableCaseRule(false); + for (PuzzleElement element : + caseRule.dependentElements(parent.getBoard(), trans.getSelection())) { + // increment and lock + PuzzleElement oldElement = + ancestor.getParent().getBoard().getPuzzleElement(element); + oldElement.setCasesDepended(oldElement.getCasesDepended() + 1); + oldElement.setModifiable(false); } } } } + viewMap.put(trans, transView); + if (trans.getChildNode() != null) { addTreeNode(trans.getChildNode()); } } - /** - * Draws the tree using the provided {@link Graphics2D} object - * - * @param graphics2D the {@link Graphics2D} object used for drawing the tree - */ + /// New Draw Methods + public void drawTree(Graphics2D graphics2D) { if (tree == null) { LOGGER.error("Unable to draw tree."); @@ -676,11 +573,6 @@ 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); @@ -714,14 +606,6 @@ public void createViews(TreeNodeView nodeView) { } } - /** - * Calculates the layout locations (x and y coordinates) of the nodes in the tree. - * This method recursively traverses the tree and updates the positions of - * nodes and transitions based on their depth and parent relationships. - * - * @param nodeView the node view to calculate the positions for - * @param depth the depth of the node in the tree, used to calculate its x-coordinate - */ public void calculateViewLocations(TreeNodeView nodeView, int depth) { nodeView.setDepth(depth); int xLoc = (NODE_GAP_WIDTH + DIAMETER) * depth + DIAMETER; @@ -827,13 +711,6 @@ public void calculateViewLocations(TreeNodeView nodeView, int depth) { } } - /** - * Calculates the span (height) required for the given view, including its children. - * This method recursively determines the span for nodes and transitions based on their - * children and the merging branches they belong to. - * - * @param view the view whose span is to be calculated - */ public void calcSpan(TreeElementView view) { if (view.getType() == NODE) { TreeNodeView nodeView = (TreeNodeView) view; @@ -902,12 +779,12 @@ public void calcSpan(TreeElementView view) { } /** - * Calculates the span of a subtree rooted at the specified view, stopping at the given - * stop view. The stop view is not included in the span calculation. + * Calculates the sub span of a given sub tree rooted at the specified view and stops at the + * tree puzzleElement view specified as stop. Stop tree puzzleElement is NOT included in the + * span calculation * - * @param view the root view of the subtree to calculate the span for - * @param stop the view at which to stop the span calculation. The stop view itself is - * not included in the span calculation + * @param view + * @param stop */ private void subCalcSpan(TreeElementView view, TreeElementView stop) { // safe-guard for infinite loop @@ -982,14 +859,12 @@ private void subCalcSpan(TreeElementView view, TreeElementView stop) { } /** - * Reorders the branches of a given node such that branches that merge are grouped together sequentially. - * Transitions are kept in their relative order based on their original positions in the list of child transitions - * of the specified node. This ensures that the visual representation of the branches and transitions maintains - * a logical and readable structure. + * Reorders branches such that merging branches are sequentially grouped together and + * transitions are kept in relative order in the list of child transitions of the specified node * - * @param node the root node whose branches are to be reordered - * @param branches a DisjointSets structure representing the merging relationships of the child branches of the - * specified node. This determines which branches should be grouped together + * @param node root node of the branches + * @param branches DisjointSets of the child branches of the specified node which determine + * which branches merge */ private void reorderBranches(TreeNode node, DisjointSets branches) { List children = node.getChildren(); diff --git a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeViewSelection.java b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeViewSelection.java index c7893b168..71a65b49e 100644 --- a/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeViewSelection.java +++ b/src/main/java/edu/rpi/legup/ui/proofeditorui/treeview/TreeViewSelection.java @@ -4,11 +4,6 @@ import java.util.ArrayList; import java.util.List; - -/** - * {@code TreeViewSelection} manages the selection and hover state of tree element views in a tree view. - * It maintains a list of selected views, tracks the currently hovered view, and manages the mouse position. - */ public class TreeViewSelection { private ArrayList selectedViews; private TreeElementView hover; 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 97c76919e..e0524f84d 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 @@ -14,36 +14,52 @@ public class ElementFrame extends JPanel { private static final String htmlTail = ""; private PlaceableElementPanel placeableElementPanel; - //private JTabbedPane tabbedPane; + private NonPlaceableElementPanel nonPlaceableElementPanel; + private JTabbedPane tabbedPane; private ButtonGroup buttonGroup; 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(); - // Parent panel to hold all elements - JPanel elementPanel = new JPanel(); - elementPanel.setLayout(new BoxLayout(elementPanel, BoxLayout.Y_AXIS)); + nonPlaceableElementPanel = new NonPlaceableElementPanel(this); + // nonPlaceableElementPanel.setMinimumSize(new Dimension(100,200)); + tabbedPane.addTab( + nonPlaceableElementPanel.getName(), + nonPlaceableElementPanel.getIcon(), + new JScrollPane(nonPlaceableElementPanel), + nonPlaceableElementPanel.getToolTip()); placeableElementPanel = new PlaceableElementPanel(this); - placeableElementPanel.setMinimumSize(new Dimension(100, 200)); - elementPanel.add(new JScrollPane(placeableElementPanel)); + // placeableElementPanel.setMinimuSize(new Dimension(100,200)); + tabbedPane.addTab( + placeableElementPanel.getName(), + placeableElementPanel.getIcon(), + new JScrollPane(placeableElementPanel), + placeableElementPanel.getToolTip()); + tabbedPane.setTabPlacement(JTabbedPane.TOP); - // Set layout and dimensions for the main panel setLayout(new BorderLayout()); setMinimumSize(new Dimension(250, 256)); setPreferredSize(new Dimension(330, 256)); - // Add components to the main panel - add(elementPanel, BorderLayout.CENTER); + add(tabbedPane); add(status, BorderLayout.SOUTH); - // Center-align the titled border TitledBorder title = BorderFactory.createTitledBorder("Elements"); title.setTitleJustification(TitledBorder.CENTER); setBorder(title); @@ -53,26 +69,29 @@ public ButtonGroup getButtonGroup() { return buttonGroup; } -// public void resetSize() { -// int buttonWidth = -// ((ElementPanel) tabbedPane.getSelectedComponent()) -// .getElementButtons()[0].getWidth(); -// this.setMinimumSize(new Dimension(2 * buttonWidth + 64, this.getHeight())); -// } + public void resetSize() { + int buttonWidth = + ((ElementPanel) tabbedPane.getSelectedComponent()) + .getElementButtons()[0].getWidth(); + this.setMinimumSize(new Dimension(2 * buttonWidth + 64, this.getHeight())); + } public void setElements(Puzzle puzzle) { - if (puzzle != null) { - placeableElementPanel.setElements(puzzle.getPlaceableElements()); - } + nonPlaceableElementPanel.setElements(puzzle.getNonPlaceableElements()); + placeableElementPanel.setElements(puzzle.getPlaceableElements()); } public EditorElementController getController() { return controller; } -// public JTabbedPane getTabbedPane() { -// return tabbedPane; -// } + public JTabbedPane getTabbedPane() { + return tabbedPane; + } + + public NonPlaceableElementPanel getNonPlaceableElementPanel() { + return nonPlaceableElementPanel; + } public PlaceableElementPanel getPlaceableElementPanel() { return placeableElementPanel; 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 70826d25c..46198e226 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 int setElements(List elements) { + public void setElements(List elements) { this.elements = elements; clearButtons(); @@ -38,7 +38,6 @@ public int setElements(List elements) { add(elementButtons[i]); } revalidate(); - return elements.size(); } protected void clearButtons() { diff --git a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/NonPlaceableElementPanel.java b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/NonPlaceableElementPanel.java index 796d1ae68..00b4f5379 100644 --- a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/NonPlaceableElementPanel.java +++ b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/NonPlaceableElementPanel.java @@ -1,15 +1,15 @@ -//package edu.rpi.legup.ui.puzzleeditorui.elementsview; -// -//import javax.swing.*; -// -//public class NonPlaceableElementPanel extends ElementPanel { -// public NonPlaceableElementPanel(ElementFrame elementFrame) { -// super(elementFrame); -// this.icon = -// new ImageIcon( -// ClassLoader.getSystemClassLoader() -// .getResource("edu/rpi/legup/images/Legup/Direct Rules.gif")); -// this.name = "Non-Placeable Elements"; -// this.toolTip = "Non-Placeable Elements"; -// } -//} +package edu.rpi.legup.ui.puzzleeditorui.elementsview; + +import javax.swing.*; + +public class NonPlaceableElementPanel extends ElementPanel { + public NonPlaceableElementPanel(ElementFrame elementFrame) { + super(elementFrame); + this.icon = + new ImageIcon( + ClassLoader.getSystemClassLoader() + .getResource("edu/rpi/legup/images/Legup/Direct Rules.gif")); + this.name = "Non-Placeable Elements"; + this.toolTip = "Non-Placeable Elements"; + } +} diff --git a/src/main/resources/edu/rpi/legup/images/Legup/Reset.png b/src/main/resources/edu/rpi/legup/images/Legup/Reset.png deleted file mode 100644 index fd6ffefa0..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/Legup/Reset.png and /dev/null 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 27ccec972..a74654d43 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 new file mode 100644 index 000000000..214aa5348 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png 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 new file mode 100644 index 000000000..73072f2ce Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png 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 new file mode 100644 index 000000000..b68f67e44 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png 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 deleted file mode 100644 index ed0701f26..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/PreventTrioDirectRule.png and /dev/null 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 deleted file mode 100644 index 5cc030a76..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/RepeatedRowColumnContradictionRule.png and /dev/null 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 deleted file mode 100644 index 7695ae2da..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/SaveBlockerDirectRule.png and /dev/null 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 new file mode 100644 index 000000000..67a4e47f3 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png 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 new file mode 100644 index 000000000..862408b63 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png 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 deleted file mode 100644 index e292ec9fa..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/TrioContradictionRule.png and /dev/null 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 bd66c16a7..029bd12ac 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 deleted file mode 100644 index 7785d198c..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/UniqueRowColumnDirectRule.png and /dev/null 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 deleted file mode 100644 index 8813d7956..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/WastedBlockerContradictionRule.png and /dev/null 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 deleted file mode 100644 index 7394bff91..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/rules/ZeroOrOneCaseRule.png and /dev/null 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 deleted file mode 100644 index 41fb61dfa..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/tiles/NumberTile.png and /dev/null 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 deleted file mode 100644 index 9ab9f7481..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/binary/tiles/UnknownTile.png and /dev/null 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 e8cca03b4..7ab0cdbef 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 307d0d754..fedbbbac8 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 6ab3cd769..7ba489c2b 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 2f5b5237d..ff999f4bc 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 285451ba1..cfe04a503 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 6c4a6e457..6d330baa6 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 ae78caf49..76947671d 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 602f62702..8862702f1 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 86a4ee8a0..8a26bbfeb 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 8db8a3bbf..216a0f3a1 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 dcf4cb2b8..1e0555648 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 b238b36aa..d3dd36bbc 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 6841a8034..40d6ff65f 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/sudoku/tiles/UnknownTile.png b/src/main/resources/edu/rpi/legup/images/starbattle/UnknownTile.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/tiles/UnknownTile.png rename to src/main/resources/edu/rpi/legup/images/starbattle/UnknownTile.png diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/black.gif b/src/main/resources/edu/rpi/legup/images/starbattle/black.gif new file mode 100644 index 000000000..13381a717 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/black.gif 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 new file mode 100644 index 000000000..0383711bb Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png 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 new file mode 100644 index 000000000..d25340b40 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png 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 new file mode 100644 index 000000000..cc019752f Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png 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 new file mode 100644 index 000000000..b468ae6f6 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png 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 new file mode 100644 index 000000000..38b91d0a2 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/empty.gif 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 new file mode 100644 index 000000000..f72fd7d7f Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png 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 new file mode 100644 index 000000000..1a88e9d07 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png 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 new file mode 100644 index 000000000..24fb0d48a Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRowsDirectRule.png 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 new file mode 100644 index 000000000..11cfbf899 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png 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 new file mode 100644 index 000000000..fde683dcd Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png 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 new file mode 100644 index 000000000..30170df40 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinRowsDirectRule.png 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 new file mode 100644 index 000000000..bac64a87c Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png 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 new file mode 100644 index 000000000..8907e0475 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png 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 new file mode 100644 index 000000000..13287f779 Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/rules/SurroundStar.png 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 new file mode 100644 index 000000000..e289b287a Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/starbattle/star.gif differ diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/tiles/NumberTile.png b/src/main/resources/edu/rpi/legup/images/starbattle/white.gif similarity index 82% rename from src/main/resources/edu/rpi/legup/images/sudoku/tiles/NumberTile.png rename to src/main/resources/edu/rpi/legup/images/starbattle/white.gif index 5a8540d02..fc2c683eb 100644 Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/tiles/NumberTile.png and b/src/main/resources/edu/rpi/legup/images/starbattle/white.gif 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 new file mode 100644 index 000000000..d51538baf Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/sudoku/AdvancedDeduction.png differ diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoSolution.png b/src/main/resources/edu/rpi/legup/images/sudoku/NoSolution.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/rules/NoSolution.png rename to src/main/resources/edu/rpi/legup/images/sudoku/NoSolution.png diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/PossibleValues.png b/src/main/resources/edu/rpi/legup/images/sudoku/PossibleValues.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/rules/PossibleValues.png rename to src/main/resources/edu/rpi/legup/images/sudoku/PossibleValues.png diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/RepeatedNumber.png b/src/main/resources/edu/rpi/legup/images/sudoku/RepeatedNumber.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/rules/RepeatedNumber.png rename to src/main/resources/edu/rpi/legup/images/sudoku/RepeatedNumber.png diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByDeduction.png b/src/main/resources/edu/rpi/legup/images/sudoku/forcedByDeduction.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByDeduction.png rename to src/main/resources/edu/rpi/legup/images/sudoku/forcedByDeduction.png diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByElimination.png b/src/main/resources/edu/rpi/legup/images/sudoku/forcedByElimination.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/rules/forcedByElimination.png rename to src/main/resources/edu/rpi/legup/images/sudoku/forcedByElimination.png diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number.png b/src/main/resources/edu/rpi/legup/images/sudoku/possible_cells_number.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number.png rename to src/main/resources/edu/rpi/legup/images/sudoku/possible_cells_number.png 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 deleted file mode 100644 index 9dcade64b..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberColumn.png and /dev/null 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 deleted file mode 100644 index 000dc8b68..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRegion.png and /dev/null 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 deleted file mode 100644 index f984f8365..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/rules/NoCellForNumberRow.png and /dev/null differ 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 deleted file mode 100644 index 2ebdc5823..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_column.png and /dev/null 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 deleted file mode 100644 index cc371e3e9..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_region.png and /dev/null 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 deleted file mode 100644 index 80476a428..000000000 Binary files a/src/main/resources/edu/rpi/legup/images/sudoku/rules/possible_cells_number_row.png and /dev/null differ diff --git a/src/main/resources/edu/rpi/legup/images/sudoku/rules/tem.png b/src/main/resources/edu/rpi/legup/images/sudoku/tem.png similarity index 100% rename from src/main/resources/edu/rpi/legup/images/sudoku/rules/tem.png rename to src/main/resources/edu/rpi/legup/images/sudoku/tem.png diff --git a/src/main/resources/edu/rpi/legup/legup/config b/src/main/resources/edu/rpi/legup/legup/config index e01767677..1ee9ed79c 100644 --- a/src/main/resources/edu/rpi/legup/legup/config +++ b/src/main/resources/edu/rpi/legup/legup/config @@ -34,22 +34,26 @@ fileCreationDisabled="false"/> + fileCreationDisabled="true"/> + - - - + + + diff --git a/src/test/java/legup/TestUtilities.java b/src/test/java/legup/TestUtilities.java index d48d648d7..83ce773d4 100644 --- a/src/test/java/legup/TestUtilities.java +++ b/src/test/java/legup/TestUtilities.java @@ -7,18 +7,10 @@ import edu.rpi.legup.model.tree.TreeTransition; import edu.rpi.legup.save.InvalidFileFormatException; -import java.io.InputStream; - public final class TestUtilities { public static void importTestBoard(String fileName, Puzzle puzzle) throws InvalidFileFormatException { - InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName); - - if (inputStream == null) { - throw new IllegalArgumentException("InputStream cannot be null. File not found: " + fileName); - } - - puzzle.importPuzzle(inputStream); + puzzle.importPuzzle(ClassLoader.getSystemResourceAsStream(fileName)); Tree tree = puzzle.getTree(); TreeNode rootNode = tree.getRootNode(); Board board = rootNode.getBoard().copy(); diff --git a/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java b/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java index a29a1c934..5f5b6d35a 100644 --- a/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java +++ b/src/test/java/puzzles/nurikabe/rules/FinishRoomCaseRuleTest.java @@ -28,12 +28,13 @@ public static void setUp() { } /** - * Tests the Finish Room case rule by ensuring it produces the correct number of children + * Tests the Finish Room case rule by ensuring that it results in 5 or less children, that + * contain a modified cell that is white */ - @Test public void FinishRoomCaseRule_FinishRoomCaseRuleBaseTest() throws InvalidFileFormatException { - TestUtilities.importTestBoard("puzzles/nurikabe/rules/FinishRoomCaseRule/FinishRoomCaseRuleBase", nurikabe); + TestUtilities.importTestBoard( + "puzzles/nurikabe/rules/FinishRoomCaseRule/FinishRoomCaseRuleBase", nurikabe); TreeNode rootNode = nurikabe.getTree().getRootNode(); TreeTransition transition = rootNode.getChildren().get(0); transition.setRule(RULE); @@ -80,6 +81,34 @@ public void FinishRoomCaseRule_FinishRoomCaseRuleBaseTest() throws InvalidFileFo NurikabeCell cell2 = board.getCell(4, 2); ArrayList cases2 = RULE.getCases(board, cell2); - Assert.assertEquals(9, cases2.size()); + 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(); + } } diff --git a/src/test/java/puzzles/sudoku/rules/LastNumberForCellDirectRuleRegionTest.java b/src/test/java/puzzles/sudoku/rules/LastNumberForCellDirectRuleRegionTest.java deleted file mode 100644 index f27f38d8a..000000000 --- a/src/test/java/puzzles/sudoku/rules/LastNumberForCellDirectRuleRegionTest.java +++ /dev/null @@ -1,100 +0,0 @@ -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 deleted file mode 100644 index 704167a29..000000000 --- a/src/test/java/puzzles/sudoku/rules/RepeatedNumberContradictionRuleTest.java +++ /dev/null @@ -1,88 +0,0 @@ -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 deleted file mode 100644 index 026742fea..000000000 --- a/src/test/resources/puzzles/binary/rules/SurroundPairDirectRule/SurroundTwoZerosWithTwoOnes +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ 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 deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/test/resources/puzzles/nurikabe/rules/BlackBetweenRegionsDirectRule/SurroundTwoZerosWithTwoOnes b/src/test/resources/puzzles/nurikabe/rules/BlackBetweenRegionsDirectRule/SurroundTwoZerosWithTwoOnes deleted file mode 100644 index 026742fea..000000000 --- a/src/test/resources/puzzles/nurikabe/rules/BlackBetweenRegionsDirectRule/SurroundTwoZerosWithTwoOnes +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ 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 new file mode 100644 index 000000000..ddcc4dc9a --- /dev/null +++ b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..f2a5b42d9 --- /dev/null +++ b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 000000000..f2a5b42d9 --- /dev/null +++ b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 deleted file mode 100644 index 4d3c57225..000000000 --- a/src/test/resources/puzzles/sudoku/rules/LastCellForNumberDirectRule/CorneredRegion +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullMixed b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullMixed deleted file mode 100644 index 55b501fec..000000000 --- a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullMixed +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ 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 deleted file mode 100644 index 58fd02162..000000000 --- a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRegion +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRow b/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRow deleted file mode 100644 index 07e502ed9..000000000 --- a/src/test/resources/puzzles/sudoku/rules/LastNumberForCellDirectRule/FullRow +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard4 b/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard4 deleted file mode 100644 index abaa0ba6b..000000000 --- a/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard4 +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard7 b/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard7 deleted file mode 100644 index 5692dea64..000000000 --- a/src/test/resources/puzzles/sudoku/rules/RepeatedNumberContradictionRule/BlankBoard7 +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - -