将随机值设置为 unassigned/optional 个参数

Setting random values to unassigned/optional parameters

我正在构建一个分块地图生成器应用程序,我希望用户在构建地图时能够将地图的子区域设置为特定类型的分块。 目前是这样实现的:

public boolean setArea(int bottomLeftX, int bottomLeftY, int subWidth, int subHeight, TerrainType aAreaType){
    boolean areaOverflow = false;
        System.out.println("Subarea coords...     x,y:"+bottomLeftX+","+bottomLeftY+" width/height:"+subWidth+"/"+subHeight);
        for(int x=bottomLeftX;x<=bottomLeftX+subWidth-1;x++){
            for(int y=bottomLeftY;y<=bottomLeftY+subHeight-1;y++){
                if(x>=0 && y>=0 &&
                   x<this.getWidth() && y<this.getHeight()){
                    this.setTile(x, y, aAreaType);
                }
                else{
                    areaOverflow = true;
                }
            }
        }
        return areaOverflow;
    }
}

(TerrainType 是一个包含地形类型信息的枚举,setTile 方法将地图数组中的值设置为特定地形类型。this.getWidth/Height() returns 大小地图数组)

但我希望用户不必决定每个值并允许随机选择一些值。我最初的想法是允许用户将一些值设置为 null,如果一个值作为 null 传入,让 Java 随机函数决定该参数的任意值(在地图的大小内),但是您不能将 int 设置为 null。我想知道替代方案会涉及什么?

您可以将参数定义为 Integers 而不是 ints。这样你就可以毫无问题地为它们传递 null 值。在该方法中,您将能够检查这些参数中的任何一个是否为 null,并根据这些检查的结果采取行动。

由于 Java 没有默认参数功能,一种方法是以 伸缩 方式重载该方法:

public class RandomArgumentsSample {

    private final Random generator = new Random();

    public void someMethod(int param1, int param2, SomeEnum someEnum) {
        // Do something useful with all the params, which are never null
    }

    public void someMethod(int param1, int param2) {
        // randomValue() static method implemented in SomeEnum
        // returns one value of the enum, randomly
        this.someMethod(param1, param2, SomeEnum.randomValue());
    }

    public void someMethod(int param1, SomeEnum someEnum) {
        int param2 = this.generator.nextInt(); // change to return number within range
        this.someMethod(param1, param2, someEnum);
    }

    // telescoping overloading is not magic
    // here order of arguments is changed
    // so we don't define a method with the same name and 
    // same argument types in the same order
    public void someMethod(SomeEnum someEnum, int param2) {
        int param1 = this.generator.nextInt(); // change to return number within range
        this.someMethod(param1, param2, someEnum);
    }

    public void someMethod(SomeEnum someEnum) {
        int param1 = this.generator.nextInt(); // change to return number within range
        this.someMethod(param1, someEnum);
        // could have also been this.someMethod(someEnum, param2); 
        // with param2 generated randomly
    }

    // here we choose to generate a default value for param2
    // we can't have another someMethod that receives only one int,
    // since it will clash with this one
    public void someMethod(int param1) {
        int param2 = this.generator.nextInt(); // change to return number within range
        this.someMethod(param1, param2);
    }

    // all arguments are random!
    public void someMethod() {
        int param1 = this.generator.nextInt(); // change to return number within range
        this.someMethod(param1);
    }
}

请阅读评论,因为他们有一些解释。

想法是参数较少的方法调用参数较多的方法,并为其未接收到的参数生成默认(或随机)值。在链的末端,调用接收所有参数并执行实际任务的方法。

这种方法并不完美,在我的例子中没有办法有两个 someMethod(int),即一个接收一个 int 作为 param1 而另一个接收一个 intparam2。但有时这就足够了,尤其是当您不需要所有可能的参数组合时。

如果出于任何原因无法将 int 更改为 Int(因此更改为 NULL),这里有一个替代方案。

重载您的方法,但仅使用用户必须显式提供的参数,并使用此方法内部的完整参数调用该方法。

简化示例:

public int myMethod(int a, int b, int c) {
  return a+b+c;
}

public int myMethod(int a) {
  return myMethod(a, (int)Math.random(),(int)Math.random());
}

至于你问的关于随机化枚举的部分,我会向你的枚举添加静态方法,例如称为randomize()。如果你问的是这个方法的具体实现 - 那是另一回事了。

返回 ENUM.values()[someRandomIndex] 只是我脑海中的一个。