Weinachtsbaum bilden

nikva

Bekanntes Mitglied
Hallo, Java Forum!

Ich habe die Aufgabe bekommen einen Weihnachtsbaum mit Hilfe von java-Schleifen zu visualisieren. Dies soll über die Eingabe der Höhe erfolgen und abhängig von dieser auch einen Stamm hinzufügen.(siehe Anhang)

Dabei sind folgende Klassen vorgegeben:
Java:
package edu.hm.cs.swe1;

import javax.swing.JFrame;

import edu.hm.cs.swe1.christmastree.ChristmasTree;


public class Main extends JFrame {

    private static final long serialVersionUID = -7793153788995243551L;

    /**
     * Main Method to start up the Christmas tree creator. No arguments are
     * required.
     *
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

        int height = HelperClass.requestUserInput("Wie hoch ist der Weihnachtsbaum?");

        ChristmasTree tree;

        if (height < 3) {
            throw new RuntimeException("Error: Tree must be greater than 2!");
        }

        tree = new ChristmasTree(height);
        System.out.println(tree.toString());

    }

}

Java:
package edu.hm.cs.swe1;

import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;


public class HelperClass {
   
    /**
     * Request some user information and transform it into an int-value.
     *
     * @param question Question the user is asked
     * @return The user's reply, transformed into an int-value.
     */
    public static int requestUserInput(String question) {
        // Request user to input information about smiley
        String answer = JOptionPane.showInputDialog(question);
       
        // Transform textual answer into int-value
        int result = Integer.parseInt(answer);
       
        // Return result to caller
        return result;
    }
   
   
    /**
     * Displays some output in its own JFrame. That frame can be closed by clicking Escape.
     * @param text The text to show in the JFrame.
     */
    public static void showOutput(String text) {
        final JFrame outputFrame = new JFrame("Output");
        text = text.replaceAll(" ", "&nbsp;");
       
        JLabel frameText = new JLabel("<html><body>" + text.replaceAll("\n", "<br>") + "</body></html>");
        outputFrame.add(frameText);
        outputFrame.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent ke) {
                if(ke.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    outputFrame.setVisible(false);
                    outputFrame.dispose();
                }
            }
        });
        outputFrame.pack();
        outputFrame.setVisible(true);
    }
   
    /**
     * Print error message in separate window
     *
     * @param message Error message
     */
    public static void printErrorMessage(String message) {
        JOptionPane.showMessageDialog(null, message, "Fehlermeldung", JOptionPane.ERROR_MESSAGE);
    }
   
     /**
       * Wait for a specified number of milliseconds before finishing.
       * This provides an easy way to specify a small delay which can be
       * used when producing animations.
       * @param  milliseconds  the number
       */
      public static void wait(int milliseconds)
      {
          try
          {
              Thread.sleep(milliseconds);
          }
          catch (Exception e)
          {
              // ignoring exception at the moment
          }
      }
     
}

bisher hab ich folgendes und kann damit die Äste darstellen, scheitere aber daran noch den Baumstamm in die Schleife einzubauen. Ich hoffe ihr könnt mich in die richtige Richtung leiten.
Java:
package edu.hm.cs.swe1.christmastree;

public class ChristmasTree {
    int height;
    int trunk;
    int width;

    public ChristmasTree(int height) {

        for (int i = 0; i < height; i++) {

            for (int j = 1; j < height - i; j++) {
                System.out.print(" ");
            }
            for (int k = 0; k < (2 * i + 1); k++) {
                System.out.print("*");
            }

            System.out.println();
        }

    }

}
 

Anhänge

Das pdf ist nur die Vorlesung, jedoch nicht die Aufgabenstellung - oder?

Naja ich habe versucht ohne den ternären Operator auszukommen,
leider erfolglos:
Java:
static void derWeihnachtsbaum(int n) {
    IntStream.iterate(0, i -> i + 1).limit(n).forEach(a -> {
        IntStream.iterate(0, i -> i + 1).limit(n - a > 2 ? n - a - 3 : n - 4).forEach(c -> System.out.print(" "));
        IntStream.iterate(0, i -> i + 1).limit(n - a > 2 ? a * 2 + 1 : 3    ).forEach(b -> System.out.print("*"));
        System.out.println("");
    });
}

public static void main(String[] args) {
    derWeihnachtsbaum(16);
}
 
