Draw two ASCII spruce trees of specific heights
Asked Answered
V

3

4

I am trying to write code which generates ASCII art of this shape:

           *
          ***
         *****
        *******      *
       *********    ***
      ***********  *****
     ********************
    **********************
   ************************
  **************************
 ****************************
******************************

The code needs to be able to generate this shape based upon an input height. As you can see from the example shape, my code correctly generates the ASCII art using a line height of 12. However, for line heights of 3, 5, 6, 7, 10, 11, 15,... it doesn't correctly generate the ASCII shape. I have tried to debug this myself, but I can't find a commonality between the failing line heights, which is preventing me from nailing down the problem with my algorithm.

This is the Java code which I am using to generate the ASCII art shape (though without a hard-coded line height of 12 of course):

int h = 12;
for (int i = 0; i < h; i++) {
    for (int j = 0; j < h - i; j++) {
        System.out.print(" ");
    }
    for (int j = 0; j < i; j++) {
        System.out.print("*");
    }
    for (int j = i; j >= 0; j--) {
        System.out.print("*");
    }
    for (int j = 0; j < h / 2 - i; j++) {
        System.out.print(" ");
    }
    for (int j = h / 2 - i; j > 0; j--) {
        System.out.print(" ");
    }
    for (int j = 0; j <= h / 2; j++) {
        if (i >= h / 2)
            System.out.print("*");
    }
    for (int j = 0; j < i - h / 5; j++) {
        if (i >= h / 4 && i < h / 2)
            System.out.print("*");
    }
    for (int j = i - h / 5 - 1; j > 0; j--) {
        if (i >= h / 4 && i < h / 2)
            System.out.print("*");
    }
    System.out.println();
}

What exactly is causing my ASCII art generator code to fail for certain line heights, and how do I fix that problem with the code so that it correctly generates ASCII art for any positive integer?

Venous answered 19/11, 2015 at 21:53 Comment(0)
P
1

This generalises the problem by having a Shape interface for any ASCII art shape, and Spruce class to record position and height of a spruce shape with intersects(x,y) to determine if any coordinates lie on the spruce.

Then the drawing can be more flexible by passing in list of Spruce and determine the hit/miss at each point of the union of the sizes of all. A Spruce can be neatly defined as JDK16 record:

public record Spruce(int left, int height) implements Shape {
    public int right() { return left+2*height-2; }
    public int top()   { return height;          }

    // Check any coordinate hits / misses this Spruce:
    public boolean intersects(int x, int y) {
        return 1 <= y && y <= height && x >= left + y - 1 && x <= left + 2 * height - 1 - y;
    }
}

... and a simple main to draw as many Spruce / other Shape as needed:

public static void main(String[] args) {
    Shape.draw(new Spruce(1, 4), new Spruce(6, 6));
    Shape.draw(new Spruce(2, 6), new Spruce(10, 4));
    Shape.draw(new Spruce(3, 10), new Spruce(30, 9), new Spruce(18, 5));
}

Returning:

Spruce[left=1, height=4]
Spruce[left=6, height=6]

          *     
         ***    
   *    *****   
  ***  *******  
 ************** 
****************

Spruce[left=2, height=6]
Spruce[left=10, height=4]

      *         
     ***        
    *****   *   
   ******* ***  
  ************* 
 ***************

Spruce[left=3, height=10]
Spruce[left=30, height=9]
Spruce[left=18, height=5]

           *                                  
          ***                        *        
         *****                      ***       
        *******                    *****      
       *********                  *******     
      ***********    *           *********    
     *************  ***         ***********   
    ********************       *************  
   **********************     *************** 
  ************************   *****************
Parity answered 25/6, 2021 at 9:59 Comment(0)
A
1

Draw an ASCII spruce forest

First, specify the dimensions of the picture, and then specify the coordinates of the vertices of the spruce trees.

Spruce forest:

                                                       *                 *      
     *                                     *          ***      *        ***     
    ***                         *         ***        *****    ***      *****    
   *****      *                ***       *****      *******  *****    *******   
  *******    ***              *****     *******    ****************  *********  
 *********  *****     *      *******   *********  ***************************** 
******************   ***    ********* ******************************************
******************* *****  *****************************************************
********************************************************************************

Try it online!

class SpruceForest {
    int width, height, plat[][];
    public SpruceForest(int width, int height) {
        this.width = width;
        this.height = height;
        this.plat = new int[height][width];
    }
    public SpruceForest addSpruce(int x, int y) {
        for (int i = 0; i < height - y; i++)
            for (int j = -i; j <= i; j++)
                if (x + j >= 0 && x + j < width)
                    this.plat[y + i][x + j] = 1;
        return this;
    }
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int[] row : this.plat) {
            for (int i : row)
                sb.append(i == 1 ? "*" : " ");
            sb.append("\n");
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        SpruceForest forest = new SpruceForest(80, 9)
                .addSpruce(5, 1).addSpruce(14, 3).addSpruce(22, 5)
                .addSpruce(32, 2).addSpruce(43, 1).addSpruce(55, 0)
                .addSpruce(63, 1).addSpruce(73, 0);
        System.out.println(forest);
    }
}
Alidaalidade answered 28/6, 2021 at 15:33 Comment(0)
J
0

Assume that the second spruce is a quarter smaller than the first, and the second spruce is at a distance of its height from the first.

public static void main(String[] args) {
    for (int h = 3; h <= 12; h = h + 3)
        drawTwoSpruces(h);
}
public static void drawTwoSpruces(int h1) {
    int h2 = h1 * 3 / 4;
    System.out.println("h1=" + h1 + "; h2=" + h2);
    for (int i = 0; i <= h1; i++) {
        for (int j = -h1; j <= h2 * 2 + 1; j++)
            if (Math.abs(j) <= i || Math.abs(j - h2 - 1) <= i - h1 + h2)
                System.out.print("*");
            else
                System.out.print(" ");
        System.out.println();
    }
}

Output:

h1=3; h2=2
   *     
  *** *  
 ******* 
*********
h1=6; h2=4
      *         
     ***        
    *****  *    
   **********   
  ************  
 ************** 
****************
h1=9; h2=6
         *             
        ***            
       *****           
      *******   *      
     ********* ***     
    ***************    
   *****************   
  *******************  
 ********************* 
***********************
h1=12; h2=9
            *                   
           ***                  
          *****                 
         *******      *         
        *********    ***        
       ***********  *****       
      ********************      
     **********************     
    ************************    
   **************************   
  ****************************  
 ****************************** 
********************************
Jus answered 20/6, 2021 at 3:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.