Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Waldbrand (Simulationen)

Ihr Programm soll einen Waldbrand simulieren. Zunächst besteht der Wald aus einem rechteckigen Raster (zweidimensionales Feld) aus Bäumen (B) und leerem Waldboden (·).

In jedem Zeitschritt geschieht nun folgendes.

  • Jeder Baum wird sich mit einer kleinen Wahrscheinlichkeit von f entzünden (Funken, Blitze, Zigarrenstummel, ...). Brennende Bäume werden mit (F) wie Feuer bezeichnet. Jeder Baum (B) , der einen brennenden Nachbarn (F) hat, wird auch brennen (F). Bäume, die in einem Zeitschritt zu brennen beginnen, sind erst im nächsten Zeitschritt fähig, weitere Bäume zu entfachen.
  • Jedes leere Feld (·) wird mit einer geringen Wahrscheinlichkeit w (Wachstum) zu einem Bäumchen (B) keimen.
  • Jeder bereits brennende Baum (F) wird absterben und ein leeres Stück humusreichen Waldboden hinterlassen (·). Natürlich tut er das erst, nachdem er die umliegenden nicht brennenden Bäume (B) auch entfacht hat (F).

Eingegeben werden die Wahrscheinlichkeiten f (zufällige Funkenentzündung) und w (Wachstum). Nach jeder Iteration soll "der Wald" ausgegeben werden. Dies kann ganz einfach auf der Konsole geschehen:

········B······B····B···
···B······B·B·········B·
·BBB····FB·····B····F·B·
···BB·BB········BB··B···

 

Tipp: Damit nicht ein Baum, der sich eben entfacht hat, erst im nächsten Zeitschritt einen Baum entfacht und damit auch ein Baum nicht gleich abstirbt, bevor er alle Nachbarbäume entfacht hat, bietet es sich an, in jedem Zeitschritt jeden Rasterpunkt aus den Rasterpunkten des alten Zeitschrittes zu berechnen. Damit sich diese beiden Raster nicht in die Quere kommen, bietet es sich an, zwei separate Matrizen (= zweidimensionale Felder) zu verwalten: "alt" und "neu". Währen dem Zeitschritt werden die obigen drei Regeln beachtet; nach jedem Zeitschritt wird der Inhalt von "alt" mit dem alten Inhalt von "neu" definiert und die neue Matrix "geleert" (bzw. als ungültig erklärt).

Alternativen:

  • Ein Baum kann über mehrere Zeitschritte Brennen (F1, F2).
  • Ein Baum kann verschiedene alter aufweisen (B1, B2, B3).
  • Bereits bei der Initialisation des Waldes (also vor dem ersten Zeitschritt) können einige Bäume brennen.
  • Das ganze kann grafisch dargestellt werden. B1, B2, B3: verschiedene Grüntöne; F1, F2, F3: gelb, orange, rot.

0 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

5 Lösung(en)

#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <windows.h>

#define hohe 15
#define breite 25

//Zustände der Felder
#define H 0
#define B 1
#define F1 2
#define F2 3
#define F3 4

int f, w; //Wachstumswahrscheinlichkeit und Funkenzündung

//Funktionsprototypen
void neuerWaldboden(int raster[hohe][breite]);
void zuenden(int raster[hohe][breite]);
void wachstum(int raster[hohe][breite]);
void absterben(int raster[hohe][breite]);
void ausgabe(int raster[hohe][breite], WORD attr);

int main()
{
    srand(time(0));

        //Blinken des Cursor ausschalten:
              {
              CONSOLE_CURSOR_INFO cci;
              GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
              cci.bVisible = false;
              SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
              }

    CONSOLE_SCREEN_BUFFER_INFO csbinfo;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbinfo);

    int raster[hohe][breite];

    printf("Zuf\x84llige Funkenentz\x81ndung in Prozent: ");
    scanf("%d", &f); fflush(stdin);
    printf("\nWachstumswahrscheinlichkeit in Prozent: ");
    scanf("%d", &w); fflush(stdin);
    printf("\n");

    neuerWaldboden(raster);

    system("CLS");
    while(1)
    {
        ausgabe(raster, csbinfo.wAttributes);

        absterben(raster);
        zuenden(raster);
        wachstum(raster);


        Sleep(500);
        system("CLS");

        if(kbhit())
        if(getch() == 27)break;
    }

    return 0;
}

void neuerWaldboden(int raster[hohe][breite])
{
    int i, j;

    for(i = 0; i < hohe; i++)
    {
        for(j = 0; j < breite; j++)
        {
            //20% Bäume
            if(rand()%100 < 20)raster[i][j] = B;
            else raster[i][j] = H;
        }
    }
}