ich habe versucht ohne den ternären Operator auszukommen
So würde es ohne ihn gehen (steigert die Lesbarkeit aber nur sehr bedingt😉):
Java:
    static void derWeihnachtsbaum(int n) {
        IntStream.iterate(0, i -> i + 1).limit(n).forEach(a -> {
            IntStream.iterate(0, i -> i + 1).limit((1-(a/(n-2)))*(n-a-3) + (a/(n-2))*(n-4)).forEach(c -> System.out.print(" "));
            IntStream.iterate(0, i -> i + 1).limit((1-(a/(n-2)))*(a*2+1) + (a/(n-2))*(3)).forEach(b -> System.out.print("*"));
            System.out.println("");
        });
    }

    public static void main(String[] args) {
        derWeihnachtsbaum(16);
    }
 
Das pdf ist nur die Vorlesung, jedoch nicht die Aufgabenstellung - oder?
ja, hab die Aufgabe jetzt angehängt
Warum willst du den Stamm denn in derselben Schleife einbauen? Es wird viel einfacher, wenn du dafür eine zweite Schleife vorsiehst.
da es sich ja nur um eine Zeile handeln soll dachte ich, dass es einfacher ist ihn dort einzubauen, aber an sich wird der ja eh angehängt und bräuchte an sich ja nicht mal eine sschleife sondern nur eine Fallunterscheidung anhand der angabe für die höhe des baumes?
 

Anhänge

da es sich ja nur um eine Zeile handeln soll dachte ich, dass es einfacher ist ihn dort einzubauen, aber an sich wird der ja eh angehängt und bräuchte an sich ja nicht mal eine sschleife sondern nur eine Fallunterscheidung anhand der angabe für die höhe des baumes?
Für die Höhe des Stammes benötigst du dann wirklich keine Schleife. Die Fallunterscheidung benötigst du aber nicht beim Ausgeben des Baumes, sondern in der Methode zum Setzen der Baumhöhe. Überhaupt hast du dich bisher kaum an die Aufgabenstellung gehalten. Der Generator soll den Baum gar nicht auf der Konsole ausgeben, sondern einen String liefern, der den Baum als Zeichenkette enthält. Das soll auch nicht im Konstruktor geschehen, sondern in der toString()-Methode. Am besten gehst du die Aufgabenstellung noch einmal beginnend mit 1b) und 1c) Punkt für Punkt durch und setzt exakt das um, was dort beschrieben ist.
 
Ok, da war ich etwas übereifrig.
Geht das in die richtige Richtung?
Java:
package edu.hm.cs.swe1.christmastree;

public class ChristmasTree {
    int height;
    int trunk;
    int width;

    public ChristmasTree(int height) {
        this.height = height;
        }
   
    public int setHeight(int h) {
        height = h;
        trunk = ((height/10)*2)+1;
        width = ((height-1)*2)+1;
       
        return height;
    }


}
 
Zuletzt bearbeitet:
Geht das in die richtige Richtung?
Ja. Allerdings liefern Setter-Methoden normalerweise keine Ergebnisse zurück. Außerdem ist der Konstruktor noch nicht ganz korrekt (siehe 1c). Angenommen ein Anwender will drei Bäume mit den Höhen 3, 4 und 5 ausgeben. Dann erzeugt er den Generator mit Höhe 3 und gibt ihn aus, ändert die Höhe auf 4 und gibt ihn aus und ändert die Höhe nochmals auf 5 und gibt ihn aus. Dann würde der erste Baum nicht korrekt gezeichnet werden, der zweite und dritte aber schon.
 
"Beachten Sie, dass die Werte der drei Attribute des Weihnachtsbaumes voneinander
abhängig sind. Erstellen Sie daher eine Methode für den schreibenden Zugriff auf die Höhe,
die nicht nur wie üblich die Höhe neu setzt, sondern gleichzeitig auch die Breite und die
Stammdicke auf passende Weise neu setzt."

das hab ich ja hier:
Java:
    public void setHeight(int h) {
        height = h;
        trunk = ((height / 10) * 2) + 1;
        width = ((height - 1) * 2) + 1;
    }

"Damit Sie diese Methode sinnvoll testen können benötigen Sie zusätzlich noch Methoden für
den lesenden Zugriff auf jedes der Attribute des Weihnachtsbaum-Generators. Erstellen Sie
diese in der standardisierten Form."

Das hab ich hier:
Java:
    public int getHeight() {
        return height;

    }

    public int getTrunk() {
        return trunk;
    }

    public int getWidth() {
        return width;
    }
"Stützen Sie die Implementierung des Konstruktors auf diese Methode für den schreibenden
Zugriff ab."
ist damit einfach gemeint,dass ich den vorherigen konstruktor so ändere, dass diese methode darin ausgeführt wird? Also in etwa so?:
Java:
    public ChristmasTree(int height) {
        setHeight(height);
    }
 
Vielleicht als Hilfe, so könnte es gefordert sein, der Stamm ist bei mir aber nicht ganz mittig (aber das ist ja bei Tannenbäumen oft so):
Java:
// ....

