Many "if" in an old game for android

Asked

Viewed 118 times

7

When checking if someone won, I need to use the IF several times. I wonder if there’s a way to simplify the code a little bit and maybe even replace the IFs.

//left, top, right, bottom are int positions relative to canvas
//state is a enum{Blank,Red,Blue} which is used to determine if the square was clicked and who clicked it

private boolean checkHorizontalWin() {
    for (Square s1 : squareList) {
        if (s1.getState() != State.BLANK) {
            for (Square s2 : squareList) {
                if (s1 != s2) {
                    if (s1.getTop() == s2.getTop()) {
                        if (s1.getState() == s2.getState()) {
                            for (Square s3 : squareList) {
                                if (s1 != s3 && s2 != s3) {
                                    if (s1.getTop() == s3.getTop()) {
                                        if (s1.getState() == s3.getState()) {
                                            return true;
                                        } else break;
                                    }
                                }
                            }
                        } else break;
                    }
                }
            }
        }
    } return false;
}

private boolean checkVerticalWin() {
    for (Square s1 : squareList) {
        if (s1.getState() != State.BLANK) {
            for (Square s2 : squareList) {
                if (s1 != s2) {
                    if (s1.getLeft() == s2.getLeft()) {
                        if (s1.getState() == s2.getState()) {
                            for (Square s3 : squareList) {
                                if (s1 != s3 && s2 != s3) {
                                    if (s1.getLeft() == s3.getLeft()) {
                                        if (s1.getState() == s3.getState()) {
                                            return true;
                                        } else break;
                                    }
                                }
                            }
                        } else break;
                    }
                }
            }
        }
    } return false;
}

private boolean checkDiagonalWin() {
    for (Square s1 : squareList) {
        if (s1.getState() != State.BLANK) {
            for (Square s2 : squareList) {
                if (s1 != s2) {
                    if (s1.getBottom() != s2.getBottom()) {
                        if (s1.getRight() == s2.getLeft()) {
                            for (Square s3 : squareList) {
                                if (s1 != s3 && s2 != s3) {
                                    if (s1.getBottom() != s3.getBottom() && s2.getBottom() != s3.getBottom()) {
                                        if (s2.getRight() == s3.getLeft()){
                                            if (s1.getState() == s2.getState() && s1.getState() == s3.getState()) {
                                                return true;
                                            } else break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    } return false;
}

squareList is created in a way similar to this:

private List<Square> squareList = new ArrayList<>();
private final int GRID_SIZE = 3;
private final int GRID_AREA = GRID_SIZE * GRID_SIZE;

private void createSquares() {
    int x = 0;
    int y = 0;
    for (int i = 0; i < gridArea; i++) {
        int left = field.getWidth() / 3 * x;
        int top = field.getHeight() / 3 * y + field.getBorder();
        int right = field.getWidth() / 3 * (x + 1);
        int bottom = field.Height() / 3 * (y + 1) + field.getBorder();
        squareList.add(new Square(left, top, right, bottom, State.BLANK));

        x++;
        if (x == GRID_SIZE) {
            x = 0;
            y++;
        }
    }
}

I prefer not to use Java 8 because of the lack of compatibility with old Apis

  • Like this squareList is built?

  • What are the attributes Top, State, Left, Right and Bottom of Square?

  • squareList is a list of the 9 squares on the board and the attributes are their position relative to the canvas

  • And how do you create the squareList? In which order the squares are inserted in that list?

  • first line from left to right, then bottom line in the same order and then the last

2 answers

14


Do something like this:

// O squareList deve ser uma lista com 9 posições onde os índices estão assim:

// +---+---+---+
// | 0 | 1 | 2 |
// +---+---+---+
// | 3 | 4 | 5 |
// +---+---+---+
// | 6 | 7 | 8 |
// +---+---+---+

private State[] getStates() {
    State[] s = new State[9];
    int i = 0;
    for (Square sq : squareList) {
        s[i] = sq.getState();
        i++;
    }
    return s;
}

private boolean isWon(State[] s, int a, int b, int c) {
    return s[a] != State.BLANK && s[a] == s[b] && s[b] == s[c];
}

private boolean checkWin() {
    State[] s = getStates();
    return isWon(s, 0, 1, 2)  // Horizontal 1.
        || isWon(s, 3, 4, 5)  // Horizontal 2.
        || isWon(s, 6, 7, 8)  // Horizontal 3.
        || isWon(s, 0, 3, 6)  // Vertical 1.
        || isWon(s, 1, 4, 7)  // Vertical 2.
        || isWon(s, 2, 5, 8)  // Vertical 3.
        || isWon(s, 0, 4, 8)  // Diagonal 1.
        || isWon(s, 2, 4, 6); // Diagonal 2.
}

If you prefer to use Java 8, you can build the method getStates() thus:

private State[] getStates() {
    return squareList.stream()
            .map(Square::getState)
            .collect(Collectors.toArray(State[]::new));
}

If the order of the elements in the squareList not the one outlined above, I strongly recommend that you change the mechanism by which the squareList is built to be.

0

I think it’s cleaner this way:

private boolean checkHorizontalWin() {
        if(isEqual(squareList.get(0), squareList.get(1), squareList.get(2))) return true;
        if(isEqual(squareList.get(3), squareList.get(4), squareList.get(5))) return true;
        if(isEqual(squareList.get(6), squareList.get(7), squareList.get(8))) return true;
        return false;
    }

    private boolean checkVerticalWin() {
        if(isEqual(squareList.get(0), squareList.get(3), squareList.get(6))) return true;
        if(isEqual(squareList.get(1), squareList.get(4), squareList.get(7))) return true;
        if(isEqual(squareList.get(2), squareList.get(5), squareList.get(8))) return true;
        return false;
    }

    private boolean checkDiagonalWin() {
        if(isEqual(squareList.get(0), squareList.get(4), squareList.get(8))) return true;
        if(isEqual(squareList.get(2), squareList.get(4), squareList.get(6))) return true;
        return false;
    }

    private boolean isEqual(Square first, Square second, Square third) {
        if(first.getState() == State.BLANK || second.getState() == State.BLANK || third.getState() == State.BLANK)
            return false;

        long equalStatus = Arrays.asList(first, second, third)
                .stream().map(square -> square.getState()).collect(Collectors.toList())
                .stream().distinct().count();

        return equalStatus == 1;
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.