void zuenden(int raster[hohe][breite])
{
    int i, j;

    char h[hohe][breite]; //Abbild wird in h gespeichert

    //kopieren
    for(i = 0; i < hohe; i++)
        for(j = 0; j < breite; j++)
            h[i][j] = raster[i][j];

    for(i = 0; i < hohe; i++)
    {
        for(j = 0; j < breite; j++)
        {
            if(raster[i][j] == B)
            {
                //Brennen die Nachbarn?
                if(i > 0)
                {
                    if(j > 0)
                    if(raster[i-1][j-1] == F2 || raster[i-1][j-1] == F3)
                        h[i][j] = F1;
                    if(raster[i-1][j] == F2 || raster[i-1][j] == F3)
                        h[i][j] = F1;

                    if(j < breite-1)
                    if(raster[i-1][j+1] == F2 || raster[i-1][j+1] == F3)
                        h[i][j] = F1;
                }

                if(j > 0)
                {
                    if(raster[i][j-1] == F2 || raster[i][j-1] == F3)
                        h[i][j] = F1;

                    if(i < hohe-1)
                    if(raster[i+1][j-1] == F2 || raster[i+1][j-1] == F3)
                        h[i][j] = F1;
                }

                if(j < breite-1)
                {
                    if(raster[i][j+1] == F2 || raster[i][j+1] == F3)
                        h[i][j] = F1;
                    if(raster[i+1][j] == F2 || raster[i+1][j] == F3)
                        h[i][j] = F1;

                    if(i < hohe-1)
                    if(raster[i+1][j+1] == F2 || raster[i+1][j+1] == F3)
                        h[i][j] = F1;
                }


                //Wahrscheinlichkeit des entfachens
                if(rand()%100 < f) h[i][j] = F1;
            }
            else if(raster[i][j] == F1)
                h[i][j] = F2;
            else if(raster[i][j] == F2)
                h[i][j] = F3;
        }
    }

    //h in raster speichern

    for(i = 0; i < hohe; i++)
        for(j = 0; j < breite; j++)
            raster[i][j] = h[i][j];


}

void wachstum(int raster[hohe][breite])
{
    int i, j;
    for(i = 0; i < hohe; i++)
        for(j = 0; j < breite; j++)
        {
            if(raster[i][j] == H)
                if(rand()%100 < w)
                    raster[i][j] = B;
        }
}

void absterben(int raster[hohe][breite])
{
    int i, j;

    int h[hohe][breite];

    //kopieren
    for(i = 0; i < hohe; i++)
        for(j = 0; j < breite; j++)
            h[i][j] = raster[i][j];

    //ändern
    for(i = 0; i < hohe; i++)
    {
        for(j = 0; j < breite; j++)
        {
            if(raster[i][j] == F3)
            {

                if(i == 0 && j == 0) //Linke Obere Ecke
                {
                    if (raster[i][j+1]    != B &&
                        raster[i+1][j]    != B &&
                        raster[i+1][j+1]  != B)
                                                h[i][j] = H;
                }
                else if(i == 0 && j == breite-1) //Rechte Obere Ecke
                {
                    if (raster[i][j-1]    != B &&
                        raster[i+1][j-1]  != B &&
                        raster[i+1][j]    != B)
                                                h[i][j] = H;
                }
                else if(i == 0) //Oberer Rand
                {
                    if (raster[i][j-1]    != B &&
                        raster[i][j+1]    != B &&
                        raster[i+1][j-1]  != B &&
                        raster[i+1][j]    != B &&
                        raster[i+1][j+1]  != B)
                                                h[i][j] = H;
                }
                else if(i == hohe-1 && j == 0) //Untere Linke Ecke
                {
                    if (raster[i-1][j]    != B &&
                        raster[i-1][j+1]  != B &&
                        raster[i][j+1]    != B)
                                                h[i][j] = H;
                }
                else if(j == 0) //Linker Rand
                {
                    if (raster[i-1][j]    != B &&
                        raster[i-1][j+1]  != B &&
                        raster[i][j+1]    != B &&
                        raster[i+1][j]    != B &&
                        raster[i+1][j+1]  != B)
                                                h[i][j] = H;
                }
                else if(i == hohe-1 && j == breite-1) //Rechte untere Ecke
                {
                    if (raster[i][j-1]    != B &&
                        raster[i-1][j-1]  != B &&
                        raster[i-1][j]    != B)
                                                h[i][j] = H;
                }
                else if(i == hohe-1) //Unterer Rand
                {
                    if (raster[i][j-1]    != B &&
                        raster[i][j+1]    != B &&
                        raster[i-1][j-1]  != B &&
                        raster[i-1][j]    != B &&
                        raster[i-1][j+1]  != B)
                                                h[i][j] = H;
                }
                else if(j == breite-1) //Rechter Rand
                {
                    if (raster[i-1][j]    != B &&
                        raster[i+1][j]    != B &&
                        raster[i-1][j-1]  != B &&
                        raster[i][j-1]    != B &&
                        raster[i+1][j-1]  != B)
                                                h[i][j] = H;
                }
                else  //liegt im Feld
                         if(raster[i-1][j-1]     != B &&
                            raster[i-1][j]       != B &&
                            raster[i-1][j+1]     != B &&
                            raster[i][j-1]       != B &&
                            raster[i][j+1]       != B &&
                            raster[i+1][j-1]     != B &&
                            raster[i+1][j]       != B &&
                            raster[i+1][j+1]     != B)
                                                        h[i][j] = H;

            }
        }
    }

    //speichern
    for(i = 0; i < hohe; i++)
        for(j = 0; j < breite; j++)
            raster[i][j] = h[i][j];
}

