瀏覽代碼

Update 'main.py'

renamed a lot of variables from karel to asset in anticipation of more shapes.
tBKwtWS 1 月之前
父節點
當前提交
9ec9835a7c
共有 1 個文件被更改,包括 618 次插入232 次删除
  1. 618 232
      main.py

+ 618 - 232
main.py

@@ -1,248 +1,634 @@
-from karel.stanfordkarel import *
+import operator
+import logging
+import random
+
+# Logging to console
+logger = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO) # Set loglevel to INFO or higher to prevent console spam.
+
+
+"""
+Helper functions
 """
-Inspired by John Conways "Game of Life" and "Biogenesis" by Joan Queralt Molina.
+# Return some hex colour
+"""
+Waiting for Stanford to fix a bug in the environment
+CIP bug: https://codeinplace.stanford.edu/cip6/report?post=ac7c4ffd-1f90-475a-b4ee-2e5b73c5348f
 
-The three phases of life start with Karel seeding a few fountains of youth, represented by beepers on black patches of "land".
+from matplotlib import colors
+import decimal
 
-Than the circle of life commences, with Karel being the fickle hand of god that moves randomly over the board,
-at certain times deciding to bless or smite the life she passes.
-Being blessed means growth and changing colour, while smiting leads to permanent death or being composted.
-After several steps of growth it is possible for life to reproduce, and spread to other patches of land;
-possible in the process overwhelming neighboring life.
+def get_random_colour():
+    return decimal.Decimal(random.randrange(0,10)/10), decimal.Decimal(random.randrange(0,10)/10), decimal.Decimal(random.randrange(0,10)/10)
 
-After an ungodly amount of divine acts, in the final ascension phase, the fountains are collected by their creatress Karel;
-leaving only the result of the onslaught of the competition that is life.
+colour = colors.rgb2hex((get_random_colour()))
+background = colors.rgb2hex((get_random_colour()))
+"""
+def generate_random_colour():
+    rgb_values = [random.randrange(256), random.randrange(256), random.randrange(256)]
+    hex_colours = [hex(value)[2:] for value in rgb_values]  # Strip the '0x' prefix
+    for i in range(len(hex_colours)):
+        if len(str(hex_colours[i])) == 1:
+            hex_colours[i] = f"0{hex_colours[i]}"
+    return '#' + ''.join(hex_colours)
 
-TIP: Run at top speed to spare your own life from wasting away...
 """
+Karel functions
+"""
+# Erase a passed Karel from the canvas
+def erase_asset(asset):
+    canvas = asset[1][0]
 
