|
|
@@ -0,0 +1,248 @@
|
|
|
+from karel.stanfordkarel import *
|
|
|
+"""
|
|
|
+Inspired by John Conways "Game of Life" and "Biogenesis" by Joan Queralt Molina.
|
|
|
+
|
|
|
+The three phases of life start with Karel seeding a few fountains of youth, represented by beepers on black patches of "land".
|
|
|
+
|
|
|
+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.
|
|
|
+
|
|
|
+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.
|
|
|
+
|
|
|
+TIP: Run at top speed to spare your own life from wasting away...
|
|
|
+"""
|
|
|
+
|
|
|
+## 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()
|
|
|
+
|
|
|
+ # Make sure not to face an obstruction
|
|
|
+ while front_is_blocked():
|
|
|
+ turn_left()
|
|
|
+
|
|
|
+
|
|
|
+## Main functions:
|
|
|
+# According to biologists, the sole goal of life.
|
|
|
+def reproduce():
|
|
|
+ move()
|
|
|
+ if no_beepers_present(): # Unseeded tile
|
|
|
+
|
|
|
+ # Seed life
|
|
|
+ paint_corner("black")
|
|
|
+ put_beeper()
|
|
|
+
|
|
|
+ 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.
|
|
|
+
|
|
|
+ # Never leave Karel facign a wall:
|
|
|
+ orient()
|
|
|
+
|
|
|
+def die():
|
|
|
+ # Permanent death:
|
|
|
+ if random(0.2): # 20% chance
|
|
|
+ paint_corner("white")
|
|
|
+ pick_beeper()
|
|
|
+
|
|
|
+ # 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()
|
|
|
+
|
|
|
+ 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()
|
|
|
+
|
|
|
+ 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 ascention():
|
|
|
+ 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()
|
|
|
+ ascention() # The script should not run forever, making some unintended biblical implications...
|
|
|
+
|
|
|
+
|
|
|
+# don't change this code
|
|
|
+if __name__ == '__main__':
|
|
|
+ main()
|