You can make this a recursion exercise with two parts:
1) Write a recursive method to repeat a char n times.
Signature:
public static String getCharRepeatedTimes(final char c, final int times)
(Read at end to see a solution)
2) Write a recursive method to create a diamond pattern.
Signature for recursive start method:
public static String getDiamondWithSize(final int size)
Signature for recursive "work" method:
private static String getDiamondWithSize(final int size, final int currentSize)
Hint 1: You can use the method from 1)
Hint 2: Think about a pattern in the diamon and how to exploit it.
(Read at end to see a solution)
Let us start with 1):
public static String getCharRepeatedTimes(final char c, final int times) {
if (times == 0)
return "";
return String.valueOf(c) + getCharRepeatedTimes(c, times - 1);
}
And continue with 2):
public static String getDiamondWithSize(final int size) {
return getDiamondWithSize(size, 2 - (size & 1));
}
The start method can be done in two ways. Starting from the outer area to the inner area or vice-versa. I have done the out->in way. If you allow even and odd diamonds, then we have to manage the start or end size in the correct way. There the 2 - (size & 1)
part, which is 2 for even size and 1 for odd size.
The idea is now to create the outer lines first and append it to the next inner part then. Until the inner part is the full part.
private static String getDiamondWithSize(final int size, final int currentSize) {
if (currentSize == size)
return getCharRepeatedTimes('*', size) + "\n";
final int nonDiamondSpace = (size - currentSize) / 2;
final String currentLine = getCharRepeatedTimes(' ', nonDiamondSpace) + getCharRepeatedTimes('*', currentSize) + "\n";
return currentLine + getDiamondWithSize(size, currentSize + 2) + currentLine;
}
The +
concatenation could be replaced by StringBuilder
, insert
and append
. For clarity and the exercise purpose, it is not done here.
Suggestions for your code:
public static void drawDiamond(String seed, int turn, final int centerLevel) {
...
if (turn <= centerLevel)
Noone would expect this if the method is called. At least for me, it is unclear how the argument centerLevel is related to the size of the diamond. You should add at least some JavaDoc, I would prefer to change the behavior.
turn++;
drawDiamond(seed, turn, centerLevel);
In general, you should avoid to change arguments, if possible. In this case, we can go with this:
drawDiamond(seed, turn + 1, centerLevel);
This looks a bit complex:
if( turn <= centerLevel ){
seed += "**";
} else {
if( seed.length() >= 3 ) {
seed = seed.substring(1,seed.length()-1);
} else {
seed = "";
}
}
You should add at least some comments. And you can decrease the branch depth by one:
if (turn <= centerLevel) //until the mid is reached, increase by two stars
seed += "**";
else if (seed.length() >= 3) //until the end is reached, reduce by 2 chars
seed = seed.substring(1, seed.length() - 1);
else //finished
seed = "";
Rest is more a subjective view. I would rather introduce a method to generate a char/String repeated n times than doing it inside the diamond method. And I would avoid the seed argument as shown above.