-## Helper functions:
-# Turn left trice:
-def turn_right():
-    for i in range(3):  
-        turn_left()
-
-# Keep moving while not blocked:
-def move_till_end():
-    while front_is_clear():
-        move()
-
-# 20% chance to move:
-def perhaps_move():
-    if random(0.2): 
-        move()
-
-def pick_if_present():
-    if beepers_present():
-        pick_beeper()
-
-# Move to next row:
-def next_row():
-    # Turn west:
-    if facing_east():
-        turn_left()
-        if front_is_clear():
-            move()
-            turn_left()
-        
-    # Turn east
-    else:   # Facing west
-        turn_right()
-        if front_is_clear():
-            move()
-            turn_right()
-
-def wall_check():
-    if front_is_blocked():    # End of row
-        next_row()
-
-# Move to southeast corner:
-def genesis_position():
-    # Move south:
-    while not_facing_south():
-        turn_left()
-    move_till_end()
-
-    # Move west:
-    while not_facing_west():
-        turn_left()
-    move_till_end()
-
-    # Turn:
-    while not_facing_east():
-        turn_left()
-
-# Do not face walls, and sometimes change direction:
-def orient():
-
-    # Perhaps turn
-    if random(0.1): # 10% chance to turn
-        if random(0.5): # 50% chance to go right or left
-            turn_left()
-        else:
-            turn_right()
+    for shape in asset[0].values():
+        canvas.delete(shape)
+    logger.debug(f"Erased asset: {asset}")
+
+# Move a passed Karel on the canvas
+"""
+Waiting for Stanford to fix a bug in the environment
+CIP bug: https://codeinplace.stanford.edu/cip6/report?post=7043ece9-7653-4e39-8a63-5f4544b1d74b
+
+def move_karel(canvas, karel, x, y):
+    for shape in karel[0].values():
+        canvas.move(shape, x, y)
+    logger.debug(f"Moved: {karel} by {x} horizontally, {y} vertically")
+"""
+# Move a passed Karel relative to previous position
+def relative_move_asset(asset, x:int=0, y:int=0):
+    # Update coordinates in list
+    asset[1][1] += x
+    asset[1][2] += y
+
+    erase_asset(asset)
+    new_asset = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
+
+    logger.debug(f"Moved: {asset} by {x} horizontally, {y} vertically, to {new_asset}")
+    return new_asset
+
+# Move a passed Karel in relation to her orientation
+def orientation_move_asset(asset, direction, amount):
+    # Direction translation
+    if asset[1][4].startswith("east"):
+        if direction.lower() == "forward" or direction.lower() == "front":
+            asset[1][1] += amount
+        if direction.lower() == "left":
+            asset[1][2] -= amount
+        if direction.lower() == "right":
+            asset[1][2] += amount
+        if direction.lower() == "backward" or direction.lower() == "back":
+            asset[1][1] -= amount
+    if asset[1][4].startswith("north"):
+        if direction.lower() == "forward" or direction.lower() == "front":
+            asset[1][2] -= amount
+        if direction.lower() == "left":
+            asset[1][1] -= amount
+        if direction.lower() == "right":
+            asset[1][1] += amount
+        if direction.lower() == "backward" or direction.lower() == "back":
+            asset[1][2] += amount
+    if asset[1][4].startswith("west"):
+        if direction.lower() == "forward" or direction.lower() == "front":
+            asset[1][1] -= amount
+        if direction.lower() == "left":
+            asset[1][2] += amount
+        if direction.lower() == "right":
+            asset[1][2] -= amount
+        if direction.lower() == "backward" or direction.lower() == "back":
+            asset[1][1] += amount
+    if asset[1][4].startswith("south"):
+        if direction.lower() == "forward" or direction.lower() == "front":
+            asset[1][2] += amount
+        if direction.lower() == "left":
+            asset[1][1] += amount
+        if direction.lower() == "right":
+            asset[1][1] -= amount
+        if direction.lower() == "backward" or direction.lower() == "back":
+            asset[1][2] -= amount
+
+    erase_asset(asset)
+    new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
+
+    logger.debug(f"Moved: {asset} {direction} by {amount} as {new_karel}")
+    return new_karel
+
+# Move a passed Karel to new coordinates
+def absolute_move_karel(asset, x:int=0, y:int=0):
+    # Update coordinates in list
+    asset[1][1] = x
+    asset[1][2] = y
+
+    erase_asset(asset)
+    new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
+
+    logger.debug(f"Moved: {asset} by {x} horizontally, {y} vertically, to {new_karel}")
+    return new_karel
+
+# Change the orientation of a passed Karel
+def rotate_karel(asset, direction):
+    # Relative turn
+    if direction == "right" or direction == "left":
+        # East
+        if asset[1][4] == "east":
+            if direction == "right":
+                asset[1][4] = "south"
+            if direction == "left":
+                asset[1][4] = "north"
+        elif asset[1][4] == "east-flipped":
+            if direction == "right":
+                asset[1][4] = "south-flipped"
+            if direction == "left":
+                asset[1][4] = "north-flipped"
+
+        # North
+        elif asset[1][4] == "north":
+            if direction == "right":
+                asset[1][4] = "east"
+            if direction == "left":
+                asset[1][4] = "west"
+        elif asset[1][4] == "north-flipped":
+            if direction == "right":
+                asset[1][4] = "east-flipped"
+            if direction == "left":
+                asset[1][4] = "west-flipped"
+
+        # West
+        elif asset[1][4] == "west":
+            if direction == "right":
+                asset[1][4] = "north"
+            if direction == "left":
+                asset[1][4] = "soutch"
+        elif asset[1][4] == "west-flipped":
+            if direction == "right":
+                asset[1][4] = "north-flipped"
+            if direction == "left":
+                asset[1][4] = "south-flipped"
+
+        # South
+        elif asset[1][4] == "south":
+            if direction == "right":
+                asset[1][4] = "west"
+            if direction == "left":
+                asset[1][4] = "east"
+        elif asset[1][4] == "north-flipped":
+            if direction == "right":
+                asset[1][4] = "west-flipped"
+            if direction == "left":
+                asset[1][4] = "east-flipped"
+    
+    # Absolute rotation
+    elif direction == "east" or direction == "east-flipped" or direction == "north" or direction == "north-flipped" or direction == "west" or direction == "west-flipped" or direction == "south" or direction == "south-flipped":
+        asset[1][4] = direction
     