void ausgabe(int raster[hohe][breite], WORD attr)
{
    int i, j;
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

    for(i = 0; i < hohe; i++)
    {
        for(j = 0; j < breite; j++)
            {
                SetConsoleTextAttribute(handle, attr);
                switch(raster[i][j])
                {
                    case H:
                        SetConsoleTextAttribute(handle, BACKGROUND_GREEN | FOREGROUND_GREEN);
                        printf(" ");
                        break;

                    case B:
                        SetConsoleTextAttribute(handle, BACKGROUND_GREEN | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
                        printf("B");
                        break;

                    case F1:
                        SetConsoleTextAttribute(handle, BACKGROUND_GREEN | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
                        printf("F");
                        break;

                    case F2:
                        SetConsoleTextAttribute(handle, BACKGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
                        printf("F");
                        break;

                    case F3:
                        SetConsoleTextAttribute(handle, BACKGROUND_GREEN | FOREGROUND_RED);
                        printf("F");
                        break;

                    default:
                        return;
                        break;
                };
            }
            SetConsoleTextAttribute(handle, attr);
            printf("\n");
    }
    SetConsoleTextAttribute(handle, attr);
}

                

Lösung von: Christian :) (Hochschule Merseburg)

package ch.programmieraufgaben.simulation.waldbrand;

/**
 * simuliert genau ein rechteckiges Waldstück.
 * @author Philipp Gressly (phi AT gressly DOT ch)
 */
public class Wald {

    public static final char KEIMLING = ',';
    public static final char JUNGBAUM = '^';
    public static final char BAUM     = 'A';
    public static final char STEIN    = 'M'; // Fels: Hier wächst nichts
    public static final char HUMUS    = ' '; // Hier können Bäume wachsen
    public static final char FEUER1   = '1';
    public static final char FEUER2   = '2';
    public static final char FEUER3   = '3'; // danach erlischt das Feuer

    char[][] parzellen;
    
    /**
     * Initialisiere zufälligen Wald.
     * @param pBaum  Wahrscheinlichkeit das an einer Stelle ein Baum steht
     * @param pFeuer Wahrscheinlichkeit für Feuer
     * @param pStein
     */
    public Wald(int breite, int tiefe, double pBaum, double pFeuer, double pStein) {
      parzellen = new char[breite][tiefe];
      // init
      for(int x = 0; x < breite; x++) {
        for(int y = 0; y < tiefe; y++) {
           parzellen[x][y] = initialWert(pBaum, pFeuer, pStein);
        }
      }   
    }
    
    public Wald(int breite, int tiefe) {
        this(breite, tiefe, 0.0, 0.0, 0.0);
    }
    
    /**
     * Zufälliger Initialisierungswert für einen Platz bei Systemstart. 
     * @param pBaum  Wahrscheinlichkeit für einen Baum (keim, jungbau, olt)
     * @param pFeuer Wahrscheinlichkeit für eine brennende Zelle
     * @param pStein Wahrscheinlichkeit für Fels (bzw. Ödland)
     * @return
     */
    char initialWert(double pBaum, double pFeuer, double pStein) {
      double rnd = Math.random();
      if(rnd < pStein)                  return STEIN;
      if(rnd < pStein + pFeuer)         return FEUER1;
      if(rnd < pStein + pFeuer + pBaum) return 
          Math.random() < 1.0/3 ? KEIMLING :
          Math.random() < 0.5   ? JUNGBAUM : BAUM;
      return HUMUS;
    }
    
    @Override 
    public String toString() {
      // breite + 1, da "\n" pro Zeile noch dazukommt.
      StringBuffer wald = new StringBuffer((getBreite() + 1) * getTiefe());
      for(int x = 0; x < getBreite(); x++) {
          for(int y = 0; y < getTiefe(); y++) {
              wald.append(parzellen[x][y]);
          }
          wald.append('\n');
      }
      return wald.toString();
    }

    int getTiefe()  { return parzellen[0].length;  }

    int getBreite() { return parzellen.length;     }

} // end of class Wald

/////////////////////////////////////////////////////////////////////////////////////////
package ch.programmieraufgaben.simulation.waldbrand;

/**
 * www.programmieraufgaben.ch -> Waldbrand
 * @author Philipp Gressly (phi AT gressly DOT ch)
 */
public class Waldbrand {

  /**
   * Führe einen Zeitschritt aus indem ein Wald (alt) in ein neues Waldmodell 
   * überführt wird.
   * 
   */
   void zeitSchritt(Wald alt, Wald neu, double pBaum, double pFeuer) {
     for(int x = 0; x < alt.getBreite(); x++) {
         for(int y = 0; y < alt.getTiefe(); y++) {
             neu.parzellen[x][y] = zeitSchritt(alt, x, y, pBaum, pFeuer); 
         }
     }
   }
    
   char zeitSchritt(Wald alt, int x, int y, double pBaum, double pFeuer) {
     char[][] f = alt.parzellen;
     return zeitSchritt(pBaum, pFeuer, 
                         getAlt(f, x  , y),
                         getAlt(f, x-1, y),
                         getAlt(f, x+1, y),
                         getAlt(f, x  , y-1),
                         getAlt(f, x  , y+1),
                         getAlt(f, x-1, y-1),
                         getAlt(f, x-1, y+1),
                         getAlt(f, x+1, y-1),
                         getAlt(f, x+1, y+1));
   }
    
   /**
    * Gib das Feld an Position x, y zurück.
    * Da diese Funktion auch mit x- und y-Werten außerhalb aufgerufen
    * wird, so wird an den Stellen außerhalb des Waldes einfach "STEIN"
    * zurückgegeben.
    */
   char getAlt(char[][] f, int x, int y) {
     if(x < 0)            return Wald.STEIN;
     if(x >= f.length)    return Wald.STEIN;
     if(y < 0)            return Wald.STEIN;
     if(y >= f[0].length) return Wald.STEIN;
     return f[x][y];
   }
  
   /**
    * n1 - n4: Nachbarn über die Kanten
    * e1 - e4: Nachbarn über die Ecken
    * @param center: Zentrum des Nachbarfeldes
    */
   char zeitSchritt(double pBaum, double pFeuer,
                           char center,
                           char n1, char n2, char n3, char n4,
                           char e1, char e2, char e3, char e4) {
     // Stein bleibt Stein
     if(Wald.STEIN  == center) return Wald.STEIN;
     
     // Feuer entfacht mehr, und erlischt in drei Schritten:
     if(Wald.FEUER1 == center) return Wald.FEUER2;
     if(Wald.FEUER2 == center) return Wald.FEUER3;
     if(Wald.FEUER3 == center) return Wald.HUMUS;
     
     // diese brennen noch nicht:
     if(Wald.KEIMLING == center) return Wald.JUNGBAUM;
     if(Wald.JUNGBAUM == center) return Wald.BAUM;
     
     if(Wald.HUMUS == center) {
        if(Math.random() < pBaum) {
            return Wald.KEIMLING;
        }
        return Wald.HUMUS;
     }
     
     // Beginnt zu brennen?
     if(Wald.BAUM == center) {
       // A) Selbstentzündung
       if(Math.random() < pFeuer) {
           return Wald.FEUER1;
       }
       // B) Entzündung durch umliegende Bäume
       if(umliegenderBaumBrennt(n1, n2, n3, n4, e1, e2, e3, e4)) {
           return Wald.FEUER1;
       }
     }
     
     // in jedem anderen Fall, wird wieder das zurückgegeben, was schon war:
     return center;
   }
    
   boolean umliegenderBaumBrennt(char n1, char n2, char n3, char n4,
           char e1, char e2, char e3, char e4) {
     return brennt(n1) || brennt(n2) || brennt(n3) || brennt(n4) ||
            brennt(e1) || brennt(e2) || brennt(e3) || brennt(e4);
   }
   
   boolean brennt(char nachbar) {
       return Wald.FEUER1 == nachbar || Wald.FEUER2 == nachbar || Wald.FEUER3 == nachbar;
   }

   public static void main(String[] args) {
       Wald w = new Wald(4, 20, 0.1, 0.01, 0.15);
       System.out.println(w);
       Wald w2 = new Wald(4, 20);
       
       Waldbrand brand = new Waldbrand();
       
   
       for(int i = 1; i <= 100; i++) {
           brand.zeitSchritt(w, w2, 0.1, 0.01);
           System.out.println(w2);
           System.out.println("-------------------");
           
           brand.zeitSchritt(w2, w, 0.1, 0.01);
           System.out.println(w);
           System.out.println("-------------------");           
       }
   }

}  // end of class Waldbrand
                

Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

package de.chmu.programmieraufgaben;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * 
 * @author Christoph Müller
 * @date 16.01.2013
 * 
 *       Screenshot der Simulation gibt es hier:
 * 
 *       http://chmu.bplaced.net/?p=274
 * 
 */

public class Waldbrand extends JPanel implements Runnable {

	/**
     * 
     */
	private static final long serialVersionUID = 3426154275216997231L;

	private final int breiteWald = 40;
	private final int hoeheWald = 25;

	private final int breiteContent = 16;
	private final int hoeheContent = 16;

	private final int baumMaxHoehe = 8;
	private final int baumMaxBrandstufe = 30;

	private Content[][] wald = new Content[breiteWald][hoeheWald];

	private Random randomGenerator = new Random();

	private Thread runner;

	/**
	 * Konstruktor
	 */
	public Waldbrand() {
		initWald();

		runner = new Thread(this);
		runner.start();
	}

	/**
	 * main-Methode
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame frame = new JFrame("Waldbrand");
		Waldbrand waldbrand = new Waldbrand();

		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setSize(670, 450);
		int x = (d.width - frame.getSize().width) / 2;
		int y = (d.height - frame.getSize().height) / 2;
		frame.setLocation(x, y);

		frame.add(waldbrand);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.setVisible(true);

	}

	/**
	 * Methode initialisiert einen Wald
	 */
	private void initWald() {
		for (int i = 0; i < breiteWald; i++) {
			for (int j = 0; j < hoeheWald; j++) {
				if (randomGenerator.nextInt(10) < 4) {
					wald[i][j] = new Baum(randomGenerator.nextInt(baumMaxHoehe));
				} else {
					wald[i][j] = new Waldboden();
				}
			}
		}
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		// zeichne den Wald
		for (int i = 0; i < breiteWald; i++) {
			for (int j = 0; j < hoeheWald; j++) {

				// Waldboden Hintergrund zeichnen
				g.setColor(Color.decode("#C4A266"));
				g.fillRect(i * breiteContent, j * hoeheContent, breiteContent, hoeheContent);

				if (wald[i][j] instanceof Baum) {

					Baum baum = (Baum) wald[i][j];

					// Baumkrone zeichnen
					if (baum.getBrandStufe() == 0) {
						// je größer der Baum, desto dunkler wird die grüne
						// Krone
						g.setColor(new Color(0, 255 - (baum.getGroesse() * (100 / baumMaxHoehe)), 0));
					} else {
						g.setColor(new Color(255 - (baum.getBrandStufe() * (255 / baumMaxBrandstufe)), 0, 0));
					}

					g.fillOval(i * breiteContent, (j * hoeheContent) - baumMaxHoehe - baum.getGroesse(), 15, 8);

					// Baumstamm zeichnen
					g.setColor(Color.BLACK);
					g.fillRect(i * breiteContent + 5, (j * hoeheContent) - baum.getGroesse(), breiteContent / 2 - 2, (hoeheContent / 2) - (baumMaxHoehe - baum.getGroesse()));
				}
			}
		}
	}

	@Override
	public void run() {
		while (true) {

			// simuliere die Ereignisse des Waldes
			for (int i = 0; i < breiteWald; i++) {
				for (int j = 0; j < hoeheWald; j++) {

					if (wald[i][j] instanceof Baum) {

						Baum baum = (Baum) wald[i][j];

						// brennender Baum ab gewisser Brandstufe kann weitere
						// infizieren (keine diagonalen Nachbarn)
						if (baum.getBrandStufe() > 3 && baum.getBrandStufe() < 20) {
							if (i < breiteWald - 1 && wald[i + 1][j] instanceof Baum) {
								if (((Baum) wald[i + 1][j]).getBrandStufe() == 0) {
									((Baum) wald[i + 1][j]).setBrandStufe(1);
								}
							}
							if (i > 0 && wald[i - 1][j] instanceof Baum) {
								if (((Baum) wald[i - 1][j]).getBrandStufe() == 0) {
									((Baum) wald[i - 1][j]).setBrandStufe(1);
								}
							}
							if (j < hoeheWald - 1 && wald[i][j + 1] instanceof Baum) {
								if (((Baum) wald[i][j + 1]).getBrandStufe() == 0) {
									((Baum) wald[i][j + 1]).setBrandStufe(1);
								}
							}
							if (j > 0 && wald[i][j - 1] instanceof Baum) {
								if (((Baum) wald[i][j - 1]).getBrandStufe() == 0) {
									((Baum) wald[i][j - 1]).setBrandStufe(1);
								}
							}
						}

						// Baum abgebrannt
						if (baum.getBrandStufe() == baumMaxBrandstufe) {
							wald[i][j] = new Waldboden();
						}

						// Baum kann noch wachsen wenn er nicht brennt
						if (baum.getGroesse() < baumMaxHoehe && baum.getBrandStufe() == 0) {
							// ein Baum wächst nicht in jedem Zyklus
							if (randomGenerator.nextInt(40) < 2) {
								baum.setGroesse(baum.getGroesse() + 1);
							}
						}

						// Brand wird schlimmer
						if (baum.getBrandStufe() > 0 && baum.getBrandStufe() < baumMaxBrandstufe) {
							baum.setBrandStufe(baum.getBrandStufe() + 1);
						}

						// Baum kann sich entzünden
						if (randomGenerator.nextInt(9000) < 2 && baum.getBrandStufe() == 0) {
							baum.setBrandStufe(1);
						}

					} else if (wald[i][j] instanceof Content) {

						// ein Baum kann entstehen
						if (randomGenerator.nextInt(1500) < 2) {
							wald[i][j] = new Baum(1);
						}
					}
				}
			}

			repaint();

			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * abstrakte Klasse zum Markieren eines Wald-Bestandteils
	 * 
	 */
	public abstract class Content {

	}

	/**
	 * Klasse zur Abbildung von Bäumen
	 * 
	 */
	public class Baum extends Content {

		private int groesse = 1;
		private int brandStufe = 0;

		public Baum(int groesse) {
			this.groesse = groesse;
		}

		public int getGroesse() {
			return groesse;
		}

		public void setGroesse(int groesse) {
			this.groesse = groesse;
		}

		public int getBrandStufe() {
			return brandStufe;
		}

		public void setBrandStufe(int brandStufe) {
			this.brandStufe = brandStufe;
		}
	}

	/**
	 * Klasse zur Abbildung des Waldbodens
	 * 
	 */
	public class Waldboden extends Content {

		public Waldboden() {

		}
	}

}

                

Lösung von: Christoph Müller ()

// Autor:				Andy Großhennig
// Solution for task:	Waldbrand (Simulationen)

#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
#include <time.h>
#include <stdio.h>

using namespace std;

// Funtion: Simulate the fire
void igniteSimulation(char c_arrForest[10][10], vector<int>&(viTrees), short sh_arrAge[100], short shRandomIgnite)
{
	short shCoordinates;
	short sh_arrPosition[2];
	short shTree;
	srand(GetTickCount());

	// Loop: Set the age of a fire from young to old
	for(short sh = 0;sh < 100;sh++)
	{
		if(sh_arrAge[sh] == 0)
			sh_arrAge[sh] = 1;
	}

	// Loop: Let a big fire expand and set the age of the new little fire's to young
	for(short shFirst = 0;shFirst < 10;shFirst++)
	{
		for(short shSecond = 0;shSecond < 10;shSecond++)
		{
			short shPosition;

			switch(c_arrForest[shFirst][shSecond])
			{
				case 'F': if((shFirst - 1) >= 0 && (shSecond - 1) >= 0 && c_arrForest[shFirst - 1][shSecond - 1] == 'B')	// -1 : -1
						  {
							  c_arrForest[shFirst - 1][shSecond - 1] = 'f';
							  shPosition = ((shFirst - 1) * 10) + (shSecond - 1);
							  sh_arrAge[shPosition] = 0;
						  }

						  if((shFirst - 1) >= 0 && c_arrForest[shFirst - 1][shSecond] == 'B')	// -1 : 0
						  {
							  c_arrForest[shFirst - 1][shSecond] = 'f';
							  shPosition = ((shFirst - 1) * 10) + shSecond;
							  sh_arrAge[shPosition] = 0;
						  }

						  if((shFirst - 1) >= 0 && (shSecond + 1) < 10 && c_arrForest[shFirst - 1][shSecond + 1] == 'B')	// -1 : +1
						  {
							  c_arrForest[shFirst - 1][shSecond + 1] = 'f';
							  shPosition = ((shFirst - 1) * 10) + (shSecond + 1);
							  sh_arrAge[shPosition] = 0;
						  }

						  if((shSecond - 1) >= 0 && c_arrForest[shFirst][shSecond - 1] == 'B')	// 0 : -1
						  {
							  c_arrForest[shFirst][shSecond - 1] = 'f';
							  shPosition = (shFirst * 10) + (shSecond - 1);
							  sh_arrAge[shPosition] = 0;
						  }

						  c_arrForest[shFirst][shSecond] = '-';	// 0 : 0

						  if((shSecond + 1) < 10 && c_arrForest[shFirst][shSecond + 1] == 'B')	// 0 : +1
						  {
							  c_arrForest[shFirst][shSecond + 1] = 'f';
							  shPosition = (shFirst * 10) + (shSecond + 1);
							  sh_arrAge[shPosition] = 0;
						  }

						  if((shFirst + 1) < 10 && (shSecond - 1) >= 0 && c_arrForest[shFirst + 1][shSecond - 1] == 'B')	// +1 : -1
						  {
							  c_arrForest[shFirst + 1][shSecond - 1] = 'f';
							  shPosition = ((shFirst + 1) * 10) + (shSecond - 1);
							  sh_arrAge[shPosition] = 0;
						  }

						  if((shFirst + 1) < 10 && c_arrForest[shFirst + 1][shSecond] == 'B')	// +1 : 0
						  {
							  c_arrForest[shFirst + 1][shSecond] = 'f';
							  shPosition = ((shFirst + 1) * 10) + shSecond;
							  sh_arrAge[shPosition] = 0;
						  }

						  if((shFirst + 1) < 10 && (shSecond + 1) < 10 && c_arrForest[shFirst + 1][shSecond + 1] == 'B')	// +1 : +1
						  {
							  c_arrForest[shFirst + 1][shSecond + 1] = 'f';
							  shPosition = ((shFirst + 1) * 10) + (shSecond + 1);
							  sh_arrAge[shPosition] = 0;
						  }
						  break;
			}
		}
	}

	// Loop: Let a little fire heighten if the age of the fire is old
	for(short shFirst = 0;shFirst < 10;shFirst++)
	{
		for(short shSecond = 0;shSecond < 10; shSecond++)
		{
			short shPosition = (shFirst * 10) + shSecond;

			switch(c_arrForest[shFirst][shSecond])
			{
				case 'f': if(sh_arrAge[shPosition] == 1)
							  c_arrForest[shFirst][shSecond] = 'F';
						  break;
			}
		}
	}

	// If: Let a tree burn
	if(rand() % shRandomIgnite == 2)
	{
		shTree = rand() % viTrees.size();

		shCoordinates = viTrees.at(shTree);

		viTrees.erase(viTrees.begin() + shTree);

		if(shCoordinates < 10)
		{
			sh_arrPosition[0] = 0;
			sh_arrPosition[1] = shCoordinates;
		}
		else
		{
			sh_arrPosition[1] = shCoordinates % 10;
			shCoordinates /= 10;
			sh_arrPosition[0] = shCoordinates % 10;
		}

		c_arrForest[sh_arrPosition[0]][sh_arrPosition[1]] = 'f';
	}
}

// Function: Simulate the tree's
void sproutSimulation(char c_arrForest[10][10], vector<int>&(viTrees), short shRandomSprout)
{
	short sh_arrPositions[2] = {0, 0};
	int iTree = 0;
	srand(GetTickCount());

	// Loop: Let grow a Tree and add it to the tree vector
	for(short shFirst = 0;shFirst < 10;shFirst++)
	{
		for(short shSecond = 0;shSecond < 10;shSecond++)
		{
			sh_arrPositions[0] = shFirst;
			sh_arrPositions[1] = shSecond;

			if(c_arrForest[shFirst][shSecond] == 'b')
			{
				c_arrForest[shFirst][shSecond] = 'B';

				switch(sh_arrPositions[0])
				{
					case 0: iTree = sh_arrPositions[1];
							break;
					default: iTree = (sh_arrPositions[0] * 10) + sh_arrPositions[1];
				}

				viTrees.push_back(iTree);
			}
		}
	}

	// If: Let sprout a Tree
	if(rand() % shRandomSprout == 0)
	{
		do
		{
			for(short sh = 0;sh < 2;sh++)
			{
				sh_arrPositions[sh] = rand() % 10;
				Sleep(100);
			}
		}
		while(c_arrForest[sh_arrPositions[0]][sh_arrPositions[1]] == ('B' | 'f' | 'F'));

		c_arrForest[sh_arrPositions[0]][sh_arrPositions[1]] = 'b';
	}
}

// Function: Simulate the time flow
void time(char c_arrForest[10][10], vector<int>&(viTrees), int iLoops, short sh_arrAge[100], short shRandomSprout, short shRandomIgnite)
{
	sproutSimulation(c_arrForest, viTrees, shRandomSprout);

	// If: Start the ignite simulation if a big tree exist
	if(viTrees.size() > 0)
		igniteSimulation(c_arrForest, viTrees, sh_arrAge, shRandomIgnite);
}

// Function: Shows the current forest
void showForest(char c_arrForest[10][10], int iLoops, short shRandomSprout, short shRandomIgnite, short shSpeed)
{
	COORD cur={0,7};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cur); //Overwrite the output

	HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE); //Set the colors

	// Loop: Show the members of the forest in the setted color
	for(short shFirst = 0;shFirst < 10;shFirst++)
	{
		for(short shSecond = 0;shSecond < 10;shSecond++)
		{
			switch(c_arrForest[shFirst][shSecond])
			{
				case '-': SetConsoleTextAttribute (hcon,2|0);
					   	  cout << c_arrForest[shFirst][shSecond] << "  ";
						  break;
				case 'b': SetConsoleTextAttribute (hcon,6|0);
						  cout << c_arrForest[shFirst][shSecond] << "  ";
						  break;
				case 'B': SetConsoleTextAttribute (hcon,6|0);
						  cout << c_arrForest[shFirst][shSecond] << "  ";
						  break;
				case 'f': SetConsoleTextAttribute (hcon,4|0);
						  cout << c_arrForest[shFirst][shSecond] << "  ";
						  break;
				case 'F': SetConsoleTextAttribute (hcon,12|0);
						  cout << c_arrForest[shFirst][shSecond] << "  ";
						  break;
			}
		}
		cout << endl;
	}
	//Show the settings
	SetConsoleTextAttribute (hcon,15|0);
	cout << "\n\n" << iLoops << ". Zeitperiode\n\n";
	cout << "Baum waechst zu 1/" << shRandomSprout << endl << "Entzuendung zu 1/" << shRandomIgnite << endl << "Verzoegerung: " << shSpeed << endl;
}

// Function: Generate a field
void generateForest(char c_arrForest[10][10])
{
	for(short shFirst = 0;shFirst < 10;shFirst++)
	{
		for(short shSecond = 0;shSecond < 10;shSecond++)
		{
			c_arrForest[shFirst][shSecond] = '-';
		}
	}
}

// Function: Manage the simulation
void forest()
{
	short shRandomSprout, shRandomIgnite, shSpeed;

	cout << "Wie hoch soll die Chance sein das ein Baum waechst? 1/";
	cin >> shRandomSprout;
	cout << "\nWie hoch soll die Chance einer Entzuendung sein? 1/";
	cin >> shRandomIgnite;
	cout << "\nWieviel Millisekunden sollen zwischen zwei Zeitperioden vergehen? ";
	cin >> shSpeed;

	char c_arrForest[10][10];
	short sh_arrAge[100];
	vector<int>(viTrees);

	int iLoops = 0;

	generateForest(c_arrForest);
	showForest(c_arrForest, iLoops, shRandomSprout, shRandomIgnite, shSpeed);

	// Loop: Set the age of all positions to old
	for(short sh = 0;sh < 100;sh++)
		sh_arrAge[sh] = 1;

	while(true)
	{
		Sleep(shSpeed);
		time(c_arrForest, viTrees, iLoops, sh_arrAge, shRandomSprout, shRandomIgnite);
		iLoops++;
		showForest(c_arrForest, iLoops, shRandomSprout, shRandomIgnite, shSpeed);
	}
}

int main()
{
	forest();
	
	cout << "\n\n";
	system("Pause");
	return 0;
}
                

Lösung von: Andy Großhennig (Bundeswehr)

% Matlab ...

W = [
    '-----BBBBBBBB--------------';
    '-------BBBBBB------------BB';
    '-----BBBBB-----------------';
    '----BBBBBBB--------BBBBB---';
    '-----BB--BB----------BBBBB-';
    '---BBBB------------BBBBB---';
    '-------------------BBB-----';
    '-------------------BB------']
f = 0.1;  % spontanes Feuer
w = 0.1;  % spontanes Wachstum

% TL/TR: Quad. Matrix (wie Höhe/Breite von W) mit 1 in den +1/-1-Diagonalen
TL = diag(ones(size(W,1)-1,1),1) + diag(ones(size(W,1)-1,1),-1);
TR = diag(ones(size(W,2)-1,1),1) + diag(ones(size(W,2)-1,1),-1);

while (true)
  % Neuer Wald = Alter Wald
  newW = W;
  
  % Nachbarsbäume entzünden sich
  newW((newW=='B') & (TL*(W=='F') | (W=='F')*TR)) = 'F';
  
  % Fackle ein paar zusätzliche Bäume an
  newW((newW=='B') & (rand(size(W)) < f)) = 'F';
  
  % Ein paar Bäumlein spriesen
  newW((newW=='-') & (rand(size(W)) < w)) = 'B';
  
  % Alte Feuer erlöschen
  newW(W=='F') = '-';
  
  % Generationswechsel (und Output)
  pause(1)
  W = newW
end

                

Lösung von: Martin Hirt (ETH Zürich)

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 2
Schwierigkeit: Mittel
Webcode: xnq0-ay7n
Autor: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen