Dies ist eine alte Version des Dokuments!
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
elif y == height - 1:
blocks.fill(AIR, position(x_now + 3, y_now + CHUNK_HEIGHT, z_now + 3), position(x_now + 13, y_now + CHUNK_HEIGHT, z_now + 13)) # Ausgang in Richtung Dach erzeugen
# 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))