-    # Make sure not to face an obstruction
-    while front_is_blocked():
-        turn_left()
+    # Syntax error
+    else:
+        logger.error(f"Invalid rotation direction: {direction}")
 
+    erase_asset(asset)
+    new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
 
-## Main functions:
-# According to biologists, the sole goal of life.
-def reproduce():
-    move()
-    if no_beepers_present():    # Unseeded tile
+    logger.debug(f"Rotated Karel: {asset} by {direction} as {asset[1][4]} to {new_karel}")
+    return new_karel
 
-        # Seed life
-        paint_corner("black")   
-        put_beeper()
+# Recolour a passed Karel on the canvas
+"""
+Waiting for Stanford to fix a bug in the environment
+CIP bug: https://codeinplace.stanford.edu/cip6/report?post=c36ed931-3019-4830-8ba6-655c1a513471
+
+def recolour_karel(canvas, karel, colour:str="black", background:str="white"):
+    for name, shape in karel[0].items():   # Loop over Karel dict
+        if name.endswith("_fill"): # Background shape
+            canvas.set_color(shape, background)
+            canvas.set_outline_color(shape, background)
+        else:   # Foreground shape
+            if name.endswith("_line") or name.endswith("_corner") or name == "mouth":
+                canvas.set_color(shape, colour)
+            elif name == "eye":
+                #canvas.set_color(shape, "transparent")
+                canvas.set_outline_color(shape, colour)
+            else:   # Legs and feet
+                canvas.set_color(shape, colour)
+                canvas.set_outline_color(shape, colour)
+"""
+def recolour_asset(asset, colour:str="black", background:str="white"):
+    # Random colours
+    if colour == "random":
+        colour = generate_random_colour()
+    if background == "random":
+        background = generate_random_colour()
+
+    # Update colours in list
+    asset[1][5] = colour
+    asset[1][6] = background
+
+    erase_asset(asset)
+    new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
+
+    logger.debug(f"Re-coloured Karel: {asset} with {colour} and {background} to {new_karel}")
+    return new_karel
+
+# Draw a Karel
+def draw_karel(
+        canvas,
+        centre_x:int=25,
+        centre_y:int=25,
+        size:int=50,
+        orientation:str="east",
+        colour:str="black",
+        background:str="white",
+        transparent:bool=False
+    ):
     
-    else:   # Seeded tile
-        if random(0.5): # 50% chance
-            paint_corner("orange")  # Accelerate life or overtake another life.
-        else:   # Remainder 50% chance
-            die()   # Compete, cancelling each other out.
+    # Body constants
+    MARGIN = size / 8
+    APPENDAGE_MULTIPLIER = MARGIN * 0.6
     
