0

Im currently working on sudoku game. I found interesting algorithm in the internet for backtracking but it doesn't work the same in my code because my task assumptions are to make it from lists of classes. I'll show my code so you get what I mean. Mainly I have list of rows that each row contains a list of elements and each element contains a list of possible number to put in that place. I want to delete every number from possible number for a element if this number is already in row, column or box 3x3 but when I go through all row,cols in my board and try to delete specific number it throws an error: ConcurrentModificationException

Goal to achieve: Main goal is to make algorithm solve sudoku well but at least now I want to see if when I delete some possible number for a element and see if algorithm works better. So if you can help me to get rid of this error that is thrown in runAlgorithm() method when I remove element I would truly appreciate that.

Element class:

public static final int EMPTY = -1;
private List<Integer> possibleFields = new ArrayList<>();
private int value;

public SudokuElement(int value) {
    this.value = value;
    for (int i=1; i<=9; i++){
        possibleFields.add(i);
    }
}

public List<Integer> getPossibleFields() {
    return possibleFields;
}

public int getValue() {
    return value;
}

public void setElement(int value){
    if (this.value == EMPTY)
        this.value = value;
}

@Override
public String toString() {
    return (value == -1 ? "-" : String.valueOf(value));
}

My row class:

private List<SudokuElement> elements = new ArrayList<>();

public SudokuRow() {
    for (int i=0; i<9; i++){
        elements.add(new SudokuElement(SudokuElement.EMPTY));
    }
}

public List<SudokuElement> getElements() {
    return elements;
}

My board class that contains rows:

    private List<SudokuRow> row = new ArrayList<>();

public SudokuBoard() {
    for (int i=0; i<9; i++){
        row.add(new SudokuRow());
    }
    setElement(0,0,8);
    setElement(2,0,6);
    setElement(2,1,5);
    setElement(1,2,3);
    setElement(1,3,6);
    setElement(2,1,7);
    setElement(2,4,9);
    setElement(2,6,2);
    setElement(3,1,5);
    setElement(3,5,7);
    setElement(4,4,4);
    setElement(4,5,5);
    setElement(4,6,7);
    setElement(5,3,1);
    setElement(5,7,3);
    setElement(6,2,1);
    setElement(6,7,6);
    setElement(6,8,8);
    setElement(7,2,8);
    setElement(7,3,5);
    setElement(7,7,1);
    setElement(8,1,9);
    setElement(8,6,4);
}
public List<SudokuRow> getRow() {
    return row;
}

private boolean checkElementRow(int x, int value){
    return row.get(x).getElements().stream().anyMatch(e -> e.getValue() == value);
}

private boolean checkElementCol(int y, int value){
    return row.stream().anyMatch(e -> e.getElements().get(y).getValue() == value);
}

private boolean checkElementBox(int row, int col, int value){
    int boxRow = row - row % 3;
    int boxCol = col - col % 3;

    for (int i = boxRow; i < boxRow+3; i++)
        for (int j = boxCol; j < boxCol+3; j++)
            if (this.row.get(i).getElements().get(j).getValue() == value)
                return true;
    return false;
}

public boolean isPlaceValid(int x, int y, int val){
    return !checkElementRow(x,val) && !checkElementCol(y,val) && !checkElementBox(x,y,val);
}

public void setElement(int x, int y, int val){
    if (isPlaceValid(x,y,val))
        row.get(x).getElements().get(y).setElement(val);
}

public boolean runAlgorithm() {
    for (int x=0; x < 9; x++){
        for (int y=0; y < 9; y++){
            for (Integer i : row.get(x).getElements().get(y).getPossibleFields()){
                row.get(0).getElements().get(0).getPossibleFields().remove(2);
            }
        }
    }

    return true;
}
javax
  • 1
  • 2
  • Do you need to repeatedly execute `row.get(0).getElements().get(0).getPossibleFields(). remove(2);` in `runAlgorithm()`? The statement does not use any of the control variables `x`, `y`, `i`. –  Aug 26 '21 at 08:03

0 Answers0