konkon / Solver.java
Solver.java
Raw
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

public class Solver {

    GameManager grid;
    int width;
    HashMap<Integer, Cell> cells;

    Solver(GameManager grid) {
        this.grid = grid;
        this.width = grid.getN();
        this.cells = grid.getCellMap();
    }

    public boolean solve(int cellIndex) {
        Cell cell = cells.get(cellIndex);
        if(cellIndex > cells.size()) {
            return true;
        }
        for(int i=1; i<width+1; i++) {
            cell.setCorrectAnswer(i);
            if(checkColumns(cell) && checkRows(cell) && checkCages(cell.cage)) {
                if(solve(cellIndex+1)) {
                    return true;
                }
            }
        }
        cell.correctAnswer = null;
        return false;
    }

    public boolean checkColumns(Cell mainCell) {
        ArrayList<Integer> currentValues = new ArrayList<>();
        for(Cell cell : cells.values()) {
            if(cell.getX() == mainCell.getX()) {
                if(currentValues.contains(cell.correctAnswer)) {
                    return false;
                } else if (cell.correctAnswer != null){
                    currentValues.add(cell.correctAnswer);
                }
            }
        }
        return true;
    }

    public boolean checkRows(Cell mainCell) {
        ArrayList<Integer> currentValues = new ArrayList<>();
        for(Cell cell : cells.values()) {
            if(cell.getY() == mainCell.getY()) {
                if(currentValues.contains(cell.correctAnswer)) {
                    return false;
                } else if (cell.correctAnswer != null){
                    currentValues.add(cell.correctAnswer);
                }
            }
        }
        return true;
    }

    public boolean checkCages(Cage cage) {
        if(!isCageFull(cage)) {
            return true;
        }
        char operator = cage.getOperator();
        if(operator == 'x' || operator == '*') {
            return multiplyCells(cage).equals(cage.getTarget());
        } else if (operator == '/' || operator == '÷') {
            Double total = divideCells(cage);
            if (total % 1 == 0) {
                return total.intValue() == cage.getTarget();
            }
            return false;
        } else if (operator == '+') {
            return addCells(cage).equals(cage.getTarget());
        } else if (operator == '-') {
            return subtractCells(cage).equals(cage.getTarget());
        }
        return cage.getCells().get(0).correctAnswer.equals(cage.getTarget());
    }

    public boolean isCageFull(Cage cage) {
        for(Cell cell : cage.getCells()) {
            if(cell.correctAnswer == null)
                return false;
        }
        return true;
    }

    public Integer multiplyCells(Cage cage) {
        int flag = 1;
        for (Cell cell : cage.getCells()) {
            flag = flag * cell.correctAnswer;
        }
        return flag;
    }

    public Integer addCells(Cage cage) {
        Integer flag = 0;
        for (Cell cell : cage.getCells()) {
            flag += cell.correctAnswer;
        }
        return flag;
    }

    public Double divideCells(Cage cage) {
        ArrayList<Integer> cellValues = new ArrayList<>();
        for(Cell cell : cage.getCells()) {
            cellValues.add(cell.correctAnswer);
        }

        Collections.sort(cellValues);
        Collections.reverse(cellValues);
        double total = cellValues.get(0);
        for (int i : cellValues.subList(1, cellValues.size())) {
            total = total / i;
        }
        return total;
    }

    public Integer subtractCells(Cage cage) {
        ArrayList<Integer> cellValues = new ArrayList<>();
        for(Cell cell : cage.getCells()) {
            cellValues.add(cell.correctAnswer);
        }
        Collections.sort(cellValues);
        Collections.reverse(cellValues);

        int total = cellValues.get(0);
        for (int i : cellValues.subList(1, cellValues.size())) {
            total -= i;
        }
        return total;
    }

}