-    # Never leave Karel facign a wall:
-    orient()
-
-def die():
-    # Permanent death:
-    if random(0.2): # 20% chance
-        paint_corner("white")
-        pick_beeper()
+    # Random colours
+    if colour == "random":
+        colour = generate_random_colour()
+    if background == "random":
+        background = generate_random_colour()
+
+    ''' Flipper case
+    In order to be able to flip Karel, the operands in the forumlas must be able to switch around.
+    Orientations are in relation to the centre of Karel.
+    '''
+    match orientation.lower():     
+        case "east" | "south-flipped":
+            left_operand = operator.sub     # Left / Top
+            top_operand = operator.sub      # Top / Left
+            right_operand = operator.add    # Right / Bottom
+            bottom_operand = operator.add   # Bottom / Right
+        case "east-flipped" | "south":
+            left_operand = operator.sub     # Left / Top
+            top_operand = operator.add      # Bottom / Right
+            right_operand = operator.add    # Right / Bottom
+            bottom_operand = operator.sub   # Top / Left
+        case "west" | "north-flipped":
+            left_operand = operator.add     # Right 
+            top_operand = operator.add      # Bottom
+            right_operand = operator.sub    # Left
+            bottom_operand = operator.sub   # Top
+        case "west-flipped" | "north":
+            left_operand = operator.add     # Right / Bottom
+            top_operand = operator.sub      # Top / Left
+            right_operand = operator.sub    # Left / Top
+            bottom_operand = operator.add   # Bottom / Right
     
-    # Seed for rebirth | Composting:
-    else:   # Remainder 80% chance
-        paint_corner("black")
-
-# Grow, die or reproduce:
-def paint_life():
-    # In reverse order, since "elif" is not available.
-    #if corner_color_is("pink"):    # End condition, but "quit()" is not available
-    #    quit()
-
-    if corner_color_is("cyan"):
-        if random(0.8):    # 80% chance
-            paint_corner("pink")    # Evolve
-            
-            # Reproduce quadrice:
-            for i in range(4):
-                reproduce()
+    # Coords case
+    if orientation.lower() == "north" or orientation.lower() == "north-flipped" or orientation.lower() == "south" or orientation.lower() == "south-flipped":
+        temp_x = centre_x
+        centre_x = centre_y
+        centre_y = temp_x
+        #pass
+
+    # Borders
+    left = left_operand(centre_x, size / 2)
+    top = top_operand(centre_y, size / 2)
+    right = right_operand(centre_x, size / 2)
+    bottom = bottom_operand(centre_y, size / 2)
+    margin = size / 8
+    appendage_multiplier = margin * 0.6
+
+    # Body borders
+    body_left = left_operand(centre_x, size / 3)
+    body_top = top
+    body_right = right_operand(centre_x, size / 3)
+    body_bottom = bottom_operand(centre_y, size / 2.6)
+    eye_left = right_operand(body_left, margin)
+    eye_top = bottom_operand(body_top, margin)
+    eye_right = left_operand(body_right, margin)
+    eye_bottom = top_operand(body_bottom, margin * 2)
+
+    # Body coordinates
+    top_left_corner = body_left, body_top
+    left_diagonal_top = body_left, top_operand(body_bottom, margin)
+    left_diagonal_bottom = eye_left, body_bottom
+    right_diagonal_top = eye_right, body_top
+    right_diagonal_bottom = body_right, bottom_operand(body_top, margin)
+    bottom_right_corner = body_right, body_bottom
+    mouth_left_corner = centre_x, bottom_operand(eye_bottom, margin)
+    mouth_right_corner = eye_right, mouth_left_corner[1]
+
+    # Left appendage borders
+    leftLeg_left = left_operand(body_left, margin)
+    leftLeg_top = eye_bottom
+    leftLeg_right = body_left
+    leftLeg_bottom = bottom_operand(leftLeg_top, appendage_multiplier)
+    leftFoot_left = leftLeg_left
+    leftFoot_top = leftLeg_bottom
+    leftFoot_right = right_operand(leftLeg_left, appendage_multiplier)
+    leftFoot_bottom = bottom_operand(leftFoot_top, appendage_multiplier)
+
+    # Right appendage borders
+    rightLeg_left = centre_x
+    rightLeg_top = body_bottom
+    rightLeg_right = right_operand(rightLeg_left, appendage_multiplier)
+    rightLeg_bottom = bottom
+    rightFoot_left = rightLeg_right
+    rightFoot_top = top_operand(bottom, appendage_multiplier)
+    rigthFoot_right = right_operand(rightLeg_right, appendage_multiplier)
+    rightFoot_bottom = bottom
+
+    # Draw Karel
+    match orientation.lower():
+        case "east" | "east-flipped" | "west" | "west-flipped":
+            if not transparent:
+                # Meat
+                top_fill = canvas.create_rectangle(
+                    top_left_corner[0],
+                    top_left_corner[1],
+                    right_diagonal_top[0],
+                    eye_top,
+                    background,
+                    background
+                )
+                top_corner_fill = canvas.create_polygon(
+                    right_diagonal_top[0] , right_diagonal_top[1],
+                    right_diagonal_bottom[0], right_diagonal_bottom[1],
+                    eye_right, eye_top,
+                    color = background,
+                    outline = background
+                )
+                left_fill = canvas.create_rectangle(
+                    top_left_corner[0],
+                    eye_top,
+                    eye_left,
+                    left_diagonal_top[1],
+                    background,
+                    background
+                )
+                right_fill = canvas.create_rectangle(
+                    eye_right,
+                    eye_top,
+                    right_diagonal_bottom[0],
+                    eye_bottom,
+                    background,
+                    background
+                )
+                bottom_fill = canvas.create_rectangle(
+                    eye_left,
+                    eye_bottom,
+                    bottom_right_corner[0],
+                    bottom_right_corner[1],
+                    background,
+                    background
+                )
+                bottom_corner_fill = canvas.create_polygon(
+                    left_diagonal_top[0], left_diagonal_top[1],
+                    eye_left, left_diagonal_top[1],
+                    left_diagonal_bottom[0], left_diagonal_bottom[1],
+                    color = background,
+                    outline = background
+                )
             
