Reputation: 256
I'm building a Tetris game in Java using some software design patterns. Basically, I created a factory algorithm that retrieves a string to figure out what type of tetris object to make when it's given a request by the main game loop, see code:
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;
}
}
If you don't know what gc is, it's simply a part of Slick 2D's library and is used to work with the full game environment. Anyways, I created a few other methods to randomly generate a shape for the game (such that the main game loop receives a random shape every time, but I feel like RNG doesn't cut it, I want to make it harder. I noticed there's a famous tetris algorithm called Bastet tetris, but it didn't make sense to me. Any suggestions you guys have for making a HARD tetris shape generation algorithm? Here's my simple RNG algorithm:
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];
}
Upvotes: 0
Views: 1315
Reputation: 24427
Any suggestions you guys have for making a HARD tetris shape generation algorithm?
To make it harder, you need a way to evaluate which shapes the player needs the most and which shapes they need the least, and then bias your random number generation towards giving them the ones they don't need.
At a basic level, the 2x2 square shape and the long 4x1 shapes are the "easiest" because you can usually stack them more easily. So you could just make a random shape generator that returns them half as often as the other shapes:
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];
}
But if you want to make it really hard, you can evaluate at each step which shape is most and least helpful to the player given the current game state:
For each shape, iterate through all valid positions where it could be placed, and all possible rotations (1, 2 or 4 of them per shape), and score each possible placement based on several criteria:
The best possible placement score for a shape is that shape's score. Then rank the pieces according to their scores, and generate a random number. Make it so there is a high chance of getting the worst shape, a slightly lesser chance of getting the second worst shape etc.
So for e.g. you could generate a number between 0 and 27 and then choose based on that:
You can vary the distribution according to how hard you want to make it.
Upvotes: 1
Reputation: 165
Instead of "==" sign use .equals() function to compare the Strings. == is used to check whether the two strings have same reference or not. Whereas .equals() method is used to check whether the two string has same value or not. Instead of
(shape=="TVIShape")
use
(shape.equals("TVIShape")
Upvotes: 1