【问题标题】:Tetris Shape Generation Algorithm in JavaJava中的俄罗斯方块形状生成算法
【发布时间】:2015-04-10 09:50:15
【问题描述】:

我正在使用一些软件设计模式用 Java 构建俄罗斯方块游戏。基本上,我创建了一个工厂算法,它检索一个字符串来确定当主游戏循环给出请求时要制作什么类型的俄罗斯方块对象,请参见代码:

public class TVShapeFactory {

    protected TVShape tvShape = null;
    protected GameContainer gc;

    TVShapeFactory(GameContainer gc) {
        this.gc = gc;
    }

    public TVShape createShape(String shape) {
        if (shape=="TVIShape") {
            tvShape = new TVIShape(gc);
        }
        else if (shape=="TVOShape") {
            tvShape = new TVOShape(gc);
        }
        else if (shape=="TVLShape") {
            tvShape = new TVLShape(gc);
        }
        else if (shape=="TVZShape") {
            tvShape = new TVZShape(gc);
        }
        else if (shape=="TVJShape") {
            tvShape = new TVJShape(gc);
        }
        else if (shape=="TVSShape") {
            tvShape = new TVSShape(gc);
        }
        else if (shape=="TVTShape") {
            tvShape = new TVTShape(gc);
        }
        else {
            System.out.println("Error: invalid type of shape");
        }
        return tvShape;
    }
}

如果您不知道什么是 gc,它只是 Slick 2D 库的一部分,用于与完整的游戏环境一起工作。 无论如何,我创建了一些其他方法来为游戏随机生成一个形状(这样主游戏循环每次都会收到一个随机形状,但我觉得 RNG 没有削减它,我想让它变得更难。我注意到有一个著名的俄罗斯方块算法,叫做 Bastet tetris,但对我来说没有意义。你们对制作 HARD 俄罗斯方块形状生成算法有什么建议吗?这是我的简单 RNG 算法:

public TVShape getRandomShape() {

    TVShape[] shapes = new TVShape[7];
    shapes[0] = createShape("TVIShape");
    shapes[1] = createShape("TVOShape");
    shapes[2] = createShape("TVLShape");
    shapes[3] = createShape("TVZShape");
    shapes[4] = createShape("TVJShape");
    shapes[5] = createShape("TVSShape");
    shapes[6] = createShape("TVTShape");

    int index = new Random().nextInt(shapes.length);
    return shapes[index];
}

【问题讨论】:

  • 对于初学者,shape=="TVZShape" 不比较字符串。你应该使用shape.equals("TVZShape")...

标签: java algorithm tetris


【解决方案1】:

使用 .equals() 函数代替“==”符号来比较字符串。 == 用于检查两个字符串是否具有相同的引用。 而 .equals() 方法用于检查两个字符串是否具有相同的值。 而不是

(shape=="TVIShape")

使用

(shape.equals("TVIShape")

【讨论】:

  • 嘿,谢谢!在我发布我的问题后,我实际上注意到了这一点。我知道这太愚蠢了!在过去的 3 周里,我一直在为另一个项目使用 PHP,并且不得不突然为这个项目切换到 Java ......并且完全忘记了 == 表示 obj 的引用。不过哈哈还是谢谢啦。
【解决方案2】:

你们对制作 HARD 俄罗斯方块形状生成算法有什么建议吗?

为了更难,您需要一种方法来评估玩家最需要哪些形状以及他们最不需要哪些形状,然后将随机数生成偏向于给他们不需要的形状。

在基本层面上,2x2 方形和长 4x1 形状是“最简单的”,因为您通常可以更轻松地堆叠它们。所以你可以制作一个随机形状生成器,它返回它们的频率是其他形状的一半:

public TVShape getRandomShape() {

    TVShape[] shapes = new TVShape[12];
    shapes[0] = createShape("TVIShape");
    shapes[1] = createShape("TVOShape");
    shapes[2] = createShape("TVLShape");
    shapes[3] = createShape("TVLShape");
    shapes[4] = createShape("TVZShape");
    shapes[5] = createShape("TVZShape");
    shapes[6] = createShape("TVJShape");
    shapes[7] = createShape("TVJShape");
    shapes[8] = createShape("TVSShape");
    shapes[9] = createShape("TVSShape");
    shapes[10] = createShape("TVTShape");
    shapes[11] = createShape("TVTShape");

    int index = new Random().nextInt(shapes.length);
    return shapes[index];
}

但如果你想让它变得更难,你可以在每一步评估在当前游戏状态下哪个形状对玩家的帮助最大和最小:

对于每个形状,遍历可以放置它的所有有效位置,以及所有可能的旋转(每个形状 1、2 或 4 个),并根据几个标准对每个可能的位置进行评分:

  • 放置后最高点的堆栈高度。每次身高增加都为负分。
  • 放置是否会导致任何行被完全填充。每个已完成的行都是正分。
  • 堆栈中有多少个孔(一列中最高占用方格下方的空白方格)。每个洞都是负分。
  • 你能想到的任何其他事情

形状的最佳放置分数是该形状的分数。然后根据分数对棋子进行排序,并生成一个随机数。使它有很高的机会获得最差的形状,获得第二差的形状的机会略小,等等。

所以例如您可以生成一个介于 0 到 27 之间的数字,然后根据该数字进行选择:

  • 0-6 最差形状
  • 7-12 次最差形状
  • 13-17 第三个最差形状
  • 18-21 第四坏形状
  • 22-24第三佳身材
  • 25-26 次最佳形状
  • 27 最佳造型

你可以根据你想要的难度来改变分布。

【讨论】:

  • 谢谢!您的反馈对我帮助很大,我对我现在想做的事情有了明确的想法:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多