javaswingreversi

Reversi will only work in legal tiles but it won't flip in between


I'm writing a Swing implementation of Reversi for APCS. My implementation will only click in legal spots, but it doesn't flip the tiles in between. Why is this and how do I fix it?

Here are the relevant sections of code:

private int[][] directions = new int[][] {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}};

public void handleTileClick(int x, int y, MouseEvent e) {
    if (player == Tile.EMPTY) return;
    boolean d = false;
    for (int[] dir : directions) {
        int dx = dir[0], dy = dir[1];
        int curX = x, curY = y;
        boolean c = false;
        while (tiles[curX+=dx][curY+=dy].getState() == Tile.opposite(player)) c = true;
        if (c && tiles[curX][curY].getState() == player) {
            while ((curX -= dx) != x && (curY -= dy) != y) {
                tiles[curX][curY].setState(player);
            }
            tiles[x][y].setState(player);
            d = true;
        }
    }
    if (d) swapTurn();
}

For completeness, I've made a gist with all the code here


Solution

  • The loop where you flip tiles was not being entered: This should work better:

    if (c && tiles[curX][curY].getState() == player) {
        do {
            curX -= dx;
            curY -= dy;
            tiles[curX][curY].setState(player);
        } while (curX != x || curY != y);
    
        tiles[x][y].setState(player);
        d = true;
    }
    

    There is also a problem as you approach the edges of the game (i.e. boundary conditions). The current logic will allow curX and curY to be invalid array indices. The following seems to work; change as you see fit:

    public void handleTileClick(int x, int y, MouseEvent e) {
        if (player == Tile.EMPTY)
            return;
        boolean d = false;
        for (int[] dir : directions) {
            int dx = dir[0], dy = dir[1];
            int curX = x, curY = y;
            boolean c = false;
            while (true) {
                curX += dx;
                curY += dy;
                if (curX > 0 && curX < 8 && curY > 0 && curY < 8 && tiles[curX][curY].getState() == Tile.opposite(player))
                    c = true;
                else {
                    break;
                }
            }
            if (c && curX > 0 && curX < 8 && curY > 0 && curY < 8 && tiles[curX][curY].getState() == player) {
                do {
                    curX -= dx;
                    curY -= dy;
                    tiles[curX][curY].setState(player);
                } while (curX != x || curY != y);
                tiles[x][y].setState(player);
                d = true;
            }
        }
        if (d)
            swapTurn();
    }