Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

October Merge #636

Merged
merged 37 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
50ba53f
Region Based Changes (#559)
19690ao Sep 29, 2023
f3dbafb
Short Truth Table Puzzle Editor (#451)
charlestian23 Sep 29, 2023
bcb8629
Have null changes be valid and fix IsolatedBlackContradicitonRule err…
04vmatsibekker Sep 29, 2023
f1c7985
Fixed a bug
charlestian23 Oct 3, 2023
7ff8873
Merge pull request #625 from charlestian23/dev
Chase-Grajeda Oct 3, 2023
473300c
Update BlackTile.java
charlestian23 Oct 3, 2023
0832621
Added unknown tile stuff
charlestian23 Oct 3, 2023
23d6558
ID error
charlestian23 Oct 3, 2023
145e316
Some Fixes to Recently Discussed UX Bugs (#563)
hansongu123 Oct 3, 2023
1357dbd
Oops pushed the wrong file
charlestian23 Oct 3, 2023
f3ba447
Number Tile working
charlestian23 Oct 3, 2023
e03cdf9
Merge branch 'dev' into dev
charlestian23 Oct 3, 2023
b603f1a
Update Exporter (#627)
ThisMatt Oct 6, 2023
47a57d2
Merge branch 'dev' into dev
charlestian23 Oct 10, 2023
ef1be26
Create run-tests.yml
charlestian23 Oct 10, 2023
20ff3dc
Update run-tests.yml
charlestian23 Oct 10, 2023
4df8313
Update run-tests.yml
charlestian23 Oct 10, 2023
60c99db
Update run-tests.yml
charlestian23 Oct 10, 2023
84517f8
Update run-tests.yml
charlestian23 Oct 10, 2023
57532c4
Windows things
charlestian23 Oct 10, 2023
aac1ed4
Added print messages
charlestian23 Oct 10, 2023
25d559a
More Windows things
charlestian23 Oct 10, 2023
48479a6
Debugging
charlestian23 Oct 10, 2023
28c06bc
Update run-tests.yml
charlestian23 Oct 10, 2023
7377a15
Update run-tests.yml
charlestian23 Oct 10, 2023
49fb14f
Maybe this will work now?
charlestian23 Oct 10, 2023
cfeee6a
Didn't work
charlestian23 Oct 10, 2023
7b49c11
Update run-tests.yml
charlestian23 Oct 10, 2023
4029b7c
Update run-tests.yml
charlestian23 Oct 10, 2023
19f0c26
Create DummyTest.java
charlestian23 Oct 10, 2023
f2b1cfa
Added another dummy test
charlestian23 Oct 10, 2023
7fd577b
Update run-tests.yml
charlestian23 Oct 10, 2023
8675598
Update run-tests.yml
charlestian23 Oct 10, 2023
4bd1787
Deleted the dummy tests
charlestian23 Oct 10, 2023
a52b65d
Merge pull request #634 from charlestian23/github-actions-test-suite
Chase-Grajeda Oct 10, 2023
f98bc7d
Merge branch 'dev' into dev
Chase-Grajeda Oct 10, 2023
97be2be
Merge pull request #629 from charlestian23/dev
Chase-Grajeda Oct 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Run JUnit Tests

on:
push:
branches:
- master
- dev
pull_request:
branches:
- master
- dev

jobs:
ubuntu-test:
runs-on: ubuntu-latest

steps:
- name: Check Out Code
uses: actions/checkout@v2

- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build with Gradle
run: ./gradlew build -x test

- name: Run JUnit Tests on Linux
run: |
./gradlew test

test-macos:
runs-on: macos-latest

steps:
- name: Check Out Code
uses: actions/checkout@v2

- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build with Gradle
run: ./gradlew build -x test

- name: Run JUnit Tests on macOS
run: |
./gradlew test

test-windows:
runs-on: windows-latest

steps:
- name: Check Out Code
uses: actions/checkout@v2

- name: Set up JDK and Gradle on Windows
uses: actions/setup-java@v2
with:
java-version: 11
distribution: 'adopt'

- name: Run JUnit Tests on Windows
run: |
.\gradlew.bat test
2 changes: 1 addition & 1 deletion bin/main/edu/rpi/legup/legup/config
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<puzzle name="ShortTruthTable"
qualifiedClassName="edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTable"
fileType=".xml"
fileCreationDisabled="true"/>
fileCreationDisabled="false"/>
<puzzle name="Sudoku" qualifiedClassName="edu.rpi.legup.puzzle.sudoku.Sudoku"
fileType=".xml"
fileCreationDisabled="true"/>
Expand Down
14 changes: 14 additions & 0 deletions puzzles files/shorttruthtable/empty_test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Legup version="2.0.0">
<puzzle name="ShortTruthTable">
<board>
<data>
<statement representation="A>(B^C)" row_index="0"/>
<statement representation="C-B" row_index="1"/>
<statement representation="~C" row_index="2"/>
<statement representation="~A" row_index="3"/>
</data>
</board>
</puzzle>
<Solved isSolved="false"/>
</Legup>
84 changes: 76 additions & 8 deletions src/main/java/edu/rpi/legup/app/GameBoardFacade.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
package edu.rpi.legup.app;

import edu.rpi.legup.history.History;
import edu.rpi.legup.history.IHistoryListener;
import edu.rpi.legup.history.IHistorySubject;
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.PuzzleImporter;
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.tree.Tree;
import edu.rpi.legup.save.InvalidFileFormatException;
import edu.rpi.legup.ui.LegupUI;
import edu.rpi.legup.ui.ProofEditorPanel;
import edu.rpi.legup.ui.PuzzleEditorPanel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import edu.rpi.legup.save.InvalidFileFormatException;
import edu.rpi.legup.ui.LegupUI;
import edu.rpi.legup.history.History;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
Expand Down Expand Up @@ -144,6 +143,30 @@ public boolean validateDimensions(String game, int rows, int columns) throws Run
}
}

/**
* Validates the given text input for the given puzzle
*
* @param game the name of the puzzle
* @param statements an array of statements
* @return true if it is possible to create a board for the given game with the given statements,
* false otherwise
* @throws RuntimeException if any of the input is invalid
*/
public boolean validateTextInput(String game, String[] statements) throws RuntimeException {
String qualifiedClassName = config.getPuzzleClassForName(game);
try {
Class<?> c = Class.forName(qualifiedClassName);
Constructor<?> constructor = c.getConstructor();
Puzzle puzzle = (Puzzle) constructor.newInstance();
return puzzle.isValidTextInput(statements);
}
catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException |
InstantiationException e) {
LOGGER.error(e);
throw new RuntimeException("Error validating puzzle text input");
}
}

/**
* Loads an empty puzzle
*
Expand All @@ -159,14 +182,20 @@ public void loadPuzzle(String game, int rows, int columns) throws RuntimeExcepti
Class<?> c = Class.forName(qualifiedClassName);
Constructor<?> cons = c.getConstructor();
Puzzle puzzle = (Puzzle) cons.newInstance();
setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle");

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");
}

setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle");
importer.initializePuzzle(rows, columns);

puzzle.initializeView();
Expand All @@ -183,6 +212,45 @@ public void loadPuzzle(String game, int rows, int columns) throws RuntimeExcepti
}
}

public void loadPuzzle(String game, String[] statements) {
String qualifiedClassName = config.getPuzzleClassForName(game);
LOGGER.debug("Loading " + qualifiedClassName);

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");
}

// Theoretically, this exception should never be thrown, since LEGUP should not be
// allowing the user to give text input for a puzzle that doesn't support it
if (!importer.acceptsTextInput()) {
throw new IllegalArgumentException(puzzle.getName() + " does not accept text input");
}

setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle");
importer.initializePuzzle(statements);

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 a puzzle file
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,17 @@ public void executeCommand() {
}
else {
TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
finalTreeElement = transitionView.getChildView().getTreeElement();
if (transitionView.getChildView() != null) {
finalTreeElement = transitionView.getChildView().getTreeElement();
}
else {
finalTreeElement = null;
}
}

if (finalTreeElement != null) {
puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
}
puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
}

Expand Down
14 changes: 14 additions & 0 deletions src/main/java/edu/rpi/legup/model/Puzzle.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,26 @@ public boolean isValidDimensions(int rows, int columns) {
return rows > 0 && columns > 0;
}

/**
* Checks if the given array of statements is valid text input for the given puzzle
*
* @param statements
* @return
*/
public boolean isValidTextInput(String[] statements) {
return statements.length > 0;
}

/**
* Determines if the edu.rpi.legup.puzzle was solves correctly
*
* @return true if the board was solved correctly, false otherwise
*/
public boolean isPuzzleComplete() {
if (tree == null) {
return false;
}

boolean isComplete = tree.isValid();
if (isComplete) {
for (TreeElement leaf : tree.getLeafTreeElements()) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/edu/rpi/legup/model/PuzzleExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public abstract class PuzzleExporter {

/**
* PuzzleExporter Constructor exports the puzzle object to a file
*
* @param puzzle puzzle that is to be exported
*/
public PuzzleExporter(Puzzle puzzle) {
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/edu/rpi/legup/model/PuzzleImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

public abstract class PuzzleImporter {
private static final Logger LOGGER = LogManager.getLogger(PuzzleImporter.class.getName());
Expand All @@ -24,12 +21,17 @@ public abstract class PuzzleImporter {

/**
* PuzzleImporter Constructor creates the puzzle object
*
* @param puzzle puzzle that is imported
*/
public PuzzleImporter(Puzzle puzzle) {
this.puzzle = puzzle;
}

public abstract boolean acceptsRowsAndColumnsInput();

public abstract boolean acceptsTextInput();

/**
* Initializes an empty puzzle
*
Expand All @@ -46,6 +48,13 @@ public void initializePuzzle(int rows, int columns) throws RuntimeException {
}
}

public void initializePuzzle(String[] statements) throws InputMismatchException, IllegalArgumentException {
// Note: Error checking for the statements will be left up to the puzzles that support
// text input. For example, some puzzles may be okay with "blank" statements (Strings with
// length = 0) while others may not.
initializeBoard(statements);
}

/**
* Initializes the puzzle attributes
*
Expand Down Expand Up @@ -116,6 +125,8 @@ public void initializePuzzle(Node node) throws InvalidFileFormatException {
*/
public abstract void initializeBoard(Node node) throws InvalidFileFormatException;

public abstract void initializeBoard(String[] statements) throws UnsupportedOperationException, IllegalArgumentException;

/**
* Creates the proof for building
*
Expand Down
14 changes: 4 additions & 10 deletions src/main/java/edu/rpi/legup/model/rules/DirectRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,12 @@ public DirectRule(String ruleID, String ruleName, String description, String ima
*/
public String checkRule(TreeTransition transition) {
Board finalBoard = transition.getBoard();

if (!finalBoard.isModified()) {
return "State must be modified";
if (transition.getParents().size() != 1 ||
transition.getParents().get(0).getChildren().size() != 1) {
return "State must have only 1 parent and 1 child";
}
else {
if (transition.getParents().size() != 1 ||
transition.getParents().get(0).getChildren().size() != 1) {
return "State must have only 1 parent and 1 child";
}
else {
return checkRuleRaw(transition);
}
return checkRuleRaw(transition);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/main/java/edu/rpi/legup/model/tree/Tree.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public Set<TreeElement> getLeafTreeElements() {

/**
* 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 sub tree
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import edu.rpi.legup.model.PuzzleExporter;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTableBoard;
import org.w3c.dom.Document;

public class BattleshipExporter extends PuzzleExporter {
Expand All @@ -18,7 +19,13 @@ public BattleshipExporter(Battleship battleShip) {
*/
@Override
protected org.w3c.dom.Element createBoardElement(Document newDocument) {
BattleshipBoard board = (BattleshipBoard) puzzle.getTree().getRootNode().getBoard();
BattleshipBoard board;
if (puzzle.getTree() != null) {
board = (BattleshipBoard) puzzle.getTree().getRootNode().getBoard();
}
else {
board = (BattleshipBoard) puzzle.getBoardView().getBoard();
}

org.w3c.dom.Element boardElement = newDocument.createElement("board");
boardElement.setAttribute("width", String.valueOf(board.getWidth()));
Expand Down
Loading
Loading