public void uncoverSquare(int x, int y) {
        assert !this.gameOver;
        Square s = this.squareAt(x, y);
        
        // ignore invalid co-ordinates and already uncovered squares
        if(s == null || !s.isCovered()) 
            return;
        
        s.surroundingMines = this.countSurroundingMines(s);
        
        if(s.hasMine) {
            this.gameOver = true;
            this.notifyGameOver(false);
        }   
        else if(this.allNonMinesUncovered()) {
            System.out.println("all non-mines uncovered");
            this.handleWin();
        } 
        else {
            if(s.surroundingMines == 0) {
                for(Square neighbor : this.getSurroundingSquares(s) ) {
                    if(neighbor.isCovered())
                        this.uncoverSquare(neighbor.x, neighbor.y);
                }
            }
        }
    }