-        else:   # Remainder 20% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("green"):
-        if random(0.8):    # 80% chance
-            paint_corner("cyan")    # Evolve
-
-            # Reproduce thrice:
-            for i in range(3):
-                reproduce()
-            
-        else:   # Remainder 20% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("blue"):
-        if random(0.8):    # 80% chance
-            paint_corner("green")   # Evolve
-
-            # Reproduce twice:
-            for i in range(2):
-                reproduce()
-            
-        else:   # Remainder 20% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("olive"):
-        if random(0.6):    # 60% chance
-            paint_corner("blue")    # Evolve
-            reproduce()
-        else:   # Remainder 40% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("orange"):
-        if random(0.5):    # 50% chance
-            paint_corner("olive")    # Evolve
-        else:   # Remainder 50% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("red"):  # Adolescence
-        if random(0.4):    # 40% chance
-            paint_corner("orange")  # Evolve
-        else:   # Remainder 60% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("purple"):   # Early stage
-        if random(0.3):    # 30% chance
-            paint_corner("red") # Evolve
-        else:  # Remainder 70% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("brown"):    # Infancy
-        if random(0.2):    # 20% chance
-            paint_corner("purple")  # Evolve
-        else:   # Remainder 80% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("gray"): # Prenatal
-        if random(0.1):    # 10% chance
-            paint_corner("brown")   # Evolve
-        else:   # Remainder 90% chance
-            if random(0.2): # 20% chance of death, else stagnation.
-                die()   # Death
-    if corner_color_is("black"):    # Field is seeded
-        paint_corner("gray")    # Sprout life
-
-# Prepare the world with habitable patches.
-def seed():
-    genesis_position()
-
-    while front_is_clear():
-
-        # Perhaps seed a fountain of life
-        if random(0.3): # 30% chance
-            paint_corner("black")
-            put_beeper()
+            # Outlines
+            top_line = canvas.create_line(
+                top_left_corner[0], top_left_corner[1],
+                right_diagonal_top[0], right_diagonal_top[1],
+                colour
+            )
+            top_corner = canvas.create_line(
+                right_diagonal_top[0], right_diagonal_top[1],
+                right_diagonal_bottom[0], right_diagonal_bottom[1],
+                colour
+            )
+            left_line = canvas.create_line(
+                top_left_corner[0], top_left_corner[1],
+                left_diagonal_top[0], left_diagonal_top[1],
+                colour
+            )
+            bottom_corner = canvas.create_line(
+                left_diagonal_top[0], left_diagonal_top[1],
+                left_diagonal_bottom[0], left_diagonal_bottom[1],
+                colour
+            )
+            bottom_line = canvas.create_line(
+                left_diagonal_bottom[0], left_diagonal_bottom[1],
+                bottom_right_corner[0], bottom_right_corner[1],
+                colour
+            )
+            right_line = canvas.create_line(
+                right_diagonal_bottom[0], right_diagonal_bottom[1],
+                bottom_right_corner[0], bottom_right_corner[1],
+                colour
+            )
+            left_leg = canvas.create_rectangle(
+                leftLeg_left,
+                leftLeg_top,
+                leftLeg_right,
+                leftLeg_bottom,
+                colour,
+                colour
+            )
+            left_foot = canvas.create_rectangle(
+                leftFoot_left,
+                leftFoot_top,
+                leftFoot_right,
+                leftFoot_bottom,
+                colour,
+                colour
+            )
+            right_leg = canvas.create_rectangle(
+                rightLeg_left,
+                rightLeg_top,
+                rightLeg_right,
+                rightLeg_bottom,
+                colour,
+                colour
+            )
+            right_foot = canvas.create_rectangle(
+                rightFoot_left,
+                rightFoot_top,
+                rigthFoot_right,
+                rightFoot_bottom,
+                colour,
+                colour
+            )
+            eye = canvas.create_rectangle(
+                eye_left,
+                eye_top,
+                eye_right,
+                eye_bottom,
+                "transparent",
+                colour,
+            )
+            mouth = canvas.create_line(
+                mouth_left_corner[0], mouth_left_corner[1],
+                mouth_right_corner[0], mouth_right_corner[1],
+                colour
+            )
         
