Skip to content

Commit

Permalink
Merge pull request #171 from Hiimadd/dev
Browse files Browse the repository at this point in the history
Fixes for TreeTent rules not dependent on links
  • Loading branch information
charlestian23 authored Jul 15, 2022
2 parents 49aa0cc 20d7a56 commit 02fb9ee
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 37,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
TreeTentCell initCell = (TreeTentCell) initialBoard.getPuzzleElement(puzzleElement);
TreeTentBoard finalBoard = (TreeTentBoard) transition.getBoard();
TreeTentCell finalCell = (TreeTentCell) finalBoard.getPuzzleElement(puzzleElement);
if (finalCell.getType() == TreeTentType.GRASS && initCell.getType() == TreeTentType.UNKNOWN) {
return null;
if (!(finalCell.getType() == TreeTentType.GRASS && initCell.getType() == TreeTentType.UNKNOWN)) {
return super.getInvalidUseOfRuleMessage() ": This cell must be grass";
}

if (isForced(finalBoard, finalCell)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 5,14 @@
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.treetent.TreeTentBoard;
import edu.rpi.legup.puzzle.treetent.TreeTentCell;
import edu.rpi.legup.puzzle.treetent.TreeTentType;
import edu.rpi.legup.puzzle.treetent.TreeTentClue;

import java.util.ArrayList;
import java.util.List;
import java.awt.*;

public class FillinRowCaseRule extends CaseRule {

Expand All @@ -18,7 24,19 @@ public FillinRowCaseRule() {

@Override
public CaseBoard getCaseBoard(Board board) {
return null;
TreeTentBoard treeTentBoard = (TreeTentBoard) board.copy();
treeTentBoard.setModifiable(false);
CaseBoard caseBoard = new CaseBoard(treeTentBoard, this);
ArrayList<TreeTentClue> clues = treeTentBoard.getRowClues();
clues.addAll(treeTentBoard.getColClues());
for (PuzzleElement element : clues) {
// if ((((TreeTentCell) element).getType() == TreeTentType.CLUE_SOUTH && treeTentBoard.getRowCol(((TreeTentCell)element).getLocation().y, TreeTentType.UNKNOWN, true).size() != 0) ||
// (((TreeTentCell) element).getType() == TreeTentType.CLUE_EAST && treeTentBoard.getRowCol(((TreeTentCell)element).getLocation().x, TreeTentType.UNKNOWN, false).size() != 0)) {
// caseBoard.addPickableElement(element);
// }
caseBoard.addPickableElement(element);
}
return caseBoard;
}

/**
Expand All @@ -30,9 48,92 @@ public CaseBoard getCaseBoard(Board board) {
*/
@Override
public ArrayList<Board> getCases(Board board, PuzzleElement puzzleElement) {
ArrayList<Board> cases = new ArrayList<Board>();
List<TreeTentCell> group;
int tentsLeft;
TreeTentClue clue = ((TreeTentClue) puzzleElement);
int clueIndex = clue.getClueIndex()-1;
TreeTentBoard tBoard = (TreeTentBoard)board;
if(clue.getType() == TreeTentType.CLUE_SOUTH) {
group = tBoard.getRowCol(clueIndex, TreeTentType.UNKNOWN, false);
tentsLeft = tBoard.getRowClues().get(clueIndex).getData() - tBoard.getRowCol(clueIndex, TreeTentType.TENT, false).size();
cases = genCombinations(tBoard, group, tentsLeft, clueIndex, false);
} else {
group = tBoard.getRowCol(clueIndex, TreeTentType.UNKNOWN, true);
tentsLeft = tBoard.getRowClues().get(clueIndex).getData() - tBoard.getRowCol(clueIndex, TreeTentType.TENT, true).size();
cases = genCombinations(tBoard, group, tentsLeft, clueIndex, true);
}

//generate every combination (nCr)
//call goodBoard for each generated combination
//alternitive would be to implement collision avoidance while generating instead of after
if(cases.size() > 0) {return cases;}
return null;
}

private ArrayList<Board> genCombinations(TreeTentBoard iBoard, List<TreeTentCell> tiles, int target, Integer index, boolean isRow)
{
return genCombRecursive(iBoard, tiles, tiles, target, 0, new ArrayList<TreeTentCell>(), index, isRow);
}

private ArrayList<Board> genCombRecursive(TreeTentBoard iBoard, List<TreeTentCell> original, List<TreeTentCell> tiles, int target, int current, List<TreeTentCell> selected, Integer index, boolean isRow)
{
ArrayList<Board> b = new ArrayList<>();
if(target == current)
{
TreeTentBoard temp = iBoard.copy();
for(TreeTentCell c : original)
{
if(selected.contains(c))
{
PuzzleElement change = temp.getPuzzleElement(c);
change.setData(TreeTentType.TENT.value);
temp.addModifiedData(change);
}
else
{
PuzzleElement change = temp.getPuzzleElement(c);
change.setData(TreeTentType.GRASS.value);
temp.addModifiedData(change);
}

}
if(goodBoard(temp, index, isRow)) {b.add(temp);}
return b;
}
for(int i = 0; i < tiles.size(); i)
{
List<TreeTentCell> sub = tiles.subList(i 1, tiles.size());
List<TreeTentCell> next = new ArrayList<TreeTentCell>(selected);
next.add(tiles.get(i));
b.addAll(genCombRecursive(iBoard, original, sub, target, current 1, next, index, isRow));
}
return b;
}

//Effectively runs TouchingTents check on all the added tents to make sure that the proposed board is valid.
//Could check more or less in the future depending on how "smart" this case rule should be.
private boolean goodBoard(TreeTentBoard board, Integer index, boolean isRow)
{
List<TreeTentCell> tents;
if(isRow)
{
tents = board.getRowCol(index, TreeTentType.TENT, true);
}
else
{
tents = board.getRowCol(index, TreeTentType.TENT, false);
}

for(TreeTentCell t : tents)
{
List<TreeTentCell> adj = board.getAdjacent(t, TreeTentType.TENT);
List<TreeTentCell> diag = board.getDiagonals(t, TreeTentType.TENT);
if(adj.size() > 0 || diag.size() > 0) {return false;}
}
return true;
}

/**
* Checks whether the transition logically follows from the parent node using this rule
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 43,33 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
return super.getInvalidUseOfRuleMessage() ": This cell must be a tent.";
}

if (isForced(initialBoard, initCell)) {
if (isForced(finalBoard, finalCell)) {
return null;
} else {
return super.getInvalidUseOfRuleMessage() ": This cell is not forced to be tent.";
}
}

private boolean isForced(TreeTentBoard board, TreeTentCell cell) {
List<TreeTentCell> adjTents = board.getAdjacent(cell, TreeTentType.TREE);
for (TreeTentCell c : adjTents) {
Point loc = c.getLocation();
for (TreeTentLine line : board.getLines()) {
if (line.getC1().getLocation().equals(loc) || line.getC2().getLocation().equals(loc)) {
return false;
List<TreeTentCell> adjTrees = board.getAdjacent(cell, TreeTentType.TREE);
for (TreeTentCell c : adjTrees) {
List<TreeTentCell> unkAroundTree = board.getAdjacent(c, TreeTentType.UNKNOWN);
List<TreeTentCell> tntAroundTree = board.getAdjacent(c, TreeTentType.TENT);
if(unkAroundTree.size() == 0)
{
if(tntAroundTree.size() == 1)
{
return true;
}
else
{
for(TreeTentCell t : tntAroundTree)
{
if(t == cell) {continue;}
List<TreeTentCell> treesAroundTents = board.getAdjacent(t, TreeTentType.TREE);
if(treesAroundTents.size() == 1) {return false;}
}
return true;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 5,9 @@
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.treetent.TreeTentBoard;
import edu.rpi.legup.puzzle.treetent.TreeTentType;
import edu.rpi.legup.puzzle.treetent.TreeTentCell;

import java.util.ArrayList;

Expand All @@ -18,7 21,13 @@ public LinkTentCaseRule() {

@Override
public CaseBoard getCaseBoard(Board board) {
return null;
TreeTentBoard treeTentBoard = (TreeTentBoard) board.copy();
treeTentBoard.setModifiable(false);
CaseBoard caseBoard = new CaseBoard(treeTentBoard, this);
for(PuzzleElement element : treeTentBoard.getPuzzleElements()) {
if(((TreeTentCell) element).getType() == TreeTentType.TENT) {caseBoard.addPickableElement(element);}
}
return caseBoard;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 5,12 @@
import edu.rpi.legup.model.rules.ContradictionRule;
import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
import edu.rpi.legup.puzzle.treetent.TreeTentCell;
import edu.rpi.legup.puzzle.treetent.TreeTentLine;
import edu.rpi.legup.puzzle.treetent.TreeTentType;

import java.util.List;
import java.util.Iterator;

public class NoTreeForTentContradictionRule extends ContradictionRule {

public NoTreeForTentContradictionRule() {
Expand All @@ -30,9 34,26 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
if (cell.getType() != TreeTentType.TENT) {
return super.getNoContradictionMessage();
}
int adjTree = treeTentBoard.getAdjacent(cell, TreeTentType.TREE).size();
int adjUnknown = treeTentBoard.getAdjacent(cell, TreeTentType.UNKNOWN).size();
if (adjTree == 0 && adjUnknown == 0) {
List<TreeTentCell> adjTrees = treeTentBoard.getAdjacent(cell, TreeTentType.TREE);
List<TreeTentLine> lines = treeTentBoard.getLines();
for(TreeTentLine l : lines)
{
Iterator<TreeTentCell> i = adjTrees.iterator();
while(i.hasNext())
{
TreeTentCell t = i.next();
if (t.getLocation().equals(l.getC1().getLocation()) && !(cell.getLocation().equals(l.getC2().getLocation())))
{
i.remove();
}
if (t.getLocation().equals(l.getC2().getLocation()) && !(cell.getLocation().equals(l.getC2().getLocation())))
{
i.remove();
}
}
}
int adjTree = adjTrees.size();
if (adjTree == 0) {
return null;
} else {
return super.getNoContradictionMessage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 29,12 @@ public TouchingTentsContradictionRule() {
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
TreeTentBoard treeTentBoard = (TreeTentBoard) board;
TreeTentCell cell = (TreeTentCell) puzzleElement;
if (cell.getType() != TreeTentType.TREE) {
if (cell.getType() != TreeTentType.TENT) {
return super.getNoContradictionMessage();
}
int adjTree = treeTentBoard.getAdjacent(cell, TreeTentType.TREE).size();
if (adjTree > 0) {
int adjTree = treeTentBoard.getAdjacent(cell, TreeTentType.TENT).size();
int diagTree = treeTentBoard.getDiagonals(cell, TreeTentType.TENT).size();
if (adjTree > 0 || diagTree > 0) {
return null;
} else {
return super.getNoContradictionMessage();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 1,15 @@
package edu.rpi.legup.puzzle.treetent.rules;

import java.util.List;
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.BasicRule;
import edu.rpi.legup.model.tree.TreeNode;
import edu.rpi.legup.model.tree.TreeTransition;
import edu.rpi.legup.puzzle.treetent.TreeTentLine;
import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
import edu.rpi.legup.puzzle.treetent.TreeTentType;
import edu.rpi.legup.puzzle.treetent.TreeTentCell;

public class TreeForTentBasicRule extends BasicRule {
public TreeForTentBasicRule() {
Expand All @@ -24,7 29,65 @@ public TreeForTentBasicRule() {
*/
@Override
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
return null;
if (!(puzzleElement instanceof TreeTentLine)) {
return super.getInvalidUseOfRuleMessage() ": Lines must be created for this rule.";
}
TreeTentBoard board = (TreeTentBoard)transition.getBoard();
TreeTentLine line = (TreeTentLine)board.getPuzzleElement(puzzleElement);
TreeTentCell tree,tent;
if (line.getC1().getType() == TreeTentType.TREE && line.getC2().getType() == TreeTentType.TENT) {
tree = line.getC1();
tent = line.getC2();
} else if (line.getC2().getType() == TreeTentType.TREE && line.getC1().getType() == TreeTentType.TENT) {
tree = line.getC2();
tent = line.getC1();
} else {
return super.getInvalidUseOfRuleMessage() ": This line must connect a tree to a tent.";
}
int forced = isForced(board, tree, tent);
if(forced == 1)
{
return null;
}
else if (forced == -1)
{
return super.getInvalidUseOfRuleMessage() ": This tent already has a link";
}
else if (forced == -2)
{
return super.getInvalidUseOfRuleMessage() ": This tree already has a link";
}
else
{
return super.getInvalidUseOfRuleMessage() ": This tree and tent don't need to be linked.";
}
}

private Integer isForced(TreeTentBoard board, TreeTentCell tree, TreeTentCell tent)
{
List<TreeTentCell> adjTrees = board.getAdjacent(tent, TreeTentType.TREE);
adjTrees.remove(tree);
List<TreeTentLine> lines = board.getLines();
for(TreeTentLine l : lines)
{
if(l.getC1().getLocation().equals(tree.getLocation()) || l.getC2().getLocation().equals(tree.getLocation())) {return -2;}
for(TreeTentCell c : adjTrees)
{
if(l.getC1().getLocation().equals(c.getLocation()))
{
if(l.getC2().getLocation().equals(tent.getLocation())) {return -1;}
adjTrees.remove(c);

}
else if(l.getC2().getLocation().equals(c.getLocation()))
{
if(l.getC1().getLocation().equals(tent.getLocation())) {return -1;}
adjTrees.remove(c);
}
}
}
if(adjTrees.size() == 0) {return 1;}
else {return 0;}
}

/**
Expand Down

0 comments on commit 02fb9ee

Please sign in to comment.