gf2:projekte:2024:minecraft:2d2gruppe3

Gruppe 3

Idee: Eine Burg mit Türmchen; siehe Bild in Teamschat

Ziel: Den versteckten Schatz finden, welcher in der Burg versteckt ist.

- Verwinkelte Räume (Labyrinth)

**Code**
 
# ------------------------------------------------------------------------------
#  Nutzung
#   In der Burg ist ein Schatz versteckt, den es zu finden gilt!
#
#  Befehle
#   • "Sesam, öffne dich!"
#   • "Sesam, schliesse dich!"
# ------------------------------------------------------------------------------
 
MIN_PADDING = 3         # Mindestabstand zwischen Räumen und Aussenwand
SIMPLIFY = 0            # Burg vereinfachen um sie schneller zu generieren
TOWERS = True           # Türme generieren
T_RADIUS = 3            # Radius der Türme
seed = 54321            # Startwert für Pseudozufallszahlen
 
# ------------------------------------------------------------------------------
# Die Koordinaten im Code folgen der Einteilung von Minecraft, nach der y die
# Höhe ist.
# Bei blocks.fill wurde FillOperation.REPLACE zwecks Leserlichkeit weggelassen,
# da es sich um den Standartwert handelt.
# ------------------------------------------------------------------------------
 
CHUNK_HEIGHT = 6 # Festgelegt durch Höhe der Burgsegmente
L = 0
materials = [STONE_BRICKS, MOSSY_STONE_BRICKS, STONE_BRICK_STAIRS, STONE_BRICKS_SLAB, OXIDIZED_COPPER, CRACKED_STONE_BRICKS]
start_pos = player.position()
 
#-----------------
# Hilfsfunktionen
#-----------------
 
# Relative Koordinaten unabhängig von der Bewegung des Spielers während der Ausführung
def position(x, y, z):
    return start_pos.add(positions.create(x, y, z))
 
# Funktion um Wert eine Position zu erhalten (da die Funktion position() mit .get_value() sonst nur Weltkoordinaten ausgibt)
def get(pos: Position, axis):
    return pos.to_world().get_value(axis) - start_pos.get_value(axis)
 
# Pseudozufallszahlengenerator https://de.wikipedia.org/wiki/Kongruenzgenerator#Linearer_Kongruenzgenerator
def lcg(value=0):
    global seed
    a, c, m = 1664525, 1013904223, 2**32 # Werte aus https://www.columbia.edu/~ks20/4106-18-Fall/Simulation-LCG.pdf
 
    if value == 0:
        seed = (seed * a + c) % m
        return seed / m
    else:
        return ((value * a + c ) % m) / m
 
#-----------------
# Burg
#-----------------
 