public class ChristmasTree {
	private String tree = "";

	public ChristmasTree() {
	}

	public void makeTree(int n) {
		if (n < 3 || n > 100) {
			throw new IllegalArgumentException("");
		}
		makeNadeln(n - 1);
		makeStamm(n, n / 10 * 2 + 1);
	}

	private void makeNadeln(int n) {
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				tree += " ";
			}
			for (int j = (n - i) * 2; j <= n * 2; j++) {
				tree += "*";
			}
			tree += "\n";
		}
	}

	private void makeStamm(int n, int n2) {
		for (int i = 0; i <= n - n2 - 2; i++) {
			tree += " ";
		}
		for (int j = 0; j < n2; j++) {
			tree += "I";
		}
		tree += "\n";
	}

	@Override
	public String toString() {
		return tree;
	}

	public static void main(String[] args) {
		for (int i = 3; i <= 20; i++) {
			ChristmasTree ct = new ChristmasTree();
			ct.makeTree(i);
			System.out.println(ct);
		}
	}
}

Code:
 *
***
 I

  *
 ***
*****
  I

   *
  ***
 *****
*******
   I

    *
   ***
  *****
 *******
*********
    I

     *
    ***
   *****
  *******
 *********
***********
     I

      *
     ***
    *****
   *******
  *********
 ***********
*************
      I

       *
      ***
     *****
    *******
   *********
  ***********
 *************
***************
       I

        *
       ***
      *****
     *******
    *********
   ***********
  *************
 ***************
*****************
      III

         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
       III

          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
*********************
        III

           *
          ***
         *****
        *******
       *********
      ***********
     *************
    ***************
   *****************
  *******************
 *********************
***********************
         III

            *
           ***
          *****
         *******
        *********
       ***********
      *************
     ***************
    *****************
   *******************
  *********************
 ***********************
*************************
          III

             *
            ***
           *****
          *******
         *********
        ***********
       *************
      ***************
     *****************
    *******************
   *********************
  ***********************
 *************************
***************************
           III

              *
             ***
            *****
           *******
          *********
         ***********
        *************
       ***************
      *****************
     *******************
    *********************
   ***********************
  *************************
 ***************************
*****************************
            III

               *
              ***
             *****
            *******
           *********
          ***********
         *************
        ***************
       *****************
      *******************
     *********************
    ***********************
   *************************
  ***************************
 *****************************
*******************************
             III

                *
               ***
              *****
             *******
            *********
           ***********
          *************
         ***************
        *****************
       *******************
      *********************
     ***********************
    *************************
   ***************************
  *****************************
 *******************************
*********************************
              III

                 *
                ***
               *****
              *******
             *********
            ***********
           *************
          ***************
         *****************
        *******************
       *********************
      ***********************
     *************************
    ***************************
   *****************************
  *******************************
 *********************************
***********************************
               III

                  *
                 ***
                *****
               *******
              *********
             ***********
            *************
           ***************
          *****************
         *******************
        *********************
       ***********************
      *************************
     ***************************
    *****************************
   *******************************
  *********************************
 ***********************************
*************************************
              IIIII


Aber das musst Du eben noch anpassen wie s gefordert ist.
 
Das wäre ja eine ganz eigene Art und an der Aufgabenstellung vorbei(ohne setter Methoden,anderer Konstruktor,2 Paramater,eine klasse)
Du solltest die Attribute aber noch mit den passenden Zugriffsmodifikatoren versehen. Das hatte ich in meinem vorigen Posting nicht erwähnt.
hab jetzt alle Methoden und Attribute bis auf den Konstruktor auf private gesetzt

jetzt muss ich ja das was ich vorher schon hatte in eine toString methode einbauen.
Code:
        for (int i = 0; i < height; i++) {

            for (int j = 1; j < height - i; j++) {
            }
            for (int k = 0; k < (2 * i + 1); k++) {
            }
 
Zuletzt bearbeitet:
Das wäre ja eine ganz eigene Art und an der Aufgabenstellung vorbei
Nicht wirklich, die - nennen wir es - for- und for-for-Konstrukte sollen wahrscheinlich durchaus genau so sein, jedoch die Klassen und Methoden nicht, das müsstest Du eben den Aufgabenstellungen gemäß "adaptieren".
Aber das habe ich auch geschrieben
Aber das musst Du eben noch anpassen wie s gefordert ist.
Diese "Transferleistung" soll von Dir erbracht werden. 😕

jetzt muss ich ja das was ich vorher schon hatte in eine toString methode einbauen
Meiner Meinung nach sollte eine toString-Methode nur etwas return en, jedoch keine Logik enthalten.

Schönen Advent allen!! 🙂
 

Neue Themen


Zurück
Oben