Classes#

In Python, a class is a blueprint for creating objects. It defines a set of attributes and methods that the objects of the class will have.

Here’s an example of a simple class:

class Person:
   def __init__(self, name, age):
      self.name = name
      self.age = age

   def say_hello(self):
      print(f"Hello, my name is {self.name} and I am {self.age} years old.")

This class defines a Person object with a name and an age attribute, and a say_hello() method that prints a greeting.

You can create an instance of a class by calling the class as if it were a function, passing in any required arguments. Here’s an example:

person1 = Person("Alice", 25)

This creates a Person object named person1 with a name of "Alice" and an age of 25.

You can access the attributes of an object using the dot notation. Here’s an example:

print(person1.name)

This will output "Alice".

You can call the methods of an object using the dot notation as well. Here’s an example:

person1.say_hello()

This will output "Hello, my name is Alice and I am 25 years old.".

I hope this helps! Let me know if you have any other questions.

TODO: elaborate on classes and demonstrate building all of the buildings inside the castle walls with this code:

from mciwb.imports import Direction, Item, Wall, get_client, get_world


class House:
    """
    A class for constructing a house in the Minecraft world.

    :param width: The new width of the house in no. of windows
    :param depth: The new depth of the house in no. of windows
    :param height: The new height of the house in no. of floors
    """

    sign_name = "house"

    house_profile = [
        [
            [Item.STONE, Item.STONE, Item.STONE, Item.STONE],
            Item.STONE,
            Item.STONE,
            Item.STONE,
        ],
        [
            [Item.STONE, Item.STONE, Item.STONE, Item.STONE],
            Item.OAK_PLANKS,
            Item.IRON_BARS,
            Item.OAK_PLANKS,
        ],
        [
            [Item.STONE, Item.STONE, Item.STONE, Item.STONE],
            Item.OAK_PLANKS,
            Item.IRON_BARS,
            Item.OAK_PLANKS,
        ],
        [
            [Item.STONE, Item.STONE, Item.STONE, Item.STONE],
            Item.STONE,
            Item.STONE,
            Item.STONE,
        ],
    ]

    def __init__(
        self,
        height=1,
        width=3,
        depth=2,
        roof_item=Item.OAK_STAIRS,
    ):
        self.resize(width, depth, height)
        self.roof_item = roof_item
        self.add_signs()

    def resize(self, width=None, depth=None, height=None):
        """
        Resize the house.

        :param width: The new width of the house in no. of windows
        :param depth: The new depth of the house in no. of windows
        :param height: The new height of the house in no. of floors
        """
        if height:
            self.height = height * 4
        if width:
            self.width = width * 4 - 1
        if depth:
            self.depth = depth * 4 - 1

    def build(self, position):
        """
        Build the house at the given position. The dimensions of the house are
        determined by the width, height, and depth attributes of the house class.

        :param position: the location of the south-west bottom corner of the house.
        """

        w = Wall(profile=self.house_profile, height=self.height)

        depth, width = self.depth, self.width
        next = position

        # build the house walls
        w.set_start(next)
        next += Direction.NORTH * depth
        w.draw(next)
        next += Direction.EAST * width
        w.draw(next)
        next += Direction.SOUTH * depth
        w.draw(next)
        next += Direction.WEST * width
        w.draw(next)

        # build the roof
        c = get_client()
        start = (
            position
            + Direction.UP * (self.height + 1)
            + Direction.WEST
            + Direction.SOUTH
        )
        width += 2
        depth += 2
        while True:
            end = start + Direction.NORTH * depth
            c.fill(start, end, str(self.roof_item) + "[facing=east]")
            start = end
            end = start + Direction.EAST * width
            c.fill(start, end, str(self.roof_item) + "[facing=south]")
            start = end
            end = start + Direction.SOUTH * depth
            c.fill(start, end, str(self.roof_item) + "[facing=west]")
            start = end
            end = start + Direction.WEST * width
            c.fill(start, end, str(self.roof_item) + "[facing=north]")
            start = end + Direction.UP + Direction.EAST + Direction.NORTH

            width -= 2
            depth -= 2
            if width <= 0 or depth <= 0:
                break

    def add_signs(self):
        signs = get_world().signs
        signs.remove_sign(self.sign_name)
        signs.add_sign(self.sign_name, self.build)
        signs.give_signs()

    def remove_signs(self):
        signs = get_world().signs
        signs.remove_sign(self.sign_name)

Note that this code can now build a complete castle from previous steps.

from demo.house import House
from demo.pagoda import build_pagoda
from demo.walls import make_walls
from mciwb.imports import Anchor3, FillMode, Item, Vec3, get_client, get_world, polygon


def make_village():
    # flatten the ground by loading our ground file
    get_world().load("blocks/ground.json", Vec3(610, 72, -1673), Anchor3.BOTTOM_NW)

    # clear an area to build the village
    polygon(
        get_client(),
        Vec3(x=640, y=73, z=-1635),
        sides=4,
        height=200,
        diameter=90,
        item=Item.AIR,
        mode=FillMode.REPLACE,
    )

    # build the pagoda
    pagoda_pos = Vec3(585, 71, -1728)
    build_pagoda(pagoda_pos, width=30)
    pagoda_pos = Vec3(x=606, y=70, z=-1500)
    build_pagoda(pagoda_pos, width=30)

    # build the perimeter walls
    make_walls()

    h = House(width=5, depth=9, height=2)
    h.build(Vec3(x=609, y=72, z=-1601))
    h.resize(3, 3, 3)
    h.build(Vec3(x=615, y=83, z=-1605))
    h.build(Vec3(x=637, y=72, z=-1614))
    h.resize(1, 1, 6)
    h.build(Vec3(x=624, y=80, z=-1633))
    h.build(Vec3(x=610, y=80, z=-1633))
    h.resize(2, 2, 1)
    h.build(Vec3(x=615, y=87, z=-1621))
    h.resize(2, 2, 5)
    h.build(Vec3(x=639, y=87, z=-1616))