5. Programmierkonzepte

Eine Variable ist ein Behälter für eine Grösse. Diese wird durch einen Namen repräsentiert und zeigt auf eine bestimmte Adresse im Speicher des Computers. Variablen können beliebig wieder überschrieben werden.

a = 4 # In der Variablen a wird der Wert 4 gespeichert
name = 'Rene Lehmann' # In der Variablen name wird 'Rene Lehmann' gespeichert
strasse = "Lärchenweg" # doppelte Anführungszeichen gehen auch
pi = 3.141592 # Eine Fliesskommazahl
a = "Hallo" #die Variable a wird wieder überschrieben

Wie wir oben gesehen haben, kann man in Variablen ganz unterschiedliche Dinge speichern. Z.B.

  • ganze Zahlen (Integers)
  • Kommazahlen (Float)
  • Zeichenketten (Strings)
  • Wahrheitswerte: True, False (bolean)
  • Listen (Listen sind Datenstrukturen). In Python kann eine Liste komplett unterschiedliche Dinge enthalten, d.h. die Datentypen können beliebig gemischt werden.

In vielen Programmiersprachen muss man sich bei einer bestimmten Variable entscheiden, von welchem Typ sie ist und kann dann nur diesen Typ verwenden. Nicht so in Python. In Python herrscht dynamische Typisierung vor, d.h. ich kann in einer Variablen a zunächst eine Zeichenkette speichern und dann diese durch eine ganze Zahl überschreiben und danach eine Kommazahl daraus machen.

if agent.get_item_count(2)>=2:
    agent.set_slot(2)
    agent.place(BACK)
    agent.move(FORWARD, 1)
    agent.place(BACK)
elif agent.get_item_count(2)==1:
    agent.set_slot(2)
    agent.place(BACK)
else:
    player.say("Nix mehr in Slot 2")

while agent.get_item_count(1)>0:
    agent.place(BACK)
    agent.move(FORWARD,1)

l1 = [GRASS, STONE, OAK_DOOR] # Liste erstellen
agent.set_slot(1)
for item_type in l1: # Liste durchgehen
    agent.set_item(item_type, 1, 1)
    agent.place(BACK)
    agent.move(FORWARD, 1)

Eine Liste kann man auch sehr elegant mit dem range-Befehl erstellen:

range(10) # => [0,1,2,3,4,5,6,7,8,9]
range(9,18,3) # => [9, 12,15]


# Eine Funktion definieren, welche zwei Parameter (n, type) nimmt
def build_line(n, type):
    agent.set_item(type,1,1)
    agent.set_slot(1)
    for i in range(n):
        agent.place(BACK)
        agent.move(FORWARD,1)

# Nun kanan die Funktion aufgerufen werden
build_line(5,GRASS)
build_line(8,STONE)

Evtl. ist es sinnvoll, für die folgenden Aufgaben agent.set_assist(PLACE_ON_MOVE, True) zu setzen, damit der Agent bei jeder Bewegung baut.

  1. Schreibe eine Funktion quadrat(n), welche den Agent dazu bringt, ein nicht ausgefülltes Quadrat der Länge n zu bauen (n ist ein Parameter und kann beim Aufrufen der Funktion gewählt werden).
  2. Schreibe eine Funktion quadratf(n) welche ein gefülltes Quadrat baut.
  3. Schreibe eine Funktion circle(n), welche einen „Kreis“ mit Radius n baut
  4. Schreibe eine Funktion tower(n,h) welche einen Turm mit quadratischer Grundfäche der Breite n und der Höhe h baut.
  5. Schreibe eine Funktion kugel(n), welche eine Kugel baut mit „Radius“ n.

Finde heraus, was das %-Zeichen macht. Öffne dazu z.B. Thonny und gib Zahlenbeispiele ein, z.B. 14 % 5, 21 % 4, 17 % 8 etc.

Überlege dir, was das untenstehende Programm macht:

for i in range(20):
    if (i % 2) == 0:
        blocks.place(GOLD_BLOCK, world(i, 4, 0))