# Funktion zum bauen der Segmente
def chunk_builder():
    blocks.saveStructure("save", world(0, 200, 0), world(16, 250, 16), True)
 
    blocks.fill(AIR, world(0, 200, 0), world(16, 250, 16)) # Bereich leeren
 
    for i in range(2):
        blocks.fill(materials[0], world(0, 200 + 5 * i, 0), world(16, 200 + 5 * i, 16))
        blocks.fill(materials[0], world(0, 201, 16 * i), world(5 + i, 204, 16 * i))
        blocks.fill(materials[0], world(10 - i, 200, 16 * i), world(16, 204, 16 * i))
        blocks.fill(materials[0], world(16 * i, 200, 0), world(16 * i, 204, 16))
        blocks.fill(materials[0], world(5 + 5 * i, 200, 0), world(5 + 5 * i, 204, 4))
        blocks.fill(materials[0], world(6 + 3 * i, 200, 5), world(6 + 3 * i, 204, 5))
        blocks.fill(materials[0], world(5 + 5 * i, 200, 16), world(5 + 5 * i, 204, 12))
        blocks.fill(materials[0], world(6 + 3 * i, 200, 11), world(6 + 3 * i, 204, 11))
        blocks.fill(materials[0], world(6 + 3 * i, 200, 6), world(6 + 3 * i, 203, 11))
        blocks.fill(materials[0], world(0 + 11 * i, 200, 4), world(4 + 11 * i, 204, 4))
        blocks.fill(materials[0], world(13 - i, 200 + 3 * i, 11), world(13 - i, 202 + 2 * i, 5))
 
    blocks.fill(materials[0], world(11, 200, 12), world(15, 204, 12))
    blocks.fill(materials[0], world(6, 204, 6), world(9, 204, 10))
    blocks.fill(materials[0], world(6, 200, 11), world(6, 204, 11))
    blocks.fill(materials[0], world(4, 200, 12), world(4, 204, 12))
    blocks.fill(materials[0], world(3, 200, 11), world(3, 204, 5))
 
    # Öffnungen für Durchgänge
    blocks.fill(AIR, world(0, 201, 7), world(0, 203, 8))
    blocks.fill(AIR, world(4, 201, 4), world(4, 202, 4))
    blocks.fill(AIR, world(14, 201, 1), world(14, 202, 4))
    blocks.fill(AIR, world(10, 201, 2), world(10, 202, 2))
    blocks.fill(AIR, world(3, 201, 5), world(3, 202, 5))
    blocks.fill(AIR, world(15, 201, 12), world(15, 202, 12))
    blocks.fill(AIR, world(11, 201, 12), world(11, 202, 12))
    blocks.fill(AIR, world(5, 201, 14), world(5, 202, 14))
    blocks.fill(AIR, world(2, 201, 16), world(3, 203, 16))
    blocks.fill(AIR, world(16, 201, 7), world(16, 203, 9))
    blocks.fill(AIR, world(5, 205, 10), world(10, 205, 6))
    blocks.fill(AIR, world(9, 205, 11), world(9, 205, 5))
    blocks.fill(AIR, world(6, 205, 11), world(6, 205, 5))
    blocks.fill(AIR, world(5, 205, 0), world(5, 205, 13))
    blocks.fill(AIR, world(10, 205, 3), world(10, 205, 16))
 
    # Stufen zur Verschönerung der Durchgänge
    blocks.place(blocks.block_with_data(materials[2], 7), world(0, 203, 7))
    blocks.place(blocks.block_with_data(materials[2], 6), world(0, 203, 8))
 
    blocks.place(blocks.block_with_data(materials[2], 5), world(2, 203, 16))
    blocks.place(blocks.block_with_data(materials[2], 4), world(3, 203, 16))
 
    blocks.place(blocks.block_with_data(materials[2], 7), world(16, 203, 7))
    blocks.place(blocks.block_with_data(materials[2], 6), world(16, 203, 9))
 
    blocks.fill(blocks.block_with_data(materials[2], 5), world(10, 204, 5), world(10, 204, 11))
    blocks.fill(blocks.block_with_data(materials[2], 4), world(5, 204, 5), world(5, 204, 11))
 
    for x in range(16):
        if x % 3 == 0:
            for z in range(16):
                if z % 3 == 0:
                    player.execute("/setblock " + x + " 205 " + z + " ochre_froglight")
 
 
    # Treppen-Segment
    blocks.fill(materials[1], world(0, 220, 0), world(16, 220, 16))
    blocks.fill(AIR, world(3, 220, 3), world(13, 220, 13))
 
    for step in range(2, 14):  # Treppenstufen erstellen
        material = materials[3] if step % 2 == 0 else materials[0]
        blocks.fill(material, world(step + 1, 220 + (step // 2), 5), world(step + 1,  220 + (step // 2), 8))
 
    # Speichern der Strukturen
    blocks.saveStructure("chunk_default", world(0, 200, 0), world(16, 205, 16), True)
    blocks.loadStructure("chunk_default", world(0, 210, 0))
    blocks.saveStructure("chunk_staircase", world(0, 220, 0), world(16, 225, 16), True)
 
    blocks.place(IRON_BLOCK, world(1, 211, 1))
    blocks.place(GOLD_BLOCK, world(2, 211, 1))
    blocks.place(GOLD_BLOCK, world(3, 211, 1))
    blocks.place(EMERALD_BLOCK, world(1, 211, 2))
    blocks.place(EMERALD_BLOCK, world(2, 211, 2))
    blocks.place(DIAMOND_BLOCK, world(1, 212, 1))
    blocks.place(DIAMOND_BLOCK, world(2, 212, 1))
    blocks.place(DIAMOND_BLOCK, world(1, 211, 3))
    blocks.place(DIAMOND_BLOCK, world(1, 212, 3))
 
    # Schatz-Segment speichern
    blocks.saveStructure("chunk_treasure", world(0, 210, 0), world(16, 215, 16), True)
 
    blocks.loadStructure("save", world(0, 200, 0))
    return 1
 
 
# Funktion zum Zusammensetzen der Segmente
def build_core(length, height, width, start_pos: Position):
    treasure = Math.round(lcg() * length * width * height)
    for x in range(length):
        for y in range(height):
            for z in range(width):
 
                x_now = x * 16 + get(start_pos, Axis.X)
                y_now = y * 6 + get(start_pos, Axis.Y)
                z_now = z * 16 + get(start_pos, Axis.Z)
 
                if x != Math.floor(length / 2) or z != Math.floor(width / 2):
                    if treasure == x + y + z:
                        blocks.loadStructure("chunk_treasure", position(x_now, y_now, z_now), Math.round(lcg()*4), Math.round(lcg()))
                    else:
                        blocks.loadStructure("chunk_default", position(x_now, y_now, z_now), Math.round(lcg()*4), Math.round(lcg()))
                else:
                    if treasure == x + y + z:
                        treasure += 1
                    blocks.loadStructure("chunk_staircase", position(x * 16 + get(start_pos, Axis.X), y * 6 + get(start_pos, Axis.Y), z * 16 + get(start_pos, Axis.Z)))
                    if y == 0:
                        blocks.fill(materials[0], position(x_now, y_now, z_now), position(x_now + 16, y_now, z_now + 16)) # Öffnung zum Boden schliessen
 
 
 
# Burgmauern
def wall(start_pos: Position, end_pos: Position, mirror):
    sx, sy, sz = get(start_pos, Axis.X), get(start_pos, Axis.Y), get(start_pos, Axis.Z)
    ex, ey, ez = get(end_pos, Axis.X), get(end_pos, Axis.Y), get(end_pos, Axis.Z)
    dir_x = 0
    dir_z = 0
 
    outside = 1 if mirror == False else -1 # Bestimmen auf welcher Seite (+ oder -) der Mauer sich die Aussenseite befindet. 1 wenn mirror == False, sonst -1.
 
    height = abs(sy - ey)
 
    # Überprüfen welche Koordinaten identisch sind um Richtung zu bestimmen
    if sx == ex:
        dir_x = outside
        length = abs(sz - ez)
    else:
        dir_z = outside
        length = abs(sx - ex)
 
    blocks.fill(materials[0], start_pos, end_pos)
 
    # Deko
    blocks.fill(materials[0], start_pos.add(pos(dir_x, 1 + ey - min(sy, ey) , dir_z)), end_pos.add(pos(dir_x, 1 + sy - min(sy, ey), dir_z)))
    for i in range(length + 1):
        if i % (2 + SIMPLIFY) == 1: # Jeder 2. Block, falls SIMPLIFY verwendet wird mit entsprechend grösseren Abständen
            stair_data = 0
            if dir_x != 0:
                stair_data = 4 if mirror else 5  # EAST oder WEST
                blocks.place(blocks.block_with_data(materials[2], stair_data), start_pos.add(pos(dir_x, max(sy, ey), i - sz)))
                blocks.place(materials[3], start_pos.add(pos(dir_x, max(sy, ey) + 2, i - sz))) # Zinnen
                # Fenster
                for j in range(height):
                    if j % CHUNK_HEIGHT == 3:
                        blocks.place(blocks.block_with_data(materials[2], 6), start_pos.add(pos(0, j, i - sz)))
                        blocks.place(blocks.block_with_data(materials[2], 2), start_pos.add(pos(0, j-1, i - sz)))
            else:
                stair_data = 6 if mirror else 7  # SOUTH oder NORTH
                blocks.place(blocks.block_with_data(materials[2], stair_data), start_pos.add(pos(i - sx, max(sy, ey), dir_z)))
                blocks.place(materials[3], start_pos.add(pos(i - sx, max(sy, ey) + 2, dir_z))) # Zinnen
                # Fenster
                for j in range(height):
                    if j % CHUNK_HEIGHT == 3:
                        blocks.place(blocks.block_with_data(materials[2], 4), start_pos.add(pos(i - sx, j, 0)))
                        blocks.place(blocks.block_with_data(materials[2], 0), start_pos.add(pos(i - sx, j-1, 0)))
 
 
# Türme
def tower(location: Position, radius, height):
    base_materials = [materials[0], materials[1], materials[5]]
 
    for i in range(height):
        mat = base_materials[randint(0, len(base_materials) - 1)]
        shapes.circle(mat, location.add(pos(0, i, 0)), radius, Axis.Y, ShapeOperation.REPLACE if i % CHUNK_HEIGHT == 0 else ShapeOperation.HOLLOW) # Auf der Höhe jedes Stockwerks einen Boden erstellen
 
    for j in range(radius + 2):
        if j % 2 == 0:
            r = radius - j / 2
        shapes.circle(materials[4], location.add(pos(0, height + j, 0)), r, Axis.Y, ShapeOperation.REPLACE)
 
def outside(length, height, width):
    if height > CHUNK_HEIGHT * 1:
        for i in range(4): # 4 Wände
 
            # Festlegen Start- und Endpositionen der aktuellen Wand (1 oder 0)
 
            #   (1/0)--(1/1)
            #     ¦      ¦
            #   (0/0)--(0/1)
 
            x1 = length if i in(1,2) else 0  # Wenn i == 1 oder i == 3: x1 = length, sonst x1 = 0
            y1 = 0
            z1 = width if i in(2,3) else 0
 
            x2 = length if i in(0,1) else 0
            y2 = height // CHUNK_HEIGHT * CHUNK_HEIGHT
            z2 = width if i in(1,2) else 0
 
            invert = i in(0,3) # True oder False, abhängig davon ob i 1 oder 2 ist
 
            wall(position(x1, y1, z1), position(x2, y2, z2), invert) # Wand
 
            if TOWERS == True:
                tower(position(x1, 0, z1), T_RADIUS, height + 2)
 
        # Eingangstor
        blocks.fill(AIR, position(length // 2 - 1, 0, 0), position(length // 2 + 1, 4, 0))
        blocks.fill(DARK_OAK_FENCE, position(length // 2 - 2, 1, 1), position(length // 2 + 2, 5, 1))
        blocks.place(blocks.block_with_data(materials[2], 5), position(length // 2 - 1, 4, 0))
        blocks.place(blocks.block_with_data(materials[2], 4), position(length // 2 + 1, 4, 0))
 
        # Böden
        for i in range(height + 1):
            if i % CHUNK_HEIGHT == 0:
                blocks.fill(materials[0], position(0, i, 0), position(length, i, width))
 
def tor_auf(a, b):
    blocks.fill(AIR, position(L // 2 - 2, 1, 1), position(L // 2 + 2, 5, 1))
 
def tor_zu(a, b):
    blocks.fill(DARK_OAK_FENCE, position(L // 2 - 2, 1, 1), position(L // 2 + 2, 5, 1))
 
def main(length, height, width, start_pos: Position):
    global L # Global, da sonst die auf() und zu() Funktionen des Eingangstors nicht verwendet weden können.
    L = length
 
    if length < 16 + 2 * MIN_PADDING + 4 or width < 16 + 2 * MIN_PADDING + 4 or height < CHUNK_HEIGHT:
        player.execute("""/tellraw @a {"rawtext":[{"text":"§c§lError: values to small"}]}""")
        return 0
 
    player.execute("""/tellraw @a {"rawtext":[{"text":"§a§lErstellung gestartet..."}]}""")
 
    # Chatbefehle
    player.on_chat("Sesam, schliesse dich!", tor_zu)
    player.on_chat("Sesam, öffne dich!", tor_auf)
 
    # Burg bauen
    chunk_builder()
 
    outside(length, height, width)
 
    core_chunks_x = (length - 2 * MIN_PADDING) // 16
    core_chunks_z = (width - 2 * MIN_PADDING) // 16
    core_start_x = (length - core_chunks_x * 16) // 2
    core_start_z = (width - core_chunks_z * 16) // 2
 
    build_core(core_chunks_x, height // CHUNK_HEIGHT, core_chunks_z, position(core_start_x, 0, core_start_z))
 
    player.execute("""/tellraw @a {"rawtext":[{"text":"§a§lDone!"}]}""")
    return 1
 
main(54, 18, 38, position(0, 0, 0))
  • gf2/projekte/2024/minecraft/2d2gruppe3.txt
  • Zuletzt geändert: 2025/04/15 11:03
  • von marroc