-        move()
-        wall_check()
-    
-    # Face away from the wall
-    orient()
-
-# The circle of life                
-def life_loop():
-    for i in range(9999):   # Incubation period
-
-        # Path of god, played by karel:
-        for step in range(9):  # Travel period
-            perhaps_move()
-            orient()
-        paint_life()
-
-# End the game neatly:
-def ascension():
-    genesis_position()
-
-    # Remove seeds
-    while front_is_clear():
-        pick_if_present()
-        move()
-        pick_if_present()
-        wall_check()
-    
-    genesis_position()
-
-
- # The three phases of life:
-def main():
-    seed()
-    life_loop()
-    ascension() # The script should not run forever, making some unintended biblical implications...
-
-
-# don't change this code
-if __name__ == '__main__':
-    main()
+        case "north" | "north-flipped" | "south" | "south-flipped":
+            if not transparent:
+                # Meat
+                top_fill = canvas.create_rectangle(
+
+                    top_left_corner[1],             # Top Y
+                    right_diagonal_top[0],          # Right X
+                    eye_top,                        # Bottom Y
+                    top_left_corner[0],             # Left X
+                    background,
+                    background
+                )
+                top_corner_fill = canvas.create_polygon(
+                    right_diagonal_top[1] , right_diagonal_top[0],
+                    right_diagonal_bottom[1], right_diagonal_bottom[0],
+                    eye_top, eye_right,
+                    color = background,
+                    outline = background
+                )
+                left_fill = canvas.create_rectangle(
+                    
+                    eye_top,
+                    eye_left,
+                    left_diagonal_top[1],
+                    top_left_corner[0],
+                    background,
+                    background
+                )
+                right_fill = canvas.create_rectangle(
+                    
+                    eye_top,
+                    right_diagonal_bottom[0],
+                    eye_bottom,
+                    eye_right,
+                    background,
+                    background
+                )
+                bottom_fill = canvas.create_rectangle(
+                    
+                    eye_bottom,
+                    bottom_right_corner[0],
+                    bottom_right_corner[1],
+                    eye_left,
+                    background,
+                    background
+                )
+                bottom_corner_fill = canvas.create_polygon(
+                    left_diagonal_top[1], left_diagonal_top[0],
+                    left_diagonal_top[1], eye_left,
+                    left_diagonal_bottom[1], left_diagonal_bottom[0],
+                    color = background,
+                    outline = background
+                )
+            
+            # Outlines
+            top_line = canvas.create_line(
+                top_left_corner[1], top_left_corner[0],
+                right_diagonal_top[1], right_diagonal_top[0],
+                colour
+            )
+            top_corner = canvas.create_line(
+                right_diagonal_top[1], right_diagonal_top[0],
+                right_diagonal_bottom[1], right_diagonal_bottom[0],
+                colour
+            )
+            left_line = canvas.create_line(
+                top_left_corner[1], top_left_corner[0],
+                left_diagonal_top[1], left_diagonal_top[0],
+                colour
+            )
+            bottom_corner = canvas.create_line(
+                left_diagonal_top[1], left_diagonal_top[0],
+                left_diagonal_bottom[1], left_diagonal_bottom[0],
+                colour
+            )
+            bottom_line = canvas.create_line(
+                left_diagonal_bottom[1], left_diagonal_bottom[0],
+                bottom_right_corner[1], bottom_right_corner[0],
+                colour
+            )
+            right_line = canvas.create_line(
+                right_diagonal_bottom[1], right_diagonal_bottom[0],
+                bottom_right_corner[1], bottom_right_corner[0],
+                colour
+            )
+            left_leg = canvas.create_rectangle(
+                leftLeg_top,
+                leftLeg_right,
+                leftLeg_bottom,
+                leftLeg_left,
+                colour,
+                colour
+            )
+            left_foot = canvas.create_rectangle(
+                leftFoot_top,
+                leftFoot_right,
+                leftFoot_bottom,
+                leftFoot_left,
+                colour,
+                colour
+            )
+            right_leg = canvas.create_rectangle(
+                rightLeg_top,
+                rightLeg_right,
+                rightLeg_bottom,
+                rightLeg_left,
+                colour,
+                colour
+            )
+            right_foot = canvas.create_rectangle(
+                rightFoot_top,
+                rigthFoot_right,
+                rightFoot_bottom,
+                rightFoot_left,
+                colour,
+                colour
+            )
+            eye = canvas.create_rectangle(
+                eye_top,
+                eye_right,
+                eye_bottom,
+                eye_left,
+                "transparent",
+                colour,
+            )
+            mouth = canvas.create_line(
+                mouth_left_corner[1], mouth_left_corner[0],
+                mouth_right_corner[1], mouth_right_corner[0],
+                colour
+            )
+
+    # Return each object so it can later be altered/destroyed
+    if transparent:
+        shapes = {
+            "top_line": top_line,
+            "top_corner": top_corner,
+            "left_line": left_line,
+            "bottom_corner": bottom_corner,
+            "bottom_line": bottom_line,
+            "right_line": right_line,
+            "left_leg": left_leg,
+            "left_foot": left_foot,
+            "right_foot": right_foot,
+            "right_leg": right_leg,
+            "right_foot": right_foot,
+            "eye": eye,
+            "mouth": mouth
+        }
+    else:   # Not transparent
+        shapes = {
+            "top_fill": top_fill,
+            "top_corner_fill": top_corner_fill,
+            "left_fill": left_fill,
+            "right_fill": right_fill,
+            "bottom_fill": bottom_fill,
+            "bottom_corner_fill": bottom_corner_fill,
+            "top_line": top_line,
+            "top_corner": top_corner,
+            "left_line": left_line,
+            "bottom_corner": bottom_corner,
+            "bottom_line": bottom_line,
+            "right_line": right_line,
+            "left_leg": left_leg,
+            "left_foot": left_foot,
+            "right_foot": right_foot,
+            "right_leg": right_leg,
+            "right_foot": right_foot,
+            "eye": eye,
+            "mouth": mouth
+        }
+
+    arguments = [canvas, centre_x, centre_y, size, orientation.lower(), colour, background, transparent]
+    logger.debug(f"Created Karel: {shapes, arguments}")
+    return [shapes, arguments]