Was ändert sich, wenn man statt %2, %3, %4 etc. schreibt?

  1. Schreibe mit Hilfe von Modulo (%) ein Programm, welches eine Linie von 40 Blocks baut, wobei immer abwechslungsweise ein Block aus EMERALD, einer aus GRANITE und einer aus Honig besteht.
  2. Versuche eine Parkettierung aus 20×20 Blöcken zu machen, welches ein Schachbrett nachahmt, d.h. die Blöcke müssen immer abwechseln (nimm z.B. Gold und Granit). Kann man hier elegant Modulo verwenden?
  3. Versuche eine Parkettierung zu machen, welche aus 20×20 Blöcken besteht, welche ein diagonales Kreuz (ein waagerechtes Kreuz oder auch beides) hat.
  4. Schreibe eine Funktion House(), welche ein Haus baut. Eine Idee wäre z.B., dass man einen gefüllten Block macht und ihn dann mit einem kleineren gefüllten Block aus 'Luft' wieder aushöhlt… danach kann man Fenster, Türe etc einfügen und das Dach machen. Man kann aber auch die Wände einzeln bauen, wenn man möchte.

Lösung 1

for i in range(40):
        if (i%3) == 0:
            blocks.place(GOLD_BLOCK,world(i,5,0))
        if (i%3) == 1:
            blocks.place(BLUE_WOOL,world(i,5,0))
        if (i%3) == 2:
            blocks.place(GREEN_WOOL,world(i,5,0))

Lösung 2

for i in range(20):
        for j in range(20):
            if (i+j) % 2 == 0:
                blocks.place(GOLD_BLOCK,pos(i,5,j))
            else:
                blocks.place(BLUE_WOOL,pos(i,5,j))

Alternative zu Nr. 2. (Léa)

def parkett3():
    for j in range(20):
        if (j % 2) == 0:
            for i in range(20):
                if (i % 2) == 0:
                    blocks.place(GOLD_BLOCK,pos(i,5,j))
                else:
                    blocks.place(BLUE_WOOL,pos(i,5,j))
        else: # (j % 2 ist hier 1)
            for i in range(20):
                if (i % 2) == 0:
                    blocks.place(BLUE_WOOL,pos(i,5,j)) 
                else:
                    blocks.place(GOLD_BLOCK,pos(i,5,j)) 

Lösung 3: Ein Kreuz (i==j oder i == 20-j

for i in range(10):
    for j in range(10):
        if (i==j or i==20-j):
            blocks.place(YELLOW_WOOL, world(i, 4, j))
        else:
            blocks.place(BLUE_WOOL,world(i,4,j))

Aufgabe 4: Ein einfaches Haus (parametrisiert)

def simple_house(xpos,ypos,zpos,breite, hoehe):
    blocks.fill(STONE_BRICKS,world(xpos,ypos,zpos),world(xpos+breite,ypos+hoehe, zpos+breite))
    blocks.fill(AIR, world(xpos+1,ypos,zpos+1),world(xpos+breite-1,ypos+hoehe-1, zpos+breite-1))
    #Tuere
    blocks.fill(AIR,world(xpos+4,ypos,zpos),world(xpos+4,ypos+1,zpos))
    blocks.place(ACACIA_DOOR,world(xpos+4,ypos,zpos))


simple_house(100,4,-18,7,10)
simple_house(140,4,-18,10,5)

6. Programmierbeispiele

def on_travelled_walk():
    x = player.position().get_value(Axis.X)
    y = player.position().get_value(Axis.Y)
    z = player.position().get_value(Axis.Z)
    
    player.say("x:"+str(x)+" y:"+str(y)+" z:"+str(z))


player.on_travelled(WALK, on_travelled_walk)

Statt z.B. blocks.place(OAK_DOOR,world(0,0,0)) kann man den Block mit zugehörigem Datenwert platzieren:

blocks.place(blocks.block_with_data(OAK_DOOR, 0),world(0,0,0))

Der Daten-Wert gibt an, ob die Türe (oder Treppe) etc. geöffnet ist, nach links aufgeht etc.

def strasse(xpos,ypos,zpos,laenge):
    blocks.fill(LIGHT_GRAY_CONCRETE,world(xpos,ypos,zpos),world(xpos+laenge,ypos,zpos+4))
    for i in range(xpos,xpos+laenge,2):
        blocks.place(CONCRETE,world(i,ypos,zpos+2))

strasse(700,3,700,40)

  • archiv/gf/gf2020_2021/minecraft/programmierkonzepte.txt
  • Zuletzt geändert: 2022/08/27 18:08
  • von lehmannr